Merge lp:~ltrager/maas-images/create into lp:maas-images

Proposed by Lee Trager
Status: Rejected
Rejected by: Scott Moser
Proposed branch: lp:~ltrager/maas-images/create
Merge into: lp:maas-images
Diff against target: 129 lines (+90/-2)
2 files modified
meph2/commands/flags.py (+19/-0)
meph2/commands/meph2_util.py (+71/-2)
To merge this branch: bzr merge lp:~ltrager/maas-images/create
Reviewer Review Type Date Requested Status
maintainers of maas images Pending
Review via email: mp+321213@code.launchpad.net

Commit message

Add create command which allows creation of streams for arbitrary images.

Description of the change

The create command allows creating streams for arbitrary images. It can be used for ubuntu-core as follows

wget http://cdimage.ubuntu.com/ubuntu-core/16/stable/current/ubuntu-core-16-amd64.img.xz

meph2-util create --fields arch=amd64,kernel_snap=pc-kernel,gadget_snap=pc,gadget_title='PC',model_name=pc-amd64,brand_id=canonical,channel=stable,label=daily,os=ubuntu-core,os_title='Ubuntu Core',release=16,release_title='16',maas_supported=2.2,support_eol=2018-04-26 --image-path-postfix 16/pc ubuntu-core amd64 com.ubuntu.maas.daily:v4:download com.ubuntu.maas.daily:v4:16:amd64:pc:stable root-dd.xz curtin-ubuntu-core-16-amd64.img.xz ubuntu-core

Sample output - http://162.213.35.187/ubuntu-core/

To post a comment you must log in.
lp:~ltrager/maas-images/create updated
360. By Lee Trager

Set the item name to the ftype

361. By Lee Trager

Set the filename to the same as the ftype

Revision history for this message
Scott Moser (smoser) wrote :

I think this is more generically already present in streams in json2streams.
Do you think that could be used?

Revision history for this message
Scott Moser (smoser) wrote :

I'm going to mark this 'rejected'.

Lee, you can feel free to re-submit it to git.

Just trying to clean things up.

Unmerged revisions

361. By Lee Trager

Set the filename to the same as the ftype

360. By Lee Trager

Set the item name to the ftype

359. By Lee Trager

Add create command which creates streams for custom images.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'meph2/commands/flags.py'
2--- meph2/commands/flags.py 2016-09-26 15:21:43 +0000
3+++ meph2/commands/flags.py 2017-03-29 19:56:36 +0000
4@@ -102,6 +102,25 @@
5 COMMON_FLAGS['data_d'], COMMON_FLAGS['no-sign'],
6 ],
7 },
8+ 'create': {
9+ 'help': 'Create a new image entry in the stream.',
10+ 'opts': [
11+ COMMON_FLAGS['no-sign'],
12+ ('--fields', {
13+ 'help': (
14+ 'Comma seperated key value pairs to be added to listing.'),
15+ }),
16+ ('--image-path-postfix', {
17+ 'help': 'Optional path to postfix to standard image-path.'}),
18+ ('os', {'help': 'The OS name'}),
19+ ('arch', {'help': 'The architecture for the image.'}),
20+ ('content_id', {'help': 'The content_id of the stream.'}),
21+ ('product_name', {'help': 'The product name in the stream.'}),
22+ ('ftype', {'help': 'The filetype of the image.'}),
23+ ('image', {'help': 'The image to be imported.'}),
24+ COMMON_FLAGS['target'],
25+ ]
26+ },
27 }
28
29 # vi: ts=4 expandtab syntax=python
30
31=== modified file 'meph2/commands/meph2_util.py'
32--- meph2/commands/meph2_util.py 2017-02-11 01:29:31 +0000
33+++ meph2/commands/meph2_util.py 2017-03-29 19:56:36 +0000
34@@ -1,9 +1,11 @@
35 #!/usr/bin/python3
36
37+from datetime import datetime
38+from functools import partial
39 import argparse
40 import copy
41+import hashlib
42 import os
43-from functools import partial
44 import shutil
45 import sys
46
47@@ -13,8 +15,9 @@
48 from simplestreams import (
49 filters,
50 mirrors,
51+ objectstores,
52 util as sutil,
53- objectstores)
54+)
55
56
57 class BareMirrorWriter(mirrors.ObjectFilterMirror):
58@@ -418,6 +421,72 @@
59 return(mimport.main_import(args))
60
61
62+def main_create(args):
63+ product_stream_path = os.path.join(
64+ 'streams', 'v1', args.content_id + '.json')
65+ product_tree = util.empty_iid_products(args.content_id)
66+ product_tree['products'] = util.load_products(
67+ args.target, [product_stream_path])
68+ product_tree['updated'] = util.timestamp()
69+ product_tree['datatype'] = 'image-downloads'
70+
71+ product = product_tree['products'].get(args.product_name, {})
72+ if 'versions' not in product:
73+ product['os'] = args.os
74+ product['arch'] = args.arch
75+ product['versions'] = {}
76+ if args.fields is not None:
77+ for pair in args.fields.split(','):
78+ key, value = pair.split('=')
79+ product[key] = value
80+
81+ today = datetime.utcnow().strftime('%Y%m%d')
82+ ver_str = today
83+ i = 0
84+ while ver_str in product['versions']:
85+ i += 1
86+ ver_str = '%s.%d' % (today, i)
87+
88+ image_path = os.path.join(args.os, args.arch, ver_str)
89+ if args.image_path_postfix is not None:
90+ image_path = os.path.join(image_path, args.image_path_postfix)
91+ image_path = os.path.join(image_path, args.ftype)
92+ full_image_path = os.path.join(args.target, image_path)
93+ os.makedirs(os.path.dirname(full_image_path))
94+ shutil.copy2(args.image, full_image_path)
95+
96+ sha256 = hashlib.sha256()
97+ size = 0
98+ with open(args.image, 'rb') as fp:
99+ while True:
100+ chunk = fp.read(2**20)
101+ if not chunk:
102+ break
103+ sha256.update(chunk)
104+ size += len(chunk)
105+
106+ product['versions'][ver_str] = {
107+ 'items': {
108+ args.ftype: {
109+ 'ftype': args.ftype,
110+ 'path': image_path,
111+ 'sha256': sha256.hexdigest(),
112+ 'size': size,
113+ },
114+ },
115+ }
116+ product_tree['products'][args.product_name] = product
117+
118+ full_product_stream_path = os.path.join(args.target, product_stream_path)
119+ full_product_stream_dir = os.path.dirname(full_product_stream_path)
120+ if not os.path.exists(full_product_stream_dir):
121+ os.makedirs(full_product_stream_dir)
122+ with open(full_product_stream_path, 'wb') as fp:
123+ fp.write(util.dump_data(product_tree))
124+
125+ util.gen_index_and_sign(args.target, not args.no_sign)
126+
127+
128 def main():
129 parser = argparse.ArgumentParser()
130

Subscribers

People subscribed via source and target branches