Browse Source

Ensure instance_info is clean before deploy and after failure

Currently stale values can be left in instance_info (and reused next time)
if a deployment attempts fails. This change ensures that we:
1) Purge instance_info completely on failures
2) Only keep traits and capabilities in instance_info on deploy.

Change-Id: I52a85620d9ac2f471bca6498294871f3bb16d47f
tags/0.12.0
Dmitry Tantsur 3 months ago
parent
commit
8e7b8d3f39

+ 11
- 8
metalsmith/_provisioner.py View File

@@ -34,6 +34,7 @@ LOG = logging.getLogger(__name__)
34 34
 
35 35
 _CREATED_PORTS = 'metalsmith_created_ports'
36 36
 _ATTACHED_PORTS = 'metalsmith_attached_ports'
37
+_PRESERVE_INSTANCE_INFO_KEYS = {'capabilities', 'traits'}
37 38
 
38 39
 
39 40
 class Provisioner(_utils.GetNodeMixin):
@@ -279,7 +280,7 @@ class Provisioner(_utils.GetNodeMixin):
279 280
 
280 281
             capabilities['boot_option'] = 'netboot' if netboot else 'local'
281 282
 
282
-            instance_info = node.instance_info.copy()
283
+            instance_info = self._clean_instance_info(node.instance_info)
283 284
             instance_info['root_gb'] = root_size_gb
284 285
             instance_info['capabilities'] = capabilities
285 286
             instance_info[self.HOSTNAME_FIELD] = hostname
@@ -360,6 +361,11 @@ class Provisioner(_utils.GetNodeMixin):
360 361
             nodes, 'active', timeout=timeout)
361 362
         return [_instance.Instance(self.connection, node) for node in nodes]
362 363
 
364
+    def _clean_instance_info(self, instance_info):
365
+        return {key: value
366
+                for key, value in instance_info.items()
367
+                if key in _PRESERVE_INSTANCE_INFO_KEYS}
368
+
363 369
     def _clean_up(self, node, nics=None):
364 370
         if nics is None:
365 371
             created_ports = node.extra.get(_CREATED_PORTS, [])
@@ -372,17 +378,14 @@ class Provisioner(_utils.GetNodeMixin):
372 378
         extra = node.extra.copy()
373 379
         for item in (_CREATED_PORTS, _ATTACHED_PORTS):
374 380
             extra.pop(item, None)
375
-        instance_info = node.instance_info.copy()
376
-        instance_info.pop(self.HOSTNAME_FIELD, None)
377
-        LOG.debug('Updating node %(node)s with instance info %(iinfo)s '
378
-                  'and extras %(extra)s and releasing the lock',
381
+        LOG.debug('Updating node %(node)s with empty instance info (was '
382
+                  '%(iinfo)s) and extras %(extra)s and releasing the lock',
379 383
                   {'node': _utils.log_res(node),
380
-                   'iinfo': instance_info,
384
+                   'iinfo': node.instance_info,
381 385
                    'extra': extra})
382 386
         try:
383 387
             self.connection.baremetal.update_node(
384
-                node, instance_info=instance_info, extra=extra,
385
-                instance_id=None)
388
+                node, instance_info={}, extra=extra, instance_id=None)
386 389
         except Exception as exc:
387 390
             LOG.debug('Failed to clear node %(node)s extra: %(exc)s',
388 391
                       {'node': _utils.log_res(node), 'exc': exc})

+ 3
- 0
metalsmith/test/test_provisioner.py View File

@@ -505,6 +505,9 @@ class TestProvisionNode(Base):
505 505
         self.image.ramdisk_id = None
506 506
         del self.instance_info['kernel']
507 507
         del self.instance_info['ramdisk']
508
+        # Ensure stale values clean up
509
+        self.node.instance_info['kernel'] = 'bad value'
510
+        self.node.instance_info['ramdisk'] = 'bad value'
508 511
 
509 512
         self.pr.provision_node(self.node, 'image', [{'network': 'network'}])
510 513
 

+ 7
- 0
releasenotes/notes/iinfo-2014b1de4dbeca2d.yaml View File

@@ -0,0 +1,7 @@
1
+---
2
+fixes:
3
+  - |
4
+    Fixes stale ``instance_info`` remaining after deploy failures.
5
+  - |
6
+    Cleans up ``instance_info`` before updating it before deployment to make
7
+    sure not stale information is left there.

Loading…
Cancel
Save