contrib/packaging/hg-docker
changeset 43659 99e231afc29c
parent 41759 aaad36b88298
equal deleted inserted replaced
43658:0796e266d26b 43659:99e231afc29c
     9 import pathlib
     9 import pathlib
    10 import shutil
    10 import shutil
    11 import subprocess
    11 import subprocess
    12 import sys
    12 import sys
    13 
    13 
       
    14 
    14 def get_docker() -> str:
    15 def get_docker() -> str:
    15     docker = shutil.which('docker.io') or shutil.which('docker')
    16     docker = shutil.which('docker.io') or shutil.which('docker')
    16     if not docker:
    17     if not docker:
    17         print('could not find docker executable')
    18         print('could not find docker executable')
    18         return 1
    19         return 1
    19 
    20 
    20     try:
    21     try:
    21         out = subprocess.check_output([docker, '-h'], stderr=subprocess.STDOUT)
    22         out = subprocess.check_output([docker, '-h'], stderr=subprocess.STDOUT)
    22 
    23 
    23         if b'Jansens' in out:
    24         if b'Jansens' in out:
    24             print('%s is the Docking System Tray; try installing docker.io' %
    25             print(
    25                   docker)
    26                 '%s is the Docking System Tray; try installing docker.io'
       
    27                 % docker
       
    28             )
    26             sys.exit(1)
    29             sys.exit(1)
    27     except subprocess.CalledProcessError as e:
    30     except subprocess.CalledProcessError as e:
    28         print('error calling `%s -h`: %s' % (docker, e.output))
    31         print('error calling `%s -h`: %s' % (docker, e.output))
    29         sys.exit(1)
    32         sys.exit(1)
    30 
    33 
    31     out = subprocess.check_output([docker, 'version'],
    34     out = subprocess.check_output([docker, 'version'], stderr=subprocess.STDOUT)
    32                                   stderr=subprocess.STDOUT)
       
    33 
    35 
    34     lines = out.splitlines()
    36     lines = out.splitlines()
    35     if not any(l.startswith((b'Client:', b'Client version:')) for l in lines):
    37     if not any(l.startswith((b'Client:', b'Client version:')) for l in lines):
    36         print('`%s version` does not look like Docker' % docker)
    38         print('`%s version` does not look like Docker' % docker)
    37         sys.exit(1)
    39         sys.exit(1)
    40         print('`%s version` does not look like Docker' % docker)
    42         print('`%s version` does not look like Docker' % docker)
    41         sys.exit(1)
    43         sys.exit(1)
    42 
    44 
    43     return docker
    45     return docker
    44 
    46 
       
    47 
    45 def get_dockerfile(path: pathlib.Path, args: list) -> bytes:
    48 def get_dockerfile(path: pathlib.Path, args: list) -> bytes:
    46     with path.open('rb') as fh:
    49     with path.open('rb') as fh:
    47         df = fh.read()
    50         df = fh.read()
    48 
    51 
    49     for k, v in args:
    52     for k, v in args:
    50         df = df.replace(bytes('%%%s%%' % k.decode(), 'utf-8'), v)
    53         df = df.replace(bytes('%%%s%%' % k.decode(), 'utf-8'), v)
    51 
    54 
    52     return df
    55     return df
       
    56 
    53 
    57 
    54 def build_docker_image(dockerfile: pathlib.Path, params: list, tag: str):
    58 def build_docker_image(dockerfile: pathlib.Path, params: list, tag: str):
    55     """Build a Docker image from a templatized Dockerfile."""
    59     """Build a Docker image from a templatized Dockerfile."""
    56     docker = get_docker()
    60     docker = get_docker()
    57 
    61 
    63     print(dockerfile.decode('utf-8', 'replace'))
    67     print(dockerfile.decode('utf-8', 'replace'))
    64 
    68 
    65     args = [
    69     args = [
    66         docker,
    70         docker,
    67         'build',
    71         'build',
    68         '--build-arg', 'http_proxy',
    72         '--build-arg',
    69         '--build-arg', 'https_proxy',
    73         'http_proxy',
    70         '--tag', tag,
    74         '--build-arg',
       
    75         'https_proxy',
       
    76         '--tag',
       
    77         tag,
    71         '-',
    78         '-',
    72     ]
    79     ]
    73 
    80 
    74     print('executing: %r' % args)
    81     print('executing: %r' % args)
    75     p = subprocess.Popen(args, stdin=subprocess.PIPE)
    82     p = subprocess.Popen(args, stdin=subprocess.PIPE)
    76     p.communicate(input=dockerfile)
    83     p.communicate(input=dockerfile)
    77     if p.returncode:
    84     if p.returncode:
    78         raise subprocess.CalledProcessException(
    85         raise subprocess.CalledProcessException(
    79                 p.returncode, 'failed to build docker image: %s %s'
    86             p.returncode,
    80                 % (p.stdout, p.stderr))
    87             'failed to build docker image: %s %s' % (p.stdout, p.stderr),
       
    88         )
       
    89 
    81 
    90 
    82 def command_build(args):
    91 def command_build(args):
    83     build_args = []
    92     build_args = []
    84     for arg in args.build_arg:
    93     for arg in args.build_arg:
    85         k, v = arg.split('=', 1)
    94         k, v = arg.split('=', 1)
    86         build_args.append((k.encode('utf-8'), v.encode('utf-8')))
    95         build_args.append((k.encode('utf-8'), v.encode('utf-8')))
    87 
    96 
    88     build_docker_image(pathlib.Path(args.dockerfile),
    97     build_docker_image(pathlib.Path(args.dockerfile), build_args, args.tag)
    89                        build_args,
    98 
    90                        args.tag)
       
    91 
    99 
    92 def command_docker(args):
   100 def command_docker(args):
    93     print(get_docker())
   101     print(get_docker())
       
   102 
    94 
   103 
    95 def main() -> int:
   104 def main() -> int:
    96     parser = argparse.ArgumentParser()
   105     parser = argparse.ArgumentParser()
    97 
   106 
    98     subparsers = parser.add_subparsers(title='subcommands')
   107     subparsers = parser.add_subparsers(title='subcommands')
    99 
   108 
   100     build = subparsers.add_parser('build', help='Build a Docker image')
   109     build = subparsers.add_parser('build', help='Build a Docker image')
   101     build.set_defaults(func=command_build)
   110     build.set_defaults(func=command_build)
   102     build.add_argument('--build-arg', action='append', default=[],
   111     build.add_argument(
   103                         help='Substitution to perform in Dockerfile; '
   112         '--build-arg',
   104                              'format: key=value')
   113         action='append',
       
   114         default=[],
       
   115         help='Substitution to perform in Dockerfile; ' 'format: key=value',
       
   116     )
   105     build.add_argument('dockerfile', help='path to Dockerfile to use')
   117     build.add_argument('dockerfile', help='path to Dockerfile to use')
   106     build.add_argument('tag', help='Tag to apply to created image')
   118     build.add_argument('tag', help='Tag to apply to created image')
   107 
   119 
   108     docker = subparsers.add_parser('docker-path', help='Resolve path to Docker')
   120     docker = subparsers.add_parser('docker-path', help='Resolve path to Docker')
   109     docker.set_defaults(func=command_docker)
   121     docker.set_defaults(func=command_docker)
   110 
   122 
   111     args = parser.parse_args()
   123     args = parser.parse_args()
   112 
   124 
   113     return args.func(args)
   125     return args.func(args)
   114 
   126 
       
   127 
   115 if __name__ == '__main__':
   128 if __name__ == '__main__':
   116     sys.exit(main())
   129     sys.exit(main())