Merge lp:~ltrager/maas/stress_ng_tests into lp:~maas-committers/maas/trunk

Proposed by Lee Trager
Status: Merged
Approved by: Lee Trager
Approved revision: no longer in the source branch.
Merged at revision: 5878
Proposed branch: lp:~ltrager/maas/stress_ng_tests
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 617 lines (+217/-51)
20 files modified
src/maasserver/api/scripts.py (+4/-1)
src/maasserver/api/tests/test_scripts.py (+14/-0)
src/maasserver/forms/script.py (+5/-0)
src/maasserver/forms/tests/test_script.py (+24/-0)
src/metadataserver/builtin_scripts/__init__.py (+32/-10)
src/metadataserver/builtin_scripts/internet_connectivity.sh (+5/-4)
src/metadataserver/builtin_scripts/memtester.sh (+4/-3)
src/metadataserver/builtin_scripts/ntp.sh (+4/-4)
src/metadataserver/builtin_scripts/stress-ng-cpu-long.sh (+6/-6)
src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh (+32/-0)
src/metadataserver/builtin_scripts/stress-ng-memory-long.sh (+16/-6)
src/metadataserver/builtin_scripts/stress-ng-memory-short.sh (+36/-0)
src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py (+15/-3)
src/metadataserver/user_data/templates/base_user_data.sh (+1/-1)
src/metadataserver/user_data/templates/snippets/maas_enlist.sh (+1/-1)
src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py (+6/-0)
src/provisioningserver/refresh/node_info_scripts.py (+6/-6)
src/provisioningserver/refresh/tests/test_node_info_scripts.py (+1/-1)
src/provisioningserver/refresh/tests/test_refresh.py (+2/-2)
src/provisioningserver/rpc/tests/test_clusterservice.py (+3/-3)
To merge this branch: bzr merge lp:~ltrager/maas/stress_ng_tests
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve
Review via email: mp+321027@code.launchpad.net

Commit message

Add stress-ng short cpu and memory tests and fix stress_ng_memory_long test.

Description of the change

Add stress-ng short cpu and memory tests. These tests run by default during commissioning and testing. This adds 10 minutes to commissioning time.

While testing I discovered the stress_ng_cpu_long fails due to using too much RAM. I've reworked it so while the OOM killer is tripped on a few stress-ng threads it still passes. I also fixed a bug where the script form was resetting any value that wasn't specified on update and new default scripts weren't being added in certain cases.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

I haven't reviewed the rest of this branch, but I'd like to suggest a policy: all shell scripts should be run with bash. Bash is fairly unpleasant for anything non-trivial, but /bin/sh in all its forms is hostile to sanity and happiness. Shell scripts are a blight, but if we must write them then let's at least stick to the least insane of the ubiquitous ones.

Revision history for this message
Lee Trager (ltrager) wrote :

Fully agree and implemented. I've been using /bin/sh because only because the existing commissioning script use it.

Revision history for this message
Gavin Panella (allenap) wrote :

Sorry, I wasn't clear. Despite the similarities between sh and bash a change from one to the other may introduce bugs, and we're close to release. I wanted your feedback on whether you thought a policy like that would be okay with you. I guess that's a yes! You may want to revert r5860 and keep it for another day. And sorry again: rereading my comment makes it clear to me now that it was unclear when I wrote it.

Revision history for this message
Lee Trager (ltrager) wrote :

I took a look how MAAS is using bash. Its used in simple commissioning and testing scripts, as part of unit tests, or in the user_data scripts. The commissioning and user_data scripts are tested pretty well by CI and bash is a superset of shell so it should be compatible even for more advanced scripts. I think its safe to switch, the riskiest would be the user_data scripts. If we really want to be cautious but move towards a bash world we could switch everywhere but the user data scripts for now.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

The code looks good. I'll test it out a bit before I approve.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Oh, and please change 'sudo' to 'sudo -n' everywhere. I know the risk is small for scripts like these which run in the ephemeral environment, but I'd rather err on the safe side.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Saw this on a machine with 64 GB of RAM (4 cores, 8 with hyperthreading, if it matters).

