Merge "Support image uploads in 'info' CLI command"

This commit is contained in:
Zuul 2020-04-07 22:02:52 +00:00 committed by Gerrit Code Review
commit cdcedc63be
4 changed files with 80 additions and 14 deletions

View File

@ -316,16 +316,19 @@ class NodePoolCmd(NodepoolApp):
def info(self):
provider_name = self.args.provider
provider_builds = self.zk.getProviderBuilds(provider_name)
provider_uploads = self.zk.getProviderUploads(provider_name)
provider_nodes = self.zk.getProviderNodes(provider_name)
print("ZooKeeper data for provider %s\n" % provider_name)
print("Image builds:")
t = PrettyTable(['Image Name', 'Build IDs'])
print("Image data:")
t = PrettyTable(['Image Name', 'Build ID', 'Upload IDs'])
t.align = 'l'
for image, builds in provider_builds.items():
t.add_row([image, ','.join(builds)])
for image in sorted(provider_uploads):
for build in sorted(provider_uploads[image]):
uploads = provider_uploads[image][build]
upload_ids = sorted([u.id for u in uploads])
t.add_row([image, build, ','.join(upload_ids)])
print(t)
print("\nNodes:")

View File

@ -51,7 +51,7 @@ class TestNodepoolCMD(tests.DBTestCase):
if col_count:
self.assertEquals(len(row), col_count)
log.debug(row)
if row[col] == val:
if col < len(row) and row[col] == val:
rows_with_val += 1
self.assertEquals(rows_with_val, count)
break
@ -320,6 +320,7 @@ class TestNodepoolCMD(tests.DBTestCase):
self.useBuilder(configfile)
pool.start()
p1_image = self.waitForImage('fake-provider', 'fake-image')
p2_image = self.waitForImage('fake-provider2', 'fake-image')
p1_nodes = self.waitForNodes('fake-label')
p2_nodes = self.waitForNodes('fake-label2')
@ -328,33 +329,47 @@ class TestNodepoolCMD(tests.DBTestCase):
# recreate the data.
self.replace_config(configfile, 'info_cmd_two_provider_remove.yaml')
IMAGE_NAME_COL = 0
BUILD_ID_COL = 1
UPLOAD_ID_COL = 2
NODE_ID_COL = 0
# Verify that the second provider image is listed
self.assert_listed(
configfile,
['info', 'fake-provider2'],
0, 'fake-image', 1)
# Verify that the second provider node is listed.
IMAGE_NAME_COL, 'fake-image', 1)
self.assert_listed(
configfile,
['info', 'fake-provider2'],
0, p2_nodes[0].id, 1)
BUILD_ID_COL, p2_image.build_id, 1)
self.assert_listed(
configfile,
['info', 'fake-provider2'],
UPLOAD_ID_COL, p2_image.id, 1)
# Verify that the second provider node is listed in the second table.
self.assert_listed(
configfile,
['info', 'fake-provider2'],
NODE_ID_COL, p2_nodes[0].id, 1)
# Erase the data for the second provider
self.patch_argv(
"-c", configfile, 'erase', 'fake-provider2', '--force')
nodepoolcmd.main()
# Verify that no build or node for the second provider is listed
# after the previous erase
# Verify that no image or node for the second provider is listed
# after the previous erase. With no build data, the image name should
# not even show up.
self.assert_listed(
configfile,
['info', 'fake-provider2'],
0, 'fake-image', 0)
IMAGE_NAME_COL, 'fake-image', 0)
self.assert_listed(
configfile,
['info', 'fake-provider2'],
0, p2_nodes[0].id, 0)
NODE_ID_COL, p2_nodes[0].id, 0)
# Verify that we did not affect the first provider
image = self.waitForImage('fake-provider', 'fake-image')

View File

@ -373,6 +373,25 @@ class TestZooKeeper(tests.DBTestCase):
d = self.zk.getMostRecentImageUpload(image, provider, zk.READY)
self.assertEqual(upload2.state_time, d.state_time)
def test_getProviderUploads(self):
image = "ubuntu-trusty"
provider = "rax"
build = zk.ImageBuild()
build.state = zk.READY
bnum = self.zk.storeBuild(image, build)
upload = zk.ImageUpload()
upload.state = zk.READY
upnum = self.zk.storeImageUpload(image, bnum, provider, upload)
d = self.zk.getProviderUploads(provider)
self.assertIn(image, d)
self.assertIn(bnum, d[image])
self.assertEqual(1, len(d[image][bnum]))
self.assertIsInstance(d[image][bnum][0], zk.ImageUpload)
self.assertEqual(upnum, d[image][bnum][0].id)
def test_getBuilds_any(self):
image = "ubuntu-trusty"
path = self.zk._imageBuildsPath(image)

View File

@ -2184,6 +2184,35 @@ class ZooKeeper(object):
provider_builds[image].append(build)
return provider_builds
def getProviderUploads(self, provider_name):
'''
Get all uploads for a provider for each image.
:param str provider_name: The provider name.
:returns: A dict, keyed by image name and build ID, of a list of
ImageUpload objects.
'''
provider_uploads = {}
image_names = self.getImageNames()
for image in image_names:
build_numbers = self.getBuildNumbers(image)
for build in build_numbers:
# If this build is not valid for this provider, move along.
if provider_name not in self.getBuildProviders(image, build):
continue
# We've determined that we at least have a build for this
# provider so init with an empty upload list.
if image not in provider_uploads:
provider_uploads[image] = {}
provider_uploads[image][build] = []
# Add any uploads we might have for this provider.
uploads = self.getUploads(image, build, provider_name)
for upload in uploads:
provider_uploads[image][build].append(upload)
return provider_uploads
def getProviderNodes(self, provider_name):
'''
Get all nodes for a provider.