Merge lp:~ltrager/maas-images/rename_squashfs into lp:maas-images
- rename_squashfs
- Merge into maas-ephemerals
Status: | Merged |
---|---|
Merged at revision: | 322 |
Proposed branch: | lp:~ltrager/maas-images/rename_squashfs |
Merge into: | lp:maas-images |
Diff against target: |
568 lines (+246/-128) 5 files modified
conf/bootloaders.yaml (+19/-11) meph2/commands/cloudimg_sync.py (+15/-21) meph2/commands/dpkg.py (+128/-8) meph2/commands/meph2_util.py (+75/-82) meph2/stream.py (+9/-6) |
To merge this branch: | bzr merge lp:~ltrager/maas-images/rename_squashfs |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Scott Moser (community) | Needs Fixing | ||
Andres Rodriguez (community) | Approve | ||
Review via email:
|
Commit message
Rename any SquashFS image to squashfs and include all versions in the bootloaders version string.
This renames any SquashFS file to squashfs, its filetype. This makes SquashFS images consistent with other filetypes which use their filetype as their filename. While testing I also noticed that the latest UEFI bootloader wasn't being downloaded. This is because the UEFI bootloader pulls from two different packages, shim.signed and grub-efi-
Description of the change
I've regenerated the beta V3 stream at http://
- 322. By Lee Trager
-
Store bootloaders in the base directory
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Scott Moser (smoser) wrote : | # |
looking at http://
Is there value in providing all the files in
http://
individually?
There are a *lot* of files there. if they're not useful individually then archiving them to a .tar might make sense.
simplestream versions (in the images streams 20160802) are C locale sorted to indicate newer or older. Are you sure that the version strings that you've used are guaranteed to continually sort newer in the C locale?
Ie,
Will all possible future versions of '3:6.03+
The thing that we've done for the 'd-i' kernels was to use the YYYYMMDD formated string of the first time we came upon these files in the archive. Then you're guaranteed to increment with dates.
I'd prefer 'root-squashfs' or 'root-image.
one inline comment
- 323. By Lee Trager
-
Limit the amount of PXE files provided, put all bootloaders in bootloaders dir, make bootloader version based on date stamp, store package names and version the bootloader came from
- 324. By Lee Trager
-
Use rename instead of move
- 325. By Lee Trager
-
Copy extra version fields during insert
- 326. By Lee Trager
-
Get all bootloaders from yakkety
- 327. By Lee Trager
-
Fix tox errors
- 328. By Lee Trager
-
Preserve other version items during insert
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Lee Trager (ltrager) wrote : | # |
> looking at http://
> level directory. Previously (v2) we only had "os" things there. Perhaps you
> could put all the bootloader things under a bootloaders/ dir ?
I actually originally had that but was trying to conform with what we were doing with the other images. I'll go back to putting everything in a bootloaders directory.
>
> Is there value in providing all the files in
> http://
> individually?
> There are a *lot* of files there. if they're not useful individually then
> archiving them to a .tar might make sense.
I limited the amount of PXE files we are publishing to just the ones we need(6).
>
> simplestream versions (in the images streams 20160802) are C locale sorted to
> indicate newer or older. Are you sure that the version strings that you've
> used are guaranteed to continually sort newer in the C locale?
> Ie,
> Will all possible future versions of '3:6.03+
> '1.66.2+
> correctly? It seems like there are cases where they would not (dpkg sorting
> is not simply C locale string based and the combined dpkg versions are even
> less likely to guarantee incremented).
>
> The thing that we've done for the 'd-i' kernels was to use the YYYYMMDD
> formated string of the first time we came upon these files in the archive.
> Then you're guaranteed to increment with dates.
I've changed the verisoning to use the date stamp as you suggested. In order to keep track of which packages are currently in the stream I've added a new item to the version, src_packages. src_packages contains a list of packages, their versions, and the release they were pulled from. This information may become useful to MAAS.
>
> I'd prefer 'root-squashfs' or 'root-image.
> squash image, but that is a nitpick and your usage of the ftype is not
> unreasonable. I just find 'squashfs' to not really tell you anything about
> the file (i have no idea of the contents by the filename).
>
I agree that squashfs isn't the most descriptive name which was why I originally kept the upstream name. I'd prefer to either conform to the upstream name or the filetype naming convention currently being used in the stream.
> one inline comment
Fixed.
I've updated http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Scott Moser (smoser) wrote : | # |
2 comments:
a.) as I said above, you should tar or other wise archive the pxe files and possibly even the other files. There is no point in delivering a 'ldlinux.c32' file as a single entity. No user (maas or other) would have an interest in downloading that file, so there is no reason to make it available as a single file.
b.) The way you've added the 'src_packages' is not valid.
Products have Versions
Versions have Items
Any of those can have key/value pairs associated with them, but the values must be be strings or integers, not arbitrary data types.
so instead of
"
{
"name": "grub-ieee1275-
"release": "yakkety",
"version": "2.02~beta2-
}
]
You should just package_name and package_version on the item if you want to maintain that information. If you have multiple package names, feel free to join them with a comma or something.
c.) Please make sure that a client (like sstream-mirror) can losslessly mirror the content you've provided.
- 329. By Lee Trager
-
Stick src_package, src_version, and src_release in each item.
- 330. By Lee Trager
-
Remove spaces from filename, make ftype sticky
- 331. By Lee Trager
-
Only take the source package name, don't include the version.
- 332. By Lee Trager
-
Tar up the bootloader files and include a description
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Lee Trager (ltrager) wrote : | # |
I've updated the branch as we discussed earlier today. I'm looking into removing release and what has to be done in MAAS for that.
Below is the output of com.ubuntu.
http://
- 333. By Lee Trager
-
Don't include release, include the arch
- 334. By Lee Trager
-
s/btype/
bootloader- type/ - 335. By Lee Trager
-
s/bootloader-
bases/bootloade r/g
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Lee Trager (ltrager) wrote : | # |
This review is getting a bit conflated with bootloaders. So I can do some SquashFS testing I've merged the original intent of this branch, renaming SquashFS images to 'squashfs' and created a new branch to finish discussing the bootloader changes at https:/
Preview Diff
1 | === modified file 'conf/bootloaders.yaml' |
2 | --- conf/bootloaders.yaml 2016-07-29 22:18:43 +0000 |
3 | +++ conf/bootloaders.yaml 2016-08-17 15:56:27 +0000 |
4 | @@ -1,33 +1,39 @@ |
5 | -product_id: "com.ubuntu.maas.daily:1:bootloaders-bases:{bootloader}" |
6 | -content_id: "com.ubuntu.maas:daily:1:bootloaders-bases-download" |
7 | +product_id: "com.ubuntu.maas.daily:1:bootloader:{firmware_platform}:{arch}" |
8 | +content_id: "com.ubuntu.maas:daily:1:bootloader-download" |
9 | |
10 | bootloaders: |
11 | - - bootloader: pxe |
12 | + - firmware-platform: pxe |
13 | packages: |
14 | - pxelinux |
15 | - syslinux-common |
16 | - arch: amd64 |
17 | + arch: i386 |
18 | + arches: i386,amd64 |
19 | archive: http://archive.ubuntu.com/ubuntu |
20 | - release: xenial |
21 | + release: yakkety |
22 | + bootloader-type: pxelinux |
23 | files: |
24 | - /usr/lib/PXELINUX/pxelinux.0 |
25 | - /usr/lib/syslinux/modules/bios/*.c32 |
26 | - - bootloader: uefi |
27 | + - firmware-platform: uefi |
28 | packages: |
29 | - shim-signed |
30 | - grub-efi-amd64-signed |
31 | arch: amd64 |
32 | + arches: amd64 |
33 | archive: http://archive.ubuntu.com/ubuntu |
34 | - release: xenial |
35 | + release: yakkety |
36 | + bootloader-type: grub-efi-signed |
37 | files: |
38 | - /usr/lib/shim/shim.efi.signed, bootx64.efi |
39 | - /usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed, grubx64.efi |
40 | - - bootloader: uefi-arm64 |
41 | + - firmware-platform: uefi |
42 | packages: |
43 | - grub-efi-arm64-bin |
44 | arch: arm64 |
45 | + arches: arm64 |
46 | archive: http://ports.ubuntu.com |
47 | - release: xenial |
48 | + release: yakkety |
49 | + bootloader-type: grub-efi |
50 | files: |
51 | - /usr/lib/grub/arm64-efi/ |
52 | grub_format: arm64-efi |
53 | @@ -41,12 +47,14 @@ |
54 | # Failed to load based on MAC address. |
55 | # Load arm64 by default, UEFI only supported by 64-bit |
56 | configfile (pxe)/grub/grub.cfg-default-arm64 |
57 | - - bootloader: powerkvm |
58 | + - firmware-platform: open-firmware |
59 | packages: |
60 | - grub-ieee1275-bin |
61 | arch: ppc64el |
62 | + arches: ppc64el,ppc64 |
63 | archive: http://ports.ubuntu.com |
64 | - release: xenial |
65 | + release: yakkety |
66 | + bootloader-type: grub-ieee1275 |
67 | files: |
68 | - /usr/lib/grub/powerpc-ieee1275/ |
69 | grub_format: powerpc-ieee1275 |
70 | |
71 | === modified file 'meph2/commands/cloudimg_sync.py' |
72 | --- meph2/commands/cloudimg_sync.py 2016-08-08 19:59:18 +0000 |
73 | +++ meph2/commands/cloudimg_sync.py 2016-08-17 15:56:27 +0000 |
74 | @@ -160,16 +160,23 @@ |
75 | for prodname, items in cvret.items(): |
76 | for i in items: |
77 | filename = os.path.join(self.out_d, items[i]['path']) |
78 | - if 'squashfs' in i and not self.squashfs: |
79 | - # If we're not publishing the SquashFS image but one |
80 | - # was used to generate root-image.gz delete it. |
81 | - if os.path.exists(filename): |
82 | - os.remove(filename) |
83 | - continue |
84 | + if i == 'squashfs': |
85 | + if self.squashfs: |
86 | + # Verify upstream SHA256 of SquashFS images and add the |
87 | + # SHA256 and size to our stream. |
88 | + self._verify_sha256(filename, flat['sha256']) |
89 | + items[i]['sha256'] = flat['sha256'] |
90 | + items[i]['size'] = int(flat['size']) |
91 | + else: |
92 | + # If we're not publishing the SquashFS image but one |
93 | + # was used to generate root-image.gz delete it. |
94 | + if os.path.exists(filename): |
95 | + os.remove(filename) |
96 | + continue |
97 | elif i == 'root-image.gz' and self.squashfs: |
98 | # If we're publishing the SquashFS image we don't need the |
99 | - # root-image after its been used to generate kernels. Older |
100 | - # Ubuntu releases (<16.04) don't have SquashFS images |
101 | + # root-image after its been used to extract the kernels. |
102 | + # Older Ubuntu releases (<16.04) don't have SquashFS images |
103 | # published, so only remove if a SquashFS file exists. |
104 | squashfs_image = os.path.join( |
105 | os.path.dirname(filename), '*squashfs') |
106 | @@ -186,19 +193,6 @@ |
107 | if os.path.exists(filename): |
108 | os.remove(filename) |
109 | continue |
110 | - if i == 'squashfs': |
111 | - # Verify upstream SHA256 of SquashFS images and add |
112 | - # SHA256 and size to our stream. |
113 | - self._verify_sha256(filename, flat['sha256']) |
114 | - items[i]['sha256'] = flat['sha256'] |
115 | - items[i]['size'] = int(flat['size']) |
116 | - elif i == 'squashfs.manifest': |
117 | - manifest_pedigree = pedigree[:2] + ('squashfs.manifest',) |
118 | - manifest_flat = sutil.products_exdata( |
119 | - src, manifest_pedigree) |
120 | - self._verify_sha256(filename, manifest_flat['sha256']) |
121 | - items[i]['sha256'] = manifest_flat['sha256'] |
122 | - items[i]['size'] = int(manifest_flat['size']) |
123 | sutil.products_set( |
124 | self.content_t, items[i], (prodname, vername, i)) |
125 | |
126 | |
127 | === modified file 'meph2/commands/dpkg.py' |
128 | --- meph2/commands/dpkg.py 2016-08-03 13:00:03 +0000 |
129 | +++ meph2/commands/dpkg.py 2016-08-17 15:56:27 +0000 |
130 | @@ -6,6 +6,7 @@ |
131 | import os |
132 | import re |
133 | import sys |
134 | +import tarfile |
135 | import tempfile |
136 | import glob |
137 | |
138 | @@ -128,13 +129,93 @@ |
139 | pkg_path = os.path.join(dest, os.path.basename(package['Filename'])) |
140 | with open(pkg_path, 'wb') as stream: |
141 | stream.write(pkg_data) |
142 | + package['files'] = [] |
143 | + output = subprocess.check_output(['dpkg', '-c', pkg_path]) |
144 | + for line in output.decode('utf-8').split('\n'): |
145 | + # The file is the last column in the list. |
146 | + file_info = line.split() |
147 | + # Last line is just a newline |
148 | + if len(file_info) == 0: |
149 | + continue |
150 | + # Remove leading '.' if it exists |
151 | + if file_info[-1].startswith('.'): |
152 | + package['files'].append(file_info[-1][1:]) |
153 | + else: |
154 | + package['files'].append(file_info[-1]) |
155 | return package |
156 | |
157 | |
158 | +def get_file_info(f): |
159 | + size = 0 |
160 | + sha256 = hashlib.sha256() |
161 | + with open(f, 'rb') as f: |
162 | + for chunk in iter(lambda: f.read(2**15), b''): |
163 | + sha256.update(chunk) |
164 | + size += len(chunk) |
165 | + return sha256.hexdigest(), size |
166 | + |
167 | + |
168 | +def make_item(ftype, src_file, dest_file, stream_path, src_packages): |
169 | + sha256, size = get_file_info(dest_file) |
170 | + for src_package in src_packages: |
171 | + if src_file in src_package['files']: |
172 | + return { |
173 | + 'ftype': ftype, |
174 | + 'sha256': sha256, |
175 | + 'path': stream_path, |
176 | + 'size': size, |
177 | + 'src_package': src_package['src_package'], |
178 | + 'src_version': src_package['src_version'], |
179 | + 'src_release': src_package['src_release'], |
180 | + } |
181 | + raise ValueError("%s not found in src_packages" % src_file) |
182 | + |
183 | + |
184 | +def archive_files(items, target): |
185 | + """Archive multiple files from a src_package into archive.tar.xz.""" |
186 | + archive_items = {} |
187 | + new_items = {} |
188 | + # Create a mapping of source packages and the files that came from them. |
189 | + for item in items.values(): |
190 | + key = "%(src_package)s-%(src_release)-%(src_version)" % item |
191 | + if archive_items.get(key) is None: |
192 | + archive_items[key] = { |
193 | + 'src_package': item['src_package'], |
194 | + 'src_release': item['src_release'], |
195 | + 'src_version': item['src_version'], |
196 | + 'files': [item['path']], |
197 | + } |
198 | + else: |
199 | + archive_items[key]['files'].append(item['path']) |
200 | + for item in archive_items.values(): |
201 | + stream_path = os.path.join( |
202 | + os.path.dirname(item['files'][0]), |
203 | + '%s.tar.xz' % item['src_package']) |
204 | + full_path = os.path.join(target, stream_path) |
205 | + tar = tarfile.open(full_path, 'w:xz') |
206 | + for f in item['files']: |
207 | + item_full_path = os.path.join(target, f) |
208 | + tar.add(item_full_path, os.path.basename(item_full_path)) |
209 | + os.remove(item_full_path) |
210 | + tar.close() |
211 | + sha256, size = get_file_info(full_path) |
212 | + new_items[item['src_package']] = { |
213 | + 'ftype': 'archive.tar.xz', |
214 | + 'sha256': sha256, |
215 | + 'path': stream_path, |
216 | + 'size': size, |
217 | + 'src_package': item['src_package'], |
218 | + 'src_release': item['src_release'], |
219 | + 'src_version': item['src_version'], |
220 | + } |
221 | + return new_items |
222 | + |
223 | + |
224 | def extract_files_from_packages( |
225 | - archive, packages, architecture, files, release, dest, |
226 | - grub_format=None, grub_config=None): |
227 | + archive, packages, architecture, files, release, target, path, |
228 | + grub_format=None, grub_config=None, grub_output=None): |
229 | tmp = tempfile.mkdtemp(prefix='maas-images-') |
230 | + src_packages = [] |
231 | for package in packages: |
232 | package = get_package(archive, package, architecture, release, tmp) |
233 | pkg_path = os.path.join(tmp, os.path.basename(package['Filename'])) |
234 | @@ -142,7 +223,23 @@ |
235 | sys.stderr.write('%s not found in archives!' % package) |
236 | sys.exit(1) |
237 | subprocess.check_output(['dpkg', '-x', pkg_path, tmp]) |
238 | - |
239 | + new_source_package = True |
240 | + for src_package in src_packages: |
241 | + if src_package['src_package'] == package['Source']: |
242 | + new_source_package = False |
243 | + src_package['files'] += package['files'] |
244 | + if new_source_package: |
245 | + # Some source packages include the package version in the source |
246 | + # name. Only take the name, not the version. |
247 | + src_package = package['Source'].split(' ')[0] |
248 | + src_packages.append({ |
249 | + 'src_package': src_package, |
250 | + 'src_version': package['Version'], |
251 | + 'src_release': release, |
252 | + 'files': package['files'], |
253 | + }) |
254 | + dest = os.path.join(target, path) |
255 | + items = {} |
256 | if grub_format is None: |
257 | for i in files: |
258 | if '*' in i or '?' in i: |
259 | @@ -150,20 +247,38 @@ |
260 | src = "%s/%s" % (tmp, i) |
261 | unglobbed_files = glob.glob(src) |
262 | for f in unglobbed_files: |
263 | - dest_file = "%s/%s" % (dest, os.path.basename(f)) |
264 | + basename = os.path.basename(f) |
265 | + dest_file = "%s/%s" % (dest, basename) |
266 | + stream_path = "%s/%s" % (path, basename) |
267 | shutil.copyfile(f, dest_file) |
268 | + pkg_file = f[len(tmp):] |
269 | + if pkg_file.startswith('//'): |
270 | + pkg_file = pkg_file[1:] |
271 | + items[basename] = make_item( |
272 | + 'bootloader', pkg_file, dest_file, stream_path, |
273 | + src_packages) |
274 | elif ',' in i: |
275 | # Copy the a file from the package using a new name |
276 | src_file, dest_file = i.split(',') |
277 | - src_file = "%s/%s" % (tmp, src_file.strip()) |
278 | - dest_file = "%s/%s" % (dest, dest_file.strip()) |
279 | - shutil.copyfile(src_file, dest_file) |
280 | + dest_file = dest_file.strip() |
281 | + full_src_file_path = "%s/%s" % (tmp, src_file.strip()) |
282 | + stream_path = "%s/%s" % (path, dest_file) |
283 | + full_dest_file_path = "%s/%s" % (dest, dest_file) |
284 | + shutil.copyfile(full_src_file_path, full_dest_file_path) |
285 | + items[dest_file] = make_item( |
286 | + 'bootloader', src_file, full_dest_file_path, stream_path, |
287 | + src_packages) |
288 | else: |
289 | # Straight copy |
290 | + basename = os.path.basename(i) |
291 | src_file = "%s/%s" % (tmp, i) |
292 | - dest_file = "%s/%s" % (dest, os.path.basename(src_file)) |
293 | + dest_file = "%s/%s" % (dest, basename) |
294 | + stream_path = "%s/%s" % (path, basename) |
295 | shutil.copyfile(src_file, dest_file) |
296 | + items[basename] = make_item( |
297 | + 'bootloader', i, dest_file, stream_path, src_packages) |
298 | else: |
299 | + dest = os.path.join(dest, grub_output) |
300 | # You can only tell grub to use modules from one directory |
301 | modules_path = "%s/%s" % (tmp, files[0]) |
302 | modules = [] |
303 | @@ -189,4 +304,9 @@ |
304 | '-O', grub_format, |
305 | '-d', modules_path, |
306 | ] + modules) |
307 | + basename = os.path.basename(dest) |
308 | + stream_path = "%s/%s" % (path, basename) |
309 | + items[basename] = make_item( |
310 | + 'bootloader', files[0], dest, stream_path, src_packages) |
311 | shutil.rmtree(tmp) |
312 | + return archive_files(items, target) |
313 | |
314 | === modified file 'meph2/commands/meph2_util.py' |
315 | --- meph2/commands/meph2_util.py 2016-08-01 19:15:59 +0000 |
316 | +++ meph2/commands/meph2_util.py 2016-08-17 15:56:27 +0000 |
317 | @@ -1,7 +1,7 @@ |
318 | #!/usr/bin/python3 |
319 | |
320 | import argparse |
321 | -import glob |
322 | +from datetime import datetime |
323 | import copy |
324 | import os |
325 | from functools import partial |
326 | @@ -176,9 +176,13 @@ |
327 | (pedigree, sutil.products_exdata( |
328 | src, pedigree, include_top=False, |
329 | insert_fieldnames=False)),) |
330 | + |
331 | return super(BareMirrorWriter, self).insert_item( |
332 | data, src, target, pedigree, contentsource) |
333 | |
334 | + def remove_item(self, data, src, target, pedigree): |
335 | + return |
336 | + |
337 | def remove_version(self, data, src, target, pedigree): |
338 | # sync doesnt filter on things to be removed, so |
339 | # we have to do that here. |
340 | @@ -187,9 +191,6 @@ |
341 | |
342 | self.removed_versions.append(pedigree) |
343 | |
344 | - def remove_item(self, data, src, target, pedigree): |
345 | - return |
346 | - |
347 | def insert_products(self, path, target, content): |
348 | # insert_item and insert_products would not be strictly necessary |
349 | # they're here, though, to keep a list of those things appended. |
350 | @@ -231,7 +232,9 @@ |
351 | |
352 | sutil.products_condense( |
353 | self.tproducts, |
354 | - sticky=['di_version', 'kpackage', 'sha256', 'md5', 'path']) |
355 | + sticky=[ |
356 | + 'di_version', 'kpackage', 'sha256', 'md5', 'path', 'ftype', |
357 | + 'src_package', 'src_version', 'src_release']) |
358 | |
359 | self.tproducts['updated'] = sutil.timestamp() |
360 | |
361 | @@ -525,100 +528,90 @@ |
362 | } |
363 | |
364 | |
365 | -def get_file_info(f): |
366 | - size = 0 |
367 | - sha256 = hashlib.sha256() |
368 | - with open(f, 'rb') as f: |
369 | - for chunk in iter(lambda: f.read(2**15), b''): |
370 | - sha256.update(chunk) |
371 | - size += len(chunk) |
372 | - return sha256.hexdigest(), size |
373 | - |
374 | - |
375 | def import_bootloaders(args, product_tree, cfgdata): |
376 | - for bootloader in cfgdata['bootloaders']: |
377 | + for firmware_platform in cfgdata['bootloaders']: |
378 | product_id = cfgdata['product_id'].format( |
379 | - bootloader=bootloader['bootloader']) |
380 | - package = get_package( |
381 | - bootloader['archive'], bootloader['packages'][0], |
382 | - bootloader['arch'], bootloader['release']) |
383 | - |
384 | - if ( |
385 | - product_id in product_tree['products'] and |
386 | - package['Version'] in product_tree['products'][product_id][ |
387 | - 'versions']): |
388 | + firmware_platform=firmware_platform['firmware-platform'], |
389 | + arch=firmware_platform['arch']) |
390 | + # Compile a list of the latest packages in the archive this bootloader |
391 | + # pulls files from |
392 | + src_packages = {} |
393 | + for package in firmware_platform['packages']: |
394 | + package_info = get_package( |
395 | + firmware_platform['archive'], package, |
396 | + firmware_platform['arch'], firmware_platform['release']) |
397 | + # Some source packages include the package version in the source |
398 | + # name. Only take the name, not the version. |
399 | + src_package_name = package_info['Source'].split(' ')[0] |
400 | + src_packages[src_package_name] = { |
401 | + 'src_version': package_info['Version'], |
402 | + 'src_release': firmware_platform['release'], |
403 | + 'found': False, |
404 | + } |
405 | + # Check if the bootloader has been built from the latest version of |
406 | + # the packages in the archive |
407 | + if product_id in product_tree['products']: |
408 | + versions = product_tree['products'][product_id]['versions'] |
409 | + for data in versions.values(): |
410 | + for item in data['items'].values(): |
411 | + src_package = src_packages.get(item['src_package']) |
412 | + if ( |
413 | + src_package is not None and |
414 | + src_package['src_version'] == item['src_version'] |
415 | + and |
416 | + src_package['src_release'] == item['src_release']): |
417 | + src_packages[item['src_package']]['found'] = True |
418 | + bootloader_uptodate = True |
419 | + for src_package in src_packages.values(): |
420 | + if not src_package['found']: |
421 | + bootloader_uptodate = False |
422 | + # Bootloader built from the latest packages already in stream |
423 | + if bootloader_uptodate: |
424 | print( |
425 | - "Product %s at version %s exists, skipping" % ( |
426 | - product_id, package['Version'])) |
427 | + "Product %s built from the latest package set, skipping" |
428 | + % product_id) |
429 | continue |
430 | + # Find an unused version |
431 | + today = datetime.utcnow().strftime('%Y%m%d') |
432 | + point = 0 |
433 | + while True: |
434 | + version = "%s.%d" % (today, point) |
435 | + products = product_tree['products'] |
436 | + if ( |
437 | + product_id not in products or |
438 | + version not in products[product_id]['versions'].keys()): |
439 | + break |
440 | + point += 1 |
441 | if product_tree['products'].get(product_id) is None: |
442 | print("Creating new product %s" % product_id) |
443 | product_tree['products'][product_id] = { |
444 | 'label': 'daily', |
445 | - 'arch': bootloader['arch'], |
446 | - 'subarch': 'generic', |
447 | - 'subarches': 'generic', |
448 | + 'arch': firmware_platform['arch'], |
449 | + 'arches': firmware_platform['arches'], |
450 | 'os': 'bootloader', |
451 | - 'release': bootloader['bootloader'], |
452 | + 'bootloader-type': firmware_platform['bootloader-type'], |
453 | 'versions': {}, |
454 | } |
455 | path = os.path.join( |
456 | - 'bootloaders', bootloader['bootloader'], bootloader['arch'], |
457 | - package['Version']) |
458 | + 'bootloaders', firmware_platform['firmware-platform'], |
459 | + firmware_platform['arch'], version) |
460 | dest = os.path.join(args.target, path) |
461 | os.makedirs(dest) |
462 | - grub_format = bootloader.get('grub_format') |
463 | + grub_format = firmware_platform.get('grub_format') |
464 | if grub_format is not None: |
465 | - dest = os.path.join(dest, bootloader['grub_output']) |
466 | + dest = os.path.join(dest, firmware_platform['grub_output']) |
467 | print( |
468 | "Downloading and creating %s version %s" % ( |
469 | - product_id, package['Version'])) |
470 | - extract_files_from_packages( |
471 | - bootloader['archive'], bootloader['packages'], |
472 | - bootloader['arch'], bootloader['files'], bootloader['release'], |
473 | - dest, grub_format, bootloader.get('grub_config')) |
474 | - if grub_format is not None: |
475 | - sha256, size = get_file_info(dest) |
476 | - product_tree['products'][product_id]['versions'][ |
477 | - package['Version']] = { |
478 | - 'items': { |
479 | - bootloader['grub_output']: { |
480 | - 'ftype': 'bootloader', |
481 | - 'sha256': sha256, |
482 | - 'path': os.path.join( |
483 | - path, bootloader['grub_output']), |
484 | - 'size': size, |
485 | - } |
486 | - } |
487 | - } |
488 | - else: |
489 | - items = {} |
490 | - for i in bootloader['files']: |
491 | - basename = os.path.basename(i) |
492 | - dest_file = os.path.join(dest, basename) |
493 | - if '*' in dest_file or '?' in dest_file: |
494 | - # Process multiple files copied with a wildcard |
495 | - unglobbed_files = glob.glob(dest_file) |
496 | - elif ',' in dest_file: |
497 | - # If we're renaming the file from the package use the new |
498 | - # name. |
499 | - _, basename = i.split(',') |
500 | - basename = basename.strip() |
501 | - dest_file = os.path.join(dest, basename) |
502 | - unglobbed_files = [dest_file] |
503 | - else: |
504 | - unglobbed_files = [dest_file] |
505 | - for f in unglobbed_files: |
506 | - basename = os.path.basename(f) |
507 | - sha256, size = get_file_info(f) |
508 | - items[basename] = { |
509 | - 'ftype': 'bootloader', |
510 | - 'sha256': sha256, |
511 | - 'path': os.path.join(path, basename), |
512 | - 'size': size, |
513 | - } |
514 | - product_tree['products'][product_id]['versions'][ |
515 | - package['Version']] = {'items': items} |
516 | + product_id, version)) |
517 | + items = extract_files_from_packages( |
518 | + firmware_platform['archive'], firmware_platform['packages'], |
519 | + firmware_platform['arch'], firmware_platform['files'], |
520 | + firmware_platform['release'], args.target, path, grub_format, |
521 | + firmware_platform.get('grub_config'), |
522 | + firmware_platform.get('grub_output')) |
523 | + product_tree['products'][product_id]['versions'][version] = { |
524 | + 'items': items |
525 | + } |
526 | |
527 | |
528 | def main_import(args): |
529 | |
530 | === modified file 'meph2/stream.py' |
531 | --- meph2/stream.py 2016-07-22 15:31:57 +0000 |
532 | +++ meph2/stream.py 2016-08-17 15:56:27 +0000 |
533 | @@ -20,10 +20,7 @@ |
534 | PATH_FORMATS = { |
535 | 'root-image.gz': PATH_COMMON + "%(version_name)s/root-image.gz", |
536 | 'manifest': PATH_COMMON + "%(version_name)s/root-image.manifest", |
537 | - 'squashfs': PATH_COMMON + "%(version_name)s/%(img_name)s", |
538 | - 'squashfs.manifest': ( |
539 | - PATH_COMMON + "%(version_name)s/%(img_name)s.manifest" |
540 | - ), |
541 | + 'squashfs': PATH_COMMON + "%(version_name)s/squashfs", |
542 | 'boot-dtb': BOOT_COMMON + "/boot-dtb%(suffix)s", |
543 | 'boot-kernel': BOOT_COMMON + "/boot-kernel%(suffix)s", |
544 | 'boot-initrd': BOOT_COMMON + "/boot-initrd%(suffix)s", |
545 | @@ -120,8 +117,7 @@ |
546 | newitems = {} |
547 | |
548 | subs = {'release': release, 'arch': arch, |
549 | - 'version_name': version_name, 'version': version, |
550 | - 'img_name': os.path.basename(img_url)} |
551 | + 'version_name': version_name, 'version': version} |
552 | |
553 | rootimg_path = PATH_FORMATS['root-image.gz'] % subs |
554 | manifest_path = PATH_FORMATS['manifest'] % subs |
555 | @@ -243,6 +239,13 @@ |
556 | subprocess.check_call(gencmd) |
557 | LOG.info("finished: %s" % gencmd) |
558 | |
559 | + # If we're downloading a SquashFS file rename it to its filetype |
560 | + if img_url.endswith('squashfs'): |
561 | + base_dir = os.path.join(out_d, release, arch, version_name) |
562 | + src_squash = os.path.join(base_dir, os.path.basename(img_url)) |
563 | + dst_squash = os.path.join(base_dir, 'squashfs') |
564 | + os.rename(src_squash, dst_squash) |
565 | + |
566 | # get checksum and size of new files created |
567 | file_info = {} |
568 | for path in newpaths: |
lgtm! Can you please update that this wont break MAAS ?
Thanks.