openstack-ansible-lxc_hosts/templates/lxc-image-fetch-url.py.j2

122 lines
3.2 KiB
Django/Jinja

#!/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 xenial amd64 default
"""
LXC_CACHE_SERVER = '{{ lxc_image_cache_server_mirrors[0].strip() }}'
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()