Mercurial > hg
view contrib/packaging/hg-docker @ 45185:a17454a189d1 stable
chgserver: discard buffered output before restoring fds (issue6207)
On Python 3, flush() appears not discarding buffered data on EPIPE, and
the buffered data will be carried over to the restored stdout.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Mon, 20 Jul 2020 20:31:24 +0900 |
parents | 99e231afc29c |
children |
line wrap: on
line source
#!/usr/bin/env python3 # # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. import argparse import pathlib import shutil import subprocess import sys def get_docker() -> str: docker = shutil.which('docker.io') or shutil.which('docker') if not docker: print('could not find docker executable') return 1 try: out = subprocess.check_output([docker, '-h'], stderr=subprocess.STDOUT) if b'Jansens' in out: print( '%s is the Docking System Tray; try installing docker.io' % docker ) sys.exit(1) except subprocess.CalledProcessError as e: print('error calling `%s -h`: %s' % (docker, e.output)) sys.exit(1) out = subprocess.check_output([docker, 'version'], stderr=subprocess.STDOUT) lines = out.splitlines() if not any(l.startswith((b'Client:', b'Client version:')) for l in lines): print('`%s version` does not look like Docker' % docker) sys.exit(1) if not any(l.startswith((b'Server:', b'Server version:')) for l in lines): print('`%s version` does not look like Docker' % docker) sys.exit(1) return docker def get_dockerfile(path: pathlib.Path, args: list) -> bytes: with path.open('rb') as fh: df = fh.read() for k, v in args: df = df.replace(bytes('%%%s%%' % k.decode(), 'utf-8'), v) return df def build_docker_image(dockerfile: pathlib.Path, params: list, tag: str): """Build a Docker image from a templatized Dockerfile.""" docker = get_docker() dockerfile_path = pathlib.Path(dockerfile) dockerfile = get_dockerfile(dockerfile_path, params) print('building Dockerfile:') print(dockerfile.decode('utf-8', 'replace')) args = [ docker, 'build', '--build-arg', 'http_proxy', '--build-arg', 'https_proxy', '--tag', tag, '-', ] print('executing: %r' % args) p = subprocess.Popen(args, stdin=subprocess.PIPE) p.communicate(input=dockerfile) if p.returncode: raise subprocess.CalledProcessException( p.returncode, 'failed to build docker image: %s %s' % (p.stdout, p.stderr), ) def command_build(args): build_args = [] for arg in args.build_arg: k, v = arg.split('=', 1) build_args.append((k.encode('utf-8'), v.encode('utf-8'))) build_docker_image(pathlib.Path(args.dockerfile), build_args, args.tag) def command_docker(args): print(get_docker()) def main() -> int: parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(title='subcommands') build = subparsers.add_parser('build', help='Build a Docker image') build.set_defaults(func=command_build) build.add_argument( '--build-arg', action='append', default=[], help='Substitution to perform in Dockerfile; ' 'format: key=value', ) build.add_argument('dockerfile', help='path to Dockerfile to use') build.add_argument('tag', help='Tag to apply to created image') docker = subparsers.add_parser('docker-path', help='Resolve path to Docker') docker.set_defaults(func=command_docker) args = parser.parse_args() return args.func(args) if __name__ == '__main__': sys.exit(main())