Fork me on GitHub
  ▖     
▃▀▄▄▖▄▄▖
 ▀▖     
        


#!/usr/bin/env python3
#
# usage: plash import-lxc IMAGE-NAME
# Import image from linuxcontainers.org

import re
import os
import sys
from subprocess import CalledProcessError, check_call
from urllib.error import URLError
from urllib.request import urlopen

from plash.utils import (assert_initialized, catch_and_die, die,
                         die_with_usage, handle_help_flag)

LXC_URL_TEMPL = 'https://images.linuxcontainers.org/images/{}/{}/{}/{}/{}/rootfs.tar.xz'
UBUNTU_ABC = 'pqrstuvwxyzabcdefghijklmno'  # rotate manually every 10 years or so

DEBIAN_RELESES = [
    # well, some constant in some file to keep updated... That here should only be fine until 2022 or something
    'bullseye',
    'buster',
    'stretch',
    'jessie',
    'wheezy'
]

handle_help_flag()
assert_initialized()

try:
    image_name = sys.argv[1]
except IndexError:
    die_with_usage()

with catch_and_die([URLError]):
    content = urlopen('https://images.linuxcontainers.org/').read().decode()
matches = re.findall(
    '<tr><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td><td>(.+?)</td></tr>',
    content)

distros = {}
names = {}
for distro, version, arch, variant, date, _, _, _ in matches:
    if not variant == 'default':
        continue

    if arch != 'amd64':  # only support this right now
        continue

    url = LXC_URL_TEMPL.format(distro, version, arch, variant, date)

    if not version == 'current':
        names['{}:{}'.format(distro, version)] = url
    else:
        names[distro] = url

    # if version == 'current':
    #     names[distro] = url

    if version[0].isalpha() and not version == 'current':
        # path parts with older upload_version also come later
        # (ignore possibel alphanumeric sort for dates on this right now)
        names[version] = url
    # else:
    #     names['{}{}'.format(distro, version)] = url

    distros.setdefault(distro, [])
    distros[distro].append(version)

#
# also add entries where we call the version name e.g. "jessie"
#
for distro, versions in distros.items():

    if versions == ['current']:
        continue

    if distro == 'alpine':
        versions.remove('edge')

    if distro == 'ubuntu':
        newest = sorted(versions, key=lambda v: UBUNTU_ABC.index(v[0]))[-1]
    elif distro == 'debian':
        versions.remove('sid')
        newest = sorted(
            versions, key=lambda v: -1 * DEBIAN_RELESES.index(v))[-1]

    else:
        newest = sorted(versions, key=lambda v: float(v.replace('x', '0')))[-1]
    # names[distro] = names['{}:{}'.format(distro, newest)]
    # print(distro, newest, file=sys.stderr)
    names[distro] = names['{}:{}'.format(distro, newest)]

try:
    url = names[image_name]
except KeyError:
    die('image not found: {}; Available images: {}'.format(
        repr(image_name), ' '.join(sorted(names))))

signature_url = '{}.asc'.format(url)
os.execlp('plash-import-url', 'plash-import-url', url, signature_url)