Merge lp:~blake-rouse/maas/fix-xenial-poweroff into lp:~maas-committers/maas/trunk
- fix-xenial-poweroff
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Blake Rouse | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 4567 | ||||
Proposed branch: | lp:~blake-rouse/maas/fix-xenial-poweroff | ||||
Merge into: | lp:~maas-committers/maas/trunk | ||||
Diff against target: |
403 lines (+70/-153) 10 files modified
contrib/preseeds_v2/enlist_userdata (+7/-31) etc/maas/templates/commissioning-user-data/user_data.template (+0/-36) etc/maas/templates/commissioning-user-data/user_data_disk_erasing.template (+0/-36) etc/maas/templates/commissioning-user-data/user_data_poweroff.template (+2/-39) src/maasserver/compose_preseed.py (+21/-3) src/maasserver/tests/test_compose_preseed.py (+22/-0) src/maasserver/websockets/protocol.py (+4/-2) src/metadataserver/models/commissioningscript.py (+3/-0) src/metadataserver/models/tests/ip_addr_results.txt (+11/-5) src/metadataserver/user_data/tests/test_poweroff.py (+0/-1) |
||||
To merge this branch: | bzr merge lp:~blake-rouse/maas/fix-xenial-poweroff | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Mike Pontillo (community) | Approve | ||
Review via email:
|
Commit message
Fix enlistment to work with Xenial. Fix commissioning on Xenial to ignore lxcbr0. Fix websocket protocol to work for sendError and sendNotify.
Description of the change
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Blake Rouse (blake-rouse) wrote : | # |
Yes this was tested with trusty. Disk erasing works on Trusty as well, who knows why Xenial does not work. I can't figure it out.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
MAAS Lander (maas-lander) wrote : | # |
The attempt to merge lp:~blake-rouse/maas/fix-xenial-poweroff into lp:maas failed. Below is the output from the failed tests.
Hit:1 http://
Get:2 http://
Hit:3 http://
Hit:4 http://
Hit:5 http://
Get:6 http://
Get:7 http://
Get:8 http://
Fetched 9,888 kB in 3s (2,590 kB/s)
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
Calculating upgrade...
The following packages were automatically installed and are no longer required:
libc-ares-dev libc-ares2 libisl13 libv8-3.14-dev libv8-3.14.5
linux-
linux-
linux-
Use 'sudo apt autoremove' to remove them.
The following packages will be upgraded:
bind9 bind9-host bind9utils dnsutils libbind9-90 libdns-export100 libdns100
libirs-export91 libisc-export95 libisc95 libisccc90 libisccfg-export90
libisccfg90 liblwres90
14 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,060 kB of archives.
After this operation, 4,096 B disk space will be freed.
Get:1 http://
Get:2 http://
Get:3 http://
Get:4 http://
Get:5 http://
Get:6 http://
Get:7 http://
Get:8 http://
Get:9 http://
Get:10 http://
Get:11 http://
Get:12 http://
Preview Diff
1 | === modified file 'contrib/preseeds_v2/enlist_userdata' |
2 | --- contrib/preseeds_v2/enlist_userdata 2015-11-12 13:45:09 +0000 |
3 | +++ contrib/preseeds_v2/enlist_userdata 2015-12-17 20:47:32 +0000 |
4 | @@ -25,6 +25,12 @@ |
5 | primary: "http://ports.ubuntu.com/ubuntu-ports" |
6 | security: "http://ports.ubuntu.com/ubuntu-ports" |
7 | |
8 | +power_state: |
9 | + delay: now |
10 | + mode: poweroff |
11 | + timeout: 1800 |
12 | + condition: test ! -e /tmp/block-poweroff |
13 | + |
14 | misc_bucket: |
15 | - &maas_enlist | |
16 | #### IPMI setup ###### |
17 | @@ -149,40 +155,12 @@ |
18 | echo "sleeping 60 seconds then poweroff" |
19 | echo |
20 | echo "login with '$user:$pass' to debug and disable poweroff" |
21 | - echo |
22 | + echo |
23 | cat /tmp/enlist.out |
24 | echo ============================================= |
25 | sleep 60 |
26 | [ -e $bfile ] && exit 0 |
27 | fi |
28 | - - &write_poweroff_job | |
29 | - cat >/etc/init/maas-poweroff.conf <<EOF |
30 | - description "poweroff when maas task is done" |
31 | - start on stopped cloud-final |
32 | - console output |
33 | - task |
34 | - script |
35 | - [ ! -e /tmp/block-poweroff ] || exit 0 |
36 | - poweroff |
37 | - end script |
38 | - EOF |
39 | - # reload required due to lack of inotify in overlayfs (LP: #882147) |
40 | - initctl reload-configuration |
41 | - - &write_systemd_poweroff_job | |
42 | - cat >/lib/systemd/system/maas-poweroff.service <<EOF |
43 | - [Unit] |
44 | - Description=Poweroff when maas task is done |
45 | - Wants=cloud-final.service |
46 | - After=cloud-final.service |
47 | - ConditionPathExists=!/tmp/block-poweroff |
48 | - |
49 | - [Service] |
50 | - ExecStart=/sbin/poweroff |
51 | - EOF |
52 | - # reload required due to lack of inotify in overlayfs (LP: #882147) |
53 | - if [ -d /run/systemd/system ]; then |
54 | - systemctl daemon-reload |
55 | - fi |
56 | |
57 | |
58 | |
59 | @@ -190,5 +168,3 @@ |
60 | output: {all: '| tee -a /var/log/cloud-init-output.log'} |
61 | runcmd: |
62 | - [ sh, -c, *maas_enlist ] |
63 | - - [ sh, -c, *write_poweroff_job ] |
64 | - - [ sh, -c, *write_systemd_poweroff_job ] |
65 | |
66 | === modified file 'etc/maas/templates/commissioning-user-data/user_data.template' |
67 | --- etc/maas/templates/commissioning-user-data/user_data.template 2015-12-16 23:51:21 +0000 |
68 | +++ etc/maas/templates/commissioning-user-data/user_data.template 2015-12-17 20:47:32 +0000 |
69 | @@ -110,36 +110,6 @@ |
70 | exit 1 |
71 | } |
72 | |
73 | -write_upstart_poweroff_job() { |
74 | - cat >/etc/init/maas-poweroff.conf <<EOF |
75 | - description "poweroff when maas task is done" |
76 | - start on stopped cloud-final |
77 | - console output |
78 | - task |
79 | - script |
80 | - [ ! -e /tmp/block-poweroff ] || exit 0 |
81 | - poweroff |
82 | - end script |
83 | -EOF |
84 | - # reload required due to lack of inotify in overlayfs (LP: #882147) |
85 | - initctl reload-configuration |
86 | -} |
87 | - |
88 | -write_systemd_poweroff_job() { |
89 | - cat >/lib/systemd/system/maas-poweroff.service <<EOF |
90 | - [Unit] |
91 | - Description=Poweroff when maas task is done |
92 | - Wants=cloud-final.service |
93 | - After=cloud-final.service |
94 | - ConditionPathExists=!/tmp/block-poweroff |
95 | - |
96 | - [Service] |
97 | - ExecStart=/sbin/poweroff |
98 | -EOF |
99 | - # reload required due to lack of inotify in overlayfs (LP: #882147) |
100 | - systemctl daemon-reload |
101 | -} |
102 | - |
103 | write_block_poweroff() { |
104 | touch /tmp/block-poweroff |
105 | } |
106 | @@ -149,12 +119,6 @@ |
107 | write_block_poweroff |
108 | {{endif}} |
109 | |
110 | - if [ -d /run/systemd/system ]; then |
111 | - write_systemd_poweroff_job |
112 | - else |
113 | - write_upstart_poweroff_job |
114 | - fi |
115 | - |
116 | # Install tools and load modules. |
117 | aptget update |
118 | aptget install python3-yaml python3-oauthlib freeipmi-tools openipmi ipmitool |
119 | |
120 | === modified file 'etc/maas/templates/commissioning-user-data/user_data_disk_erasing.template' |
121 | --- etc/maas/templates/commissioning-user-data/user_data_disk_erasing.template 2015-12-16 23:51:21 +0000 |
122 | +++ etc/maas/templates/commissioning-user-data/user_data_disk_erasing.template 2015-12-17 20:47:32 +0000 |
123 | @@ -73,36 +73,6 @@ |
124 | exit 1 |
125 | } |
126 | |
127 | -write_upstart_poweroff_job() { |
128 | - cat >/etc/init/maas-poweroff.conf <<EOF |
129 | - description "poweroff when maas task is done" |
130 | - start on stopped cloud-final |
131 | - console output |
132 | - task |
133 | - script |
134 | - [ ! -e /tmp/block-poweroff ] || exit 0 |
135 | - poweroff |
136 | - end script |
137 | -EOF |
138 | - # reload required due to lack of inotify in overlayfs (LP: #882147) |
139 | - initctl reload-configuration |
140 | -} |
141 | - |
142 | -write_systemd_poweroff_job() { |
143 | - cat >/lib/systemd/system/maas-poweroff.service <<EOF |
144 | - [Unit] |
145 | - Description=Poweroff when maas task is done |
146 | - Wants=cloud-final.service |
147 | - After=cloud-final.service |
148 | - ConditionPathExists=!/tmp/block-poweroff |
149 | - |
150 | - [Service] |
151 | - ExecStart=/sbin/poweroff |
152 | -EOF |
153 | - # reload required due to lack of inotify in overlayfs (LP: #882147) |
154 | - systemctl daemon-reload |
155 | -} |
156 | - |
157 | erase_disks() { |
158 | for disk in `lsblk -d -n -oKNAME,TYPE,RO | grep '^\w*\s*disk\s*0' | awk {'print $1'}` |
159 | do |
160 | @@ -113,12 +83,6 @@ |
161 | } |
162 | |
163 | main() { |
164 | - if [ -d /run/systemd/system ]; then |
165 | - write_systemd_poweroff_job |
166 | - else |
167 | - write_upstart_poweroff_job |
168 | - fi |
169 | - |
170 | # Install tools and load modules. |
171 | aptget update |
172 | aptget install python3-yaml python3-oauthlib |
173 | |
174 | === modified file 'etc/maas/templates/commissioning-user-data/user_data_poweroff.template' |
175 | --- etc/maas/templates/commissioning-user-data/user_data_poweroff.template 2015-12-16 23:51:21 +0000 |
176 | +++ etc/maas/templates/commissioning-user-data/user_data_poweroff.template 2015-12-17 20:47:32 +0000 |
177 | @@ -1,46 +1,9 @@ |
178 | #!/bin/sh |
179 | |
180 | -#### script setup ###### |
181 | -PATH="$BIN_D:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" |
182 | - |
183 | -write_upstart_poweroff_job() { |
184 | - cat >/etc/init/maas-poweroff.conf <<EOF |
185 | - description "Power-off when MAAS task is done" |
186 | - start on stopped cloud-final |
187 | - console output |
188 | - task |
189 | - script |
190 | - [ ! -e /tmp/block-poweroff ] || exit 0 |
191 | - /sbin/poweroff |
192 | - end script |
193 | -EOF |
194 | - # reload required due to lack of inotify in overlayfs (LP: #882147) |
195 | - initctl reload-configuration |
196 | -} |
197 | - |
198 | -write_systemd_poweroff_job() { |
199 | - cat >/lib/systemd/system/maas-poweroff.service <<EOF |
200 | - [Unit] |
201 | - Description=Poweroff when maas task is done |
202 | - Wants=cloud-final.service |
203 | - After=cloud-final.service |
204 | - ConditionPathExists=!/tmp/block-poweroff |
205 | - |
206 | - [Service] |
207 | - ExecStart=/sbin/poweroff |
208 | -EOF |
209 | - # reload required due to lack of inotify in overlayfs (LP: #882147) |
210 | - systemctl daemon-reload |
211 | -} |
212 | - |
213 | main() { |
214 | - if [ -d /run/systemd/system ]; then |
215 | - write_systemd_poweroff_job |
216 | - else |
217 | - write_upstart_poweroff_job |
218 | - fi |
219 | - |
220 | echo "Powering node off." |
221 | + |
222 | + # Cloud-init will handle powering off the node. Nothing to do. |
223 | } |
224 | |
225 | main |
226 | |
227 | === modified file 'src/maasserver/compose_preseed.py' |
228 | --- src/maasserver/compose_preseed.py 2015-12-01 18:12:59 +0000 |
229 | +++ src/maasserver/compose_preseed.py 2015-12-17 20:47:32 +0000 |
230 | @@ -7,10 +7,14 @@ |
231 | 'compose_preseed', |
232 | ] |
233 | |
234 | +from datetime import timedelta |
235 | from urllib.parse import urlencode |
236 | |
237 | from maasserver.clusterrpc.osystems import get_preseed_data |
238 | -from maasserver.enum import PRESEED_TYPE |
239 | +from maasserver.enum import ( |
240 | + NODE_STATUS, |
241 | + PRESEED_TYPE, |
242 | +) |
243 | from maasserver.models.config import Config |
244 | from maasserver.server_address import get_maas_facing_server_host |
245 | from maasserver.utils import absolute_reverse |
246 | @@ -139,8 +143,13 @@ |
247 | """Compose the preseed value for a Commissioning node.""" |
248 | apt_proxy = get_apt_proxy_for_node(node) |
249 | metadata_url = absolute_reverse('metadata', base_url=base_url) |
250 | + poweroff_timeout = timedelta(hours=1).total_seconds() # 1 hour |
251 | + if node.status == NODE_STATUS.DISK_ERASING: |
252 | + poweroff_timeout = timedelta(days=7).total_seconds() # 1 week |
253 | return _compose_cloud_init_preseed( |
254 | - node, token, metadata_url, base_url=base_url, apt_proxy=apt_proxy) |
255 | + node, token, metadata_url, base_url=base_url, apt_proxy=apt_proxy, |
256 | + poweroff=True, poweroff_timeout=int(poweroff_timeout), |
257 | + poweroff_condition="test ! -e /tmp/block-poweroff") |
258 | |
259 | |
260 | def compose_curtin_preseed(node, token, base_url=''): |
261 | @@ -152,7 +161,8 @@ |
262 | |
263 | |
264 | def _compose_cloud_init_preseed( |
265 | - node, token, metadata_url, base_url, apt_proxy=None): |
266 | + node, token, metadata_url, base_url, apt_proxy=None, |
267 | + poweroff=False, poweroff_timeout=3600, poweroff_condition=None): |
268 | cloud_config = { |
269 | 'datasource': { |
270 | 'MAAS': { |
271 | @@ -179,6 +189,14 @@ |
272 | cloud_config.update(get_system_info()) |
273 | if apt_proxy: |
274 | cloud_config['apt_proxy'] = apt_proxy |
275 | + if poweroff: |
276 | + cloud_config['power_state'] = { |
277 | + 'delay': 'now', |
278 | + 'mode': 'poweroff', |
279 | + 'timeout': poweroff_timeout, |
280 | + } |
281 | + if poweroff_condition is not None: |
282 | + cloud_config['power_state']['condition'] = poweroff_condition |
283 | return "#cloud-config\n%s" % yaml.safe_dump(cloud_config) |
284 | |
285 | |
286 | |
287 | === modified file 'src/maasserver/tests/test_compose_preseed.py' |
288 | --- src/maasserver/tests/test_compose_preseed.py 2015-12-01 18:12:59 +0000 |
289 | +++ src/maasserver/tests/test_compose_preseed.py 2015-12-17 20:47:32 +0000 |
290 | @@ -132,6 +132,28 @@ |
291 | absolute_reverse('metadata-status', args=[node.system_id]), |
292 | preseed['reporting']['maas']['endpoint']) |
293 | |
294 | + def test_compose_preseed_for_commissioning_includes_poweroff(self): |
295 | + node = factory.make_Node(status=NODE_STATUS.COMMISSIONING) |
296 | + preseed = yaml.safe_load( |
297 | + compose_preseed(PRESEED_TYPE.COMMISSIONING, node)) |
298 | + self.assertEquals({ |
299 | + 'delay': 'now', |
300 | + 'mode': 'poweroff', |
301 | + 'timeout': 3600, |
302 | + 'condition': 'test ! -e /tmp/block-poweroff', |
303 | + }, preseed['power_state']) |
304 | + |
305 | + def test_compose_preseed_for_disk_erasing_includes_poweroff(self): |
306 | + node = factory.make_Node(status=NODE_STATUS.DISK_ERASING) |
307 | + preseed = yaml.safe_load( |
308 | + compose_preseed(PRESEED_TYPE.COMMISSIONING, node)) |
309 | + self.assertEquals({ |
310 | + 'delay': 'now', |
311 | + 'mode': 'poweroff', |
312 | + 'timeout': 604800, |
313 | + 'condition': 'test ! -e /tmp/block-poweroff', |
314 | + }, preseed['power_state']) |
315 | + |
316 | def test_compose_preseed_includes_node_oauth_token(self): |
317 | node = factory.make_Node(status=NODE_STATUS.READY) |
318 | node.nodegroup.accept() |
319 | |
320 | === modified file 'src/maasserver/websockets/protocol.py' |
321 | --- src/maasserver/websockets/protocol.py 2015-12-15 22:44:22 +0000 |
322 | +++ src/maasserver/websockets/protocol.py 2015-12-17 20:47:32 +0000 |
323 | @@ -324,7 +324,8 @@ |
324 | "rtype": RESPONSE_TYPE.ERROR, |
325 | "error": error, |
326 | } |
327 | - self.transport.write(json.dumps(error_msg).encode("utf-8")) |
328 | + self.transport.write( |
329 | + json.dumps(error_msg, default=self._json_encode).encode("ascii")) |
330 | return None |
331 | |
332 | def sendNotify(self, name, action, data): |
333 | @@ -335,7 +336,8 @@ |
334 | "action": action, |
335 | "data": data, |
336 | } |
337 | - self.transport.write(json.dumps(notify_msg).encode("utf-8")) |
338 | + self.transport.write( |
339 | + json.dumps(notify_msg, default=self._json_encode).encode("ascii")) |
340 | |
341 | def buildHandler(self, handler_class): |
342 | """Return an initialised instance of `handler_class`.""" |
343 | |
344 | === modified file 'src/metadataserver/models/commissioningscript.py' |
345 | --- src/metadataserver/models/commissioningscript.py 2015-12-16 18:07:33 +0000 |
346 | +++ src/metadataserver/models/commissioningscript.py 2015-12-17 20:47:32 +0000 |
347 | @@ -178,6 +178,9 @@ |
348 | # Ignore loopback interfaces. |
349 | if link_mac is None: |
350 | continue |
351 | + # Ignore lxcbr0 which is created by default on Xenial+. |
352 | + elif link['name'] == 'lxcbr0': |
353 | + continue |
354 | else: |
355 | ifname = link['name'] |
356 | try: |
357 | |
358 | === modified file 'src/metadataserver/models/tests/ip_addr_results.txt' |
359 | --- src/metadataserver/models/tests/ip_addr_results.txt 2015-07-16 08:30:38 +0000 |
360 | +++ src/metadataserver/models/tests/ip_addr_results.txt 2015-12-17 20:47:32 +0000 |
361 | @@ -2,21 +2,27 @@ |
362 | link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 |
363 | inet 127.0.0.1/8 scope host lo |
364 | valid_lft forever preferred_lft forever |
365 | - inet6 ::1/128 scope host |
366 | + inet6 ::1/128 scope host |
367 | valid_lft forever preferred_lft forever |
368 | 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 |
369 | link/ether 00:00:00:00:00:01 brd ff:ff:ff:ff:ff:ff |
370 | inet 192.168.0.3/24 brd 192.168.0.255 scope global eth0 |
371 | valid_lft forever preferred_lft forever |
372 | - inet6 fe80::3e97:efe:fe0e:56dc/64 scope link |
373 | - valid_lft forever preferred_lft forever |
374 | - inet6 2001:db8:a::123/64 scope link |
375 | + inet6 fe80::3e97:efe:fe0e:56dc/64 scope link |
376 | + valid_lft forever preferred_lft forever |
377 | + inet6 2001:db8:a::123/64 scope link |
378 | valid_lft forever preferred_lft forever |
379 | 3: eth1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000 |
380 | link/ether 00:00:00:00:00:02 brd ff:ff:ff:ff:ff:ff |
381 | inet 172.17.42.1/16 scope global eth1 |
382 | valid_lft forever preferred_lft forever |
383 | -3: eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000 |
384 | +4: eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN mode DORMANT group default qlen 1000 |
385 | link/ether 00:00:00:00:00:03 brd ff:ff:ff:ff:ff:ff |
386 | inet 172.17.12.1/16 scope global eth2 |
387 | valid_lft forever preferred_lft forever |
388 | +5: lxcbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000 |
389 | + link/ether 00:00:00:00:00:04 brd ff:ff:ff:ff:ff:ff |
390 | + inet 10.0.3.1/24 scope global lxcbr0 |
391 | + valid_lft forever preferred_lft forever |
392 | + inet6 fe80::e477:64ff:fec5:25a3/64 scope link |
393 | + valid_lft forever preferred_lft forever |
394 | |
395 | === modified file 'src/metadataserver/user_data/tests/test_poweroff.py' |
396 | --- src/metadataserver/user_data/tests/test_poweroff.py 2015-12-02 23:30:15 +0000 |
397 | +++ src/metadataserver/user_data/tests/test_poweroff.py 2015-12-17 20:47:32 +0000 |
398 | @@ -43,5 +43,4 @@ |
399 | self.assertThat( |
400 | base64.b64decode(user_data_script.get_payload()), ContainsAll({ |
401 | b'Powering node off', |
402 | - b'poweroff', |
403 | })) |
Elegant. Looks good, assuming you also tested on trusty.