Refactor: use convert_image from ironic_lib
Change-Id: If890baf3545cff6cef7c645c42e7f9d9038c9aa7
This commit is contained in:
		@@ -23,7 +23,6 @@ from ironic_lib import exception
 | 
				
			|||||||
from oslo_concurrency import processutils
 | 
					from oslo_concurrency import processutils
 | 
				
			||||||
from oslo_config import cfg
 | 
					from oslo_config import cfg
 | 
				
			||||||
from oslo_log import log
 | 
					from oslo_log import log
 | 
				
			||||||
from oslo_utils import units
 | 
					 | 
				
			||||||
import requests
 | 
					import requests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ironic_python_agent import errors
 | 
					from ironic_python_agent import errors
 | 
				
			||||||
@@ -203,20 +202,8 @@ def _write_whole_disk_image(image, image_info, device):
 | 
				
			|||||||
               image, device]
 | 
					               image, device]
 | 
				
			||||||
    LOG.info('Writing image with command: {}'.format(' '.join(command)))
 | 
					    LOG.info('Writing image with command: {}'.format(' '.join(command)))
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        # TODO(dtantsur): switch to disk_utils.convert_image when it supports
 | 
					        disk_utils.convert_image(image, device, out_format='host_device',
 | 
				
			||||||
        # -t and -W flags and defaults to 2 GiB memory limit.
 | 
					                                 cache='directsync', out_of_order=True)
 | 
				
			||||||
        limits = processutils.ProcessLimits(address_space=2048 * units.Mi)
 | 
					 | 
				
			||||||
        # TODO(TheJulia): qemu-img uses a default of 8 * nCPU to determine
 | 
					 | 
				
			||||||
        # how many chunks of memory to allocate based upon the discussion in
 | 
					 | 
				
			||||||
        # https://bugzilla.redhat.com/show_bug.cgi?id=1892773.
 | 
					 | 
				
			||||||
        # Setting MALLOC_AREA_MAX=1 results in a process memory footprint of
 | 
					 | 
				
			||||||
        # ~250mb. Setting it to 3 will allow for multiple areas, but won't
 | 
					 | 
				
			||||||
        # greatly exceed the footprint.
 | 
					 | 
				
			||||||
        env_vars = {'MALLOC_ARENA_MAX': '3'}
 | 
					 | 
				
			||||||
        # Entirely disabling threading results in the same memory footprint
 | 
					 | 
				
			||||||
        # as 1 areana, but multiple threads are useful for performance
 | 
					 | 
				
			||||||
        # as the file could be fragmented/compressed.
 | 
					 | 
				
			||||||
        utils.execute(*command, prlimit=limits, env_variables=env_vars)
 | 
					 | 
				
			||||||
    except processutils.ProcessExecutionError as e:
 | 
					    except processutils.ProcessExecutionError as e:
 | 
				
			||||||
        raise errors.ImageWriteError(device, e.exit_code, e.stdout, e.stderr)
 | 
					        raise errors.ImageWriteError(device, e.exit_code, e.stdout, e.stderr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -169,22 +169,21 @@ class TestStandbyExtension(base.IronicAgentTest):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.fix_gpt_partition', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.fix_gpt_partition', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.trigger_device_rescan', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.trigger_device_rescan', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_python_agent.utils.execute', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.convert_image', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.udev_settle', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.udev_settle', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.destroy_disk_metadata', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.destroy_disk_metadata', autospec=True)
 | 
				
			||||||
    def test_write_image(self, wipe_mock, udev_mock, execute_mock,
 | 
					    def test_write_image(self, wipe_mock, udev_mock, convert_mock,
 | 
				
			||||||
                         rescan_mock, fix_gpt_mock):
 | 
					                         rescan_mock, fix_gpt_mock):
 | 
				
			||||||
        image_info = _build_fake_image_info()
 | 
					        image_info = _build_fake_image_info()
 | 
				
			||||||
        device = '/dev/sda'
 | 
					        device = '/dev/sda'
 | 
				
			||||||
        location = standby._image_location(image_info)
 | 
					        location = standby._image_location(image_info)
 | 
				
			||||||
        command = ['qemu-img', 'convert', '-t', 'directsync',
 | 
					 | 
				
			||||||
                   '-O', 'host_device', '-W', location, device]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        standby._write_image(image_info, device)
 | 
					        standby._write_image(image_info, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        execute_mock.assert_called_once_with(
 | 
					        convert_mock.assert_called_once_with(location, device,
 | 
				
			||||||
            *command, prlimit=mock.ANY,
 | 
					                                             out_format='host_device',
 | 
				
			||||||
            env_variables={'MALLOC_ARENA_MAX': '3'})
 | 
					                                             cache='directsync',
 | 
				
			||||||
 | 
					                                             out_of_order=True)
 | 
				
			||||||
        wipe_mock.assert_called_once_with(device, '')
 | 
					        wipe_mock.assert_called_once_with(device, '')
 | 
				
			||||||
        udev_mock.assert_called_once_with()
 | 
					        udev_mock.assert_called_once_with()
 | 
				
			||||||
        rescan_mock.assert_called_once_with(device)
 | 
					        rescan_mock.assert_called_once_with(device)
 | 
				
			||||||
@@ -192,10 +191,10 @@ class TestStandbyExtension(base.IronicAgentTest):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.fix_gpt_partition', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.fix_gpt_partition', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.trigger_device_rescan', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.trigger_device_rescan', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_python_agent.utils.execute', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.convert_image', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.udev_settle', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.udev_settle', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.destroy_disk_metadata', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.destroy_disk_metadata', autospec=True)
 | 
				
			||||||
    def test_write_image_gpt_fails(self, wipe_mock, udev_mock, execute_mock,
 | 
					    def test_write_image_gpt_fails(self, wipe_mock, udev_mock, convert_mock,
 | 
				
			||||||
                                   rescan_mock, fix_gpt_mock):
 | 
					                                   rescan_mock, fix_gpt_mock):
 | 
				
			||||||
        image_info = _build_fake_image_info()
 | 
					        image_info = _build_fake_image_info()
 | 
				
			||||||
        device = '/dev/sda'
 | 
					        device = '/dev/sda'
 | 
				
			||||||
