Merge lp:~barry/ubuntu-system-image/citrain-250u1 into lp:~ubuntu-managed-branches/ubuntu-system-image/system-image
- citrain-250u1
- Merge into system-image
Proposed by
Barry Warsaw
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Ken VanDine | ||||||||
Approved revision: | 241 | ||||||||
Merged at revision: | 239 | ||||||||
Proposed branch: | lp:~barry/ubuntu-system-image/citrain-250u1 | ||||||||
Merge into: | lp:~ubuntu-managed-branches/ubuntu-system-image/system-image | ||||||||
Diff against target: |
497 lines (+84/-184) 14 files modified
NEWS.rst (+7/-0) PKG-INFO (+1/-1) dbus-manpage.rst (+15/-6) debian/changelog (+9/-0) setup.cfg (+1/-1) system_image.egg-info/PKG-INFO (+1/-1) system_image.egg-info/SOURCES.txt (+0/-1) systemimage/bindings.py (+0/-98) systemimage/dbus.py (+10/-2) systemimage/main.py (+0/-27) systemimage/testing/dbus.py (+3/-1) systemimage/testing/nose.py (+0/-1) systemimage/tests/test_dbus.py (+36/-44) systemimage/version.txt (+1/-1) |
||||||||
To merge this branch: | bzr merge lp:~barry/ubuntu-system-image/citrain-250u1 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu CI managed package branches | Pending | ||
Review via email: mp+236403@code.launchpad.net |
To post a comment you must log in.
- 241. By Barry Warsaw
-
Unrelease
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'NEWS.rst' |
2 | --- NEWS.rst 2014-09-17 13:41:31 +0000 |
3 | +++ NEWS.rst 2014-09-29 18:55:39 +0000 |
4 | @@ -2,6 +2,13 @@ |
5 | NEWS for system-image updater |
6 | ============================= |
7 | |
8 | +2.5 (2014-XX-XX) |
9 | +================ |
10 | + * Remove the previously deprecated `system-image-cli --dbus` command line |
11 | + switch. (LP: #1369717) |
12 | + * Add a `target_build_number` key to the mapping returned by the |
13 | + `.Information()` D-Bus method. (LP: #1370586) |
14 | + |
15 | 2.4 (2014-09-16) |
16 | ================ |
17 | * The channel.ini file can override the device name by setting |
18 | |
19 | === modified file 'PKG-INFO' |
20 | --- PKG-INFO 2014-09-17 02:59:15 +0000 |
21 | +++ PKG-INFO 2014-09-29 18:55:39 +0000 |
22 | @@ -1,6 +1,6 @@ |
23 | Metadata-Version: 1.0 |
24 | Name: system-image |
25 | -Version: 2.4 |
26 | +Version: 2.5 |
27 | Summary: Ubuntu System Image Based Upgrades |
28 | Home-page: UNKNOWN |
29 | Author: Barry Warsaw |
30 | |
31 | === modified file 'dbus-manpage.rst' |
32 | --- dbus-manpage.rst 2014-07-23 22:51:19 +0000 |
33 | +++ dbus-manpage.rst 2014-09-29 18:55:39 +0000 |
34 | @@ -128,19 +128,28 @@ |
35 | This is a **synchronous** call which returns an extensible mapping of |
36 | UTF-8 keys to UTF-8 values. The following keys are currently defined: |
37 | |
38 | - * *current_build_number* - the current build number as an integer. |
39 | - * *device_name* - the name of the device type. |
40 | - * *channel_name* - the channel the device is currently on. |
41 | - * *last_update_date* - the last time this device was updated as a |
42 | + * *current_build_number* - The current build number as an integer. |
43 | + * *target_build_number* - If an update is known to be available, this will |
44 | + be the build number that an update will leave the device at. If no |
45 | + `CheckForUpdate()` has been previously performed, then the |
46 | + *target_build_number* will be "-1". If a previous check has been |
47 | + performed, but no update is available (i.e., the device is already at |
48 | + the latest version), then *target_build_number* will be the same as |
49 | + *current_build_number*. |
50 | + * *device_name* - The name of the device type. |
51 | + * *channel_name* - The channel the device is currently on. |
52 | + * *last_update_date* - The last time this device was updated as a |
53 | datetime, e.g. "YYYY-MM-DDTHH:MM:SS" |
54 | - * *version_detail* - a string containing a comma-separated list of |
55 | + * *version_detail* - A string containing a comma-separated list of |
56 | key-value pairs providing additional component version details, |
57 | e.g. "ubuntu=123,mako=456,custom=789". |
58 | - * *last_check_date* - the last time a ``CheckForUpdate()`` call was |
59 | + * *last_check_date* - The last time a ``CheckForUpdate()`` call was |
60 | performed. |
61 | |
62 | *New in system-image 2.3* |
63 | |
64 | + *New in system-image 2.5: target_build_number* |
65 | + |
66 | ``FactoryReset()`` |
67 | This is a **synchronous** call which wipes the data partition and issue a |
68 | reboot to recovery. A ``Rebooting`` signal may be sent, depending on |
69 | |
70 | === modified file 'debian/changelog' |
71 | --- debian/changelog 2014-09-17 17:56:46 +0000 |
72 | +++ debian/changelog 2014-09-29 18:55:39 +0000 |
73 | @@ -1,3 +1,12 @@ |
74 | +system-image (2.5-0ubuntu1) UNRELEASED; urgency=medium |
75 | + |
76 | + * New upstream release. |
77 | + - LP: #1369717 - Remove `system-image-cli --dbus` command line switch. |
78 | + - LP: #1370586 - Add a `target_build_number` key to the mapping |
79 | + returned by the `.Information()` D-Bus method. |
80 | + |
81 | + -- Barry Warsaw <barry@ubuntu.com> Fri, 26 Sep 2014 10:36:13 -0400 |
82 | + |
83 | system-image (2.4-0ubuntu1) utopic; urgency=medium |
84 | |
85 | [ Barry Warsaw ] |
86 | |
87 | === modified file 'setup.cfg' |
88 | --- setup.cfg 2014-09-17 13:41:31 +0000 |
89 | +++ setup.cfg 2014-09-29 18:55:39 +0000 |
90 | @@ -4,7 +4,7 @@ |
91 | logging-filter = systemimage |
92 | |
93 | [egg_info] |
94 | +tag_svn_revision = 0 |
95 | tag_build = |
96 | tag_date = 0 |
97 | -tag_svn_revision = 0 |
98 | |
99 | |
100 | === modified file 'system_image.egg-info/PKG-INFO' |
101 | --- system_image.egg-info/PKG-INFO 2014-09-17 02:59:15 +0000 |
102 | +++ system_image.egg-info/PKG-INFO 2014-09-29 18:55:39 +0000 |
103 | @@ -1,6 +1,6 @@ |
104 | Metadata-Version: 1.0 |
105 | Name: system-image |
106 | -Version: 2.4 |
107 | +Version: 2.5 |
108 | Summary: Ubuntu System Image Based Upgrades |
109 | Home-page: UNKNOWN |
110 | Author: Barry Warsaw |
111 | |
112 | === modified file 'system_image.egg-info/SOURCES.txt' |
113 | --- system_image.egg-info/SOURCES.txt 2014-09-17 02:59:15 +0000 |
114 | +++ system_image.egg-info/SOURCES.txt 2014-09-29 18:55:39 +0000 |
115 | @@ -18,7 +18,6 @@ |
116 | systemimage/__init__.py |
117 | systemimage/api.py |
118 | systemimage/bag.py |
119 | -systemimage/bindings.py |
120 | systemimage/candidates.py |
121 | systemimage/channel.py |
122 | systemimage/config.py |
123 | |
124 | === removed file 'systemimage/bindings.py' |
125 | --- systemimage/bindings.py 2014-09-17 13:41:31 +0000 |
126 | +++ systemimage/bindings.py 1970-01-01 00:00:00 +0000 |
127 | @@ -1,98 +0,0 @@ |
128 | -# Copyright (C) 2013-2014 Canonical Ltd. |
129 | -# Author: Barry Warsaw <barry@ubuntu.com> |
130 | - |
131 | -# This program is free software: you can redistribute it and/or modify |
132 | -# it under the terms of the GNU General Public License as published by |
133 | -# the Free Software Foundation; version 3 of the License. |
134 | -# |
135 | -# This program is distributed in the hope that it will be useful, |
136 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
137 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
138 | -# GNU General Public License for more details. |
139 | -# |
140 | -# You should have received a copy of the GNU General Public License |
141 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
142 | - |
143 | -"""Helpers for when the command line script is used as a DBus client.""" |
144 | - |
145 | - |
146 | -__all__ = [ |
147 | - 'DBusClient', |
148 | - 'UASRecord', |
149 | - ] |
150 | - |
151 | - |
152 | -import dbus |
153 | -import logging |
154 | - |
155 | -from collections import namedtuple |
156 | -from systemimage.reactor import Reactor |
157 | - |
158 | -log = logging.getLogger('systemimage') |
159 | - |
160 | - |
161 | -# Use a namedtuple for more convenient argument unpacking. |
162 | -UASRecord = namedtuple('UASRecord', |
163 | - 'is_available downloading available_version update_size ' |
164 | - 'last_update_date error_reason') |
165 | - |
166 | - |
167 | -class DBusClient(Reactor): |
168 | - """Python bindings to be used as a DBus client.""" |
169 | - |
170 | - def __init__(self): |
171 | - super().__init__(dbus.SystemBus()) |
172 | - service = self._bus.get_object('com.canonical.SystemImage', '/Service') |
173 | - self.iface = dbus.Interface(service, 'com.canonical.SystemImage') |
174 | - self.react_to('UpdateAvailableStatus') |
175 | - self.react_to('UpdateDownloaded') |
176 | - self.react_to('UpdateFailed') |
177 | - self.failed = False |
178 | - self.is_available = False |
179 | - self.downloaded = False |
180 | - |
181 | - def _do_UpdateAvailableStatus(self, signal, path, *args): |
182 | - payload = UASRecord(*args) |
183 | - if payload.error_reason != '': # pragma: no cover |
184 | - # Cancel the download, set the failed flag and log the reason. |
185 | - log.error('CheckForUpdate returned an error: {}', |
186 | - payload.error_reason) |
187 | - self.failed = True |
188 | - self.quit() |
189 | - return |
190 | - if not payload.is_available: |
191 | - log.info('No update available') |
192 | - self.quit() |
193 | - return |
194 | - if not payload.downloading: # pragma: no cover |
195 | - # We should be in auto download mode, so why aren't we downloading |
196 | - # the update? Do it manually. |
197 | - log.info('Update available, downloading manually') |
198 | - self.iface.DownloadUpdate() |
199 | - self.is_available = True |
200 | - |
201 | - def _do_UpdateDownloaded(self, signal, path): |
202 | - self.downloaded = True |
203 | - self.quit() |
204 | - |
205 | - def _do_UpdateFailed(self, signal, path, |
206 | - consecutive_failure_count, last_reason): |
207 | - log.error('UpdateFailed: {}', last_reason) |
208 | - self.failed = True |
209 | - self.quit() |
210 | - |
211 | - def check_for_update(self): |
212 | - # Switch to auto-download mode for this run. |
213 | - old_value = self.iface.GetSetting('auto_download') |
214 | - self.iface.SetSetting('auto_download', '2') |
215 | - self.schedule(self.iface.CheckForUpdate) |
216 | - self.run() |
217 | - self.iface.SetSetting('auto_download', old_value) |
218 | - |
219 | - def _do_Rebooting(self, signal, path, status): |
220 | - self.quit() |
221 | - |
222 | - def reboot(self): |
223 | - self.react_to('Rebooting') |
224 | - self.schedule(self.iface.ApplyUpdate) |
225 | - self.run() |
226 | |
227 | === modified file 'systemimage/dbus.py' |
228 | --- systemimage/dbus.py 2014-09-17 13:41:31 +0000 |
229 | +++ systemimage/dbus.py 2014-09-29 18:55:39 +0000 |
230 | @@ -334,14 +334,22 @@ |
231 | def Information(self): |
232 | self._loop.keepalive() |
233 | settings = Settings() |
234 | - return dict( |
235 | - current_build_number=str(config.build_number), |
236 | + current_build_number = str(config.build_number) |
237 | + response = dict( |
238 | + current_build_number=current_build_number, |
239 | device_name=config.device, |
240 | channel_name=config.channel, |
241 | last_update_date=last_update_date(), |
242 | version_detail=getattr(config.service, 'version_detail', ''), |
243 | last_check_date=settings.get('last_check_date'), |
244 | ) |
245 | + if self._update is None: |
246 | + response['target_build_number'] = '-1' |
247 | + elif not self._update.is_available: |
248 | + response['target_build_number'] = current_build_number |
249 | + else: |
250 | + response['target_build_number'] = str(self._update.version) |
251 | + return response |
252 | |
253 | @log_and_exit |
254 | @method('com.canonical.SystemImage', in_signature='ss') |
255 | |
256 | === modified file 'systemimage/main.py' |
257 | --- systemimage/main.py 2014-09-17 13:41:31 +0000 |
258 | +++ systemimage/main.py 2014-09-29 18:55:39 +0000 |
259 | @@ -25,11 +25,9 @@ |
260 | import sys |
261 | import logging |
262 | import argparse |
263 | -import warnings |
264 | |
265 | from dbus.mainloop.glib import DBusGMainLoop |
266 | from pkg_resources import resource_string as resource_bytes |
267 | -from systemimage.bindings import DBusClient |
268 | from systemimage.candidates import delta_filter, full_filter |
269 | from systemimage.config import config |
270 | from systemimage.helpers import last_update_date, makedirs, version_detail |
271 | @@ -72,9 +70,6 @@ |
272 | parser.add_argument('-d', '--device', |
273 | default=None, action='store', |
274 | help='Override the device name just this once') |
275 | - parser.add_argument('--dbus', |
276 | - default=False, action='store_true', |
277 | - help='Run in D-Bus client mode.') |
278 | parser.add_argument('-f', '--filter', |
279 | default=None, action='store', |
280 | help="""Filter the candidate paths to contain only |
281 | @@ -266,28 +261,6 @@ |
282 | print(' {} (alias for: {})'.format(key, alias)) |
283 | return 0 |
284 | |
285 | - # 2014-09-15 BAW: --dbus is deprecated (LP: #1369714) and will be removed |
286 | - # in system-image 2.5 (LP: #1369717). |
287 | - if args.dbus: # pragma: no cover |
288 | - print('WARNING: --dbus is deprecated and will be removed soon', |
289 | - file=sys.stderr) |
290 | - warnings.warn('--dbus is deprecated and will be removed soon', |
291 | - DeprecationWarning) |
292 | - client = DBusClient() |
293 | - client.check_for_update() |
294 | - if not client.is_available: |
295 | - log.info('No update is available') |
296 | - return 0 |
297 | - if not client.downloaded: |
298 | - log.info('No update was downloaded') |
299 | - return 1 |
300 | - if client.failed: |
301 | - log.info('Update failed') |
302 | - return 2 |
303 | - client.reboot() |
304 | - # We probably won't get here.. |
305 | - return 0 |
306 | - |
307 | # When verbosity is at 1, logging every progress signal from |
308 | # ubuntu-download-manager would be way too noisy. OTOH, not printing |
309 | # anything leads some folks to think the process is just hung, since it |
310 | |
311 | === modified file 'systemimage/testing/dbus.py' |
312 | --- systemimage/testing/dbus.py 2014-09-17 13:41:31 +0000 |
313 | +++ systemimage/testing/dbus.py 2014-09-29 18:55:39 +0000 |
314 | @@ -334,6 +334,7 @@ |
315 | self._updated = '2099-08-01 04:45:45' |
316 | self._version = 'ubuntu=123,mako=456,custom=789' |
317 | self._checked = '2099-08-01 04:45:00' |
318 | + self._target = 53 |
319 | |
320 | @log_and_exit |
321 | @method('com.canonical.SystemImage') |
322 | @@ -354,7 +355,8 @@ |
323 | channel_name=self._channel, |
324 | last_update_date=self._updated, |
325 | version_detail=self._version, |
326 | - last_check_date=self._checked) |
327 | + last_check_date=self._checked, |
328 | + target_build_number=str(self._target)) |
329 | |
330 | |
331 | class _Crasher(Service): |
332 | |
333 | === modified file 'systemimage/testing/nose.py' |
334 | --- systemimage/testing/nose.py 2014-09-17 13:41:31 +0000 |
335 | +++ systemimage/testing/nose.py 2014-09-29 18:55:39 +0000 |
336 | @@ -22,7 +22,6 @@ |
337 | |
338 | import re |
339 | import atexit |
340 | -import logging |
341 | |
342 | from dbus.mainloop.glib import DBusGMainLoop |
343 | from nose2.events import Plugin |
344 | |
345 | === modified file 'systemimage/tests/test_dbus.py' |
346 | --- systemimage/tests/test_dbus.py 2014-09-17 13:41:31 +0000 |
347 | +++ systemimage/tests/test_dbus.py 2014-09-29 18:55:39 +0000 |
348 | @@ -20,7 +20,6 @@ |
349 | 'TestDBusCheckForUpdate', |
350 | 'TestDBusCheckForUpdateToUnwritablePartition', |
351 | 'TestDBusCheckForUpdateWithBrokenIndex', |
352 | - 'TestDBusClient', |
353 | 'TestDBusDownload', |
354 | 'TestDBusFactoryReset', |
355 | 'TestDBusGetSet', |
356 | @@ -51,11 +50,11 @@ |
357 | import unittest |
358 | |
359 | from contextlib import ExitStack, suppress |
360 | +from collections import namedtuple |
361 | from datetime import datetime |
362 | from dbus.exceptions import DBusException |
363 | from functools import partial |
364 | from pathlib import Path |
365 | -from systemimage.bindings import DBusClient, UASRecord |
366 | from systemimage.config import Configuration |
367 | from systemimage.helpers import MiB, atomic, safe_remove |
368 | from systemimage.reactor import Reactor |
369 | @@ -66,6 +65,12 @@ |
370 | from systemimage.testing.nose import SystemImagePlugin |
371 | |
372 | |
373 | +# Use a namedtuple for more convenient argument unpacking. |
374 | +UASRecord = namedtuple('UASRecord', |
375 | + 'is_available downloading available_version update_size ' |
376 | + 'last_update_date error_reason') |
377 | + |
378 | + |
379 | class SignalCapturingReactor(Reactor): |
380 | def __init__(self, *signals): |
381 | super().__init__(dbus.SystemBus()) |
382 | @@ -1097,48 +1102,6 @@ |
383 | self.assertIsNotNone(reactor.status) |
384 | |
385 | |
386 | -class TestDBusClient(_LiveTesting): |
387 | - """Test the DBus client (used with --dbus).""" |
388 | - |
389 | - def setUp(self): |
390 | - super().setUp() |
391 | - self._client = DBusClient() |
392 | - |
393 | - def test_check_for_update(self): |
394 | - # There is an update available. |
395 | - self._client.check_for_update() |
396 | - self.assertTrue(self._client.is_available) |
397 | - self.assertTrue(self._client.downloaded) |
398 | - |
399 | - def test_check_for_no_update(self): |
400 | - # There is no update available. |
401 | - self._touch_build(1701) |
402 | - self._client.check_for_update() |
403 | - self.assertFalse(self._client.is_available) |
404 | - self.assertFalse(self._client.downloaded) |
405 | - |
406 | - def test_update_failed(self): |
407 | - # For some reason <wink>, the update fails. |
408 | - # |
409 | - # Cause the update to fail by deleting a file from the server. |
410 | - os.remove(os.path.join(SystemImagePlugin.controller.serverdir, |
411 | - '4/5/6.txt.asc')) |
412 | - self._client.check_for_update() |
413 | - self.assertTrue(self._client.is_available) |
414 | - self.assertFalse(self._client.downloaded) |
415 | - self.assertTrue(self._client.failed) |
416 | - |
417 | - def test_reboot(self): |
418 | - # After a successful update, we can reboot. |
419 | - self._client.check_for_update() |
420 | - self.assertTrue(self._client.is_available) |
421 | - self.assertTrue(self._client.downloaded) |
422 | - self._client.reboot() |
423 | - with open(self.reboot_log, encoding='utf-8') as fp: |
424 | - reboot = fp.read() |
425 | - self.assertEqual(reboot, '/sbin/reboot -f recovery') |
426 | - |
427 | - |
428 | class TestDBusRegressions(_LiveTesting): |
429 | """Test that various regressions have been fixed.""" |
430 | |
431 | @@ -1355,9 +1318,11 @@ |
432 | 'device_name', |
433 | 'last_check_date', |
434 | 'last_update_date', |
435 | + 'target_build_number', |
436 | 'version_detail', |
437 | ]) |
438 | self.assertEqual(response['current_build_number'], '45') |
439 | + self.assertEqual(response['target_build_number'], '53') |
440 | self.assertEqual(response['device_name'], 'nexus11') |
441 | self.assertEqual(response['channel_name'], 'daily-proposed') |
442 | self.assertEqual(response['last_update_date'], '2099-08-01 04:45:45') |
443 | @@ -1388,6 +1353,7 @@ |
444 | self.assertEqual(response['last_update_date'], '2022-08-01 04:45:45') |
445 | self.assertEqual(response['version_detail'], '') |
446 | self.assertEqual(response['last_check_date'], '') |
447 | + self.assertEqual(response['target_build_number'], '-1') |
448 | |
449 | def test_information_no_details(self): |
450 | # .Information() where there is no channel.ini with version details, |
451 | @@ -1414,6 +1380,7 @@ |
452 | self.assertEqual(response['last_update_date'], '2022-08-01 04:45:45') |
453 | self.assertEqual(response['version_detail'], '') |
454 | self.assertEqual(response['last_check_date'], '2055-08-01 21:12:00') |
455 | + self.assertEqual(response['target_build_number'], '1600') |
456 | |
457 | def test_information(self): |
458 | # .Information() where there is a channel.ini with version details, |
459 | @@ -1453,6 +1420,31 @@ |
460 | # in a robust way. E.g. what if we just happen to be at 12:59:59 on |
461 | # December 31st? Let's at least make sure it has a sane format. |
462 | self.assertRegex(response['last_check_date'], '2055-08-01 21:12:01') |
463 | + self.assertEqual(response['target_build_number'], '1600') |
464 | + |
465 | + def test_information_no_update_available(self): |
466 | + # .Information() where we know that no update is available, gives us a |
467 | + # target build number equal to the current build number. |
468 | + self._touch_build(1701) |
469 | + reactor = SignalCapturingReactor('UpdateAvailableStatus') |
470 | + reactor.run(self.iface.CheckForUpdate) |
471 | + signal = reactor.signals[0] |
472 | + self.assertEqual(signal.available_version, '') |
473 | + response = self.iface.Information() |
474 | + self.assertEqual(response['target_build_number'], '1701') |
475 | + |
476 | + def test_information_workflow(self): |
477 | + # At first, .Information() won't know whether there is an update |
478 | + # available or not. Then we check, and it tells us there is one. |
479 | + self._touch_build(45) |
480 | + response = self.iface.Information() |
481 | + self.assertEqual(response['target_build_number'], '-1') |
482 | + reactor = SignalCapturingReactor('UpdateAvailableStatus') |
483 | + reactor.run(self.iface.CheckForUpdate) |
484 | + signal = reactor.signals[0] |
485 | + self.assertEqual(signal.available_version, '1600') |
486 | + response = self.iface.Information() |
487 | + self.assertEqual(response['target_build_number'], '1600') |
488 | |
489 | |
490 | class TestLiveDBusInfoWithChannelIni(_LiveTesting): |
491 | |
492 | === modified file 'systemimage/version.txt' |
493 | --- systemimage/version.txt 2014-09-17 13:41:31 +0000 |
494 | +++ systemimage/version.txt 2014-09-29 18:55:39 +0000 |
495 | @@ -1,1 +1,1 @@ |
496 | -2.4 |
497 | +2.5 |