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


#!/usr/bin/env python3
#
# usage: plash import-url URL [ GPG_SIGNATURE_URL ]
# Import a container from an url.

import os
import subprocess
import sys
from http.client import HTTPException
from urllib.error import URLError
from urllib.request import urlopen, urlretrieve

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

MAX_SIGNATURE_LENGTH = 8192


def reporthook(count, block_size, total_size):
    if total_size not in (0, -1):
        sys.stderr.write('plash: fetching {}%\r'.format(
            round(100 * count * min(block_size / total_size, 1))))
        if count * block_size >= total_size:
            sys.stderr.write('\n')


handle_help_flag()
assert_initialized()

try:
    url = sys.argv[1]
except IndexError:
    die_with_usage()
try:
    gpg_signature_url = sys.argv[2]
except IndexError:
    gpg_signature_url = None

gpg_keyring = os.path.join(
    os.path.dirname(plash.__file__), 'fixtures', 'trusted_gpg_keyring')

downloaded_rootfs = os.path.join(mkdtemp(), 'rootfs')
with catch_and_die(
    [HTTPException, ValueError, URLError],
        debug='geturl({})'.format(repr(url))):
    urlretrieve(url, downloaded_rootfs, reporthook=reporthook)

if gpg_signature_url:
    signature = urlopen(gpg_signature_url).read(MAX_SIGNATURE_LENGTH)
    try:
        p = subprocess.Popen(
            [
                'gpgv', '--quiet', '--keyring', gpg_keyring, '-',
                downloaded_rootfs
            ],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.PIPE,
            stdin=subprocess.PIPE)
    except FileNotFoundError:
        sys.stderr.write(
            'plash: WARNING: not verifying image signature, gpgv not in PATH\n'
        )
    else:
        p.stdin.write(signature)
        p.stdin.close()
        exit = p.wait()
        out = p.stderr.read().decode()
        if exit:
            sys.stderr.write(out)
            die('signature check failed')

sys.stderr.write('plash: extracting...\n')
os.execlp('plash-import-tar', 'plash-import-tar', downloaded_rootfs)