forked from pangeo-data/pangeo-stacks
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build.py
112 lines (94 loc) · 2.83 KB
/
build.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python3
"""
Build an image in the pangeo stack.
"""
import docker
import os
from repo2docker.app import Repo2Docker
import argparse
def docker_build(image_spec, path, build_args, cache_from=None):
pwd = os.getcwd()
print(f'Building {image_spec}')
os.system('docker images')
if os.path.exists(os.path.join(path, 'Dockerfile')):
df_path = os.path.join(path, 'Dockerfile')
else:
df_path = os.path.join(path, 'binder', 'Dockerfile')
cmd = f'docker build {path} -t {image_spec} -f {df_path}'
if cache_from:
cmd +=' --cache-from {cache_from}'
for k, v in build_args.items():
cmd += f' --build-arg {k}={v}'
print(cmd)
os.system(cmd)
def pull_latest(image_latest):
print(f'Pulling {image_latest} for docker layer cache...')
cmd = f'docker pull {image_latest}'
print(cmd)
os.system(cmd)
def r2d_build(image, image_spec, cache_from=None):
r2d = Repo2Docker()
r2d.subdir = image
r2d.output_image_spec = image_spec
r2d.user_id = 1000
r2d.user_name = 'jovyan'
if cache_from:
r2d.cache_from = [cache_from]
r2d.initialize()
r2d.build()
def main():
argparser = argparse.ArgumentParser()
argparser.add_argument(
'image',
help='Image to build. Subdirectory with this name must exist'
)
argparser.add_argument(
'--tag',
help='Docker image tag'
)
argparser.add_argument(
'--image-prefix',
help='Prefix for image to be built. Usually contains registry url and name',
default='pangeo/'
)
args = argparser.parse_args()
image_name = f'{args.image_prefix}{args.image}'
tag = args.tag
image_spec = f'{image_name}:{tag}'
image_latest = f'{image_name}:latest'
print(f'Building {image_name}')
client = docker.from_env()
# Temporary fix b/c pulling 8GB pangeo-ml:latest runs out of space
if args.image == 'pangeo-ml':
image_latest = None
else:
pull_latest(image_latest)
dockerfile_paths = [
os.path.join(args.image, 'binder', 'Dockerfile'),
os.path.join(args.image, 'Dockerfile')
]
if any((os.path.exists(df) for df in dockerfile_paths)):
# Use docker if we have a Dockerfile
# Can be just r2d once we can pass arbitrary BUILD ARGs to it
# https://github.com/jupyter/repo2docker/issues/645
docker_build(
image_spec,
args.image,
{'VERSION': tag},
cache_from=image_latest
)
else:
# Build regular image
r2d_build(
args.image,
image_spec,
cache_from=image_latest
)
# Build onbuild image
docker_build(
f'{image_name}-onbuild:{tag}',
'onbuild',
{'BASE_IMAGE_SPEC': image_spec}
)
if __name__ == '__main__':
main()