Mercurial > hg
annotate contrib/packaging/hg-docker @ 41234:4c0d4bbdc395
packaging: allow running packaging with custom uid+gid for CentOS
rpmbuild in CentOS 7 has a bug causing rpmbuild to fail
with "Bad owner/group" if spec or source files are owned
by a different user: https://github.com/rpm-software-management/rpm/issues/2
This makes it very annoying to try and build the CentOS RPMs
on CentOS with Docker.
As an alternative, this change makes it possible to do so,
using an environment variable.
Differential Revision: https://phab.mercurial-scm.org/D5571
author | Mathias De Mare <mathias.de_mare@nokia.com> |
---|---|
date | Fri, 11 Jan 2019 14:55:31 +0100 |
parents | 92b3811fd15f |
children | aaad36b88298 |
rev | line source |
---|---|
38458
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 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
14 def get_docker() -> str: |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
15 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
|
16 if not docker: |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
17 print('could not find docker executable') |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
18 return 1 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
19 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
20 try: |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
21 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
|
22 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
23 if b'Jansens' in out: |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
24 print('%s is the Docking System Tray; try installing docker.io' % |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
25 docker) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
26 sys.exit(1) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
27 except subprocess.CalledProcessError as e: |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
28 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
|
29 sys.exit(1) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
30 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
31 out = subprocess.check_output([docker, 'version'], |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
32 stderr=subprocess.STDOUT) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
33 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
34 lines = out.splitlines() |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
35 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
|
36 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
|
37 sys.exit(1) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
38 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
39 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
|
40 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
|
41 sys.exit(1) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
42 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
43 return docker |
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 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
|
46 with path.open('rb') as fh: |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
47 df = fh.read() |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
48 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
49 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
|
50 df = df.replace(bytes('%%%s%%' % k.decode(), 'utf-8'), v) |
38458
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 return df |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
53 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
54 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
|
55 """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
|
56 docker = get_docker() |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
57 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
58 dockerfile_path = pathlib.Path(dockerfile) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
59 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
60 dockerfile = get_dockerfile(dockerfile_path, params) |
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 print('building Dockerfile:') |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
63 print(dockerfile.decode('utf-8', 'replace')) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
64 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
65 args = [ |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
66 docker, |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
67 'build', |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
68 '--build-arg', 'http_proxy', |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
69 '--build-arg', 'https_proxy', |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
70 '--tag', tag, |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
71 '-', |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
72 ] |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
73 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
74 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:
38458
diff
changeset
|
75 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:
38458
diff
changeset
|
76 p.communicate(input=dockerfile) |
92b3811fd15f
hg-docker: fix Python 3.4 compatibility (for CentOS 7)
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
38458
diff
changeset
|
77 if p.returncode: |
92b3811fd15f
hg-docker: fix Python 3.4 compatibility (for CentOS 7)
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
38458
diff
changeset
|
78 raise subprocess.CalledProcessException( |
92b3811fd15f
hg-docker: fix Python 3.4 compatibility (for CentOS 7)
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
38458
diff
changeset
|
79 p.returncode, 'failed to build docker image: %s %s' \ |
92b3811fd15f
hg-docker: fix Python 3.4 compatibility (for CentOS 7)
Mathias De Mare <mathias.de_mare@nokia.com>
parents:
38458
diff
changeset
|
80 % (p.stdout, p.stderr)) |
38458
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
81 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
82 def command_build(args): |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
83 build_args = [] |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
84 for arg in args.build_arg: |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
85 k, v = arg.split('=', 1) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
86 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
|
87 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
88 build_docker_image(pathlib.Path(args.dockerfile), |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
89 build_args, |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
90 args.tag) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
91 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
92 def command_docker(args): |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
93 print(get_docker()) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
94 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
95 def main() -> int: |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
96 parser = argparse.ArgumentParser() |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
97 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
98 subparsers = parser.add_subparsers(title='subcommands') |
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 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
|
101 build.set_defaults(func=command_build) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
102 build.add_argument('--build-arg', action='append', default=[], |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
103 help='Substitution to perform in Dockerfile; ' |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
104 'format: key=value') |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
105 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
|
106 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
|
107 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
108 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
|
109 docker.set_defaults(func=command_docker) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
110 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
111 args = parser.parse_args() |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
112 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
113 return args.func(args) |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
114 |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
115 if __name__ == '__main__': |
e5916f1236f3
packaging: replace dockerlib.sh with a Python script
Gregory Szorc <gregory.szorc@gmail.com>
parents:
diff
changeset
|
116 sys.exit(main()) |