@@ -203,13 +202,13 @@ class TestStandbyExtension(base.IronicAgentTest):
 | 
				
			|||||||
        fix_gpt_mock.side_effect = exception.InstanceDeployFailure
 | 
					        fix_gpt_mock.side_effect = exception.InstanceDeployFailure
 | 
				
			||||||
        standby._write_image(image_info, device)
 | 
					        standby._write_image(image_info, device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @mock.patch('ironic_python_agent.utils.execute', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.convert_image', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.udev_settle', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.udev_settle', autospec=True)
 | 
				
			||||||
    @mock.patch('ironic_lib.disk_utils.destroy_disk_metadata', autospec=True)
 | 
					    @mock.patch('ironic_lib.disk_utils.destroy_disk_metadata', autospec=True)
 | 
				
			||||||
    def test_write_image_fails(self, wipe_mock, udev_mock, execute_mock):
 | 
					    def test_write_image_fails(self, wipe_mock, udev_mock, convert_mock):
 | 
				
			||||||
        image_info = _build_fake_image_info()
 | 
					        image_info = _build_fake_image_info()
 | 
				
			||||||
        device = '/dev/sda'
 | 
					        device = '/dev/sda'
 | 
				
			||||||
        execute_mock.side_effect = processutils.ProcessExecutionError
 | 
					        convert_mock.side_effect = processutils.ProcessExecutionError
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.assertRaises(errors.ImageWriteError,
 | 
					        self.assertRaises(errors.ImageWriteError,
 | 
				
			||||||
                          standby._write_image,
 | 
					                          standby._write_image,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,6 @@ pyudev>=0.18 # LGPLv2.1+
 | 
				
			|||||||
requests>=2.14.2 # Apache-2.0
 | 
					requests>=2.14.2 # Apache-2.0
 | 
				
			||||||
stevedore>=1.20.0 # Apache-2.0
 | 
					stevedore>=1.20.0 # Apache-2.0
 | 
				
			||||||
tenacity>=6.2.0 # Apache-2.0
 | 
					tenacity>=6.2.0 # Apache-2.0
 | 
				
			||||||
ironic-lib>=4.5.0 # Apache-2.0
 | 
					ironic-lib>=4.7.1 # Apache-2.0
 | 
				
			||||||
Werkzeug>=1.0.1 # BSD License
 | 
					Werkzeug>=1.0.1 # BSD License
 | 
				
			||||||
cryptography>=2.3 # BSD/Apache-2.0
 | 
					cryptography>=2.3 # BSD/Apache-2.0
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user