Merge lp:~barry/ubuntu-system-image/grabber into lp:ubuntu-system-image/server

Proposed by Barry Warsaw
Status: Merged
Merged at revision: 268
Proposed branch: lp:~barry/ubuntu-system-image/grabber
Merge into: lp:ubuntu-system-image/server
Diff against target: 135 lines (+131/-0)
1 file modified
bin/grabber (+131/-0)
To merge this branch: bzr merge lp:~barry/ubuntu-system-image/grabber
Reviewer Review Type Date Requested Status
Registry Administrators Pending
Review via email: mp+259055@code.launchpad.net

Description of the change

Dead stupid grabber of device-channels.

To post a comment you must log in.
268. By Barry Warsaw

Put the index.json in the device subdir.

269. By Barry Warsaw

Now I know what the version-*.json files are for! (hint: copy-image)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'bin/grabber'
2--- bin/grabber 1970-01-01 00:00:00 +0000
3+++ bin/grabber 2015-05-14 18:22:27 +0000
4@@ -0,0 +1,131 @@
5+#!/usr/bin/python3
6+
7+# Copyright (C) 2015 Canonical Ltd.
8+# Author: Barry Warsaw <barry@ubuntu.com>
9+
10+# This program is free software: you can redistribute it and/or modify
11+# it under the terms of the GNU General Public License as published by
12+# the Free Software Foundation; version 3 of the License.
13+#
14+# This program is distributed in the hope that it will be useful,
15+# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+# GNU General Public License for more details.
18+#
19+# You should have received a copy of the GNU General Public License
20+# along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
22+"""Mirror a specific device/channel."""
23+
24+import os
25+import sys
26+import argparse
27+
28+from contextlib import suppress
29+from pathlib import Path
30+from systemimage.channel import Channels
31+from systemimage.curl import CurlDownloadManager
32+from systemimage.download import Record
33+from systemimage.index import Index
34+
35+
36+def main():
37+ parser = argparse.ArgumentParser(description=__doc__)
38+ parser.add_argument('root', help='Root directory for the local mirror')
39+ parser.add_argument('-c', '--channel', required=True,
40+ help='The channel to use')
41+ parser.add_argument('-d', '--device', required=True,
42+ help='The device to use')
43+ args = parser.parse_args()
44+
45+ root = Path(args.root).resolve()
46+ if not root.is_dir():
47+ print(root, 'must exist and be a directory', file=sys.stderr)
48+ return 1
49+
50+ # Make some local directories.
51+ gpg = root / 'gpg'
52+ with suppress(FileExistsError):
53+ gpg.mkdir(parents=True)
54+ channel_dir = root / args.channel
55+ with suppress(FileExistsError):
56+ channel_dir.mkdir(parents=True)
57+
58+ # Start by grabbing the channels.json* files and the gpg keyrings.
59+ records = [
60+ Record('http://system-image.ubuntu.com/channels.json',
61+ str(root / 'channels.json')),
62+ Record('http://system-image.ubuntu.com/channels.json.asc',
63+ str(root / 'channels.json.asc')),
64+ ]
65+ for keyring in ('archive-master',
66+ 'blacklist',
67+ 'image-master',
68+ 'image-signing'):
69+ url = 'http://system-image.ubuntu.com/gpg/{}.tar.xz'.format(keyring)
70+ dest = gpg / '{}.tar.xz'.format(keyring)
71+ records.append(Record(url, str(dest)))
72+ downloader = CurlDownloadManager()
73+ downloader.get_files(records)
74+
75+ # Chase the channel/device to find the index.json file.
76+ channels_json = root / 'channels.json'
77+ with channels_json.open('r', encoding='utf-8') as fp:
78+ channels = Channels.from_json(fp.read())
79+ index_path = channels[args.channel]['devices'][args.device]['index']
80+ index_json = channel_dir / args.device / 'index.json'
81+
82+ records = [
83+ Record('http://system-image.ubuntu.com/{}'.format(index_path),
84+ str(index_json)),
85+ ]
86+ downloader.get_files(records)
87+
88+ with index_json.open('r', encoding='utf-8') as fp:
89+ index = Index.from_json(fp.read())
90+
91+ # Collect all the data files for all the images in this channel.
92+ records = []
93+ parents = []
94+ for image in index['images']:
95+ for file in image['files']:
96+ path = Path(file['path'])
97+ signature = Path(file['signature'])
98+ checksum = file['checksum']
99+ if path.is_absolute():
100+ path = path.relative_to('/')
101+ if signature.is_absolute():
102+ signature = signature.relative_to('/')
103+ local_path = root / path
104+ parents.append(local_path.parent)
105+ records.append(
106+ Record(
107+ 'http://system-image.ubuntu.com/{}'.format(path),
108+ str(local_path),
109+ checksum))
110+ records.append(
111+ Record(
112+ 'http://system-image.ubuntu.com/{}'.format(signature),
113+ str(root / signature)))
114+ # We also need the version-*.json files, which are used by
115+ # bin/copy-image
116+ version_details = path.name.split('.')
117+ if (version_details[0].startswith('version')
118+ and version_details[-1] == 'xz'
119+ and version_details[-2] == 'tar'):
120+ prefix, version = version_details[0].split('-')
121+ version_file = 'version-{}.json'.format(version)
122+ url = 'http://system-image.ubuntu.com/{}/{}'.format(
123+ path.parent, version_file)
124+ dest = local_path.parent / version_file
125+ records.append(Record(url, str(dest)))
126+ for parent in parents:
127+ with suppress(FileExistsError):
128+ parent.mkdir(parents=True)
129+ downloader.get_files(records)
130+
131+ return 0
132+
133+
134+if __name__ == '__main__':
135+ sys.exit(main())

Subscribers

People subscribed via source and target branches

to all changes: