contrib/packaging/hg-docker
changeset 38462 e5916f1236f3
child 41233 92b3811fd15f
equal deleted inserted replaced
38461:11eda1f1b6e7 38462:e5916f1236f3
       
     1 #!/usr/bin/env python3
       
     2 #
       
     3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
       
     4 #
       
     5 # This software may be used and distributed according to the terms of the
       
     6 # GNU General Public License version 2 or any later version.
       
     7 
       
     8 import argparse
       
     9 import pathlib
       
    10 import shutil
       
    11 import subprocess
       
    12 import sys
       
    13 
       
    14 def get_docker() -> str:
       
    15     docker = shutil.which('docker.io') or shutil.which('docker')
       
    16     if not docker:
       
    17         print('could not find docker executable')
       
    18         return 1
       
    19 
       
    20     try:
       
    21         out = subprocess.check_output([docker, '-h'], stderr=subprocess.STDOUT)
       
    22 
       
    23         if b'Jansens' in out:
       
    24             print('%s is the Docking System Tray; try installing docker.io' %
       
    25                   docker)
       
    26             sys.exit(1)
       
    27     except subprocess.CalledProcessError as e:
       
    28         print('error calling `%s -h`: %s' % (docker, e.output))
       
    29         sys.exit(1)
       
    30 
       
    31     out = subprocess.check_output([docker, 'version'],
       
    32                                   stderr=subprocess.STDOUT)
       
    33 
       
    34     lines = out.splitlines()
       
    35     if not any(l.startswith((b'Client:', b'Client version:')) for l in lines):
       
    36         print('`%s version` does not look like Docker' % docker)
       
    37         sys.exit(1)
       
    38 
       
    39     if not any(l.startswith((b'Server:', b'Server version:')) for l in lines):
       
    40         print('`%s version` does not look like Docker' % docker)
       
    41         sys.exit(1)
       
    42 
       
    43     return docker
       
    44 
       
    45 def get_dockerfile(path: pathlib.Path, args: list) -> bytes:
       
    46     with path.open('rb') as fh:
       
    47         df = fh.read()
       
    48 
       
    49     for k, v in args:
       
    50         df = df.replace(b'%%%s%%' % k, v)
       
    51 
       
    52     return df
       
    53 
       
    54 def build_docker_image(dockerfile: pathlib.Path, params: list, tag: str):
       
    55     """Build a Docker image from a templatized Dockerfile."""
       
    56     docker = get_docker()
       
    57 
       
    58     dockerfile_path = pathlib.Path(dockerfile)
       
    59 
       
    60     dockerfile = get_dockerfile(dockerfile_path, params)
       
    61 
       
    62     print('building Dockerfile:')
       
    63     print(dockerfile.decode('utf-8', 'replace'))
       
    64 
       
    65     args = [
       
    66         docker,
       
    67         'build',
       
    68         '--build-arg', 'http_proxy',
       
    69         '--build-arg', 'https_proxy',
       
    70         '--tag', tag,
       
    71         '-',
       
    72     ]
       
    73 
       
    74     print('executing: %r' % args)
       
    75     subprocess.run(args, input=dockerfile, check=True)
       
    76 
       
    77 def command_build(args):
       
    78     build_args = []
       
    79     for arg in args.build_arg:
       
    80         k, v = arg.split('=', 1)
       
    81         build_args.append((k.encode('utf-8'), v.encode('utf-8')))
       
    82 
       
    83     build_docker_image(pathlib.Path(args.dockerfile),
       
    84                        build_args,
       
    85                        args.tag)
       
    86 
       
    87 def command_docker(args):
       
    88     print(get_docker())
       
    89 
       
    90 def main() -> int:
       
    91     parser = argparse.ArgumentParser()
       
    92 
       
    93     subparsers = parser.add_subparsers(title='subcommands')
       
    94 
       
    95     build = subparsers.add_parser('build', help='Build a Docker image')
       
    96     build.set_defaults(func=command_build)
       
    97     build.add_argument('--build-arg', action='append', default=[],
       
    98                         help='Substitution to perform in Dockerfile; '
       
    99                              'format: key=value')
       
   100     build.add_argument('dockerfile', help='path to Dockerfile to use')
       
   101     build.add_argument('tag', help='Tag to apply to created image')
       
   102 
       
   103     docker = subparsers.add_parser('docker-path', help='Resolve path to Docker')
       
   104     docker.set_defaults(func=command_docker)
       
   105 
       
   106     args = parser.parse_args()
       
   107 
       
   108     return args.func(args)
       
   109 
       
   110 if __name__ == '__main__':
       
   111     sys.exit(main())