From: Thanh Ha Date: Fri, 7 Sep 2018 03:06:18 +0000 (-0400) Subject: Add cmd to share openstack images X-Git-Tag: v0.18.0~9^2~1 X-Git-Url: https://gerrit.linuxfoundation.org/infra/gitweb?a=commitdiff_plain;h=50ce256a1e792c82f409c7b66b7b8bad1a9b5a37;p=releng%2Flftools.git Add cmd to share openstack images Allows us to more easily share images to multiple openstack tenants. Issue: RELENG-1201 Change-Id: I58dc200f7b29429ee1215bacdc533d234ad153fb Signed-off-by: Thanh Ha --- diff --git a/lftools/openstack/cmd.py b/lftools/openstack/cmd.py index a0b6c5f2..9cafdf3d 100644 --- a/lftools/openstack/cmd.py +++ b/lftools/openstack/cmd.py @@ -81,8 +81,18 @@ def list(ctx, days, hide_public, ci_managed): hide_public=hide_public) +@click.command() +@click.argument('image') +@click.argument('dest', nargs=-1) +@click.pass_context +def share(ctx, image, dest): + """Share image with another tenant.""" + os_image.share(ctx.obj['os_cloud'], image, dest) + + image.add_command(cleanup) image.add_command(list) +image.add_command(share) @openstack.group() diff --git a/lftools/openstack/image.py b/lftools/openstack/image.py index 5ca92592..4757a001 100644 --- a/lftools/openstack/image.py +++ b/lftools/openstack/image.py @@ -14,9 +14,14 @@ __author__ = 'Thanh Ha' from datetime import datetime from datetime import timedelta +import logging +import subprocess +import sys import shade +log = logging.getLogger(__name__) + def _filter_images(images, days=0, hide_public=False, ci_managed=True): """Filter image data and return list. @@ -100,3 +105,78 @@ def cleanup(os_cloud, days=0, hide_public=False, ci_managed=True, clouds=None): _remove_images_from_cloud(filtered_images, c) else: _remove_images_from_cloud(filtered_images, cloud) + + +def share(os_cloud, image, clouds): + """Share image with another tenant.""" + def _get_image_id(os_cloud, image): + cmd = ['openstack', '--os-cloud', os_cloud, 'image', 'list', + '--name', image, '-f', 'value', '-c', 'ID'] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + log.debug('exit code: {}'.format(p.returncode)) + log.debug(stderr.decode('utf-8')) + if p.returncode: + sys.exit(1) + + image_id = stdout.decode('utf-8').strip() + log.debug('image_id: {}'.format(image_id)) + return image_id + + def _mark_image_shared(os_cloud, image): + cmd = ['openstack', '--os-cloud', os_cloud, 'image', 'set', '--shared', image] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + log.debug('exit code: {}'.format(p.returncode)) + log.debug(stderr.decode('utf-8')) + if p.returncode: + sys.exit(1) + + def _get_token(cloud): + cmd = ['openstack', '--os-cloud', cloud, 'token', 'issue', + '-c', 'project_id', '-f', 'value'] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + log.debug('exit code: {}'.format(p.returncode)) + log.debug(stderr.decode('utf-8')) + if p.returncode: + sys.exit(1) + + token = stdout.decode('utf-8').strip() + log.debug('token: {}'.format(token)) + return token + + def _share_to_cloud(os_cloud, image, token): + log.debug('Sharing image {} to {}'.format(image, token)) + cmd = ['openstack', '--os-cloud', os_cloud, 'image', 'add', 'project', + image, token] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + log.debug('exit code: {}'.format(p.returncode)) + log.debug(stderr.decode('utf-8')) + + if p.returncode: + if stderr.decode('utf-8').startswith('409 Conflict'): + log.info(' Image is already shared.') + else: + sys.exit(1) + + def _accept_shared_image(cloud, image): + log.debug('Accepting image {}'.format(image)) + cmd = ['openstack', '--os-cloud', cloud, 'image', 'set', + '--accept', image] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + log.debug('exit code: {}'.format(p.returncode)) + log.debug(stderr.decode('utf-8')) + if p.returncode: + sys.exit(1) + + log.info('Marking {}\'s image "{}" as shared.'.format(os_cloud, image)) + image_id = _get_image_id(os_cloud, image) + _mark_image_shared(os_cloud, image_id) + + for cloud in clouds: + log.info('Sharing to {}.'.format(cloud)) + _share_to_cloud(os_cloud, image_id, _get_token(cloud)) + _accept_shared_image(cloud, image_id) diff --git a/releasenotes/notes/share-openstack-images-4f1e3d18fdcb488b.yaml b/releasenotes/notes/share-openstack-images-4f1e3d18fdcb488b.yaml new file mode 100644 index 00000000..7a72b2a2 --- /dev/null +++ b/releasenotes/notes/share-openstack-images-4f1e3d18fdcb488b.yaml @@ -0,0 +1,8 @@ +--- +features: + - | + Add an ``openstack image share`` sub-command to handle sharing images + between multiple tenants. Command accepts a space-separated list of tenants + to share the provided image with. + + Usage: ``lftools openstack image share [OPTIONS] IMAGE [DEST]...``