Merge lp:~barry/ubuntu-system-image/reload-configuration into lp:~snappy-dev/ubuntu-system-image/ppa-upload

Proposed by Barry Warsaw
Status: Merged
Merged at revision: 303
Proposed branch: lp:~barry/ubuntu-system-image/reload-configuration
Merge into: lp:~snappy-dev/ubuntu-system-image/ppa-upload
Diff against target: 160 lines (+94/-5)
4 files modified
debian/changelog (+8/-0)
systemimage/dbus.py (+24/-0)
systemimage/tests/test_config.py (+6/-2)
systemimage/tests/test_dbus.py (+56/-3)
To merge this branch: bzr merge lp:~barry/ubuntu-system-image/reload-configuration
Reviewer Review Type Date Requested Status
Steve Langasek Approve
James Hunt Pending
Michael Vogt Pending
Snappy Developers Pending
Review via email: mp+246507@code.launchpad.net

Description of the change

Adds a new D-Bus method called ReloadConfiguration() which takes a single argument, the path to the new client.ini file. Reloads the D-Bus service's configuration from the new path. A channel.ini file may live next to the client.ini file. The empty string is returned on success, otherwise an error string is returned.

You should be able to use this to load the configuration from the B partition.

To post a comment you must log in.
Revision history for this message
Barry Warsaw (barry) wrote :

I should mention that while I think this will do what you want in the immediate case, we'll have to work out something different for si 3.0, which will have the config.d/ directory support (soon to land in trunk). So consider this expedient rather than permanent.

Oh, and I fixed the test suite so now you can run `tox` again. :)

305. By Barry Warsaw

Remove some comments.

Revision history for this message
Steve Langasek (vorlon) wrote :

This looks good to me. Merging and uploading.

review: Approve
Revision history for this message
Michael Vogt (mvo) wrote :

