Set pool info on leaked instances

We need to set pool info on leaked instances so that they are properly
accounted for against quota. When a znode has provider details but not
pool details we can't count it against quota used but also don't count
it as unmanaged quota so end up in limbo.

To fix this we set pool info metadata so that when an instance leaks we
can recover the pool info and set it on the phony instance znode records
used to delete those instances.

Change-Id: Iba51655f7bf86987f9f88bb45059464f9f211ee9
This commit is contained in:
Clark Boylan 2020-04-20 15:45:18 -07:00
parent d63c833815
commit 257e26b0a4
3 changed files with 24 additions and 0 deletions

View File

@ -133,6 +133,7 @@ class OpenStackNodeLauncher(NodeLauncher):
nodepool_node_id=self.node.id,
nodepool_node_label=self.node.type[0],
nodepool_image_name=image_name,
nodepool_pool_name=self.node.pool,
networks=self.label.networks,
security_groups=self.pool.security_groups,
boot_from_volume=self.label.boot_from_volume,

View File

@ -290,6 +290,7 @@ class OpenStackProvider(Provider):
az=None, key_name=None, config_drive=True,
nodepool_node_id=None, nodepool_node_label=None,
nodepool_image_name=None,
nodepool_pool_name=None,
networks=None, security_groups=None,
boot_from_volume=False, volume_size=50,
instance_properties=None, userdata=None):
@ -338,6 +339,7 @@ class OpenStackProvider(Provider):
meta = dict(
groups=",".join(groups_list),
nodepool_provider_name=self.provider.name,
nodepool_pool_name=nodepool_pool_name,
)
# merge in any provided properties
if instance_properties:
@ -533,6 +535,7 @@ class OpenStackProvider(Provider):
node = zk.Node()
node.external_id = server.id
node.provider = self.provider.name
node.pool = meta.get('nodepool_pool_name')
node.state = zk.DELETING
self._zk.storeNode(node)

View File

@ -495,6 +495,26 @@ class TestLauncher(tests.DBTestCase):
self.assertEqual(nodes[0].attributes,
{'key1': 'value1', 'key2': 'value2'})
def test_node_metadata(self):
"""Test that node metadata is set"""
configfile = self.setup_config('node.yaml')
pool = self.useNodepool(configfile, watermark_sleep=1)
self.useBuilder(configfile)
pool.start()
image = self.waitForImage('fake-provider', 'fake-image')
self.assertEqual(image.username, 'zuul')
nodes = self.waitForNodes('fake-label')
self.assertEqual(len(nodes), 1)
# We check the "cloud" side attributes are set from nodepool side
provider = pool.getProviderManager('fake-provider')
cloud_node = provider.getServer(nodes[0].hostname)
self.assertEqual(
cloud_node.metadata['nodepool_provider_name'],
'fake-provider')
self.assertEqual(cloud_node.metadata['nodepool_pool_name'], 'main')
def test_node_network_cli(self):
"""Same as test_node but using connection-type network_cli"""
configfile = self.setup_config('node-network_cli.yaml')