Merge lp:~vbocek/ubuntu-system-image/support_http into lp:~registry/ubuntu-system-image/client

Proposed by Vojtech Bocek
Status: Merged
Approved by: Barry Warsaw
Approved revision: 242
Merged at revision: 241
Proposed branch: lp:~vbocek/ubuntu-system-image/support_http
Merge into: lp:~registry/ubuntu-system-image/client
Diff against target: 290 lines (+180/-11)
7 files modified
ini-manpage.rst (+4/-2)
systemimage/bag.py (+8/-0)
systemimage/config.py (+30/-9)
systemimage/tests/data/config_05.ini (+36/-0)
systemimage/tests/data/config_06.ini (+36/-0)
systemimage/tests/data/config_07.ini (+36/-0)
systemimage/tests/test_config.py (+30/-0)
To merge this branch: bzr merge lp:~vbocek/ubuntu-system-image/support_http
Reviewer Review Type Date Requested Status
Barry Warsaw (community) Approve
Review via email: mp+208242@code.launchpad.net

Description of the change

* Add support for "disabled" value in http_port and https_port config options, which disables that protocol.
* Support overriding of [system] section from channel.ini

- The tests are incomplete.

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

Just a quick comment as I'm going through your branch.

=== modified file 'systemimage/config.py'
--- systemimage/config.py 2014-02-13 18:16:17 +0000
+++ systemimage/config.py 2014-02-25 22:24:24 +0000
> @@ -64,32 +78,39 @@
> if files_read != [path]:
> raise FileNotFoundError(path)
> self.config_file = path
> - self.service = Bag(converters=dict(http_port=int,
> - https_port=int,
> + self.service.update(converters=dict(http_port=port_value_converter,
> + https_port=port_value_converter,
> build_number=int),
> **parser['service'])
> + if (self.service.http_port is DISABLED_PROTOCOL and
> + self.service.https_port is DISABLED_PROTOCOL):
> + raise ValueError('both http and https ports were disabled')
> # Construct the HTTP and HTTPS base urls, which most applications will
> # actually use.
> if self.service.http_port == 80:
> self.service['http_base'] = 'http://{}'.format(self.service.base)
> - else:
> + elif self.service.http_port is not DISABLED_PROTOCOL:
> self.service['http_base'] = 'http://{}:{}'.format(
> self.service.base, self.service.http_port)
> if self.service.https_port == 443:
> self.service['https_base'] = 'https://{}'.format(self.service.base)
> - else:
> + elif self.service.http_port is not DISABLED_PROTOCOL:
> self.service['https_base'] = 'https://{}:{}'.format(
> self.service.base, self.service.https_port)
> - # Short-circuit, since we're loading a channel.ini file.
> - self._override = override
> - if override:
> - return
> - self.system = Bag(converters=dict(timeout=as_timedelta,
> + if self.service.http_port is DISABLED_PROTOCOL:
> + self.service['http_base'] = self.service['https_base']
> + elif self.service.https_port is DISABLED_PROTOCOL:
> + self.service['https_base'] = self.service['http_base']
> + self.system.update(converters=dict(timeout=as_timedelta,
> build_file=expand_path,
> loglevel=as_loglevel,
> settings_db=expand_path,
> tempdir=expand_path),
> **parser['system'])

The changes above are problematic because currently, Bags have the semantic
that their values cannot change after the initial setting. So updating as is
done here raises a ValueError. It's worse too because the test infrastructure
requires a Configuration object before any tests run (for unfortunate reasons
having to do with the D-Bus tests).

I'm not exactly sure of the best way to resolve this. I should probably just
remove this read-only restriction, since it's not really serving a useful
purpose.

Revision history for this message
Barry Warsaw (barry) wrote :

On Feb 26, 2014, at 12:03 AM, Barry Warsaw wrote:

>I'm not exactly sure of the best way to resolve this. I should probably just
>remove this read-only restriction, since it's not really serving a useful
>purpose.

nm, I know how to resolve this.

Revision history for this message
Vojtech Bocek (vbocek) wrote :

It didn't raise any error while I was testing it, the exception in __setitem__ affects only external changes via [] operator.

>>> from bag import Bag
>>> b=Bag(a=4, b=8)
>>> b.update(a=0, b=2)
>>> b['a']
0
>>> b['b']
2

Revision history for this message
Barry Warsaw (barry) wrote :

Thanks very much for this branch. I'm going to merge it to trunk after some
tweaks, and fleshing out of the test suite.

I ended up making these changes to your branch:

  * Renamed DISABLED_PROTOCOL to DISABLED
  * Some minor code style issues.
  * Allow for the [system] section to be missing from a channel.ini file.
  * Bag class API change: Setting an attribute via the setitem API no longer
    makes that item read-only. IOW, only keywords set in the constructor are
    read-only.
  * Flesh out tests.
  * Tweak the manpage.

Once I've merged this to trunk, you can take a look at the specific diff
there. Please let me know if I've missed anything or if you have any
questions or comments.

Revision history for this message
Barry Warsaw (barry) wrote :

Approved, with tweaks. See lp:~barry/ubuntu-system-image/lp1278589

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ini-manpage.rst'
2--- ini-manpage.rst 2014-02-13 18:16:17 +0000
3+++ ini-manpage.rst 2014-02-25 22:24:24 +0000
4@@ -49,10 +49,12 @@
5 provide both HTTP and HTTPS services.
6
7 http_port
8- The port for HTTP connections.
9+ The port for HTTP connections. This is an integer or string ``disabled``,
10+ if you wish to disable all HTTP connections and use only HTTPS.
11
12 https_port
13- The port for HTTPS connections.
14+ The port for HTTPS connections. This is an integer or string ``disabled``,
15+ if you wish to disable all HTTPS connections and use only HTTP.
16
17 channel
18 The upgrade channel.
19
20=== modified file 'systemimage/bag.py'
21--- systemimage/bag.py 2014-02-13 18:16:17 +0000
22+++ systemimage/bag.py 2014-02-25 22:24:24 +0000
23@@ -45,6 +45,14 @@
24 self._converters = make_converter(converters)
25 self.__original__ = {}
26 self.__untranslated__ = {}
27+ self._load_items(kws)
28+
29+ def update(self, *, converters=None, **kws):
30+ if converters is not None:
31+ self._converters.update(converters)
32+ self._load_items(kws)
33+
34+ def _load_items(self, kws):
35 for key, value in kws.items():
36 self.__original__[key] = value
37 safe_key, converted_value = self._normalize_key_value(key, value)
38
39=== modified file 'systemimage/config.py'
40--- systemimage/config.py 2014-02-13 18:16:17 +0000
41+++ systemimage/config.py 2014-02-25 22:24:24 +0000
42@@ -18,6 +18,7 @@
43 __all__ = [
44 'Configuration',
45 'config',
46+ 'DISABLED_PROTOCOL'
47 ]
48
49
50@@ -31,14 +32,27 @@
51 Bag, as_loglevel, as_object, as_timedelta, makedirs, temporary_directory)
52
53
54+DISABLED_PROTOCOL = object()
55+
56+
57 def expand_path(path):
58 return os.path.abspath(os.path.expanduser(path))
59
60+def port_value_converter(value):
61+ if value == 'disabled' or value == 'disable':
62+ return DISABLED_PROTOCOL
63+ else:
64+ res = int(value)
65+ if res < 0:
66+ raise ValueError
67+ return res
68
69 class Configuration:
70 def __init__(self):
71 # Defaults.
72 self.config_file = None
73+ self.service = Bag()
74+ self.system = Bag()
75 ini_path = resource_filename('systemimage.data', 'client.ini')
76 self.load(ini_path)
77 self._override = False
78@@ -64,32 +78,39 @@
79 if files_read != [path]:
80 raise FileNotFoundError(path)
81 self.config_file = path
82- self.service = Bag(converters=dict(http_port=int,
83- https_port=int,
84+ self.service.update(converters=dict(http_port=port_value_converter,
85+ https_port=port_value_converter,
86 build_number=int),
87 **parser['service'])
88+ if (self.service.http_port is DISABLED_PROTOCOL and
89+ self.service.https_port is DISABLED_PROTOCOL):
90+ raise ValueError('both http and https ports were disabled')
91 # Construct the HTTP and HTTPS base urls, which most applications will
92 # actually use.
93 if self.service.http_port == 80:
94 self.service['http_base'] = 'http://{}'.format(self.service.base)
95- else:
96+ elif self.service.http_port is not DISABLED_PROTOCOL:
97 self.service['http_base'] = 'http://{}:{}'.format(
98 self.service.base, self.service.http_port)
99 if self.service.https_port == 443:
100 self.service['https_base'] = 'https://{}'.format(self.service.base)
101- else:
102+ elif self.service.http_port is not DISABLED_PROTOCOL:
103 self.service['https_base'] = 'https://{}:{}'.format(
104 self.service.base, self.service.https_port)
105- # Short-circuit, since we're loading a channel.ini file.
106- self._override = override
107- if override:
108- return
109- self.system = Bag(converters=dict(timeout=as_timedelta,
110+ if self.service.http_port is DISABLED_PROTOCOL:
111+ self.service['http_base'] = self.service['https_base']
112+ elif self.service.https_port is DISABLED_PROTOCOL:
113+ self.service['https_base'] = self.service['http_base']
114+ self.system.update(converters=dict(timeout=as_timedelta,
115 build_file=expand_path,
116 loglevel=as_loglevel,
117 settings_db=expand_path,
118 tempdir=expand_path),
119 **parser['system'])
120+ # Short-circuit, since we're loading a channel.ini file.
121+ self._override = override
122+ if override:
123+ return
124 self.gpg = Bag(**parser['gpg'])
125 self.updater = Bag(**parser['updater'])
126 self.hooks = Bag(converters=dict(device=as_object,
127
128=== added file 'systemimage/tests/data/config_05.ini'
129--- systemimage/tests/data/config_05.ini 1970-01-01 00:00:00 +0000
130+++ systemimage/tests/data/config_05.ini 2014-02-25 22:24:24 +0000
131@@ -0,0 +1,36 @@
132+# Configuration file for specifying relatively static information about the
133+# upgrade resolution process.
134+
135+[service]
136+base: phablet.example.com
137+# Disabled port
138+http_port: disabled
139+https_port: 80443
140+channel: stable
141+build_number: 0
142+
143+[system]
144+timeout: 10s
145+build_file: /etc/ubuntu-build
146+tempdir: /tmp
147+logfile: /var/log/system-image/client.log
148+loglevel: error
149+settings_db: /var/lib/phablet/settings.db
150+
151+[gpg]
152+archive_master: /etc/phablet/archive-master.tar.xz
153+image_master: /etc/phablet/image-master.tar.xz
154+image_signing: /var/lib/phablet/image-signing.tar.xz
155+device_signing: /var/lib/phablet/device-signing.tar.xz
156+
157+[updater]
158+cache_partition: /android/cache
159+data_partition: /var/lib/phablet/updater
160+
161+[hooks]
162+device: systemimage.device.SystemProperty
163+scorer: systemimage.scores.WeightedScorer
164+reboot: systemimage.reboot.Reboot
165+
166+[dbus]
167+lifetime: 3s
168
169=== added file 'systemimage/tests/data/config_06.ini'
170--- systemimage/tests/data/config_06.ini 1970-01-01 00:00:00 +0000
171+++ systemimage/tests/data/config_06.ini 2014-02-25 22:24:24 +0000
172@@ -0,0 +1,36 @@
173+# Configuration file for specifying relatively static information about the
174+# upgrade resolution process.
175+
176+[service]
177+base: phablet.example.com
178+# Disabled port
179+http_port: 80
180+https_port: disabled
181+channel: stable
182+build_number: 0
183+
184+[system]
185+timeout: 10s
186+build_file: /etc/ubuntu-build
187+tempdir: /tmp
188+logfile: /var/log/system-image/client.log
189+loglevel: error
190+settings_db: /var/lib/phablet/settings.db
191+
192+[gpg]
193+archive_master: /etc/phablet/archive-master.tar.xz
194+image_master: /etc/phablet/image-master.tar.xz
195+image_signing: /var/lib/phablet/image-signing.tar.xz
196+device_signing: /var/lib/phablet/device-signing.tar.xz
197+
198+[updater]
199+cache_partition: /android/cache
200+data_partition: /var/lib/phablet/updater
201+
202+[hooks]
203+device: systemimage.device.SystemProperty
204+scorer: systemimage.scores.WeightedScorer
205+reboot: systemimage.reboot.Reboot
206+
207+[dbus]
208+lifetime: 3s
209
210=== added file 'systemimage/tests/data/config_07.ini'
211--- systemimage/tests/data/config_07.ini 1970-01-01 00:00:00 +0000
212+++ systemimage/tests/data/config_07.ini 2014-02-25 22:24:24 +0000
213@@ -0,0 +1,36 @@
214+# Configuration file for specifying relatively static information about the
215+# upgrade resolution process.
216+
217+[service]
218+base: phablet.example.com
219+# Both ports disabled
220+http_port: disabled
221+https_port: disabled
222+channel: stable
223+build_number: 0
224+
225+[system]
226+timeout: 10s
227+build_file: /etc/ubuntu-build
228+tempdir: /tmp
229+logfile: /var/log/system-image/client.log
230+loglevel: error
231+settings_db: /var/lib/phablet/settings.db
232+
233+[gpg]
234+archive_master: /etc/phablet/archive-master.tar.xz
235+image_master: /etc/phablet/image-master.tar.xz
236+image_signing: /var/lib/phablet/image-signing.tar.xz
237+device_signing: /var/lib/phablet/device-signing.tar.xz
238+
239+[updater]
240+cache_partition: /android/cache
241+data_partition: /var/lib/phablet/updater
242+
243+[hooks]
244+device: systemimage.device.SystemProperty
245+scorer: systemimage.scores.WeightedScorer
246+reboot: systemimage.reboot.Reboot
247+
248+[dbus]
249+lifetime: 3s
250
251=== modified file 'systemimage/tests/test_config.py'
252--- systemimage/tests/test_config.py 2014-02-13 18:16:17 +0000
253+++ systemimage/tests/test_config.py 2014-02-25 22:24:24 +0000
254@@ -136,6 +136,36 @@
255 self.assertEqual(config.service.https_base,
256 'https://phablet.example.com:80443')
257
258+ def test_disabled_http_port(self):
259+ # config_05.ini has http port disabled and non-standard https port.
260+ ini_file = data_path('config_05.ini')
261+ config = Configuration()
262+ config.load(ini_file)
263+ self.assertEqual(config.service.base, 'phablet.example.com')
264+ self.assertEqual(config.service.http_base,
265+ 'https://phablet.example.com:80443')
266+ self.assertEqual(config.service.https_base,
267+ 'https://phablet.example.com:80443')
268+
269+ def test_disabled_https_port(self):
270+ # config_06.ini has https port disabled and standard http port.
271+ ini_file = data_path('config_06.ini')
272+ config = Configuration()
273+ config.load(ini_file)
274+ self.assertEqual(config.service.base, 'phablet.example.com')
275+ self.assertEqual(config.service.http_base,
276+ 'http://phablet.example.com')
277+ self.assertEqual(config.service.https_base,
278+ 'http://phablet.example.com')
279+
280+ def test_both_ports_disabled(self):
281+ # config_07.ini has both http and https ports disabled
282+ ini_file = data_path('config_07.ini')
283+ config = Configuration()
284+ with self.assertRaises(ValueError) as ex:
285+ config.load(ini_file)
286+ self.assertEqual(str(ex.exception), 'both http and https ports were disabled')
287+
288 @configuration
289 def test_get_build_number(self, ini_file):
290 # The current build number is stored in a file specified in the

Subscribers

People subscribed via source and target branches