From 2e691d797142984e9c9d6b834465789f8a485443 Mon Sep 17 00:00:00 2001 From: Jim Rollenhagen Date: Mon, 21 Apr 2014 10:44:49 -0700 Subject: [PATCH] Check configdrive size before writing to partition Avoids writing a configdrive out to disk that is larger than the intended partition. Change-Id: I4e067ccb23ba528d96e4faad39219f67b4178e82 --- ironic_python_agent/errors.py | 11 ++++++++++ ironic_python_agent/extensions/standby.py | 5 +++++ .../tests/extensions/standby.py | 21 ++++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/ironic_python_agent/errors.py b/ironic_python_agent/errors.py index 4223ab9f7..151d8ceaa 100644 --- a/ironic_python_agent/errors.py +++ b/ironic_python_agent/errors.py @@ -151,6 +151,17 @@ class ImageWriteError(RESTError): self.details = self.details.format(device, exit_code) +class ConfigDriveTooLargeError(RESTError): + """Error raised when a configdrive is larger than the partition.""" + message = 'Configdrive is too large for intended partition.' + + def __init__(self, filename, filesize): + details = ('Configdrive at {0} has size {1}, which is larger than ' + 'the intended partition.').format(filename, filesize) + super(ConfigDriveTooLargeError, self).__init__(details) + self.details = details + + class ConfigDriveWriteError(RESTError): """Error raised when a configdrive directory cannot be written to a device. diff --git a/ironic_python_agent/extensions/standby.py b/ironic_python_agent/extensions/standby.py index 17c031c78..906f8fd57 100644 --- a/ironic_python_agent/extensions/standby.py +++ b/ironic_python_agent/extensions/standby.py @@ -72,6 +72,11 @@ def _write_configdrive_to_partition(configdrive, device): filename = _configdrive_location() _write_configdrive_to_file(configdrive, filename) + # check configdrive size before writing it + filesize = os.stat(filename).st_size + if filesize > (64 * 1024 * 1024): + raise errors.ConfigDriveTooLargeError(filename, filesize) + starttime = time.time() script = _path_to_script('shell/copy_configdrive_to_disk.sh') command = ['/bin/bash', script, filename, device] diff --git a/ironic_python_agent/tests/extensions/standby.py b/ironic_python_agent/tests/extensions/standby.py index a1449d0d5..24cb7c852 100644 --- a/ironic_python_agent/tests/extensions/standby.py +++ b/ironic_python_agent/tests/extensions/standby.py @@ -140,18 +140,20 @@ class TestStandbyExtension(test_base.BaseTestCase): gzip_read_mock.assert_called_once_with() write_mock.assert_called_once_with('ungzipped') + @mock.patch('os.stat', autospec=True) @mock.patch(('ironic_python_agent.extensions.standby.' '_write_configdrive_to_file'), autospec=True) @mock.patch(OPEN_FUNCTION_NAME, autospec=True) @mock.patch('ironic_python_agent.utils.execute', autospec=True) def test_write_configdrive_to_partition(self, execute_mock, open_mock, - configdrive_mock): + configdrive_mock, stat_mock): device = '/dev/sda' configdrive = standby._configdrive_location() script = standby._path_to_script('shell/copy_configdrive_to_disk.sh') command = ['/bin/bash', script, configdrive, device] execute_mock.return_value = 0 + stat_mock.return_value.st_size = 5 standby._write_configdrive_to_partition(configdrive, device) execute_mock.assert_called_once_with(*command) @@ -166,6 +168,23 @@ class TestStandbyExtension(test_base.BaseTestCase): execute_mock.assert_called_once_with(*command) + @mock.patch('os.stat', autospec=True) + @mock.patch(('ironic_python_agent.extensions.standby.' + '_write_configdrive_to_file'), + autospec=True) + @mock.patch(OPEN_FUNCTION_NAME, autospec=True) + @mock.patch('ironic_python_agent.utils.execute', autospec=True) + def test_write_configdrive_too_large(self, execute_mock, open_mock, + configdrive_mock, stat_mock): + device = '/dev/sda' + configdrive = standby._configdrive_location() + stat_mock.return_value.st_size = 65 * 1024 * 1024 + + self.assertRaises(errors.ConfigDriveTooLargeError, + standby._write_configdrive_to_partition, + configdrive, + device) + @mock.patch('hashlib.md5', autospec=True) @mock.patch(OPEN_FUNCTION_NAME, autospec=True) @mock.patch('requests.get', autospec=True)