230.1.1
by Aaron Bentley
Implement making agents. |
1 |
#!/usr/bin/env python
|
2 |
from argparse import ArgumentParser |
|
231.1.1
by Aaron Bentley
Support multiple series. |
3 |
from copy import deepcopy |
231.1.6
by Aaron Bentley
Updates from review. |
4 |
from datetime import datetime |
230.1.1
by Aaron Bentley
Implement making agents. |
5 |
import hashlib |
6 |
import os |
|
284.1.1
by Aaron Bentley
Support building gui json. |
7 |
import re |
230.1.1
by Aaron Bentley
Implement making agents. |
8 |
import sys |
9 |
||
251.1.1
by Aaron Bentley
Remove obsolete functionality. |
10 |
from simplestreams.generate_simplestreams import json_dump |
11 |
||
231.1.4
by Aaron Bentley
Support using one agent for all living ubuntu. |
12 |
from build_package import juju_series |
230.1.1
by Aaron Bentley
Implement making agents. |
13 |
|
284.1.1
by Aaron Bentley
Support building gui json. |
14 |
__metaclass__ = type |
15 |
||
230.1.1
by Aaron Bentley
Implement making agents. |
16 |
|
231.1.6
by Aaron Bentley
Updates from review. |
17 |
supported_windows_releases = ( |
262.1.3
by Curtis Hovey
Add win2016 and win2016nano. |
18 |
'win2012', 'win2012hv', 'win2012hvr2', 'win2012r2', 'win2016', |
19 |
'win2016nano', 'win7', 'win81', 'win8', 'win10', |
|
231.1.6
by Aaron Bentley
Updates from review. |
20 |
)
|
21 |
||
22 |
||
230.1.1
by Aaron Bentley
Implement making agents. |
23 |
def parse_args(): |
24 |
parser = ArgumentParser() |
|
25 |
parsers = parser.add_subparsers(dest='command') |
|
26 |
ubuntu = parsers.add_parser('ubuntu') |
|
231.1.4
by Aaron Bentley
Support using one agent for all living ubuntu. |
27 |
living_ubuntu = parsers.add_parser('living-ubuntu') |
231.1.2
by Aaron Bentley
Support Windows. |
28 |
windows = parsers.add_parser('windows') |
231.1.3
by Aaron Bentley
Support Centos. |
29 |
centos = parsers.add_parser('centos') |
231.1.4
by Aaron Bentley
Support using one agent for all living ubuntu. |
30 |
for subparser in [ubuntu, living_ubuntu, windows, centos]: |
231.1.5
by Aaron Bentley
Unify argument order. |
31 |
subparser.add_argument('tarfile') |
32 |
subparser.add_argument('revision_build') |
|
231.1.2
by Aaron Bentley
Support Windows. |
33 |
subparser.add_argument('version') |
231.1.5
by Aaron Bentley
Unify argument order. |
34 |
for subparser in [ubuntu, living_ubuntu]: |
35 |
subparser.add_argument('arch') |
|
36 |
ubuntu.add_argument('release') |
|
37 |
ubuntu.add_argument('series') |
|
284.1.1
by Aaron Bentley
Support building gui json. |
38 |
gui = parsers.add_parser('gui') |
39 |
gui.add_argument('tarfile') |
|
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
40 |
gui.add_argument('stream') |
230.1.1
by Aaron Bentley
Implement making agents. |
41 |
return parser.parse_args() |
42 |
||
43 |
||
284.1.5
by Aaron Bentley
Cleanup. |
44 |
class FileStanzaWriter: |
45 |
"""Base class to write stanzas about files."""
|
|
284.1.1
by Aaron Bentley
Support building gui json. |
46 |
|
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
47 |
def __init__(self, filename, stream, version, ftype, tarfile, |
48 |
path): |
|
284.1.1
by Aaron Bentley
Support building gui json. |
49 |
self.filename = filename |
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
50 |
self.stream = stream |
284.1.1
by Aaron Bentley
Support building gui json. |
51 |
self.version = version |
52 |
self.tarfile = tarfile |
|
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
53 |
self.path = path |
284.1.1
by Aaron Bentley
Support building gui json. |
54 |
self.version_name = datetime.utcnow().strftime('%Y%m%d') |
55 |
self.ftype = ftype |
|
56 |
||
284.1.2
by Aaron Bentley
Make product_name and item_name make_path_stanza parameters. |
57 |
def make_path_stanza(self, product_name, item_name, hashes, size): |
284.1.5
by Aaron Bentley
Cleanup. |
58 |
"""Make a path stanza.
|
59 |
||
60 |
:param product_name: The simplestreams product name.
|
|
61 |
:param item_name: The simplestream item name.
|
|
62 |
:param hahes: A dict mapping hash name to the hash of the file with
|
|
63 |
that hash. hashlib names (e.g. "sha256") should be used.
|
|
64 |
"""
|
|
284.1.1
by Aaron Bentley
Support building gui json. |
65 |
stanza = { |
66 |
'content_id': self.content_id, |
|
284.1.2
by Aaron Bentley
Make product_name and item_name make_path_stanza parameters. |
67 |
'product_name': product_name, |
68 |
'item_name': item_name, |
|
284.1.1
by Aaron Bentley
Support building gui json. |
69 |
'version_name': self.version_name, |
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
70 |
'path': self.path, |
284.1.1
by Aaron Bentley
Support building gui json. |
71 |
'size': size, |
72 |
'version': self.version, |
|
73 |
'format': 'products:1.0', |
|
74 |
'ftype': self.ftype, |
|
75 |
}
|
|
76 |
stanza.update(deepcopy(hashes)) |
|
77 |
return stanza |
|
78 |
||
79 |
def write_stanzas(self): |
|
284.1.5
by Aaron Bentley
Cleanup. |
80 |
"""Write stanzas about the file to the filename.
|
81 |
||
82 |
This calculates the hashes as part of the procedure.
|
|
83 |
"""
|
|
284.1.1
by Aaron Bentley
Support building gui json. |
84 |
with open(self.tarfile) as tarfile_fp: |
85 |
content = tarfile_fp.read() |
|
86 |
hashes = {} |
|
87 |
for hash_algorithm in self.hash_algorithms: |
|
88 |
hash_obj = hashlib.new(hash_algorithm) |
|
89 |
hash_obj.update(content) |
|
90 |
hashes[hash_algorithm] = hash_obj.hexdigest() |
|
91 |
stanzas = list(self.make_stanzas(hashes, len(content))) |
|
92 |
json_dump(stanzas, self.filename) |
|
93 |
||
94 |
||
284.1.5
by Aaron Bentley
Cleanup. |
95 |
class StanzaWriter(FileStanzaWriter): |
231.1.1
by Aaron Bentley
Support multiple series. |
96 |
|
259.1.7
by Aaron Bentley
Use specified agent-streams. |
97 |
def __init__(self, releases, arch, version, tarfile, filename, |
98 |
revision_build=None, agent_stream=None): |
|
99 |
if agent_stream is None: |
|
284.1.1
by Aaron Bentley
Support building gui json. |
100 |
agent_stream = 'revision-build-{}'.format(revision_build) |
259.1.7
by Aaron Bentley
Use specified agent-streams. |
101 |
if revision_build is None: |
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
102 |
path = 'agent/{}/{}'.format( |
259.1.7
by Aaron Bentley
Use specified agent-streams. |
103 |
version, os.path.basename(tarfile)) |
104 |
else: |
|
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
105 |
path = 'agent/revision-build-{}/{}'.format( |
259.1.7
by Aaron Bentley
Use specified agent-streams. |
106 |
revision_build, os.path.basename(tarfile)) |
284.1.1
by Aaron Bentley
Support building gui json. |
107 |
super(StanzaWriter, self).__init__(filename, agent_stream, version, |
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
108 |
'tar.gz', tarfile, path) |
284.1.1
by Aaron Bentley
Support building gui json. |
109 |
self.releases = releases |
110 |
self.arch = arch |
|
231.1.1
by Aaron Bentley
Support multiple series. |
111 |
self.filename = filename |
112 |
||
284.1.5
by Aaron Bentley
Cleanup. |
113 |
hash_algorithms = frozenset(['sha256', 'md5']) |
284.1.1
by Aaron Bentley
Support building gui json. |
114 |
|
115 |
@property
|
|
116 |
def content_id(self): |
|
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
117 |
return 'com.ubuntu.juju:{}:tools'.format(self.stream) |
284.1.1
by Aaron Bentley
Support building gui json. |
118 |
|
231.1.1
by Aaron Bentley
Support multiple series. |
119 |
@classmethod
|
259.1.7
by Aaron Bentley
Use specified agent-streams. |
120 |
def for_ubuntu(cls, release, series, arch, version, tarfile, |
121 |
revision_build=None, agent_stream=None): |
|
122 |
if revision_build is None: |
|
123 |
filename = '{}-{}-{}-{}.json'.format( |
|
124 |
agent_stream, version, series, arch) |
|
125 |
else: |
|
126 |
filename = 'revision-build-{}-{}-{}.json'.format( |
|
127 |
revision_build, series, arch) |
|
231.1.1
by Aaron Bentley
Support multiple series. |
128 |
return cls( |
259.1.7
by Aaron Bentley
Use specified agent-streams. |
129 |
[(release, series)], arch, version, tarfile, filename, |
130 |
revision_build, agent_stream) |
|
231.1.1
by Aaron Bentley
Support multiple series. |
131 |
|
231.1.2
by Aaron Bentley
Support Windows. |
132 |
@classmethod
|
259.1.10
by Aaron Bentley
Support agent-streams for make_agent_json. |
133 |
def for_living_ubuntu(cls, arch, version, tarfile, revision_build=None, |
134 |
agent_stream=None): |
|
135 |
if revision_build is None: |
|
136 |
filename = '{}-{}-ubuntu-{}.json'.format( |
|
308
by Curtis Hovey
Added install-deps target. |
137 |
agent_stream, version, arch) |
259.1.10
by Aaron Bentley
Support agent-streams for make_agent_json. |
138 |
else: |
139 |
filename = 'revision-build-{}-ubuntu-{}.json'.format( |
|
308
by Curtis Hovey
Added install-deps target. |
140 |
revision_build, arch) |
231.1.4
by Aaron Bentley
Support using one agent for all living ubuntu. |
141 |
releases = [ |
142 |
(juju_series.get_version(name), name) for name |
|
143 |
in juju_series.get_living_names()] |
|
144 |
return cls( |
|
259.1.10
by Aaron Bentley
Support agent-streams for make_agent_json. |
145 |
releases, arch, version, tarfile, filename, revision_build, |
146 |
agent_stream) |
|
231.1.4
by Aaron Bentley
Support using one agent for all living ubuntu. |
147 |
|
148 |
@classmethod
|
|
259.1.10
by Aaron Bentley
Support agent-streams for make_agent_json. |
149 |
def for_windows(cls, version, tarfile, revision_build=None, |
150 |
agent_stream=None): |
|
151 |
if revision_build is None: |
|
152 |
filename = '{}-{}-windows.json'.format(agent_stream, version) |
|
153 |
else: |
|
154 |
filename = 'revision-build-{}-windows.json'.format( |
|
155 |
revision_build) |
|
231.1.6
by Aaron Bentley
Updates from review. |
156 |
releases = [(r, r) for r in supported_windows_releases] |
259.1.7
by Aaron Bentley
Use specified agent-streams. |
157 |
return cls(releases, 'amd64', version, tarfile, filename, |
259.1.10
by Aaron Bentley
Support agent-streams for make_agent_json. |
158 |
revision_build, agent_stream) |
231.1.2
by Aaron Bentley
Support Windows. |
159 |
|
231.1.3
by Aaron Bentley
Support Centos. |
160 |
@classmethod
|
259.1.10
by Aaron Bentley
Support agent-streams for make_agent_json. |
161 |
def for_centos(cls, version, tarfile, revision_build=None, |
162 |
agent_stream=None): |
|
163 |
if revision_build is None: |
|
164 |
filename = '{}-{}-centos.json'.format(agent_stream, version) |
|
165 |
else: |
|
166 |
filename = 'revision-build-{}-centos.json'.format(revision_build) |
|
259.1.7
by Aaron Bentley
Use specified agent-streams. |
167 |
return cls([('centos7', 'centos7')], 'amd64', version, tarfile, |
259.1.10
by Aaron Bentley
Support agent-streams for make_agent_json. |
168 |
filename, revision_build, agent_stream) |
231.1.3
by Aaron Bentley
Support Centos. |
169 |
|
259.1.7
by Aaron Bentley
Use specified agent-streams. |
170 |
def make_stanzas(self, hashes, size): |
231.1.1
by Aaron Bentley
Support multiple series. |
171 |
for release, series in self.releases: |
284.1.2
by Aaron Bentley
Make product_name and item_name make_path_stanza parameters. |
172 |
item_name = '{}-{}-{}'.format(self.version, series, self.arch) |
173 |
product_name = 'com.ubuntu.juju:{}:{}'.format(release, self.arch) |
|
174 |
stanza = self.make_path_stanza(product_name, item_name, hashes, |
|
175 |
size) |
|
284.1.1
by Aaron Bentley
Support building gui json. |
176 |
stanza.update({ |
231.1.1
by Aaron Bentley
Support multiple series. |
177 |
'arch': self.arch, |
178 |
'release': series, |
|
284.1.1
by Aaron Bentley
Support building gui json. |
179 |
})
|
231.1.1
by Aaron Bentley
Support multiple series. |
180 |
yield stanza |
230.1.1
by Aaron Bentley
Implement making agents. |
181 |
|
182 |
||
284.1.5
by Aaron Bentley
Cleanup. |
183 |
class GUIStanzaWriter(FileStanzaWriter): |
284.1.1
by Aaron Bentley
Support building gui json. |
184 |
|
284.1.5
by Aaron Bentley
Cleanup. |
185 |
hash_algorithms = frozenset(['sha256', 'sha1', 'md5']) |
284.1.1
by Aaron Bentley
Support building gui json. |
186 |
|
187 |
@property
|
|
188 |
def content_id(self): |
|
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
189 |
return 'com.canonical.streams:{}:gui'.format(self.stream) |
284.1.1
by Aaron Bentley
Support building gui json. |
190 |
|
191 |
@classmethod
|
|
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
192 |
def from_tarfile(cls, tarfile, stream): |
284.1.5
by Aaron Bentley
Cleanup. |
193 |
"""Use a tarfile and stream to instantiate this class."""
|
284.1.1
by Aaron Bentley
Support building gui json. |
194 |
tar_base = os.path.basename(tarfile) |
285.1.1
by Aaron Bentley
Update to match real jujugui tarball name. |
195 |
version = re.match('jujugui-(.*).tar.bz2', tar_base).group(1) |
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
196 |
filename = 'juju-gui-{}-{}.json'.format(stream, version) |
197 |
path = '/'.join(['gui', version, tar_base]) |
|
285.1.1
by Aaron Bentley
Update to match real jujugui tarball name. |
198 |
return cls(filename, stream, version, 'tar.bz2', tarfile, |
284.1.4
by Aaron Bentley
Remove incorrect agent references. |
199 |
path) |
284.1.1
by Aaron Bentley
Support building gui json. |
200 |
|
201 |
def make_stanzas(self, hashes, size): |
|
284.1.5
by Aaron Bentley
Cleanup. |
202 |
"""Return a single stanza for the gui.
|
203 |
||
204 |
The GUI is arch/os independent, so only one stanza is needed.
|
|
205 |
"""
|
|
286.1.1
by Aaron Bentley
Add juju-version to juju-gui metadata. |
206 |
stanza = self.make_path_stanza( |
207 |
'com.canonical.streams:gui', self.version, hashes, size) |
|
208 |
stanza['juju-version'] = 2 |
|
209 |
return [stanza] |
|
284.1.1
by Aaron Bentley
Support building gui json. |
210 |
|
211 |
||
230.1.1
by Aaron Bentley
Implement making agents. |
212 |
def main(): |
213 |
args = parse_args() |
|
214 |
kwargs = dict(args.__dict__) |
|
215 |
del kwargs['command'] |
|
231.1.1
by Aaron Bentley
Support multiple series. |
216 |
if args.command == 'ubuntu': |
217 |
writer = StanzaWriter.for_ubuntu(**kwargs) |
|
231.1.4
by Aaron Bentley
Support using one agent for all living ubuntu. |
218 |
if args.command == 'living-ubuntu': |
219 |
writer = StanzaWriter.for_living_ubuntu(**kwargs) |
|
231.1.3
by Aaron Bentley
Support Centos. |
220 |
elif args.command == 'windows': |
231.1.2
by Aaron Bentley
Support Windows. |
221 |
writer = StanzaWriter.for_windows(**kwargs) |
231.1.3
by Aaron Bentley
Support Centos. |
222 |
elif args.command == 'centos': |
223 |
writer = StanzaWriter.for_centos(**kwargs) |
|
284.1.1
by Aaron Bentley
Support building gui json. |
224 |
elif args.command == 'gui': |
225 |
writer = GUIStanzaWriter.from_tarfile(**kwargs) |
|
231.1.1
by Aaron Bentley
Support multiple series. |
226 |
writer.write_stanzas() |
230.1.1
by Aaron Bentley
Implement making agents. |
227 |
|
228 |
if __name__ == '__main__': |
|
229 |
sys.exit(main()) |