Value 8262470656 is out of range for vm-bytes, allowed: 4096 .. 4294967296

review: Needs Fixing
Revision history for this message
Lee Trager (ltrager) wrote :

Thanks for running the tests! I've added -n to all test scripts which use sudo. The failure you saw was because stress-ng only allows 4GB of testing memory per thread. None of my test systems have more then 4GB total so I never ran into it. I've modified the stress-ng-memory tests to use enough threads so that no thread uses more then 4GB of RAM.

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Thanks for the fix. Re-tested and it's looking good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/api/scripts.py'
2--- src/maasserver/api/scripts.py 2017-03-23 18:20:00 +0000
3+++ src/maasserver/api/scripts.py 2017-03-29 23:42:47 +0000
4@@ -259,7 +259,8 @@
5 def download(self, request, name):
6 """Download a script.
7
8- :param revision: What revision to download, latest by default.
9+ :param revision: What revision to download, latest by default. Can use
10+ rev as a shortcut.
11 :type revision: integer
12 """
13 if name.isdigit():
14@@ -267,6 +268,8 @@
15 else:
16 script = get_object_or_404(Script, name=name)
17 revision = get_optional_param(request.GET, 'revision', None, Int)
18+ if revision is None:
19+ revision = get_optional_param(request.GET, 'rev', None, Int)
20 if revision is not None:
21 for rev in script.script.previous_versions():
22 if rev.id == revision:
23
24=== modified file 'src/maasserver/api/tests/test_scripts.py'
25--- src/maasserver/api/tests/test_scripts.py 2017-03-23 18:20:00 +0000
26+++ src/maasserver/api/tests/test_scripts.py 2017-03-29 23:42:47 +0000
27@@ -356,6 +356,20 @@
28 self.assertEquals(
29 script.script.previous_version.data, response.content.decode())
30
31+ def test_download_gets_previous_rev(self):
32+ script = factory.make_Script()
33+ script.script = script.script.update(factory.make_string())
34+ script.save()
35+ response = self.client.get(
36+ self.get_script_uri(script),
37+ {
38+ 'op': 'download',
39+ 'rev': script.script.previous_version.id,
40+ })
41+ self.assertThat(response, HasStatusCode(http.client.OK))
42+ self.assertEquals(
43+ script.script.previous_version.data, response.content.decode())
44+
45 def test_download_errors_on_unknown_revision(self):
46 script = factory.make_Script()
47 response = self.client.get(
48
49=== modified file 'src/maasserver/forms/script.py'
50--- src/maasserver/forms/script.py 2017-03-10 09:15:31 +0000
51+++ src/maasserver/forms/script.py 2017-03-29 23:42:47 +0000
52@@ -83,6 +83,11 @@
53 self, 'script_type',
54 'Must be %d, test, testing, %d, commission, or commissioning.'
55 % (SCRIPT_TYPE.TESTING, SCRIPT_TYPE.COMMISSIONING))
56+ # If a field wasn't passed in keep the old values when updating.
57+ if self.instance.id is not None:
58+ for field in self._meta.fields:
59+ if field not in self.data:
60+ cleaned_data[field] = getattr(self.instance, field)
61 return cleaned_data
62
63 def is_valid(self):
64
65=== modified file 'src/maasserver/forms/tests/test_script.py'
66--- src/maasserver/forms/tests/test_script.py 2017-03-10 09:15:31 +0000
67+++ src/maasserver/forms/tests/test_script.py 2017-03-29 23:42:47 +0000
68@@ -193,6 +193,30 @@
69 ]
70 }, form.errors)
71
72+ def test__update_script_doesnt_effect_other_fields(self):
73+ script = factory.make_Script()
74+ script_content = factory.make_string()
75+ name = script.name
76+ title = script.title
77+ description = script.description
78+ tags = script.tags
79+ script_type = script.script_type
80+ timeout = script.timeout
81+ destructive = script.destructive
82+
83+ form = ScriptForm(data={'script': script_content}, instance=script)
84+ self.assertTrue(form.is_valid(), form.errors)
85+ script = form.save()
86+
87+ self.assertEquals(name, script.name)
88+ self.assertEquals(title, script.title)
89+ self.assertEquals(description, script.description)
90+ self.assertEquals(tags, script.tags)
91+ self.assertEquals(script_type, script.script_type)
92+ self.assertEquals(timeout, script.timeout)
93+ self.assertEquals(destructive, script.destructive)
94+ self.assertFalse(script.default)
95+
96 def test__can_use_script_type_name(self):
97 script_type_name = random.choice([
98 'test', 'testing',
99
100=== modified file 'src/metadataserver/builtin_scripts/__init__.py'
101--- src/metadataserver/builtin_scripts/__init__.py 2017-03-29 21:13:51 +0000
102+++ src/metadataserver/builtin_scripts/__init__.py 2017-03-29 23:42:47 +0000
103@@ -7,6 +7,7 @@
104 'load_builtin_scripts',
105 ]
106
107+from datetime import timedelta
108 import os
109
110 import attr
111@@ -48,7 +49,8 @@
112 tags = attr.ib(default=None, validator=instance_of(list))
113 script_type = attr.ib(
114 default=SCRIPT_TYPE.TESTING, validator=instance_of(int))
115- timeout = attr.ib(default=0, validator=instance_of(int))
116+ timeout = attr.ib(
117+ default=timedelta(seconds=0), validator=instance_of(timedelta))
118 destructive = attr.ib(default=False, validator=instance_of(bool))
119 filename = attr.ib(default=None, validator=instance_of(str))
120
121@@ -63,7 +65,7 @@
122 title='Storage status',
123 description='Validate SMART health for all drives in parallel.',
124 tags=['storage', 'commissioning'],
125- timeout=60 * 5,
126+ timeout=timedelta(minutes=5),
127 filename='smartctl.py',
128 ),
129 BuiltinScript(
130@@ -73,7 +75,7 @@
131 'Run the short SMART self-test and validate SMART health on all '
132 'drives in parallel'),
133 tags=['storage'],
134- timeout=60 * 10,
135+ timeout=timedelta(minutes=10),
136 filename='smartctl.py',
137 ),
138 BuiltinScript(
139@@ -106,7 +108,7 @@
140 title='Network validation',
141 description='Download a file from images.maas.io.',
142 tags=['network', 'internet'],
143- timeout=60 * 5,
144+ timeout=timedelta(minutes=5),
145 filename='internet_connectivity.sh',
146 ),
147 BuiltinScript(
148@@ -114,23 +116,39 @@
149 title='CPU validation',
150 description='Run the stress-ng CPU tests over 12 hours.',
151 tags=['cpu'],
152- timeout=60 * 60 * 12,
153- filename='stress_ng_cpu_long.sh',
154+ timeout=timedelta(hours=12),
155+ filename='stress-ng-cpu-long.sh',
156+ ),
157+ BuiltinScript(
158+ name='stress-ng-cpu-short',
159+ title='CPU validation',
160+ description='Stress test the CPU for 5 minutes.',
161+ tags=['cpu'],
162+ timeout=timedelta(minutes=5),
163+ filename='stress-ng-cpu-short.sh',
164 ),
165 BuiltinScript(
166 name='stress-ng-memory-long',
167 title='Memory integrity',
168 description='Run the stress-ng memory tests over 12 hours.',
169 tags=['memory'],
170- timeout=60 * 60 * 12,
171- filename='stress_ng_memory_long.sh',
172+ timeout=timedelta(hours=12),
173+ filename='stress-ng-memory-long.sh',
174+ ),
175+ BuiltinScript(
176+ name='stress-ng-memory-short',
177+ title='Memory validation',
178+ description='Stress test memory for 5 minutes.',
179+ tags=['memory'],
180+ timeout=timedelta(minutes=5),
181+ filename='stress-ng-memory-short.sh',
182 ),
183 BuiltinScript(
184 name='ntp',
185 title='NTP validation',
186 description='Run ntp clock set to verify NTP connectivity.',
187 tags=['network', 'ntp'],
188- timeout=60,
189+ timeout=timedelta(minutes=1),
190 filename='ntp.sh',
191 ),
192 ]
193@@ -161,11 +179,15 @@
194 # Don't add back old versions of a script. This prevents two
195 # connected regions with different versions of a script from
196 # fighting with eachother.
197+ no_update = False
198 for vtf in script_in_db.script.previous_versions():
199 if vtf.data == script_content:
200 # Don't update anything if we detect we have an old
201 # version of the builtin scripts
202- return
203+ no_update = True
204+ break
205+ if no_update:
206+ continue
207 script_in_db.script = script_in_db.script.update(
208 script_content,
209 "Updated by maas-%s" % get_maas_package_version())
210
211=== modified file 'src/metadataserver/builtin_scripts/internet_connectivity.sh'
212--- src/metadataserver/builtin_scripts/internet_connectivity.sh 2017-03-10 16:34:33 +0000
213+++ src/metadataserver/builtin_scripts/internet_connectivity.sh 2017-03-29 23:42:47 +0000
214@@ -1,4 +1,4 @@
215-#!/bin/sh -e
216+#!/bin/bash -e
217 #
218 # internet_connectivity - Check if the system has access to the Internet.
219 #
220@@ -20,6 +20,7 @@
221 # along with this program. If not, see <http://www.gnu.org/licenses/>.
222
223 # Download the index.sjson file used by MAAS to download images to validate
224-# internet connectivity. Close stderr so we don't get the progress from curl.
225-curl -I -A maas_internet_connectivity_test \
226- https://images.maas.io/ephemeral-v3/daily/streams/v1/index.sjson
227+# internet connectivity.
228+URL="https://images.maas.io/ephemeral-v3/daily/streams/v1/index.sjson"
229+echo "Attempting to retrieve: $URL"
230+curl -ILSsv -A maas_internet_connectivity_test $URL
231
232=== modified file 'src/metadataserver/builtin_scripts/memtester.sh'
233--- src/metadataserver/builtin_scripts/memtester.sh 2017-03-23 18:20:00 +0000
234+++ src/metadataserver/builtin_scripts/memtester.sh 2017-03-29 23:42:47 +0000
235@@ -1,4 +1,4 @@
236-#!/bin/sh -e
237+#!/bin/bash -e
238 #
239 # memtester - Run memtester against all available userspace memory.
240 #
241@@ -19,10 +19,11 @@
242 # You should have received a copy of the GNU Affero General Public License
243 # along with this program. If not, see <http://www.gnu.org/licenses/>.
244
245-sudo apt-get install -q -y memtester
246+sudo -n apt-get install -q -y memtester
247+echo
248
249 # Memtester can only test memory available to userspace. Reserve 32M so the
250 # test doesn't fail due to the OOM killer. Only run memtester against available
251 # RAM once.
252-sudo memtester \
253+sudo -n memtester \
254 $(awk '/MemAvailable/ { print ($2 - 32768) "K"}' /proc/meminfo) 1
255
256=== modified file 'src/metadataserver/builtin_scripts/ntp.sh'
257--- src/metadataserver/builtin_scripts/ntp.sh 2017-03-23 18:20:00 +0000
258+++ src/metadataserver/builtin_scripts/ntp.sh 2017-03-29 23:42:47 +0000
259@@ -1,4 +1,4 @@
260-#!/bin/sh -e
261+#!/bin/bash -e
262 #
263 # ntp - Run ntp clock set to verify NTP connectivity.
264 #
265@@ -24,7 +24,7 @@
266 # the configured NTP server is accessible.
267 e=0
268 ntpq -np
269-sudo systemctl stop ntp.service
270-sudo timeout 10 ntpd -gq || e=$?
271-sudo systemctl start ntp.service
272+sudo -n systemctl stop ntp.service
273+sudo -n timeout 10 ntpd -gq || e=$?
274+sudo -n systemctl start ntp.service
275 exit $e
276
277=== renamed file 'src/metadataserver/builtin_scripts/stress_ng_cpu_long.sh' => 'src/metadataserver/builtin_scripts/stress-ng-cpu-long.sh'
278--- src/metadataserver/builtin_scripts/stress_ng_cpu_long.sh 2017-03-23 18:20:00 +0000
279+++ src/metadataserver/builtin_scripts/stress-ng-cpu-long.sh 2017-03-29 23:42:47 +0000
280@@ -1,6 +1,6 @@
281-#!/bin/sh -e
282+#!/bin/bash -e
283 #
284-# stress_ng_cpu_long - Run stress-ng memory tests over 12 hours.
285+# stress-ng-cpu-long - Run stress-ng memory tests over 12 hours.
286 #
287 # Author: Lee Trager <lee.trager@canonical.com>
288 #
289@@ -19,8 +19,8 @@
290 # You should have received a copy of the GNU Affero General Public License
291 # along with this program. If not, see <http://www.gnu.org/licenses/>.
292
293-sudo apt-get install -q -y stress-ng
294+sudo -n apt-get install -q -y stress-ng
295+echo
296
297-sudo stress-ng \
298- --aggressive -a 0 --class cpu,cpu-cache --ignite-cpu --log-brief \
299- --metrics --times --tz --verify --timeout 12h
300+sudo -n stress-ng --aggressive -a 0 --class cpu,cpu-cache --ignite-cpu \
301+ --log-brief --metrics-brief --times --tz --verify --timeout 12h
302
303=== added file 'src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh'
304--- src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh 1970-01-01 00:00:00 +0000
305+++ src/metadataserver/builtin_scripts/stress-ng-cpu-short.sh 2017-03-29 23:42:47 +0000
306@@ -0,0 +1,32 @@
307+#!/bin/bash -e
308+#
309+# stress-ng-cpu-short - Stress test the CPU for 5 minutes.
310+#
311+# Author: Lee Trager <lee.trager@canonical.com>
312+#
313+# Copyright (C) 2017 Canonical
314+#
315+# This program is free software: you can redistribute it and/or modify
316+# it under the terms of the GNU Affero General Public License as
317+# published by the Free Software Foundation, either version 3 of the
318+# License, or (at your option) any later version.
319+#
320+# This program is distributed in the hope that it will be useful,
321+# but WITHOUT ANY WARRANTY; without even the implied warranty of
322+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
323+# GNU Affero General Public License for more details.
324+#
325+# You should have received a copy of the GNU Affero General Public License
326+# along with this program. If not, see <http://www.gnu.org/licenses/>.
327+
328+sudo -n apt-get install -q -y stress-ng
329+echo
330+
331+sudo -n stress-ng --matrix 0 --ignite-cpu --log-brief --metrics-brief --times \
332+ --tz --verify --timeout 2m
333+echo
334+sudo -n stress-ng --cache 0 --ignite-cpu --log-brief --metrics-brief --times \
335+ --tz --verify --timeout 1m
336+echo
337+sudo -n stress-ng --cpu 0 --ignite-cpu --log-brief --metrics-brief --times --tz \
338+ --verify --timeout 2m
339
340=== renamed file 'src/metadataserver/builtin_scripts/stress_ng_memory_long.sh' => 'src/metadataserver/builtin_scripts/stress-ng-memory-long.sh'
341--- src/metadataserver/builtin_scripts/stress_ng_memory_long.sh 2017-03-23 18:20:00 +0000
342+++ src/metadataserver/builtin_scripts/stress-ng-memory-long.sh 2017-03-29 23:42:47 +0000
343@@ -1,4 +1,4 @@
344-#!/bin/sh -e
345+#!/bin/bash -e
346 #
347 # stress_ng_memory_long - Run stress-ng memory tests over 12 hours.
348 #
349@@ -19,8 +19,18 @@
350 # You should have received a copy of the GNU Affero General Public License
351 # along with this program. If not, see <http://www.gnu.org/licenses/>.
352
353-sudo apt-get install -q -y stress-ng
354-
355-sudo stress-ng \
356- --aggressive -a 0 --class memory --ignite-cpu --log-brief --metrics \
357- --times --tz --verify --timeout 12h
358+sudo -n apt-get install -q -y stress-ng
359+echo
360+
361+# Reserve 64M so the test doesn't fail due to the OOM killer.
362+total_memory=$(awk '/MemAvailable/ { print ($2 - 65536) }' /proc/meminfo)
363+threads=$(lscpu --all --parse | grep -v '#' | wc -l)
364+memory_per_thread=$(($total_memory / $threads))
365+# stress-ng only allows 4GB of memory per thread.
366+if [ $memory_per_thread -ge 4194304 ]; then
367+ threads=$(($total_memory / 4194304 + 1))
368+ memory_per_thread=$(($total_memory / $threads))
369+fi
370+
371+stress-ng --vm $threads --vm-bytes ${memory_per_thread}k --page-in \
372+ --log-brief --metrics-brief --times --tz --verify --timeout 12h
373
374=== added file 'src/metadataserver/builtin_scripts/stress-ng-memory-short.sh'
375--- src/metadataserver/builtin_scripts/stress-ng-memory-short.sh 1970-01-01 00:00:00 +0000
376+++ src/metadataserver/builtin_scripts/stress-ng-memory-short.sh 2017-03-29 23:42:47 +0000
377@@ -0,0 +1,36 @@
378+#!/bin/bash -e
379+#
380+# stress-ng-memory-short - Stress test memory for 5 minutes.
381+#
382+# Author: Lee Trager <lee.trager@canonical.com>
383+#
384+# Copyright (C) 2017 Canonical
385+#
386+# This program is free software: you can redistribute it and/or modify
387+# it under the terms of the GNU Affero General Public License as
388+# published by the Free Software Foundation, either version 3 of the
389+# License, or (at your option) any later version.
390+#
391+# This program is distributed in the hope that it will be useful,
392+# but WITHOUT ANY WARRANTY; without even the implied warranty of
393+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
394+# GNU Affero General Public License for more details.
395+#
396+# You should have received a copy of the GNU Affero General Public License
397+# along with this program. If not, see <http://www.gnu.org/licenses/>.
398+
399+sudo -n apt-get install -q -y stress-ng
400+echo
401+
402+# Reserve 64M so the test doesn't fail due to the OOM killer.
403+total_memory=$(awk '/MemAvailable/ { print ($2 - 65536) }' /proc/meminfo)
404+threads=$(lscpu --all --parse | grep -v '#' | wc -l)
405+memory_per_thread=$(($total_memory / $threads))
406+# stress-ng only allows 4GB of memory per thread.
407+if [ $memory_per_thread -ge 4194304 ]; then
408+ threads=$(($total_memory / 4194304 + 1))
409+ memory_per_thread=$(($total_memory / $threads))
410+fi
411+
412+stress-ng --vm $threads --vm-bytes ${memory_per_thread}k --page-in \
413+ --log-brief --metrics-brief --times --tz --verify --timeout 5m
414
415=== modified file 'src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py'
416--- src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py 2017-03-23 18:20:00 +0000
417+++ src/metadataserver/builtin_scripts/tests/test_builtin_scripts.py 2017-03-29 23:42:47 +0000
418@@ -34,8 +34,7 @@
419 script_in_db.script.comment)
420 self.assertItemsEqual(script.tags, script_in_db.tags)
421 self.assertEquals(script.script_type, script_in_db.script_type)
422- self.assertEquals(
423- timedelta(seconds=script.timeout), script_in_db.timeout)
424+ self.assertEquals(script.timeout, script_in_db.timeout)
425 self.assertEquals(script.destructive, script_in_db.destructive)
426 self.assertTrue(script_in_db.default)
427
428@@ -79,7 +78,8 @@
429
430 def test_update_doesnt_revert_script(self):
431 load_builtin_scripts()
432- update_script_values = random.choice(BUILTIN_SCRIPTS)
433+ update_script_index = random.randint(0, len(BUILTIN_SCRIPTS) - 2)
434+ update_script_values = BUILTIN_SCRIPTS[update_script_index]
435 script = Script.objects.get(name=update_script_values.name)
436 # Put fake new data in to simulate another MAAS region updating
437 # to a newer version.
438@@ -99,6 +99,14 @@
439 script.timeout = user_timeout
440 script.save()
441
442+ # Test that subsequent scripts still get updated
443+ second_update_script_values = BUILTIN_SCRIPTS[update_script_index + 1]
444+ second_script = Script.objects.get(
445+ name=second_update_script_values.name)
446+ # Put fake old data in to simulate updating a script.
447+ second_script.title = factory.make_string()
448+ second_script.save()
449+
450 load_builtin_scripts()
451 script = reload_object(script)
452
453@@ -111,3 +119,7 @@
454 self.assertEquals(user_tags, script.tags)
455 self.assertEquals(user_timeout, script.timeout)
456 self.assertTrue(script.default)
457+
458+ second_script = reload_object(second_script)
459+ self.assertEquals(
460+ second_update_script_values.title, second_script.title)
461
462=== modified file 'src/metadataserver/user_data/templates/base_user_data.sh'
463--- src/metadataserver/user_data/templates/base_user_data.sh 2017-02-16 00:27:35 +0000
464+++ src/metadataserver/user_data/templates/base_user_data.sh 2017-03-29 23:42:47 +0000
465@@ -1,4 +1,4 @@
466-#!/bin/sh
467+#!/bin/bash
468 #
469 # This script carries inside it multiple files. When executed, it creates
470 # the files into a temporary directory and uses them to execute commands
471
472=== modified file 'src/metadataserver/user_data/templates/snippets/maas_enlist.sh'
473--- src/metadataserver/user_data/templates/snippets/maas_enlist.sh 2017-03-08 10:10:12 +0000
474+++ src/metadataserver/user_data/templates/snippets/maas_enlist.sh 2017-03-29 23:42:47 +0000
475@@ -1,4 +1,4 @@
476-#!/bin/sh
477+#!/bin/bash
478 #
479 # maas-enlist: MAAS Enlistment Tool
480 #
481
482=== modified file 'src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py'
483--- src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py 2017-03-03 00:50:43 +0000
484+++ src/metadataserver/user_data/templates/snippets/maas_run_remote_scripts.py 2017-03-29 23:42:47 +0000
485@@ -233,6 +233,12 @@
486 fail("URL must be provided either in --url or in config\n")
487 url = "%s/%s/" % (url, args.apiver)
488
489+ # Disable the OOM killer on the runner process, the OOM killer will still
490+ # go after any tests spawned.
491+ oom_score_adj_path = os.path.join(
492+ '/proc', str(os.getpid()), 'oom_score_adj')
493+ open(oom_score_adj_path, 'w').write('-1000')
494+
495 heart_beat = HeartBeat(url, creds)
496 heart_beat.start()
497
498
499=== modified file 'src/provisioningserver/refresh/node_info_scripts.py'
500--- src/provisioningserver/refresh/node_info_scripts.py 2017-03-29 21:13:51 +0000
501+++ src/provisioningserver/refresh/node_info_scripts.py 2017-03-29 23:42:47 +0000
502@@ -60,19 +60,19 @@
503
504 # Built-in script to run lshw.
505 LSHW_SCRIPT = dedent("""\
506- #!/bin/sh
507+ #!/bin/bash
508 sudo -n /usr/bin/lshw -xml
509 """)
510
511 # Built-in script to run `ip addr`
512 IPADDR_SCRIPT = dedent("""\
513- #!/bin/sh
514+ #!/bin/bash
515 ip addr
516 """)
517
518 # Built-in script to detect virtual instances.
519 VIRTUALITY_SCRIPT = dedent("""\
520- #!/bin/sh
521+ #!/bin/bash
522 # In Bourne Shell `type -p` does not work; `which` is closest.
523 if which systemd-detect-virt > /dev/null; then
524 # systemd-detect-virt prints "none" and returns nonzero if
525@@ -90,7 +90,7 @@
526 """)
527
528 CPUINFO_SCRIPT = dedent("""\
529- #!/bin/sh
530+ #!/bin/bash
531 # Gather the standard output as it has some extra info
532 lscpu
533 # Gather the machine readable output for processing
534@@ -108,7 +108,7 @@
535 """)
536
537 SRIOV_SCRIPT = dedent("""\
538- #!/bin/sh
539+ #!/bin/bash
540 for file in $(find /sys/devices/ -name sriov_numvfs); do
541 dir=$(dirname "$file")
542 for eth in $(ls "$dir/net/"); do
543@@ -388,7 +388,7 @@
544
545 LIST_MODALIASES_OUTPUT_NAME = '00-maas-04-list-modaliases'
546 LIST_MODALIASES_SCRIPT = dedent("""\
547- #!/bin/sh
548+ #!/bin/bash
549 find /sys -name modalias -print0 | xargs -0 cat | sort -u
550 """)
551
552
553=== modified file 'src/provisioningserver/refresh/tests/test_node_info_scripts.py'
554--- src/provisioningserver/refresh/tests/test_node_info_scripts.py 2017-03-23 18:20:00 +0000
555+++ src/provisioningserver/refresh/tests/test_node_info_scripts.py 2017-03-29 23:42:47 +0000
556@@ -944,7 +944,7 @@
557 self.sysdv.unlink()
558 sysdv_name = factory.make_name("virt")
559 with self.sysdv.open("w") as fd:
560- fd.write("#!/bin/sh\n")
561+ fd.write("#!/bin/bash\n")
562 fd.write("echo %s\n" % sysdv_name)
563 fd.write("exit 1\n")
564 self.sysdv.chmod(0o700)
565
566=== modified file 'src/provisioningserver/refresh/tests/test_refresh.py'
567--- src/provisioningserver/refresh/tests/test_refresh.py 2017-03-03 00:50:43 +0000
568+++ src/provisioningserver/refresh/tests/test_refresh.py 2017-03-29 23:42:47 +0000
569@@ -137,7 +137,7 @@
570 if script_name is None:
571 script_name = factory.make_name('script_name')
572 TEST_SCRIPT = dedent("""\
573- #!/bin/sh
574+ #!/bin/bash
575 echo 'test script'
576 """)
577 refresh.NODE_INFO_SCRIPTS = OrderedDict([
578@@ -151,7 +151,7 @@
579 if script_name is None:
580 script_name = factory.make_name('script_name')
581 TEST_SCRIPT = dedent("""\
582- #!/bin/sh
583+ #!/bin/bash
584 echo 'test failed'
585 exit 1
586 """)
587
588=== modified file 'src/provisioningserver/rpc/tests/test_clusterservice.py'
589--- src/provisioningserver/rpc/tests/test_clusterservice.py 2017-03-27 14:35:23 +0000
590+++ src/provisioningserver/rpc/tests/test_clusterservice.py 2017-03-29 23:42:47 +0000
591@@ -2479,7 +2479,7 @@
592 @inlineCallbacks
593 def test_spawnProcessAndNullifyStdout_nullifies_stdout(self):
594 done, protocol = makeDeferredWithProcessProtocol()
595- args = [b"/bin/sh", b'-c', b"echo foo"]
596+ args = [b"/bin/bash", b'-c', b"echo foo"]
597 outReceived = Mock()
598 protocol.outReceived = outReceived
599 spawnProcessAndNullifyStdout(protocol, args)
600@@ -2489,7 +2489,7 @@
601 @inlineCallbacks
602 def test_spawnProcessAndNullifyStdout_captures_stderr(self):
603 done, protocol = makeDeferredWithProcessProtocol()
604- args = [b"/bin/sh", b'-c', b"echo foo >&2"]
605+ args = [b"/bin/bash", b'-c', b"echo foo >&2"]
606 errReceived = Mock()
607 protocol.errReceived = errReceived
608 spawnProcessAndNullifyStdout(protocol, args)
609@@ -2500,7 +2500,7 @@
610 def test_executeScanNetworksSubprocess(self):
611 mock_scan_args = self.patch(
612 clusterservice, 'get_scan_all_networks_args')
613- mock_scan_args.return_value = [b"/bin/sh", b'-c', b"echo -n foo >&2"]
614+ mock_scan_args.return_value = [b"/bin/bash", b'-c', b"echo -n foo >&2"]
615 mock_log_msg = self.patch(clusterservice.log, 'msg')
616 d = executeScanNetworksSubprocess()
617 yield d