def test_generic_get_deploy_patch_traits_ignores_not_required(self): node = ironic_utils.get_test_node(driver='fake') self.flavor['extra_specs']['trait:CUSTOM_FOO'] = 'invalid' expected = self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def _cleanup_deploy(self, context, node, instance, network_info, flavor=None): if flavor is None: flavor = instance.flavor patch = patcher.create(node).get_cleanup_patch(instance, network_info, flavor) # Unassociate the node patch.append({'op': 'remove', 'path': '/instance_uuid'}) try: self.ironicclient.call('node.update', node.uuid, patch) except ironic.exc.BadRequest: LOG.error( _LE("Failed to clean up the parameters on node %(node)s " "when unprovisioning the instance %(instance)s"), { 'node': node.uuid, 'instance': instance.uuid }) reason = (_("Fail to clean up node %s parameters") % node.uuid) raise exception.InstanceTerminationFailure(reason=reason) self._unplug_vifs(node, instance, network_info) self._stop_firewall(instance, network_info)
def _cleanup_deploy(self, context, node, instance, network_info, flavor=None): if flavor is None: # TODO(mrda): It would be better to use instance.get_flavor() here # but right now that doesn't include extra_specs which are required # NOTE(pmurray): Flavor may have been deleted ctxt = context.elevated(read_deleted="yes") flavor = objects.Flavor.get_by_id(ctxt, instance.instance_type_id) patch = patcher.create(node).get_cleanup_patch(instance, network_info, flavor) # Unassociate the node patch.append({'op': 'remove', 'path': '/instance_uuid'}) try: self.ironicclient.call('node.update', node.uuid, patch) except ironic.exc.BadRequest: LOG.error(_LE("Failed to clean up the parameters on node %(node)s " "when unprovisioning the instance %(instance)s"), {'node': node.uuid, 'instance': instance.uuid}) reason = (_("Fail to clean up node %s parameters") % node.uuid) raise exception.InstanceTerminationFailure(reason=reason) self._unplug_vifs(node, instance, network_info) self._stop_firewall(instance, network_info)
def _add_driver_fields(self, node, instance, image_meta, flavor, preserve_ephemeral=None): icli = client_wrapper.IronicClientWrapper() patch = patcher.create(node).get_deploy_patch(instance, image_meta, flavor, preserve_ephemeral) # Associate the node with an instance patch.append({ 'path': '/instance_uuid', 'op': 'add', 'value': instance['uuid'] }) try: icli.call('node.update', node.uuid, patch) except ironic.exc.BadRequest: msg = (_("Failed to add deploy parameters on node %(node)s " "when provisioning the instance %(instance)s") % { 'node': node.uuid, 'instance': instance['uuid'] }) LOG.error(msg) raise exception.InstanceDeployFailure(msg)
def _cleanup_deploy(self, context, node, instance, network_info): icli = client_wrapper.IronicClientWrapper() # TODO(mrda): It would be better to use instance.get_flavor() here # but right now that doesn't include extra_specs which are required flavor = objects.Flavor.get_by_id(context, instance['instance_type_id']) patch = patcher.create(node).get_cleanup_patch(instance, network_info, flavor) # Unassociate the node patch.append({'op': 'remove', 'path': '/instance_uuid'}) try: icli.call('node.update', node.uuid, patch) except ironic.exc.BadRequest: LOG.error( _LE("Failed to clean up the parameters on node %(node)s " "when unprovisioning the instance %(instance)s"), { 'node': node.uuid, 'instance': instance['uuid'] }) reason = (_("Fail to clean up node %s parameters") % node.uuid) raise exception.InstanceTerminationFailure(reason=reason) self._unplug_vifs(node, instance, network_info) self._stop_firewall(instance, network_info)
def test_generic_get_deploy_patch_image_flavor_traits_none(self): node = ironic_utils.get_test_node(driver='fake') self.image_meta.properties = objects.ImageMetaProps() expected = self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def _cleanup_deploy(self, context, node, instance, network_info, flavor=None): if flavor is None: flavor = instance.flavor patch = patcher.create(node).get_cleanup_patch(instance, network_info, flavor) # TODO(lucasagomes): This code is here for backwards compatibility # with old versions of Ironic that won't clean up the instance # association as part of the node's tear down. Should be removed # on the next cycle (M). patch.append({'op': 'remove', 'path': '/instance_uuid'}) try: self._validate_instance_and_node(instance) self.ironicclient.call('node.update', node.uuid, patch) except exception.InstanceNotFound: LOG.debug("Instance already removed from Ironic node %s. Skip " "updating it", node.uuid, instance=instance) except ironic.exc.BadRequest: LOG.error(_LE("Failed to clean up the parameters on node %(node)s " "when unprovisioning the instance %(instance)s"), {'node': node.uuid, 'instance': instance.uuid}) reason = (_("Fail to clean up node %s parameters") % node.uuid) raise exception.InstanceTerminationFailure(reason=reason) self._unplug_vifs(node, instance, network_info) self._stop_firewall(instance, network_info)
def test_pxe_get_cleanup_patch_no_flavor_kernel_ramdisk_ids(self): self.flavor = ironic_utils.get_test_flavor(extra_specs={}) node = ironic_utils.get_test_node(driver='pxe_fake') patch = patcher.create(node).get_cleanup_patch(self.instance, None, self.flavor) # If there's no extra_specs patch should be exactly like a # generic patch self.assertEqual(self._expected_cleanup_patch, patch)
def test_pxe_get_deploy_patch_no_flavor_kernel_ramdisk_ids(self): flavor = ironic_utils.get_test_flavor(extra_specs={}) node = ironic_utils.get_test_node(driver='pxe_fake') patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, flavor) # If there's no extra_specs patch should be exactly like a # generic patch self.assertEqual(sorted(self._expected_deploy_patch), sorted(patch))
def test_generic_get_deploy_patch_traits_ignores_not_required(self): node = ironic_utils.get_test_node(driver='fake') self.flavor['extra_specs']['trait:CUSTOM_FOO'] = 'invalid' expected = self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch(self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_boot_from_volume(self): node = ironic_utils.get_test_node(driver='fake') expected = [patch for patch in self._expected_deploy_patch if patch['path'] != '/instance_info/image_source'] patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor, boot_from_volume=True) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_image_flavor_traits_none(self): node = ironic_utils.get_test_node(driver='fake') self.image_meta.properties = objects.ImageMetaProps() expected = self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch(self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def test_pxe_get_cleanup_patch_no_flavor_kernel_ramdisk_ids(self): self.flavor = ironic_utils.get_test_flavor(extra_specs={}) driver_info = {'pxe_deploy_kernel': 'fake-kernel-id', 'pxe_deploy_ramdisk': 'fake-ramdisk-id'} node = ironic_utils.get_test_node(driver='pxe_fake', driver_info=driver_info) instance = fake_instance.fake_instance_obj(self.ctx, node=node.uuid) patch = patcher.create(node).get_cleanup_patch(instance, None, self.flavor) self.assertEqual([], patch)
def test_generic_get_deploy_patch_capabilities_op(self): node = ironic_utils.get_test_node(driver='fake') self.flavor['extra_specs']['capabilities:boot_mode'] = '<in> bios' expected = [{'path': '/instance_info/capabilities', 'value': '{"boot_mode": "<in> bios"}', 'op': 'add'}] expected += self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_preserve_ephemeral(self): node = ironic_utils.get_test_node(driver='fake') for preserve in [True, False]: patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor, preserve_ephemeral=preserve) expected = [{'path': '/instance_info/preserve_ephemeral', 'value': str(preserve), 'op': 'add', }] expected += self._expected_deploy_patch self.assertEqual(sorted(expected), sorted(patch))
def test_pxe_get_deploy_patch_no_preserve_ephemeral(self): node = ironic_utils.get_test_node(driver='pxe_fake') instance = fake_instance.fake_instance_obj( self.ctx, node=node.uuid, ephemeral_gb=10) patch = patcher.create(node).get_deploy_patch( instance, self.image_meta, self.flavor) for preserve in [True, False]: unexpected = {'path': '/instance_info/preserve_ephemeral', 'value': str(preserve), 'op': 'add', } self.assertNotIn(unexpected, patch)
def test_generic_get_deploy_patch_traits_granular(self): node = ironic_utils.get_test_node(driver='fake') self.flavor['extra_specs']['trait1:CUSTOM_FOO'] = 'required' expected = [{'path': '/instance_info/traits', 'value': ["CUSTOM_FOO"], 'op': 'add'}] expected += self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_preserve_ephemeral(self): node = ironic_utils.get_test_node(driver='fake') for preserve in [True, False]: patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor, preserve_ephemeral=preserve) expected = [{'path': '/instance_info/preserve_ephemeral', 'value': str(preserve), 'op': 'add', }] expected += self._expected_deploy_patch self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_capabilities_nested_key(self): node = ironic_utils.get_test_node(driver='fake') self.flavor['extra_specs']['capabilities:key1:key2'] = '<in> bios' expected = [{'path': '/instance_info/capabilities', 'value': '{"key1:key2": "<in> bios"}', 'op': 'add'}] expected += self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor) self.assertEqual(sorted(expected), sorted(patch))
def test_generic_get_deploy_patch_image_traits_required(self): node = ironic_utils.get_test_node(driver='fake') self.image_meta.properties = objects.ImageMetaProps( traits_required=['CUSTOM_TRUSTED']) expected = [{'path': '/instance_info/traits', 'value': ["CUSTOM_TRUSTED"], 'op': 'add'}] expected += self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def test_pxe_get_cleanup_patch(self): driver_info = {'pxe_deploy_kernel': 'fake-kernel-id', 'pxe_deploy_ramdisk': 'fake-ramdisk-id'} node = ironic_utils.get_test_node(driver='pxe_fake', driver_info=driver_info) patch = patcher.create(node).get_cleanup_patch(self.instance, None, self.flavor) expected = [{'path': '/driver_info/pxe_deploy_kernel', 'op': 'remove'}, {'path': '/driver_info/pxe_deploy_ramdisk', 'op': 'remove'}] self.assertEqual(sorted(expected), sorted(patch))
def test_pxe_get_deploy_patch_with_ephemeral(self): node = ironic_utils.get_test_node(driver='pxe_fake') instance = fake_instance.fake_instance_obj( self.ctx, node=node.uuid, ephemeral_gb=10) CONF.set_override('default_ephemeral_format', 'testfmt') patch = patcher.create(node).get_deploy_patch( instance, self.image_meta, self.flavor) expected1 = {'path': '/instance_info/ephemeral_gb', 'value': '10', 'op': 'add'} expected2 = {'path': '/instance_info/ephemeral_format', 'value': 'testfmt', 'op': 'add'} self.assertIn(expected1, patch) self.assertIn(expected2, patch)
def test_pxe_get_deploy_patch(self): node = ironic_utils.get_test_node(driver='pxe_fake') extra_specs = self.flavor['extra_specs'] expected = [{'path': '/driver_info/pxe_deploy_kernel', 'value': extra_specs['baremetal:deploy_kernel_id'], 'op': 'add'}, {'path': '/driver_info/pxe_deploy_ramdisk', 'value': extra_specs['baremetal:deploy_ramdisk_id'], 'op': 'add'}] expected += self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor) self.assertEqual(sorted(expected), sorted(patch))
def test_generic_get_deploy_patch_traits_granular(self): node = ironic_utils.get_test_node(driver='fake') self.flavor['extra_specs']['trait1:CUSTOM_FOO'] = 'required' expected = [{ 'path': '/instance_info/traits', 'value': '["CUSTOM_FOO"]', 'op': 'add' }] expected += self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch(self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def _add_driver_fields(self, node, instance, image_meta, flavor, preserve_ephemeral=None): icli = client_wrapper.IronicClientWrapper() patch = patcher.create(node).get_deploy_patch(instance, image_meta, flavor, preserve_ephemeral) # Associate the node with an instance patch.append({"path": "/instance_uuid", "op": "add", "value": instance["uuid"]}) try: icli.call("node.update", node.uuid, patch) except ironic.exc.BadRequest: msg = _( "Failed to add deploy parameters on node %(node)s " "when provisioning the instance %(instance)s" ) % {"node": node.uuid, "instance": instance["uuid"]} LOG.error(msg) raise exception.InstanceDeployFailure(msg)
def test_generic_get_deploy_patch_image_traits_required(self): node = ironic_utils.get_test_node(driver='fake') self.image_meta.properties = objects.ImageMetaProps( traits_required=['CUSTOM_TRUSTED']) expected = [{ 'path': '/instance_info/traits', 'value': ["CUSTOM_TRUSTED"], 'op': 'add' }] expected += self._expected_deploy_patch patch = patcher.create(node).get_deploy_patch(self.instance, self.image_meta, self.flavor) self.assertPatchEqual(expected, patch)
def test_generic_get_deploy_patch_ephemeral(self): CONF.set_override('default_ephemeral_format', 'testfmt') node = ironic_utils.get_test_node(driver='fake') instance = fake_instance.fake_instance_obj(self.ctx, ephemeral_gb=10) patch = patcher.create(node).get_deploy_patch( instance, self.image_meta, self.flavor) expected = [{'path': '/instance_info/ephemeral_gb', 'value': str(instance.ephemeral_gb), 'op': 'add'}, {'path': '/instance_info/ephemeral_format', 'value': 'testfmt', 'op': 'add'}] expected += self._expected_deploy_patch self.assertEqual(sorted(expected), sorted(patch))
def test_pxe_get_deploy_patch_no_flavor_kernel_ramdisk_ids(self): self.flavor = ironic_utils.get_test_flavor(extra_specs={}) node = ironic_utils.get_test_node(driver='pxe_fake') instance = fake_instance.fake_instance_obj(self.ctx, node=node.uuid) expected = [{'path': '/instance_info/image_source', 'value': self.image_meta['id'], 'op': 'add'}, {'path': '/instance_info/root_gb', 'value': str(instance['root_gb']), 'op': 'add'}, {'path': '/instance_info/swap_mb', 'value': str(self.flavor['swap']), 'op': 'add'}] patch = patcher.create(node).get_deploy_patch( instance, self.image_meta, self.flavor) self.assertEqual(sorted(expected), sorted(patch))
def test_generic_get_deploy_patch_boot_from_volume_image_traits_required( self): node = ironic_utils.get_test_node(driver='fake') self.image_meta.properties = objects.ImageMetaProps( traits_required=['CUSTOM_TRUSTED']) expected_deploy_patch_volume = [patch for patch in self._expected_deploy_patch if patch['path'] != '/instance_info/image_source'] expected = [{'path': '/instance_info/traits', 'value': ["CUSTOM_TRUSTED"], 'op': 'add'}] expected += expected_deploy_patch_volume patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor, boot_from_volume=True) self.assertPatchEqual(expected, patch)
def _add_driver_fields(self, node, instance, image_meta, flavor, preserve_ephemeral=None): patch = patcher.create(node).get_deploy_patch(instance, image_meta, flavor, preserve_ephemeral) # Associate the node with an instance patch.append({"path": "/instance_uuid", "op": "add", "value": instance.uuid}) try: # FIXME(lucasagomes): The "retry_on_conflict" parameter was added # to basically causes the deployment to fail faster in case the # node picked by the scheduler is already associated with another # instance due bug #1341420. self.ironicclient.call("node.update", node.uuid, patch, retry_on_conflict=False) except ironic.exc.BadRequest: msg = _( "Failed to add deploy parameters on node %(node)s " "when provisioning the instance %(instance)s" ) % {"node": node.uuid, "instance": instance.uuid} LOG.error(msg) raise exception.InstanceDeployFailure(msg)
def _add_driver_fields(self, node, instance, image_meta, flavor, preserve_ephemeral=None): patch = patcher.create(node).get_deploy_patch(instance, image_meta, flavor, preserve_ephemeral) # Associate the node with an instance patch.append({'path': '/instance_uuid', 'op': 'add', 'value': instance.uuid}) try: self.ironicclient.call('node.update', node.uuid, patch) except ironic.exc.BadRequest: msg = (_("Failed to add deploy parameters on node %(node)s " "when provisioning the instance %(instance)s") % {'node': node.uuid, 'instance': instance.uuid}) LOG.error(msg) raise exception.InstanceDeployFailure(msg)
def _cleanup_deploy(self, node, instance, network_info): icli = client_wrapper.IronicClientWrapper() flavor = instance.get_flavor() patch = patcher.create(node).get_cleanup_patch(instance, network_info, flavor) # Unassociate the node patch.append({'op': 'remove', 'path': '/instance_uuid'}) try: icli.call('node.update', node.uuid, patch) except ironic.exc.BadRequest: LOG.error(_LE("Failed to clean up the parameters on node %(node)s " "when unprovisioning the instance %(instance)s"), {'node': node.uuid, 'instance': instance['uuid']}) reason = (_("Fail to clean up node %s parameters") % node.uuid) raise exception.InstanceTerminationFailure(reason=reason) self._unplug_vifs(node, instance, network_info) self._stop_firewall(instance, network_info)
def test_generic_get_deploy_patch_boot_from_volume_image_traits_required( self): node = ironic_utils.get_test_node(driver='fake') self.image_meta.properties = objects.ImageMetaProps( traits_required=['CUSTOM_TRUSTED']) expected_deploy_patch_volume = [ patch for patch in self._expected_deploy_patch if patch['path'] != '/instance_info/image_source' ] expected = [{ 'path': '/instance_info/traits', 'value': ["CUSTOM_TRUSTED"], 'op': 'add' }] expected += expected_deploy_patch_volume patch = patcher.create(node).get_deploy_patch(self.instance, self.image_meta, self.flavor, boot_from_volume=True) self.assertPatchEqual(expected, patch)
def _cleanup_deploy(self, node, instance, network_info): icli = client_wrapper.IronicClientWrapper() context = nova_context.get_admin_context() flavor = flavor_obj.Flavor.get_by_id(context, instance['instance_type_id']) patch = patcher.create(node).get_cleanup_patch(instance, network_info, flavor) # Unassociate the node patch.append({'op': 'remove', 'path': '/instance_uuid'}) try: icli.call('node.update', node.uuid, patch) except ironic_exception.BadRequest: msg = (_("Failed clean up the parameters on node %(node)s " "when unprovisioning the instance %(instance)s") % {'node': node.uuid, 'instance': instance['uuid']}) LOG.error(msg) reason = _("Fail to clean up node %s parameters") % node.uuid raise exception.InstanceTerminationFailure(reason=reason) self._unplug_vifs(node, instance, network_info) self._stop_firewall(instance, network_info)
def _cleanup_deploy(self, context, node, instance, network_info): icli = client_wrapper.IronicClientWrapper() # TODO(mrda): It would be better to use instance.get_flavor() here # but right now that doesn't include extra_specs which are required flavor = objects.Flavor.get_by_id(context, instance['instance_type_id']) patch = patcher.create(node).get_cleanup_patch(instance, network_info, flavor) # Unassociate the node patch.append({'op': 'remove', 'path': '/instance_uuid'}) try: icli.call('node.update', node.uuid, patch) except ironic.exc.BadRequest: LOG.error(_LE("Failed to clean up the parameters on node %(node)s " "when unprovisioning the instance %(instance)s"), {'node': node.uuid, 'instance': instance['uuid']}) reason = (_("Fail to clean up node %s parameters") % node.uuid) raise exception.InstanceTerminationFailure(reason=reason) self._unplug_vifs(node, instance, network_info) self._stop_firewall(instance, network_info)
def _add_driver_fields(self, node, instance, image_meta, flavor, preserve_ephemeral=None): patch = patcher.create(node).get_deploy_patch(instance, image_meta, flavor, preserve_ephemeral) # Associate the node with an instance patch.append({'path': '/instance_uuid', 'op': 'add', 'value': instance.uuid}) try: # FIXME(lucasagomes): The "retry_on_conflict" parameter was added # to basically causes the deployment to fail faster in case the # node picked by the scheduler is already associated with another # instance due bug #1341420. self.ironicclient.call('node.update', node.uuid, patch, retry_on_conflict=False) except ironic.exc.BadRequest: msg = (_("Failed to add deploy parameters on node %(node)s " "when provisioning the instance %(instance)s") % {'node': node.uuid, 'instance': instance.uuid}) LOG.error(msg) raise exception.InstanceDeployFailure(msg)
def test_generic_get_cleanup_patch(self): node = ironic_utils.get_test_node(driver='fake') patch = patcher.create(node).get_cleanup_patch(self.instance, None, self.flavor) self.assertEqual(self._expected_cleanup_patch, patch)
def test_generic_get_deploy_patch(self): node = ironic_utils.get_test_node(driver='fake') patch = patcher.create(node).get_deploy_patch( self.instance, self.image_meta, self.flavor) self.assertEqual(sorted(self._expected_deploy_patch), sorted(patch))
def test_generic_get_deploy_patch(self): node = ironic_utils.get_test_node(driver='fake') patch = patcher.create(node).get_deploy_patch(self.instance, self.image_meta, self.flavor) self.assertPatchEqual(self._expected_deploy_patch, patch)
def test_create_generic(self): node = ironic_utils.get_test_node(driver='fake') patcher_obj = patcher.create(node) self.assertIsInstance(patcher_obj, patcher.GenericDriverFields)
def test_create_pxe(self): node = ironic_utils.get_test_node(driver='pxe_fake') patcher_obj = patcher.create(node) self.assertIsInstance(patcher_obj, patcher.PXEDriverFields)
def test_create_generic(self): node = ironic_utils.get_test_node(driver='pxe_fake') patcher_obj = patcher.create(node) self.assertIsInstance(patcher_obj, patcher.GenericDriverFields)