-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathbuild_all.py
More file actions
executable file
·156 lines (133 loc) · 5.02 KB
/
build_all.py
File metadata and controls
executable file
·156 lines (133 loc) · 5.02 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python3
import argparse
import errno
import os
import subprocess
from datetime import date
ALL_ARCHES = [
# 'amd64', Use the standard images from docker
'armhf',
'arm64',
'i386',
]
arch_uname_mapping = {
'arm64': 'aarch64',
'armhf': 'armv7l',
'i386': 'x86_64', # No qemu, just using 32bit support mode
}
SUPPORTED_TARGETS = {
'debian': {
'stretch': ['arm64', 'armhf'],
'buster': ['arm64', 'armhf'],
},
'ubuntu': {
'trusty': ['i386', 'armhf'],
'xenial': ALL_ARCHES,
'bionic': ALL_ARCHES,
'disco' : ALL_ARCHES,
'focal' : ['arm64', 'armhf'],
}
}
# Generator to yeild the above tree as tuples
def get_supported_targets():
for (os_name, os) in SUPPORTED_TARGETS.items():
for (suite_name, suite) in os.items():
for arch in suite:
yield (os_name, suite_name, arch)
def construct_image_name(operating_system, arch, suite):
return "osrf/%s_%s:%s" % (operating_system, arch, suite)
def image_save_name_encode(image_name):
image_name = image_name.replace('/', '__')
image_name = image_name.replace(':', '__')
return image_name + '-' + date.today().isoformat()
def backup_image(image_name, directory):
try:
os.makedirs(directory)
except OSError as ex:
if ex.errno == errno.EEXIST and os.path.isdir(directory):
pass
else:
raise
image_filename = os.path.join(directory,
image_save_name_encode(image_name) + '.tar')
if os.path.exists(image_filename):
print("Backup %s already exists; skipping." % image_filename)
return True
try:
print("Pulling %s for backup" % image_name)
pull_command = 'docker pull %s' % (image_name)
subprocess.check_output(pull_command, shell=True, stderr=subprocess.STDOUT)
backup_command = 'docker save %s -o %s' % (image_name, image_filename)
print("Saving image %s with command [%s]" % (image_name, backup_command))
subprocess.check_output(backup_command, shell=True, stderr=subprocess.STDOUT)
return True
except subprocess.CalledProcessError as ex:
print("Failed to backup %s to %s: %s\nContinuing..." %
(image_name, image_filename, ex))
return False
parser = argparse.ArgumentParser()
parser.add_argument("--os",
help="Filter results to a specific OS such as 'ubuntu' or 'debian'")
parser.add_argument("--suite",
help="Filter results to a specific suite such as 'xenial' or 'jessie'")
parser.add_argument("--arch", help="Filter results to a specific architecture such as 'arm64' or 'armhf'")
parser.add_argument("--backup", help="Backup the previous images to this directory.")
args = parser.parse_args()
failed_backups = []
if args.backup:
for (o, s, a) in get_supported_targets():
image_name = construct_image_name(o, a, s)
backup_success = backup_image(image_name, args.backup)
if not backup_success:
failed_backups.append(image_name)
successful_builds = []
failed_builds = []
for (o, s, a) in get_supported_targets():
image_name = construct_image_name(o, a, s)
if args.os and args.os != o:
print("%s does not match os argument %s" % (image_name, args.os))
continue
if args.suite and args.suite != s:
print("%s does not match suite argument %s" % (image_name, args.suite))
continue
if args.arch and args.arch != a:
print("%s does not match arch argument %s" % (image_name, args.arch))
continue
print('Processing:', o, s, a)
env_override = {
'IMAGE_OS': o,
'IMAGE_SUITE': s,
'IMAGE_ARCH': a,
}
cmd = 'sudo -E ./build-image.sh'
try:
subprocess.check_call(cmd, env=env_override, shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as ex:
print("failed to process %s: %s" % (image_name, ex))
failed_builds.append(image_name)
continue
verify_command = 'docker run %s uname -a' % image_name
try:
output = subprocess.check_output(verify_command, env=env_override, shell=True, stderr=subprocess.STDOUT)
str_out = output.decode("utf-8")
if not arch_uname_mapping[a] in str_out:
print("Failed to get correct uname result for %s, aborting" % image_name)
failed_builds.append(image_name)
continue
except subprocess.CalledProcessError as ex:
print("failed to test %s" % image_name)
failed_builds.append(image_name)
continue
print("Successfully detected uname %s in %s" % (arch_uname_mapping[a], image_name))
successful_builds.append(image_name)
print("Summary:")
if failed_builds:
print("Failed to build:\n%s" % failed_builds)
if failed_backups:
print("Failed to backup:\n%s" % failed_backups)
print("Successfully built the following images.")
print("%s " % successful_builds)
print("Please verify and push.")
print("For your convenience the push commands are listed below:")
for im in successful_builds:
print("docker push %s" % im)