Merge lp:~ltrager/maas-images/bootloaders_part2 into lp:maas-images
- bootloaders_part2
- Merge into maas-ephemerals
Proposed by
Lee Trager
Status: | Merged |
---|---|
Merged at revision: | 325 |
Proposed branch: | lp:~ltrager/maas-images/bootloaders_part2 |
Merge into: | lp:maas-images |
Diff against target: |
485 lines (+231/-104) 3 files modified
conf/bootloaders.yaml (+21/-13) meph2/commands/dpkg.py (+133/-8) meph2/commands/meph2_util.py (+77/-83) |
To merge this branch: | bzr merge lp:~ltrager/maas-images/bootloaders_part2 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Scott Moser (community) | Approve | ||
Review via email:
|
Commit message
Description of the change
Update bootloader format as per discussion in https:/
Sample output:
http://
To post a comment you must log in.
- 324. By Lee Trager
-
Put os in bootloader product name
- 325. By Lee Trager
-
Use bootloaders from Xenial
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Lee Trager (ltrager) wrote : | # |
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Scott Moser (smoser) wrote : | # |
the data looks good.
i have one nit pick in the conf/bootloader
I think better to have:
files:
- usr/lib/
than
files:
- /usr/lib/
just to make it clear that the files are coming from the package itself and not the isntalled system, and also to avoid the pitfall of:
os.path.
review:
Approve
- 326. By Lee Trager
-
Remove leading / from bootloader files
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'conf/bootloaders.yaml' | |||
2 | --- conf/bootloaders.yaml 2016-08-23 15:17:16 +0000 | |||
3 | +++ conf/bootloaders.yaml 2016-08-24 20:40:59 +0000 | |||
4 | @@ -1,35 +1,41 @@ | |||
7 | 1 | product_id: "com.ubuntu.maas.daily:1:bootloaders-bases:{bootloader}" | 1 | product_id: "com.ubuntu.maas.daily:1:{os}:{firmware_platform}:{arch}" |
8 | 2 | content_id: "com.ubuntu.maas:daily:1:bootloaders-bases-download" | 2 | content_id: "com.ubuntu.maas:daily:1:bootloader-download" |
9 | 3 | 3 | ||
10 | 4 | bootloaders: | 4 | bootloaders: |
12 | 5 | - bootloader: pxe | 5 | - firmware-platform: pxe |
13 | 6 | packages: | 6 | packages: |
14 | 7 | - pxelinux | 7 | - pxelinux |
15 | 8 | - syslinux-common | 8 | - syslinux-common |
17 | 9 | arch: amd64 | 9 | arch: i386 |
18 | 10 | arches: i386,amd64 | ||
19 | 10 | archive: http://archive.ubuntu.com/ubuntu | 11 | archive: http://archive.ubuntu.com/ubuntu |
20 | 11 | release: xenial | 12 | release: xenial |
21 | 13 | os: pxelinux | ||
22 | 12 | files: | 14 | files: |
26 | 13 | - /usr/lib/PXELINUX/pxelinux.0 | 15 | - usr/lib/PXELINUX/pxelinux.0 |
27 | 14 | - /usr/lib/syslinux/modules/bios/*.c32 | 16 | - usr/lib/syslinux/modules/bios/*.c32 |
28 | 15 | - bootloader: uefi | 17 | - firmware-platform: uefi |
29 | 16 | packages: | 18 | packages: |
30 | 17 | - shim-signed | 19 | - shim-signed |
31 | 18 | - grub-efi-amd64-signed | 20 | - grub-efi-amd64-signed |
32 | 19 | arch: amd64 | 21 | arch: amd64 |
33 | 22 | arches: amd64 | ||
34 | 20 | archive: http://archive.ubuntu.com/ubuntu | 23 | archive: http://archive.ubuntu.com/ubuntu |
35 | 21 | release: xenial | 24 | release: xenial |
36 | 25 | os: grub-efi-signed | ||
37 | 22 | files: | 26 | files: |
41 | 23 | - /usr/lib/shim/shim.efi.signed, bootx64.efi | 27 | - usr/lib/shim/shim.efi.signed, bootx64.efi |
42 | 24 | - /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed, grubx64.efi | 28 | - usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed, grubx64.efi |
43 | 25 | - bootloader: uefi-arm64 | 29 | - firmware-platform: uefi |
44 | 26 | packages: | 30 | packages: |
45 | 27 | - grub-efi-arm64-bin | 31 | - grub-efi-arm64-bin |
46 | 28 | arch: arm64 | 32 | arch: arm64 |
47 | 33 | arches: arm64 | ||
48 | 29 | archive: http://ports.ubuntu.com | 34 | archive: http://ports.ubuntu.com |
49 | 30 | release: xenial | 35 | release: xenial |
50 | 36 | os: grub-efi | ||
51 | 31 | files: | 37 | files: |
53 | 32 | - /usr/lib/grub/arm64-efi/ | 38 | - usr/lib/grub/arm64-efi/ |
54 | 33 | grub_format: arm64-efi | 39 | grub_format: arm64-efi |
55 | 34 | grub_output: grubaa64.efi | 40 | grub_output: grubaa64.efi |
56 | 35 | grub_config: | | 41 | grub_config: | |
57 | @@ -41,14 +47,16 @@ | |||
58 | 41 | # Failed to load based on MAC address. | 47 | # Failed to load based on MAC address. |
59 | 42 | # Load arm64 by default, UEFI only supported by 64-bit | 48 | # Load arm64 by default, UEFI only supported by 64-bit |
60 | 43 | configfile (pxe)/grub/grub.cfg-default-arm64 | 49 | configfile (pxe)/grub/grub.cfg-default-arm64 |
62 | 44 | - bootloader: powerkvm | 50 | - firmware-platform: open-firmware |
63 | 45 | packages: | 51 | packages: |
64 | 46 | - grub-ieee1275-bin | 52 | - grub-ieee1275-bin |
65 | 47 | arch: ppc64el | 53 | arch: ppc64el |
66 | 54 | arches: ppc64el,ppc64 | ||
67 | 48 | archive: http://ports.ubuntu.com | 55 | archive: http://ports.ubuntu.com |
68 | 49 | release: xenial | 56 | release: xenial |
69 | 57 | os: grub-ieee1275 | ||
70 | 50 | files: | 58 | files: |
72 | 51 | - /usr/lib/grub/powerpc-ieee1275/ | 59 | - usr/lib/grub/powerpc-ieee1275/ |
73 | 52 | grub_format: powerpc-ieee1275 | 60 | grub_format: powerpc-ieee1275 |
74 | 53 | grub_output: bootppc64.bin | 61 | grub_output: bootppc64.bin |
75 | 54 | grub_config: | | 62 | grub_config: | |
76 | 55 | 63 | ||
77 | === modified file 'meph2/commands/dpkg.py' | |||
78 | --- meph2/commands/dpkg.py 2016-08-03 13:00:03 +0000 | |||
79 | +++ meph2/commands/dpkg.py 2016-08-24 20:40:59 +0000 | |||
80 | @@ -6,6 +6,7 @@ | |||
81 | 6 | import os | 6 | import os |
82 | 7 | import re | 7 | import re |
83 | 8 | import sys | 8 | import sys |
84 | 9 | import tarfile | ||
85 | 9 | import tempfile | 10 | import tempfile |
86 | 10 | import glob | 11 | import glob |
87 | 11 | 12 | ||
88 | @@ -128,13 +129,98 @@ | |||
89 | 128 | pkg_path = os.path.join(dest, os.path.basename(package['Filename'])) | 129 | pkg_path = os.path.join(dest, os.path.basename(package['Filename'])) |
90 | 129 | with open(pkg_path, 'wb') as stream: | 130 | with open(pkg_path, 'wb') as stream: |
91 | 130 | stream.write(pkg_data) | 131 | stream.write(pkg_data) |
92 | 132 | package['files'] = [] | ||
93 | 133 | output = subprocess.check_output(['dpkg', '-c', pkg_path]) | ||
94 | 134 | for line in output.decode('utf-8').split('\n'): | ||
95 | 135 | # The file is the last column in the list. | ||
96 | 136 | file_info = line.split() | ||
97 | 137 | # Last line is just a newline | ||
98 | 138 | if len(file_info) == 0: | ||
99 | 139 | continue | ||
100 | 140 | if file_info[-1].startswith('./'): | ||
101 | 141 | # Remove leading './' if it exists | ||
102 | 142 | f = file_info[-1][2:] | ||
103 | 143 | elif file_info[-1].startswith('/'): | ||
104 | 144 | # Removing leading '/' if it exists | ||
105 | 145 | f = file_info[-1][1:] | ||
106 | 146 | else: | ||
107 | 147 | f = file_info[-1] | ||
108 | 148 | if f != '': | ||
109 | 149 | package['files'].append(f) | ||
110 | 131 | return package | 150 | return package |
111 | 132 | 151 | ||
112 | 133 | 152 | ||
113 | 153 | def get_file_info(f): | ||
114 | 154 | size = 0 | ||
115 | 155 | sha256 = hashlib.sha256() | ||
116 | 156 | with open(f, 'rb') as f: | ||
117 | 157 | for chunk in iter(lambda: f.read(2**15), b''): | ||
118 | 158 | sha256.update(chunk) | ||
119 | 159 | size += len(chunk) | ||
120 | 160 | return sha256.hexdigest(), size | ||
121 | 161 | |||
122 | 162 | |||
123 | 163 | def make_item(ftype, src_file, dest_file, stream_path, src_packages): | ||
124 | 164 | sha256, size = get_file_info(dest_file) | ||
125 | 165 | for src_package in src_packages: | ||
126 | 166 | if src_file in src_package['files']: | ||
127 | 167 | return { | ||
128 | 168 | 'ftype': ftype, | ||
129 | 169 | 'sha256': sha256, | ||
130 | 170 | 'path': stream_path, | ||
131 | 171 | 'size': size, | ||
132 | 172 | 'src_package': src_package['src_package'], | ||
133 | 173 | 'src_version': src_package['src_version'], | ||
134 | 174 | 'src_release': src_package['src_release'], | ||
135 | 175 | } | ||
136 | 176 | raise ValueError("%s not found in src_packages" % src_file) | ||
137 | 177 | |||
138 | 178 | |||
139 | 179 | def archive_files(items, target): | ||
140 | 180 | """Archive multiple files from a src_package into archive.tar.xz.""" | ||
141 | 181 | archive_items = {} | ||
142 | 182 | new_items = {} | ||
143 | 183 | # Create a mapping of source packages and the files that came from them. | ||
144 | 184 | for item in items.values(): | ||
145 | 185 | key = "%(src_package)s-%(src_release)-%(src_version)" % item | ||
146 | 186 | if archive_items.get(key) is None: | ||
147 | 187 | archive_items[key] = { | ||
148 | 188 | 'src_package': item['src_package'], | ||
149 | 189 | 'src_release': item['src_release'], | ||
150 | 190 | 'src_version': item['src_version'], | ||
151 | 191 | 'files': [item['path']], | ||
152 | 192 | } | ||
153 | 193 | else: | ||
154 | 194 | archive_items[key]['files'].append(item['path']) | ||
155 | 195 | for item in archive_items.values(): | ||
156 | 196 | stream_path = os.path.join( | ||
157 | 197 | os.path.dirname(item['files'][0]), | ||
158 | 198 | '%s.tar.xz' % item['src_package']) | ||
159 | 199 | full_path = os.path.join(target, stream_path) | ||
160 | 200 | tar = tarfile.open(full_path, 'w:xz') | ||
161 | 201 | for f in item['files']: | ||
162 | 202 | item_full_path = os.path.join(target, f) | ||
163 | 203 | tar.add(item_full_path, os.path.basename(item_full_path)) | ||
164 | 204 | os.remove(item_full_path) | ||
165 | 205 | tar.close() | ||
166 | 206 | sha256, size = get_file_info(full_path) | ||
167 | 207 | new_items[item['src_package']] = { | ||
168 | 208 | 'ftype': 'archive.tar.xz', | ||
169 | 209 | 'sha256': sha256, | ||
170 | 210 | 'path': stream_path, | ||
171 | 211 | 'size': size, | ||
172 | 212 | 'src_package': item['src_package'], | ||
173 | 213 | 'src_release': item['src_release'], | ||
174 | 214 | 'src_version': item['src_version'], | ||
175 | 215 | } | ||
176 | 216 | return new_items | ||
177 | 217 | |||
178 | 218 | |||
179 | 134 | def extract_files_from_packages( | 219 | def extract_files_from_packages( |
182 | 135 | archive, packages, architecture, files, release, dest, | 220 | archive, packages, architecture, files, release, target, path, |
183 | 136 | grub_format=None, grub_config=None): | 221 | grub_format=None, grub_config=None, grub_output=None): |
184 | 137 | tmp = tempfile.mkdtemp(prefix='maas-images-') | 222 | tmp = tempfile.mkdtemp(prefix='maas-images-') |
185 | 223 | src_packages = [] | ||
186 | 138 | for package in packages: | 224 | for package in packages: |
187 | 139 | package = get_package(archive, package, architecture, release, tmp) | 225 | package = get_package(archive, package, architecture, release, tmp) |
188 | 140 | pkg_path = os.path.join(tmp, os.path.basename(package['Filename'])) | 226 | pkg_path = os.path.join(tmp, os.path.basename(package['Filename'])) |
189 | @@ -142,7 +228,23 @@ | |||
190 | 142 | sys.stderr.write('%s not found in archives!' % package) | 228 | sys.stderr.write('%s not found in archives!' % package) |
191 | 143 | sys.exit(1) | 229 | sys.exit(1) |
192 | 144 | subprocess.check_output(['dpkg', '-x', pkg_path, tmp]) | 230 | subprocess.check_output(['dpkg', '-x', pkg_path, tmp]) |
194 | 145 | 231 | new_source_package = True | |
195 | 232 | for src_package in src_packages: | ||
196 | 233 | if src_package['src_package'] == package['Source']: | ||
197 | 234 | new_source_package = False | ||
198 | 235 | src_package['files'] += package['files'] | ||
199 | 236 | if new_source_package: | ||
200 | 237 | # Some source packages include the package version in the source | ||
201 | 238 | # name. Only take the name, not the version. | ||
202 | 239 | src_package = package['Source'].split(' ')[0] | ||
203 | 240 | src_packages.append({ | ||
204 | 241 | 'src_package': src_package, | ||
205 | 242 | 'src_version': package['Version'], | ||
206 | 243 | 'src_release': release, | ||
207 | 244 | 'files': package['files'], | ||
208 | 245 | }) | ||
209 | 246 | dest = os.path.join(target, path) | ||
210 | 247 | items = {} | ||
211 | 146 | if grub_format is None: | 248 | if grub_format is None: |
212 | 147 | for i in files: | 249 | for i in files: |
213 | 148 | if '*' in i or '?' in i: | 250 | if '*' in i or '?' in i: |
214 | @@ -150,20 +252,38 @@ | |||
215 | 150 | src = "%s/%s" % (tmp, i) | 252 | src = "%s/%s" % (tmp, i) |
216 | 151 | unglobbed_files = glob.glob(src) | 253 | unglobbed_files = glob.glob(src) |
217 | 152 | for f in unglobbed_files: | 254 | for f in unglobbed_files: |
219 | 153 | dest_file = "%s/%s" % (dest, os.path.basename(f)) | 255 | basename = os.path.basename(f) |
220 | 256 | dest_file = "%s/%s" % (dest, basename) | ||
221 | 257 | stream_path = "%s/%s" % (path, basename) | ||
222 | 154 | shutil.copyfile(f, dest_file) | 258 | shutil.copyfile(f, dest_file) |
223 | 259 | pkg_file = f[len(tmp):] | ||
224 | 260 | while pkg_file.startswith('/'): | ||
225 | 261 | pkg_file = pkg_file[1:] | ||
226 | 262 | items[basename] = make_item( | ||
227 | 263 | 'bootloader', pkg_file, dest_file, stream_path, | ||
228 | 264 | src_packages) | ||
229 | 155 | elif ',' in i: | 265 | elif ',' in i: |
230 | 156 | # Copy the a file from the package using a new name | 266 | # Copy the a file from the package using a new name |
231 | 157 | src_file, dest_file = i.split(',') | 267 | src_file, dest_file = i.split(',') |
235 | 158 | src_file = "%s/%s" % (tmp, src_file.strip()) | 268 | dest_file = dest_file.strip() |
236 | 159 | dest_file = "%s/%s" % (dest, dest_file.strip()) | 269 | full_src_file_path = "%s/%s" % (tmp, src_file.strip()) |
237 | 160 | shutil.copyfile(src_file, dest_file) | 270 | stream_path = "%s/%s" % (path, dest_file) |
238 | 271 | full_dest_file_path = "%s/%s" % (dest, dest_file) | ||
239 | 272 | shutil.copyfile(full_src_file_path, full_dest_file_path) | ||
240 | 273 | items[dest_file] = make_item( | ||
241 | 274 | 'bootloader', src_file, full_dest_file_path, stream_path, | ||
242 | 275 | src_packages) | ||
243 | 161 | else: | 276 | else: |
244 | 162 | # Straight copy | 277 | # Straight copy |
245 | 278 | basename = os.path.basename(i) | ||
246 | 163 | src_file = "%s/%s" % (tmp, i) | 279 | src_file = "%s/%s" % (tmp, i) |
248 | 164 | dest_file = "%s/%s" % (dest, os.path.basename(src_file)) | 280 | dest_file = "%s/%s" % (dest, basename) |
249 | 281 | stream_path = "%s/%s" % (path, basename) | ||
250 | 165 | shutil.copyfile(src_file, dest_file) | 282 | shutil.copyfile(src_file, dest_file) |
251 | 283 | items[basename] = make_item( | ||
252 | 284 | 'bootloader', i, dest_file, stream_path, src_packages) | ||
253 | 166 | else: | 285 | else: |
254 | 286 | dest = os.path.join(dest, grub_output) | ||
255 | 167 | # You can only tell grub to use modules from one directory | 287 | # You can only tell grub to use modules from one directory |
256 | 168 | modules_path = "%s/%s" % (tmp, files[0]) | 288 | modules_path = "%s/%s" % (tmp, files[0]) |
257 | 169 | modules = [] | 289 | modules = [] |
258 | @@ -189,4 +309,9 @@ | |||
259 | 189 | '-O', grub_format, | 309 | '-O', grub_format, |
260 | 190 | '-d', modules_path, | 310 | '-d', modules_path, |
261 | 191 | ] + modules) | 311 | ] + modules) |
262 | 312 | basename = os.path.basename(dest) | ||
263 | 313 | stream_path = "%s/%s" % (path, basename) | ||
264 | 314 | items[basename] = make_item( | ||
265 | 315 | 'bootloader', files[0], dest, stream_path, src_packages) | ||
266 | 192 | shutil.rmtree(tmp) | 316 | shutil.rmtree(tmp) |
267 | 317 | return archive_files(items, target) | ||
268 | 193 | 318 | ||
269 | === modified file 'meph2/commands/meph2_util.py' | |||
270 | --- meph2/commands/meph2_util.py 2016-08-01 19:15:59 +0000 | |||
271 | +++ meph2/commands/meph2_util.py 2016-08-24 20:40:59 +0000 | |||
272 | @@ -1,7 +1,7 @@ | |||
273 | 1 | #!/usr/bin/python3 | 1 | #!/usr/bin/python3 |
274 | 2 | 2 | ||
275 | 3 | import argparse | 3 | import argparse |
277 | 4 | import glob | 4 | from datetime import datetime |
278 | 5 | import copy | 5 | import copy |
279 | 6 | import os | 6 | import os |
280 | 7 | from functools import partial | 7 | from functools import partial |
281 | @@ -176,9 +176,13 @@ | |||
282 | 176 | (pedigree, sutil.products_exdata( | 176 | (pedigree, sutil.products_exdata( |
283 | 177 | src, pedigree, include_top=False, | 177 | src, pedigree, include_top=False, |
284 | 178 | insert_fieldnames=False)),) | 178 | insert_fieldnames=False)),) |
285 | 179 | |||
286 | 179 | return super(BareMirrorWriter, self).insert_item( | 180 | return super(BareMirrorWriter, self).insert_item( |
287 | 180 | data, src, target, pedigree, contentsource) | 181 | data, src, target, pedigree, contentsource) |
288 | 181 | 182 | ||
289 | 183 | def remove_item(self, data, src, target, pedigree): | ||
290 | 184 | return | ||
291 | 185 | |||
292 | 182 | def remove_version(self, data, src, target, pedigree): | 186 | def remove_version(self, data, src, target, pedigree): |
293 | 183 | # sync doesnt filter on things to be removed, so | 187 | # sync doesnt filter on things to be removed, so |
294 | 184 | # we have to do that here. | 188 | # we have to do that here. |
295 | @@ -187,9 +191,6 @@ | |||
296 | 187 | 191 | ||
297 | 188 | self.removed_versions.append(pedigree) | 192 | self.removed_versions.append(pedigree) |
298 | 189 | 193 | ||
299 | 190 | def remove_item(self, data, src, target, pedigree): | ||
300 | 191 | return | ||
301 | 192 | |||
302 | 193 | def insert_products(self, path, target, content): | 194 | def insert_products(self, path, target, content): |
303 | 194 | # insert_item and insert_products would not be strictly necessary | 195 | # insert_item and insert_products would not be strictly necessary |
304 | 195 | # they're here, though, to keep a list of those things appended. | 196 | # they're here, though, to keep a list of those things appended. |
305 | @@ -231,7 +232,9 @@ | |||
306 | 231 | 232 | ||
307 | 232 | sutil.products_condense( | 233 | sutil.products_condense( |
308 | 233 | self.tproducts, | 234 | self.tproducts, |
310 | 234 | sticky=['di_version', 'kpackage', 'sha256', 'md5', 'path']) | 235 | sticky=[ |
311 | 236 | 'di_version', 'kpackage', 'sha256', 'md5', 'path', 'ftype', | ||
312 | 237 | 'src_package', 'src_version', 'src_release']) | ||
313 | 235 | 238 | ||
314 | 236 | self.tproducts['updated'] = sutil.timestamp() | 239 | self.tproducts['updated'] = sutil.timestamp() |
315 | 237 | 240 | ||
316 | @@ -525,100 +528,91 @@ | |||
317 | 525 | } | 528 | } |
318 | 526 | 529 | ||
319 | 527 | 530 | ||
320 | 528 | def get_file_info(f): | ||
321 | 529 | size = 0 | ||
322 | 530 | sha256 = hashlib.sha256() | ||
323 | 531 | with open(f, 'rb') as f: | ||
324 | 532 | for chunk in iter(lambda: f.read(2**15), b''): | ||
325 | 533 | sha256.update(chunk) | ||
326 | 534 | size += len(chunk) | ||
327 | 535 | return sha256.hexdigest(), size | ||
328 | 536 | |||
329 | 537 | |||
330 | 538 | def import_bootloaders(args, product_tree, cfgdata): | 531 | def import_bootloaders(args, product_tree, cfgdata): |
332 | 539 | for bootloader in cfgdata['bootloaders']: | 532 | for firmware_platform in cfgdata['bootloaders']: |
333 | 540 | product_id = cfgdata['product_id'].format( | 533 | product_id = cfgdata['product_id'].format( |
343 | 541 | bootloader=bootloader['bootloader']) | 534 | os=firmware_platform['os'], |
344 | 542 | package = get_package( | 535 | firmware_platform=firmware_platform['firmware-platform'], |
345 | 543 | bootloader['archive'], bootloader['packages'][0], | 536 | arch=firmware_platform['arch']) |
346 | 544 | bootloader['arch'], bootloader['release']) | 537 | # Compile a list of the latest packages in the archive this bootloader |
347 | 545 | 538 | # pulls files from | |
348 | 546 | if ( | 539 | src_packages = {} |
349 | 547 | product_id in product_tree['products'] and | 540 | for package in firmware_platform['packages']: |
350 | 548 | package['Version'] in product_tree['products'][product_id][ | 541 | package_info = get_package( |
351 | 549 | 'versions']): | 542 | firmware_platform['archive'], package, |
352 | 543 | firmware_platform['arch'], firmware_platform['release']) | ||
353 | 544 | # Some source packages include the package version in the source | ||
354 | 545 | # name. Only take the name, not the version. | ||
355 | 546 | src_package_name = package_info['Source'].split(' ')[0] | ||
356 | 547 | src_packages[src_package_name] = { | ||
357 | 548 | 'src_version': package_info['Version'], | ||
358 | 549 | 'src_release': firmware_platform['release'], | ||
359 | 550 | 'found': False, | ||
360 | 551 | } | ||
361 | 552 | # Check if the bootloader has been built from the latest version of | ||
362 | 553 | # the packages in the archive | ||
363 | 554 | if product_id in product_tree['products']: | ||
364 | 555 | versions = product_tree['products'][product_id]['versions'] | ||
365 | 556 | for data in versions.values(): | ||
366 | 557 | for item in data['items'].values(): | ||
367 | 558 | src_package = src_packages.get(item['src_package']) | ||
368 | 559 | if ( | ||
369 | 560 | src_package is not None and | ||
370 | 561 | src_package['src_version'] == item['src_version'] | ||
371 | 562 | and | ||
372 | 563 | src_package['src_release'] == item['src_release']): | ||
373 | 564 | src_packages[item['src_package']]['found'] = True | ||
374 | 565 | bootloader_uptodate = True | ||
375 | 566 | for src_package in src_packages.values(): | ||
376 | 567 | if not src_package['found']: | ||
377 | 568 | bootloader_uptodate = False | ||
378 | 569 | # Bootloader built from the latest packages already in stream | ||
379 | 570 | if bootloader_uptodate: | ||
380 | 550 | print( | 571 | print( |
383 | 551 | "Product %s at version %s exists, skipping" % ( | 572 | "Product %s built from the latest package set, skipping" |
384 | 552 | product_id, package['Version'])) | 573 | % product_id) |
385 | 553 | continue | 574 | continue |
386 | 575 | # Find an unused version | ||
387 | 576 | today = datetime.utcnow().strftime('%Y%m%d') | ||
388 | 577 | point = 0 | ||
389 | 578 | while True: | ||
390 | 579 | version = "%s.%d" % (today, point) | ||
391 | 580 | products = product_tree['products'] | ||
392 | 581 | if ( | ||
393 | 582 | product_id not in products or | ||
394 | 583 | version not in products[product_id]['versions'].keys()): | ||
395 | 584 | break | ||
396 | 585 | point += 1 | ||
397 | 554 | if product_tree['products'].get(product_id) is None: | 586 | if product_tree['products'].get(product_id) is None: |
398 | 555 | print("Creating new product %s" % product_id) | 587 | print("Creating new product %s" % product_id) |
399 | 556 | product_tree['products'][product_id] = { | 588 | product_tree['products'][product_id] = { |
400 | 557 | 'label': 'daily', | 589 | 'label': 'daily', |
406 | 558 | 'arch': bootloader['arch'], | 590 | 'arch': firmware_platform['arch'], |
407 | 559 | 'subarch': 'generic', | 591 | 'arches': firmware_platform['arches'], |
408 | 560 | 'subarches': 'generic', | 592 | 'os': firmware_platform['os'], |
409 | 561 | 'os': 'bootloader', | 593 | 'bootloader-type': firmware_platform['firmware-platform'], |
405 | 562 | 'release': bootloader['bootloader'], | ||
410 | 563 | 'versions': {}, | 594 | 'versions': {}, |
411 | 564 | } | 595 | } |
412 | 565 | path = os.path.join( | 596 | path = os.path.join( |
415 | 566 | 'bootloaders', bootloader['bootloader'], bootloader['arch'], | 597 | 'bootloaders', firmware_platform['firmware-platform'], |
416 | 567 | package['Version']) | 598 | firmware_platform['arch'], version) |
417 | 568 | dest = os.path.join(args.target, path) | 599 | dest = os.path.join(args.target, path) |
418 | 569 | os.makedirs(dest) | 600 | os.makedirs(dest) |
420 | 570 | grub_format = bootloader.get('grub_format') | 601 | grub_format = firmware_platform.get('grub_format') |
421 | 571 | if grub_format is not None: | 602 | if grub_format is not None: |
423 | 572 | dest = os.path.join(dest, bootloader['grub_output']) | 603 | dest = os.path.join(dest, firmware_platform['grub_output']) |
424 | 573 | print( | 604 | print( |
425 | 574 | "Downloading and creating %s version %s" % ( | 605 | "Downloading and creating %s version %s" % ( |
473 | 575 | product_id, package['Version'])) | 606 | product_id, version)) |
474 | 576 | extract_files_from_packages( | 607 | items = extract_files_from_packages( |
475 | 577 | bootloader['archive'], bootloader['packages'], | 608 | firmware_platform['archive'], firmware_platform['packages'], |
476 | 578 | bootloader['arch'], bootloader['files'], bootloader['release'], | 609 | firmware_platform['arch'], firmware_platform['files'], |
477 | 579 | dest, grub_format, bootloader.get('grub_config')) | 610 | firmware_platform['release'], args.target, path, grub_format, |
478 | 580 | if grub_format is not None: | 611 | firmware_platform.get('grub_config'), |
479 | 581 | sha256, size = get_file_info(dest) | 612 | firmware_platform.get('grub_output')) |
480 | 582 | product_tree['products'][product_id]['versions'][ | 613 | product_tree['products'][product_id]['versions'][version] = { |
481 | 583 | package['Version']] = { | 614 | 'items': items |
482 | 584 | 'items': { | 615 | } |
436 | 585 | bootloader['grub_output']: { | ||
437 | 586 | 'ftype': 'bootloader', | ||
438 | 587 | 'sha256': sha256, | ||
439 | 588 | 'path': os.path.join( | ||
440 | 589 | path, bootloader['grub_output']), | ||
441 | 590 | 'size': size, | ||
442 | 591 | } | ||
443 | 592 | } | ||
444 | 593 | } | ||
445 | 594 | else: | ||
446 | 595 | items = {} | ||
447 | 596 | for i in bootloader['files']: | ||
448 | 597 | basename = os.path.basename(i) | ||
449 | 598 | dest_file = os.path.join(dest, basename) | ||
450 | 599 | if '*' in dest_file or '?' in dest_file: | ||
451 | 600 | # Process multiple files copied with a wildcard | ||
452 | 601 | unglobbed_files = glob.glob(dest_file) | ||
453 | 602 | elif ',' in dest_file: | ||
454 | 603 | # If we're renaming the file from the package use the new | ||
455 | 604 | # name. | ||
456 | 605 | _, basename = i.split(',') | ||
457 | 606 | basename = basename.strip() | ||
458 | 607 | dest_file = os.path.join(dest, basename) | ||
459 | 608 | unglobbed_files = [dest_file] | ||
460 | 609 | else: | ||
461 | 610 | unglobbed_files = [dest_file] | ||
462 | 611 | for f in unglobbed_files: | ||
463 | 612 | basename = os.path.basename(f) | ||
464 | 613 | sha256, size = get_file_info(f) | ||
465 | 614 | items[basename] = { | ||
466 | 615 | 'ftype': 'bootloader', | ||
467 | 616 | 'sha256': sha256, | ||
468 | 617 | 'path': os.path.join(path, basename), | ||
469 | 618 | 'size': size, | ||
470 | 619 | } | ||
471 | 620 | product_tree['products'][product_id]['versions'][ | ||
472 | 621 | package['Version']] = {'items': items} | ||
483 | 622 | 616 | ||
484 | 623 | 617 | ||
485 | 624 | def main_import(args): | 618 | def main_import(args): |
As discussed on IRC pull the bootloaders from Xenial. The sample output has been updated.