contrib/packaging/hg-docker
author Matt Harbison <matt_harbison@yahoo.com>
Tue, 08 Dec 2020 12:43:18 -0500
changeset 46098 1b5e0d0bdb05
parent 43703 99e231afc29c
permissions -rwxr-xr-x
hghave: update the check for virtualenv This started as `hghave --test-features` failing on Windows in `test-hghave.t`. IDK how this worked, as neither my Linux nor Windows machines have the old attribute with virtualenv 20.2.2, even on py2. I think this was noticed recently because 357d8415aa27 mentioned an AttributeError, and mitigated by making this py2 only. But as mentioned, this is also a problem on py2 (where the failure was observed). When I got this working by removing the attribute reference, the command in the test failed because the `--no-site-package` argument was removed some time ago. Therefore, this backs out 357d8415aa27 and references a known good attribute (which was done to suppress the warning about an unused import) that also ensures the command does not need the argument. Since there appears to be (minor) broken stuff on py3, manually apply the `no-py3` guard that was backed out of the check itself. Differential Revision: https://phab.mercurial-scm.org/D9547
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     1
#!/usr/bin/env python3
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     2
#
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     3
# Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     4
#
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     7
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     8
import argparse
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
     9
import pathlib
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    10
import shutil
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    11
import subprocess
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    12
import sys
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    13
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    14
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    15
def get_docker() -> str:
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    16
    docker = shutil.which('docker.io') or shutil.which('docker')
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    17
    if not docker:
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    18
        print('could not find docker executable')
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    19
        return 1
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    20
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    21
    try:
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    22
        out = subprocess.check_output([docker, '-h'], stderr=subprocess.STDOUT)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    23
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    24
        if b'Jansens' in out:
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    25
            print(
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    26
                '%s is the Docking System Tray; try installing docker.io'
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    27
                % docker
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    28
            )
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    29
            sys.exit(1)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    30
    except subprocess.CalledProcessError as e:
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    31
        print('error calling `%s -h`: %s' % (docker, e.output))
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    32
        sys.exit(1)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    33
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    34
    out = subprocess.check_output([docker, 'version'], stderr=subprocess.STDOUT)
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    35
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    36
    lines = out.splitlines()
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    37
    if not any(l.startswith((b'Client:', b'Client version:')) for l in lines):
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    38
        print('`%s version` does not look like Docker' % docker)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    39
        sys.exit(1)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    40
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    41
    if not any(l.startswith((b'Server:', b'Server version:')) for l in lines):
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    42
        print('`%s version` does not look like Docker' % docker)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    43
        sys.exit(1)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    44
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    45
    return docker
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    46
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    47
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    48
def get_dockerfile(path: pathlib.Path, args: list) -> bytes:
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    49
    with path.open('rb') as fh:
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    50
        df = fh.read()
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    51
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    52
    for k, v in args:
41234
4c0d4bbdc395 packaging: allow running packaging with custom uid+gid for CentOS
Mathias De Mare <mathias.de_mare@nokia.com>
parents: 41233
diff changeset
    53
        df = df.replace(bytes('%%%s%%' % k.decode(), 'utf-8'), v)
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    54
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    55
    return df
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    56
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    57
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    58
def build_docker_image(dockerfile: pathlib.Path, params: list, tag: str):
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    59
    """Build a Docker image from a templatized Dockerfile."""
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    60
    docker = get_docker()
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    61
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    62
    dockerfile_path = pathlib.Path(dockerfile)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    63
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    64
    dockerfile = get_dockerfile(dockerfile_path, params)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    65
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    66
    print('building Dockerfile:')
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    67
    print(dockerfile.decode('utf-8', 'replace'))
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    68
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    69
    args = [
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    70
        docker,
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    71
        'build',
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    72
        '--build-arg',
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    73
        'http_proxy',
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    74
        '--build-arg',
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    75
        'https_proxy',
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    76
        '--tag',
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    77
        tag,
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    78
        '-',
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    79
    ]
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    80
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    81
    print('executing: %r' % args)
41233
92b3811fd15f hg-docker: fix Python 3.4 compatibility (for CentOS 7)
Mathias De Mare <mathias.de_mare@nokia.com>
parents: 38462
diff changeset
    82
    p = subprocess.Popen(args, stdin=subprocess.PIPE)
92b3811fd15f hg-docker: fix Python 3.4 compatibility (for CentOS 7)
Mathias De Mare <mathias.de_mare@nokia.com>
parents: 38462
diff changeset
    83
    p.communicate(input=dockerfile)
92b3811fd15f hg-docker: fix Python 3.4 compatibility (for CentOS 7)
Mathias De Mare <mathias.de_mare@nokia.com>
parents: 38462
diff changeset
    84
    if p.returncode:
92b3811fd15f hg-docker: fix Python 3.4 compatibility (for CentOS 7)
Mathias De Mare <mathias.de_mare@nokia.com>
parents: 38462
diff changeset
    85
        raise subprocess.CalledProcessException(
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    86
            p.returncode,
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    87
            'failed to build docker image: %s %s' % (p.stdout, p.stderr),
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    88
        )
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    89
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    90
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    91
def command_build(args):
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    92
    build_args = []
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    93
    for arg in args.build_arg:
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    94
        k, v = arg.split('=', 1)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    95
        build_args.append((k.encode('utf-8'), v.encode('utf-8')))
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    96
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    97
    build_docker_image(pathlib.Path(args.dockerfile), build_args, args.tag)
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
    98
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
    99
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   100
def command_docker(args):
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   101
    print(get_docker())
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   102
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
   103
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   104
def main() -> int:
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   105
    parser = argparse.ArgumentParser()
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   106
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   107
    subparsers = parser.add_subparsers(title='subcommands')
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   108
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   109
    build = subparsers.add_parser('build', help='Build a Docker image')
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   110
    build.set_defaults(func=command_build)
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
   111
    build.add_argument(
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
   112
        '--build-arg',
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
   113
        action='append',
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
   114
        default=[],
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
   115
        help='Substitution to perform in Dockerfile; ' 'format: key=value',
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
   116
    )
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   117
    build.add_argument('dockerfile', help='path to Dockerfile to use')
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   118
    build.add_argument('tag', help='Tag to apply to created image')
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   119
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   120
    docker = subparsers.add_parser('docker-path', help='Resolve path to Docker')
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   121
    docker.set_defaults(func=command_docker)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   122
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   123
    args = parser.parse_args()
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   124
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   125
    return args.func(args)
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   126
43703
99e231afc29c black: blacken scripts
Gregory Szorc <gregory.szorc@gmail.com>
parents: 41768
diff changeset
   127
38462
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   128
if __name__ == '__main__':
e5916f1236f3 packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff changeset
   129
    sys.exit(main())