Thanks a lot Barry!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2014-12-17 07:20:40 +0000
3+++ debian/changelog 2015-01-14 21:47:42 +0000
4@@ -1,3 +1,11 @@
5+system-image (2.5-0ubuntu1+ppa15) UNRELEASED; urgency=medium
6+
7+ * Added D-Bus API ReloadConfiguration() which takes a path to the new
8+ client.ini file. A channel.ini file can live next to that. Using
9+ this method will reload the configuration, e.g. to the B partition.
10+
11+ -- Barry Warsaw <barry@ubuntu.com> Wed, 14 Jan 2015 16:37:12 -0500
12+
13 system-image (2.5-0ubuntu1+ppa14) vivid; urgency=medium
14
15 * From userdata to writable
16
17=== modified file 'systemimage/dbus.py'
18--- systemimage/dbus.py 2014-09-25 20:13:57 +0000
19+++ systemimage/dbus.py 2015-01-14 21:47:42 +0000
20@@ -403,6 +403,30 @@
21 self._loop.quit()
22
23 @log_and_exit
24+ @method('com.canonical.SystemImage',
25+ in_signature='s', out_signature='s')
26+ def ReloadConfiguration(self, path):
27+ """Reload the process's configuration from the given path.
28+
29+ `path` must point to the client.ini file to load. If a channel.ini
30+ file lives next to the client.ini file, it will also be loaded in
31+ 'override' mode.
32+ """
33+ try:
34+ config.load(path)
35+ except OSError as error:
36+ return str(error)
37+ try:
38+ # This can legitimately fail if there's no channel.ini file.
39+ channel_ini = os.path.join(
40+ os.path.dirname(path),
41+ 'channel.ini')
42+ config.load(channel_ini, override=True)
43+ except FileNotFoundError:
44+ pass
45+ return ''
46+
47+ @log_and_exit
48 @signal('com.canonical.SystemImage', signature='bbsiss')
49 def UpdateAvailableStatus(self,
50 is_available, downloading,
51
52=== modified file 'systemimage/tests/test_config.py'
53--- systemimage/tests/test_config.py 2014-10-10 11:15:04 +0000
54+++ systemimage/tests/test_config.py 2015-01-14 21:47:42 +0000
55@@ -77,7 +77,11 @@
56 # [hooks]
57 self.assertEqual(config.hooks.device, SystemProperty)
58 self.assertEqual(config.hooks.scorer, WeightedScorer)
59- self.assertEqual(config.hooks.reboot, Reboot)
60+ # There's no ubuntucoreupgrader module in the current package, so mock
61+ # that out.
62+ rebooter = object()
63+ with patch.dict(config.hooks.__dict__, {'reboot': rebooter}):
64+ self.assertEqual(config.hooks.reboot, rebooter)
65 # [gpg]
66 self.assertEqual(config.gpg.archive_master,
67 '/etc/system-image/archive-master.tar.xz')
68@@ -92,7 +96,7 @@
69 '/var/lib/system-image/keyrings/device-signing.tar.xz')
70 # [updater]
71 self.assertEqual(config.updater.cache_partition,
72- '/userdata/cache/')
73+ '/writable/cache/')
74 self.assertEqual(config.updater.data_partition,
75 '/var/lib/system-image')
76 # [dbus]
77
78=== modified file 'systemimage/tests/test_dbus.py'
79--- systemimage/tests/test_dbus.py 2014-09-25 20:13:57 +0000
80+++ systemimage/tests/test_dbus.py 2015-01-14 21:47:42 +0000
81@@ -36,6 +36,7 @@
82 'TestDBusPauseResume',
83 'TestDBusProgress',
84 'TestDBusRegressions',
85+ 'TestDBusReloadConfiguration',
86 'TestDBusUseCache',
87 'TestLiveDBusInfo',
88 'TestLiveDBusInfoWithChannelIni',
89@@ -56,12 +57,12 @@
90 from functools import partial
91 from pathlib import Path
92 from systemimage.config import Configuration
93-from systemimage.helpers import MiB, atomic, safe_remove
94+from systemimage.helpers import MiB, atomic, safe_remove, temporary_directory
95 from systemimage.reactor import Reactor
96 from systemimage.settings import Settings
97 from systemimage.testing.helpers import (
98- copy, find_dbus_process, make_http_server, setup_index, setup_keyring_txz,
99- setup_keyrings, sign, write_bytes)
100+ copy, data_path, find_dbus_process, make_http_server, setup_index,
101+ setup_keyring_txz, setup_keyrings, sign, write_bytes)
102 from systemimage.testing.nose import SystemImagePlugin
103
104
105@@ -1909,3 +1910,55 @@
106 # Failure count.
107 self.assertEqual(failure[0], 1)
108 self.assertEqual(failure[1], 'Canceled')
109+
110+
111+class TestDBusReloadConfiguration(_LiveTesting):
112+ """Test reload of the configuration files."""
113+
114+ def test_reload(self):
115+ # Create a second configuration directory with a different
116+ # build_number so that we can test that the reload actually worked.
117+ with temporary_directory() as tmpdir:
118+ with ExitStack() as files:
119+ infp = files.enter_context(
120+ open(SystemImagePlugin.controller.ini_path, 'r',
121+ encoding='utf-8'))
122+ client_ini = os.path.join(tmpdir, 'client.ini')
123+ outfp = files.enter_context(
124+ open(client_ini, 'w', encoding='utf-8'))
125+ ubuntu_build = os.path.join(tmpdir, 'ubuntu-build')
126+ with open(ubuntu_build, 'w', encoding='utf-8') as fp:
127+ print(801, file=fp)
128+ for line in infp:
129+ if line.startswith('build_file:'):
130+ print('build_file: {}'.format(ubuntu_build),
131+ file=outfp)
132+ else:
133+ outfp.write(line)
134+ # Start by asking the D-Bus process what the current build number
135+ # is with the old configuraiton.
136+ response = self.iface.Information()
137+ self.assertEqual(response['current_build_number'], '0')
138+ # Now reload the new configuration and recheck the build number.
139+ status = self.iface.ReloadConfiguration(client_ini)
140+ self.assertEqual(status, '')
141+ response = self.iface.Information()
142+ self.assertEqual(response['current_build_number'], '801')
143+
144+ def test_reload_with_channel_ini(self):
145+ # Create a second configuration directory with a different
146+ # build_number so that we can test that the reload actually worked.
147+ with temporary_directory() as tmpdir:
148+ client_ini = os.path.join(tmpdir, 'client.ini')
149+ shutil.copy(SystemImagePlugin.controller.ini_path, client_ini)
150+ shutil.copy(data_path('channel_01.ini'),
151+ os.path.join(tmpdir, 'channel.ini'))
152+ # Start by asking the D-Bus process what the current build number
153+ # is with the old configuraiton.
154+ response = self.iface.Information()
155+ self.assertEqual(response['current_build_number'], '0')
156+ # Now reload the new configuration and recheck the build number.
157+ status = self.iface.ReloadConfiguration(client_ini)
158+ self.assertEqual(status, '')
159+ response = self.iface.Information()
160+ self.assertEqual(response['current_build_number'], '1833')

Subscribers

People subscribed via source and target branches