Merge lp:~blake-rouse/maas/fix-xenial-poweroff into lp:~maas-committers/maas/trunk

Proposed by Blake Rouse
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
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve
Review via email: mp+280914@code.launchpad.net

Commit message

Fix enlistment to work with Xenial. Fix commissioning on Xenial to ignore lxcbr0. Fix websocket protocol to work for sendError and sendNotify.

To post a comment you must log in.
Revision history for this message
Mike Pontillo (mpontillo) wrote :

 Elegant. Looks good, assuming you also tested on trusty.

review: Approve
Revision history for this message
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.

Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (1.0 MiB)

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://security.ubuntu.com/ubuntu xenial-security InRelease
Get:2 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial InRelease [227 kB]
Hit:3 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial-updates InRelease
Hit:4 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial-backports InRelease
Hit:5 http://ppa.launchpad.net/maas-maintainers/experimental3/ubuntu xenial InRelease
Get:6 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main Sources [1,121 kB]
Get:7 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 Packages [1,462 kB]
Get:8 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [7,078 kB]
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-headers-4.3.0-1 linux-headers-4.3.0-1-generic
  linux-image-4.2.0-18-generic linux-image-4.3.0-1-generic
  linux-image-extra-4.3.0-1-generic python-twisted-lore
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://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 libisc-export95 amd64 1:9.9.5.dfsg-12.1 [120 kB]
Get:2 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 libdns-export100 amd64 1:9.9.5.dfsg-12.1 [427 kB]
Get:3 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 libisccfg-export90 amd64 1:9.9.5.dfsg-12.1 [19.9 kB]
Get:4 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 libirs-export91 amd64 1:9.9.5.dfsg-12.1 [17.2 kB]
Get:5 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 bind9-host amd64 1:9.9.5.dfsg-12.1 [46.2 kB]
Get:6 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 dnsutils amd64 1:9.9.5.dfsg-12.1 [96.2 kB]
Get:7 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 bind9 amd64 1:9.9.5.dfsg-12.1 [287 kB]
Get:8 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 libisc95 amd64 1:9.9.5.dfsg-12.1 [147 kB]
Get:9 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 libisccc90 amd64 1:9.9.5.dfsg-12.1 [15.5 kB]
Get:10 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 libisccfg90 amd64 1:9.9.5.dfsg-12.1 [36.2 kB]
Get:11 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubuntu xenial/main amd64 liblwres90 amd64 1:9.9.5.dfsg-12.1 [32.5 kB]
Get:12 http://prodstack-zone-1.clouds.archive.ubuntu.com/ubunt...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 }))