Make it snazzy

Shows statuses that "fill in" when run interactively.
pull/1784/head
Jason Rhinelander 3 years ago
parent 2064ca049d
commit 09e97eef77

@ -5,6 +5,7 @@ import tempfile
import optparse
import sys
from concurrent.futures import ThreadPoolExecutor
import threading
parser = optparse.OptionParser()
parser.add_option("--no-cache", action="store_true",
@ -19,6 +20,7 @@ distros = [*(('debian', x) for x in ('sid', 'stable', 'testing', 'bullseye', 'bu
*(('ubuntu', x) for x in ('rolling', 'lts', 'impish', 'hirsute', 'focal', 'bionic'))]
manifests = {} # "image:latest": ["image/amd64", "image/arm64v8", ...]
manifestlock = threading.Lock()
def arches(distro):
@ -30,45 +32,65 @@ def arches(distro):
failure = False
lineno = 0
linelock = threading.Lock()
def run_or_report(*args):
def print_line(myline, value):
linelock.acquire()
global lineno
if myline != lineno and sys.__stdout__.isatty():
jump = lineno - myline
print("\033[{jump}A\r\033[K{value}\033[{jump}B\r".format(jump=jump, value=value), end='')
sys.stdout.flush()
else:
print(value)
lineno += 1
linelock.release()
def run_or_report(*args, myline):
try:
subprocess.run(
args, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding='utf8')
except subprocess.CalledProcessError as e:
with tempfile.NamedTemporaryFile(suffix=".log", delete=False) as log:
log.write("Error running {}: {}\n\nOutput:\n\n".format(' '.join(args), e).encode())
log.write(e.output.encode())
global failure
failure = True
print("""
\033[31;1mAn error occured ({}) running:
{}
See {} for the command log.\033[0m
""".format(e, ' '.join(args), log.name), file=sys.stderr)
print_line(myline, "\033[31;1mError! See {} for details", log.name)
raise e
def build_tag(tag_base, arch, contents):
if failure:
raise ChildProcessError()
linelock.acquire()
myline = lineno
linelock.release()
with tempfile.NamedTemporaryFile() as dockerfile:
dockerfile.write(contents.encode())
dockerfile.flush()
tag = '{}/{}'.format(tag_base, arch)
print("\033[33;1mrebuilding \033[35;1m{}\033[0m".format(tag))
print_line(myline, "\033[33;1mRebuilding \033[35;1m{}\033[0m".format(tag))
run_or_report('docker', 'build', '--pull', '-f', dockerfile.name, '-t', tag,
*(('--no-cache',) if options.no_cache else ()), '.')
print("\033[33;1mpushing \033[35;1m{}\033[0m".format(tag))
run_or_report('docker', 'push', tag)
print("\033[32;1mFinished \033[35;1m{}\033[0m".format(tag))
*(('--no-cache',) if options.no_cache else ()), '.', myline=myline)
print_line(myline, "\033[33;1mPushing \033[35;1m{}\033[0m".format(tag))
run_or_report('docker', 'push', tag, myline=myline)
print_line(myline, "\033[32;1mFinished build \033[35;1m{}\033[0m".format(tag))
latest = tag_base + ':latest'
global manifests
manifestlock.acquire()
if latest in manifests:
manifests[latest].append(tag)
else:
manifests[latest] = [tag]
manifestlock.release()
def base_distro_build(distro, arch):
@ -258,10 +280,35 @@ if failure:
sys.exit(1)
for latest, tags in manifests.items():
print("\033[32;1mpushing new manifest for \033[33;1m{}[\033[35;1m{}\033[33;1m]\033[0m".format(
latest, ', '.join(tags)))
print("\n\n\033[32;1mAll builds finished successfully; pushing manifests...\033[0m\n")
def push_manifest(latest, tags):
if failure:
raise ChildProcessError()
linelock.acquire()
myline = lineno
linelock.release()
subprocess.run(['docker', 'manifest', 'rm', latest], stderr=subprocess.DEVNULL, check=False)
run_or_report('docker', 'manifest', 'create', latest, *tags)
run_or_report('docker', 'manifest', 'push', latest)
print_line(myline, "\033[33;1mCreating manifest \033[35;1m{}\033[0m".format(latest))
run_or_report('docker', 'manifest', 'create', latest, *tags, myline=myline)
print_line(myline, "\033[33;1mPushing manifest \033[35;1m{}\033[0m".format(latest))
run_or_report('docker', 'manifest', 'push', latest, myline=myline)
print_line(myline, "\033[32;1mFinished manifest \033[35;1m{}\033[0m".format(latest))
for latest, tags in manifests.items():
jobs.append(executor.submit(push_manifest, latest, tags))
while len(jobs):
j = jobs.pop(0)
try:
j.result()
except (ChildProcessError, subprocess.CalledProcessError):
for k in jobs:
k.cancel()
print("\n\n\033[32;1mAll done!\n")

Loading…
Cancel
Save