#!/usr/bin/env python # Copyright 2017, Rackspace US, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. try: import httplib except ImportError: import http.client as httplib import ssl try: import urlparse except ImportError: import urllib.parse as urlparse import sys __DOC__ = """ USAGE: This script will take arguments passed into it to discover the url of a given container image using the distro, release, architecture, and variant as the parameters. EXAMPLE: # python lxc-image-fetch-url ubuntu bionic amd64 default """ LXC_CACHE_SERVER = 'https://us.images.linuxcontainers.org' LXC_INDEX = '{0}/meta/1.0/index-system'.format(LXC_CACHE_SERVER) def get_image_url(url, depth=0): if depth > 10: raise SystemExit('Too many redirects') url_path = urlparse.urlparse(url, allow_fragments=True) if url_path.scheme == 'https': conn = httplib.HTTPSConnection( host=url_path.netloc, context=ssl._create_unverified_context() ) else: conn = httplib.HTTPConnection(host=url_path.netloc) try: conn.request('GET', url_path.path) except httplib.BadStatusLine: raise SystemExit('Connection Failure') else: resp = conn.getresponse() headers = dict(resp.getheaders()) check_redirect = headers.get('location', None) if not check_redirect: check_redirect = headers.get('Location', None) if check_redirect: depth += 1 return get_image_url( url=check_redirect, depth=depth ) else: return ( str(url), resp.read().decode('UTF-8').splitlines() ) finally: conn.close() def main(): try: distro = sys.argv[1] release = sys.argv[2] arch = sys.argv[3] variant = sys.argv[4] except IndexError: print('Missing argument, Please see the documentation.') raise SystemExit(__DOC__) _, meta = get_image_url(url=LXC_INDEX, depth=0) image_hint = '{0};{1};{2};{3}'.format( distro, release, arch, variant ) images = sorted([i for i in meta if i.strip().startswith(image_hint)]) if not images: print(__DOC__ + '\nAvailable options:') for line in meta: print(';'.join(line.split(';')[:-2])) raise SystemExit( 'No Image found with image hint "{0}"'.format(image_hint) ) container_url = urlparse.urljoin( urlparse.urljoin( LXC_CACHE_SERVER, images[0].split(';')[-1] ), 'rootfs.tar.xz' ) print(container_url) if __name__ == '__main__': main()