Wire in file image support

Change-Id: If729c8cde28186dc28ec994ddd23c981c9313fe2
Story: #2002048
Task: #26380
This commit is contained in:
Dmitry Tantsur 2018-09-12 12:42:03 +02:00
parent fc85cb9230
commit 98ad1d86cd
4 changed files with 129 additions and 3 deletions

View File

@ -73,6 +73,23 @@ def _do_deploy(api, args, formatter):
**kwargs)
else:
source = sources.HttpWholeDiskImage(args.image, **kwargs)
elif args.image.startswith('file://'):
if not args.image_checksum:
raise RuntimeError("File images require --image-checksum")
if args.image_kernel or args.image_ramdisk:
if not (args.image_kernel.startswith('file://') and
args.image_ramdisk.startswith('file://')):
raise RuntimeError('Images with the file:// schema require '
'kernel and ramdisk images to also use '
'the file:// schema')
source = sources.FilePartitionImage(args.image,
args.image_kernel,
args.image_ramdisk,
args.image_checksum)
else:
source = sources.FileWholeDiskImage(args.image,
args.image_checksum)
else:
source = args.image
@ -152,8 +169,10 @@ def _parse_args(args, config):
required=True)
deploy.add_argument('--image-checksum',
help='image MD5 checksum or URL with checksums')
deploy.add_argument('--image-kernel', help='URL of the image\'s kernel')
deploy.add_argument('--image-ramdisk', help='URL of the image\'s ramdisk')
deploy.add_argument('--image-kernel', help='URL of the image\'s kernel',
default='')
deploy.add_argument('--image-ramdisk', help='URL of the image\'s ramdisk',
default='')
deploy.add_argument('--network', help='network to use (name or UUID)',
dest='nics', action=NICAction)
deploy.add_argument('--port', help='port to attach (name or UUID)',

View File

@ -208,7 +208,7 @@ class FileWholeDiskImage(_Source):
}
class FilePartitionImage(_Source):
class FilePartitionImage(FileWholeDiskImage):
"""A partition image from a local file location.
.. warning::

View File

@ -393,6 +393,54 @@ class TestDeploy(testtools.TestCase):
self.assertEqual('https://example.com/ramdisk', source.ramdisk_url)
self.assertEqual('95e750180c7921ea0d545c7165db66b8', source.checksum)
def test_args_file_whole_disk_image(self, mock_pr):
args = ['deploy', '--image', 'file:///var/lib/ironic/image.img',
'--image-checksum', '95e750180c7921ea0d545c7165db66b8',
'--network', 'mynet', '--resource-class', 'compute']
self._check(mock_pr, args, {}, {'image': mock.ANY})
source = mock_pr.return_value.provision_node.call_args[1]['image']
self.assertIsInstance(source, sources.FileWholeDiskImage)
self.assertEqual('file:///var/lib/ironic/image.img', source.location)
self.assertEqual('95e750180c7921ea0d545c7165db66b8', source.checksum)
def test_args_file_partition_disk_image(self, mock_pr):
args = ['deploy', '--image', 'file:///var/lib/ironic/image.img',
'--image-kernel', 'file:///var/lib/ironic/image.vmlinuz',
'--image-ramdisk', 'file:///var/lib/ironic/image.initrd',
'--image-checksum', '95e750180c7921ea0d545c7165db66b8',
'--network', 'mynet', '--resource-class', 'compute']
self._check(mock_pr, args, {}, {'image': mock.ANY})
source = mock_pr.return_value.provision_node.call_args[1]['image']
self.assertIsInstance(source, sources.FilePartitionImage)
self.assertEqual('file:///var/lib/ironic/image.img', source.location)
self.assertEqual('file:///var/lib/ironic/image.vmlinuz',
source.kernel_location)
self.assertEqual('file:///var/lib/ironic/image.initrd',
source.ramdisk_location)
self.assertEqual('95e750180c7921ea0d545c7165db66b8', source.checksum)
@mock.patch.object(_cmd.LOG, 'critical', autospec=True)
def test_args_file_image_without_checksum(self, mock_log, mock_pr):
args = ['deploy', '--image', 'file:///var/lib/ironic/image.img',
'--resource-class', 'compute']
self.assertRaises(SystemExit, _cmd.main, args)
self.assertTrue(mock_log.called)
self.assertFalse(mock_pr.return_value.reserve_node.called)
self.assertFalse(mock_pr.return_value.provision_node.called)
@mock.patch.object(_cmd.LOG, 'critical', autospec=True)
def test_args_file_image_with_incorrect_kernel(self, mock_log, mock_pr):
args = ['deploy', '--image', 'file:///var/lib/ironic/image.img',
'--image-kernel', 'http://example.com/image.vmlinuz',
'--image-checksum', '95e750180c7921ea0d545c7165db66b8',
'--resource-class', 'compute']
self.assertRaises(SystemExit, _cmd.main, args)
self.assertTrue(mock_log.called)
self.assertFalse(mock_pr.return_value.reserve_node.called)
self.assertFalse(mock_pr.return_value.provision_node.called)
def test_args_custom_wait(self, mock_pr):
args = ['deploy', '--network', 'mynet', '--image', 'myimg',
'--wait', '3600', '--resource-class', 'compute']

View File

@ -585,6 +585,65 @@ abcd image
self.assertFalse(self.api.release_node.called)
self.assertFalse(self.conn.network.delete_port.called)
def test_with_file_whole_disk(self):
self.updates['/instance_info/image_source'] = 'file:///foo/img'
self.updates['/instance_info/image_checksum'] = 'abcd'
del self.updates['/instance_info/kernel']
del self.updates['/instance_info/ramdisk']
inst = self.pr.provision_node(
self.node,
sources.FileWholeDiskImage('file:///foo/img', checksum='abcd'),
[{'network': 'network'}])
self.assertEqual(inst.uuid, self.node.uuid)
self.assertEqual(inst.node, self.node)
self.assertFalse(self.conn.image.find_image.called)
self.conn.network.create_port.assert_called_once_with(
network_id=self.conn.network.find_network.return_value.id)
self.api.attach_port_to_node.assert_called_once_with(
self.node.uuid, self.conn.network.create_port.return_value.id)
self.api.update_node.assert_called_once_with(self.node, self.updates)
self.api.validate_node.assert_called_once_with(self.node,
validate_deploy=True)
self.api.node_action.assert_called_once_with(self.node, 'active',
configdrive=mock.ANY)
self.assertFalse(self.wait_mock.called)
self.assertFalse(self.api.release_node.called)
self.assertFalse(self.conn.network.delete_port.called)
def test_with_file_partition(self):
self.updates['/instance_info/image_source'] = 'file:///foo/img'
self.updates['/instance_info/image_checksum'] = 'abcd'
self.updates['/instance_info/kernel'] = 'file:///foo/vmlinuz'
self.updates['/instance_info/ramdisk'] = 'file:///foo/initrd'
inst = self.pr.provision_node(
self.node,
sources.FilePartitionImage('/foo/img',
'/foo/vmlinuz',
'/foo/initrd',
checksum='abcd'),
[{'network': 'network'}])
self.assertEqual(inst.uuid, self.node.uuid)
self.assertEqual(inst.node, self.node)
self.assertFalse(self.conn.image.find_image.called)
self.conn.network.create_port.assert_called_once_with(
network_id=self.conn.network.find_network.return_value.id)
self.api.attach_port_to_node.assert_called_once_with(
self.node.uuid, self.conn.network.create_port.return_value.id)
self.api.update_node.assert_called_once_with(self.node, self.updates)
self.api.validate_node.assert_called_once_with(self.node,
validate_deploy=True)
self.api.node_action.assert_called_once_with(self.node, 'active',
configdrive=mock.ANY)
self.assertFalse(self.wait_mock.called)
self.assertFalse(self.api.release_node.called)
self.assertFalse(self.conn.network.delete_port.called)
def test_with_root_size(self):
self.updates['/instance_info/root_gb'] = 50