Merge ~ltrager/maas:lp1807991_2.5 into maas:2.5
- Git
- lp:~ltrager/maas
- lp1807991_2.5
- Merge into 2.5
Proposed by
Lee Trager
Status: | Merged |
---|---|
Approved by: | Lee Trager |
Approved revision: | 03561be1f8a6f7285b0b876362b7ea4eb31b99a0 |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~ltrager/maas:lp1807991_2.5 |
Merge into: | maas:2.5 |
Diff against target: |
455 lines (+118/-26) 12 files modified
src/maasserver/api/machines.py (+19/-6) src/maasserver/api/tests/test_enlistment.py (+22/-3) src/maasserver/forms/__init__.py (+23/-0) src/maasserver/forms/settings.py (+11/-0) src/maasserver/forms/tests/test_machine.py (+2/-0) src/maasserver/forms/tests/test_machinewithmacaddresses.py (+17/-1) src/maasserver/models/config.py (+2/-0) src/metadataserver/api.py (+6/-6) src/metadataserver/tests/test_api.py (+0/-4) src/metadataserver/user_data/templates/enlistment.template (+5/-1) src/metadataserver/user_data/templates/snippets/maas_enlist.sh (+9/-4) src/metadataserver/user_data/tests/test_generate_user_data.py (+2/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Lee Trager (community) | Approve | ||
Review via email: mp+361631@code.launchpad.net |
Commit message
Backport 51b971 LP: #1807991 - Directly go into commissioning during enlistment.
The anonymous API now accepts the 'commission' flag. When set to true
newly created machines will be created in COMMISSIONING and a ScriptSet
with all builtin Scripts will be set as the current_
Commissioning during enlistment can now be disabled using the
'enlist_
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/src/maasserver/api/machines.py b/src/maasserver/api/machines.py | |||
2 | index 0ac51b1..0af350b 100644 | |||
3 | --- a/src/maasserver/api/machines.py | |||
4 | +++ b/src/maasserver/api/machines.py | |||
5 | @@ -1611,6 +1611,12 @@ class AnonMachinesHandler(AnonNodesHandler): | |||
6 | 1611 | power_type. `Power types`_ section for a list of the available power | 1611 | power_type. `Power types`_ section for a list of the available power |
7 | 1612 | parameters for each power type. | 1612 | parameters for each power type. |
8 | 1613 | 1613 | ||
9 | 1614 | @param (boolean) "commission" [required=false,formatting=true] Request | ||
10 | 1615 | the newly created machine to be created with status set to | ||
11 | 1616 | COMMISSIONING. Machines will wait for COMMISSIONING results and not | ||
12 | 1617 | time out. After commissioning is complete machines will still have to | ||
13 | 1618 | be accepted by an administrator. | ||
14 | 1619 | |||
15 | 1614 | @success (http-status-code) "200" 200 | 1620 | @success (http-status-code) "200" 200 |
16 | 1615 | @success (json) "success-json" A JSON object containing the machine | 1621 | @success (json) "success-json" A JSON object containing the machine |
17 | 1616 | information. | 1622 | information. |
18 | @@ -1621,6 +1627,8 @@ class AnonMachinesHandler(AnonNodesHandler): | |||
19 | 1621 | power_type = request.data.get('power_type') | 1627 | power_type = request.data.get('power_type') |
20 | 1622 | power_parameters = request.data.get('power_parameters') | 1628 | power_parameters = request.data.get('power_parameters') |
21 | 1623 | mac_addresses = request.data.getlist('mac_addresses') | 1629 | mac_addresses = request.data.getlist('mac_addresses') |
22 | 1630 | commission = get_optional_param( | ||
23 | 1631 | request.data, 'commission', default=False, validator=StringBool) | ||
24 | 1624 | machine = None | 1632 | machine = None |
25 | 1625 | 1633 | ||
26 | 1626 | # BMC enlistment - Check if there is a pre-existing machine within MAAS | 1634 | # BMC enlistment - Check if there is a pre-existing machine within MAAS |
27 | @@ -1667,12 +1675,12 @@ class AnonMachinesHandler(AnonNodesHandler): | |||
28 | 1667 | if machine is None: | 1675 | if machine is None: |
29 | 1668 | machine = create_machine(request, requires_arch=True) | 1676 | machine = create_machine(request, requires_arch=True) |
30 | 1669 | 1677 | ||
37 | 1670 | if machine.status == NODE_STATUS.NEW: | 1678 | if commission: |
38 | 1671 | # Make sure an enlisting NodeMetadata object exists if the machine | 1679 | # Make sure an enlisting NodeMetadata object exists if the |
39 | 1672 | # is NEW. When commissioning finishes this is how MAAS knows to | 1680 | # machine is NEW. When commissioning finishes this is how |
40 | 1673 | # set the status to NEW instead of READY. | 1681 | # MAAS knows to set the status to NEW instead of READY. |
41 | 1674 | NodeMetadata.objects.update_or_create( | 1682 | NodeMetadata.objects.update_or_create( |
42 | 1675 | node=machine, key='enlisting', defaults={'value': 'True'}) | 1683 | node=machine, key='enlisting', defaults={'value': 'True'}) |
43 | 1676 | 1684 | ||
44 | 1677 | return machine | 1685 | return machine |
45 | 1678 | 1686 | ||
46 | @@ -1743,6 +1751,11 @@ class MachinesHandler(NodesHandler, PowersMixin): | |||
47 | 1743 | power_type. `Power types`_ section for a list of the available power | 1751 | power_type. `Power types`_ section for a list of the available power |
48 | 1744 | parameters for each power type. | 1752 | parameters for each power type. |
49 | 1745 | 1753 | ||
50 | 1754 | @param (boolean) "commission" [required=false,formatting=true] Request | ||
51 | 1755 | the newly created machine to be created with status set to | ||
52 | 1756 | COMMISSIONING. Machines will wait for COMMISSIONING results and not | ||
53 | 1757 | time out. | ||
54 | 1758 | |||
55 | 1746 | @success (http-status-code) "200" 200 | 1759 | @success (http-status-code) "200" 200 |
56 | 1747 | @success (json) "success-json" A JSON object containing the machine | 1760 | @success (json) "success-json" A JSON object containing the machine |
57 | 1748 | information. | 1761 | information. |
58 | diff --git a/src/maasserver/api/tests/test_enlistment.py b/src/maasserver/api/tests/test_enlistment.py | |||
59 | index 30a3413..8111f6b 100644 | |||
60 | --- a/src/maasserver/api/tests/test_enlistment.py | |||
61 | +++ b/src/maasserver/api/tests/test_enlistment.py | |||
62 | @@ -452,8 +452,6 @@ class AnonymousEnlistmentAPITest(APITestCase.ForAnonymous): | |||
63 | 452 | self.assertEqual(architecture, machine.architecture) | 452 | self.assertEqual(architecture, machine.architecture) |
64 | 453 | self.assertDictContainsSubset( | 453 | self.assertDictContainsSubset( |
65 | 454 | machine.bmc.power_parameters, power_parameters) | 454 | machine.bmc.power_parameters, power_parameters) |
66 | 455 | node_metadata = NodeMetadata.objects.get(node=machine, key='enlisting') | ||
67 | 456 | self.assertEqual(node_metadata.value, 'True') | ||
68 | 457 | self.assertThat(mock_create_machine, MockNotCalled()) | 455 | self.assertThat(mock_create_machine, MockNotCalled()) |
69 | 458 | self.assertEqual( | 456 | self.assertEqual( |
70 | 459 | machine.system_id, json_load_bytes(response.content)['system_id']) | 457 | machine.system_id, json_load_bytes(response.content)['system_id']) |
71 | @@ -501,12 +499,33 @@ class AnonymousEnlistmentAPITest(APITestCase.ForAnonymous): | |||
72 | 501 | }) | 499 | }) |
73 | 502 | self.assertEqual(http.client.OK, response.status_code) | 500 | self.assertEqual(http.client.OK, response.status_code) |
74 | 503 | node_metadata = NodeMetadata.objects.get(key='enlisting') | 501 | node_metadata = NodeMetadata.objects.get(key='enlisting') |
76 | 504 | self.assertEqual(node_metadata.value, 'True') | 502 | self.assertIsNone(node_metadata) |
77 | 505 | [machine] = Machine.objects.filter(hostname=hostname) | 503 | [machine] = Machine.objects.filter(hostname=hostname) |
78 | 506 | self.assertEqual(architecture, machine.architecture) | 504 | self.assertEqual(architecture, machine.architecture) |
79 | 507 | self.assertEqual( | 505 | self.assertEqual( |
80 | 508 | machine.system_id, json_load_bytes(response.content)['system_id']) | 506 | machine.system_id, json_load_bytes(response.content)['system_id']) |
81 | 509 | 507 | ||
82 | 508 | def test_POST_create_creates_machine_commission(self): | ||
83 | 509 | hostname = factory.make_name("hostname") | ||
84 | 510 | architecture = make_usable_architecture(self) | ||
85 | 511 | response = self.client.post( | ||
86 | 512 | reverse('machines_handler'), | ||
87 | 513 | { | ||
88 | 514 | 'hostname': hostname, | ||
89 | 515 | 'architecture': architecture, | ||
90 | 516 | 'power_type': 'manual', | ||
91 | 517 | 'mac_addresses': ['aa:bb:cc:dd:ee:ff', '22:bb:cc:dd:ee:ff'], | ||
92 | 518 | 'commission': True, | ||
93 | 519 | }) | ||
94 | 520 | self.assertEqual(http.client.OK, response.status_code) | ||
95 | 521 | node_metadata = NodeMetadata.objects.get(key='enlisting') | ||
96 | 522 | self.assertEqual('True', node_metadata.value) | ||
97 | 523 | [machine] = Machine.objects.filter(hostname=hostname) | ||
98 | 524 | self.assertEqual(architecture, machine.architecture) | ||
99 | 525 | self.assertEqual( | ||
100 | 526 | machine.system_id, json_load_bytes(response.content)['system_id']) | ||
101 | 527 | self.assertEqual(NODE_STATUS.COMMISSIONING, machine.status) | ||
102 | 528 | |||
103 | 510 | def test_POST_create_requires_architecture(self): | 529 | def test_POST_create_requires_architecture(self): |
104 | 511 | hostname = factory.make_name("hostname") | 530 | hostname = factory.make_name("hostname") |
105 | 512 | response = self.client.post( | 531 | response = self.client.post( |
106 | diff --git a/src/maasserver/forms/__init__.py b/src/maasserver/forms/__init__.py | |||
107 | index 582b2af..6c3ab95 100644 | |||
108 | --- a/src/maasserver/forms/__init__.py | |||
109 | +++ b/src/maasserver/forms/__init__.py | |||
110 | @@ -113,6 +113,7 @@ from maasserver.enum import ( | |||
111 | 113 | FILESYSTEM_GROUP_RAID_TYPE_CHOICES, | 113 | FILESYSTEM_GROUP_RAID_TYPE_CHOICES, |
112 | 114 | FILESYSTEM_TYPE, | 114 | FILESYSTEM_TYPE, |
113 | 115 | INTERFACE_TYPE, | 115 | INTERFACE_TYPE, |
114 | 116 | NODE_STATUS, | ||
115 | 116 | NODE_TYPE, | 117 | NODE_TYPE, |
116 | 117 | ) | 118 | ) |
117 | 118 | from maasserver.exceptions import NodeActionError | 119 | from maasserver.exceptions import NodeActionError |
118 | @@ -893,6 +894,27 @@ class MachineForm(NodeForm): | |||
119 | 893 | self.is_bound = True | 894 | self.is_bound = True |
120 | 894 | self.data['install_kvm'] = install_kvm | 895 | self.data['install_kvm'] = install_kvm |
121 | 895 | 896 | ||
122 | 897 | def save(self, *args, **kwargs): | ||
123 | 898 | # Prevent circular imports | ||
124 | 899 | from metadataserver.models import ScriptSet | ||
125 | 900 | # LP:1807991 - If requested when creating a new Machine, set the status | ||
126 | 901 | # to COMMISSIONING when the object is created. | ||
127 | 902 | commission = not self.instance.id and self.cleaned_data['commission'] | ||
128 | 903 | if commission: | ||
129 | 904 | self.instance.status = NODE_STATUS.COMMISSIONING | ||
130 | 905 | machine = super(MachineForm, self).save(*args, **kwargs) | ||
131 | 906 | # For a ScriptSet to be created it must be associated with a Node | ||
132 | 907 | # object in the database. | ||
133 | 908 | if commission: | ||
134 | 909 | script_set = ScriptSet.objects.create_commissioning_script_set( | ||
135 | 910 | machine, ['none']) | ||
136 | 911 | machine.current_commissioning_script_set = script_set | ||
137 | 912 | machine.save(update_fields=['current_commissioning_script_set']) | ||
138 | 913 | |||
139 | 914 | return machine | ||
140 | 915 | |||
141 | 916 | commission = forms.BooleanField(required=False, widget=forms.HiddenInput()) | ||
142 | 917 | |||
143 | 896 | class Meta: | 918 | class Meta: |
144 | 897 | model = Machine | 919 | model = Machine |
145 | 898 | 920 | ||
146 | @@ -905,6 +927,7 @@ class MachineForm(NodeForm): | |||
147 | 905 | 'hwe_kernel', | 927 | 'hwe_kernel', |
148 | 906 | 'install_rackd', | 928 | 'install_rackd', |
149 | 907 | 'install_kvm', | 929 | 'install_kvm', |
150 | 930 | 'commission' | ||
151 | 908 | ) | 931 | ) |
152 | 909 | 932 | ||
153 | 910 | 933 | ||
154 | diff --git a/src/maasserver/forms/settings.py b/src/maasserver/forms/settings.py | |||
155 | index d318759..e6bae82 100644 | |||
156 | --- a/src/maasserver/forms/settings.py | |||
157 | +++ b/src/maasserver/forms/settings.py | |||
158 | @@ -766,6 +766,17 @@ CONFIG_ITEMS = { | |||
159 | 766 | "in minutes.") | 766 | "in minutes.") |
160 | 767 | } | 767 | } |
161 | 768 | }, | 768 | }, |
162 | 769 | 'enlist_commissioning': { | ||
163 | 770 | 'default': True, | ||
164 | 771 | 'form': forms.BooleanField, | ||
165 | 772 | 'form_kwargs': { | ||
166 | 773 | 'label': 'Whether to run commissioning during enlistment.', | ||
167 | 774 | 'required': False, | ||
168 | 775 | 'help_text': ( | ||
169 | 776 | 'Enables running all built-in commissioning scripts during ' | ||
170 | 777 | 'enlistment.'), | ||
171 | 778 | } | ||
172 | 779 | }, | ||
173 | 769 | } | 780 | } |
174 | 770 | 781 | ||
175 | 771 | 782 | ||
176 | diff --git a/src/maasserver/forms/tests/test_machine.py b/src/maasserver/forms/tests/test_machine.py | |||
177 | index c8ed726..b4564d6 100644 | |||
178 | --- a/src/maasserver/forms/tests/test_machine.py | |||
179 | +++ b/src/maasserver/forms/tests/test_machine.py | |||
180 | @@ -51,6 +51,7 @@ class TestMachineForm(MAASServerTestCase): | |||
181 | 51 | 'hwe_kernel', | 51 | 'hwe_kernel', |
182 | 52 | 'install_rackd', | 52 | 'install_rackd', |
183 | 53 | 'install_kvm', | 53 | 'install_kvm', |
184 | 54 | 'commission', | ||
185 | 54 | ], list(form.fields)) | 55 | ], list(form.fields)) |
186 | 55 | 56 | ||
187 | 56 | def test_accepts_usable_architecture(self): | 57 | def test_accepts_usable_architecture(self): |
188 | @@ -374,6 +375,7 @@ class TestAdminMachineForm(MAASServerTestCase): | |||
189 | 374 | 'power_parameters', | 375 | 'power_parameters', |
190 | 375 | 'power_type', | 376 | 'power_type', |
191 | 376 | 'pool', | 377 | 'pool', |
192 | 378 | 'commission', | ||
193 | 377 | ], | 379 | ], |
194 | 378 | list(form.fields)) | 380 | list(form.fields)) |
195 | 379 | 381 | ||
196 | diff --git a/src/maasserver/forms/tests/test_machinewithmacaddresses.py b/src/maasserver/forms/tests/test_machinewithmacaddresses.py | |||
197 | index fefaaf9..8bc5f98 100644 | |||
198 | --- a/src/maasserver/forms/tests/test_machinewithmacaddresses.py | |||
199 | +++ b/src/maasserver/forms/tests/test_machinewithmacaddresses.py | |||
200 | @@ -6,7 +6,10 @@ | |||
201 | 6 | __all__ = [] | 6 | __all__ = [] |
202 | 7 | 7 | ||
203 | 8 | from django.http import QueryDict | 8 | from django.http import QueryDict |
205 | 9 | from maasserver.enum import INTERFACE_TYPE | 9 | from maasserver.enum import ( |
206 | 10 | INTERFACE_TYPE, | ||
207 | 11 | NODE_STATUS, | ||
208 | 12 | ) | ||
209 | 10 | from maasserver.forms import MachineWithMACAddressesForm | 13 | from maasserver.forms import MachineWithMACAddressesForm |
210 | 11 | from maasserver.testing.architecture import ( | 14 | from maasserver.testing.architecture import ( |
211 | 12 | make_usable_architecture, | 15 | make_usable_architecture, |
212 | @@ -160,15 +163,18 @@ class MachineWithMACAddressesFormTest(MAASServerTestCase): | |||
213 | 160 | macs = ['aa:bb:cc:dd:ee:ff', '9a:bb:c3:33:e5:7f'] | 163 | macs = ['aa:bb:cc:dd:ee:ff', '9a:bb:c3:33:e5:7f'] |
214 | 161 | form = MachineWithMACAddressesForm( | 164 | form = MachineWithMACAddressesForm( |
215 | 162 | data=self.make_params(mac_addresses=macs)) | 165 | data=self.make_params(mac_addresses=macs)) |
216 | 166 | self.assertTrue(form.is_valid()) | ||
217 | 163 | node = form.save() | 167 | node = form.save() |
218 | 164 | 168 | ||
219 | 165 | self.assertIsNotNone(node.id) # The node is persisted. | 169 | self.assertIsNotNone(node.id) # The node is persisted. |
220 | 170 | self.assertEquals(NODE_STATUS.NEW, node.status) | ||
221 | 166 | self.assertItemsEqual( | 171 | self.assertItemsEqual( |
222 | 167 | macs, | 172 | macs, |
223 | 168 | [nic.mac_address for nic in node.interface_set.all()]) | 173 | [nic.mac_address for nic in node.interface_set.all()]) |
224 | 169 | 174 | ||
225 | 170 | def test_form_without_hostname_generates_hostname(self): | 175 | def test_form_without_hostname_generates_hostname(self): |
226 | 171 | form = MachineWithMACAddressesForm(data=self.make_params(hostname='')) | 176 | form = MachineWithMACAddressesForm(data=self.make_params(hostname='')) |
227 | 177 | self.assertTrue(form.is_valid()) | ||
228 | 172 | node = form.save() | 178 | node = form.save() |
229 | 173 | self.assertTrue(len(node.hostname) > 0) | 179 | self.assertTrue(len(node.hostname) > 0) |
230 | 174 | 180 | ||
231 | @@ -176,6 +182,7 @@ class MachineWithMACAddressesFormTest(MAASServerTestCase): | |||
232 | 176 | ip_based_hostname = '192-168-12-10.maas' | 182 | ip_based_hostname = '192-168-12-10.maas' |
233 | 177 | form = MachineWithMACAddressesForm( | 183 | form = MachineWithMACAddressesForm( |
234 | 178 | data=self.make_params(hostname=ip_based_hostname)) | 184 | data=self.make_params(hostname=ip_based_hostname)) |
235 | 185 | self.assertTrue(form.is_valid()) | ||
236 | 179 | node = form.save() | 186 | node = form.save() |
237 | 180 | self.assertNotEqual('192-168-12-10', node.hostname) | 187 | self.assertNotEqual('192-168-12-10', node.hostname) |
238 | 181 | 188 | ||
239 | @@ -183,5 +190,14 @@ class MachineWithMACAddressesFormTest(MAASServerTestCase): | |||
240 | 183 | ip_prefixed_hostname = '192-168-12-10-extra.maas' | 190 | ip_prefixed_hostname = '192-168-12-10-extra.maas' |
241 | 184 | form = MachineWithMACAddressesForm( | 191 | form = MachineWithMACAddressesForm( |
242 | 185 | data=self.make_params(hostname=ip_prefixed_hostname)) | 192 | data=self.make_params(hostname=ip_prefixed_hostname)) |
243 | 193 | self.assertTrue(form.is_valid()) | ||
244 | 186 | node = form.save() | 194 | node = form.save() |
245 | 187 | self.assertEqual('192-168-12-10-extra', node.hostname) | 195 | self.assertEqual('192-168-12-10-extra', node.hostname) |
246 | 196 | |||
247 | 197 | def test_form_with_commissioning(self): | ||
248 | 198 | form = MachineWithMACAddressesForm(data={ | ||
249 | 199 | 'commission': True, **self.make_params()}) | ||
250 | 200 | self.assertTrue(form.is_valid()) | ||
251 | 201 | machine = form.save() | ||
252 | 202 | self.assertEquals(NODE_STATUS.COMMISSIONING, machine.status) | ||
253 | 203 | self.assertIsNotNone(machine.current_commissioning_script_set) | ||
254 | diff --git a/src/maasserver/models/config.py b/src/maasserver/models/config.py | |||
255 | index a95246b..0c76e3c 100644 | |||
256 | --- a/src/maasserver/models/config.py | |||
257 | +++ b/src/maasserver/models/config.py | |||
258 | @@ -130,6 +130,8 @@ def get_default_config(): | |||
259 | 130 | 'prometheus_enabled': False, | 130 | 'prometheus_enabled': False, |
260 | 131 | 'prometheus_push_gateway': None, | 131 | 'prometheus_push_gateway': None, |
261 | 132 | 'prometheus_push_interval': 60, | 132 | 'prometheus_push_interval': 60, |
262 | 133 | # Enlistment options | ||
263 | 134 | 'enlist_commissioning': True, | ||
264 | 133 | } | 135 | } |
265 | 134 | 136 | ||
266 | 135 | 137 | ||
267 | diff --git a/src/metadataserver/api.py b/src/metadataserver/api.py | |||
268 | index e76a651..3470a29 100644 | |||
269 | --- a/src/metadataserver/api.py | |||
270 | +++ b/src/metadataserver/api.py | |||
271 | @@ -509,9 +509,9 @@ class VersionIndexHandler(MetadataViewHandler): | |||
272 | 509 | script_result.save(update_fields=['status']) | 509 | script_result.save(update_fields=['status']) |
273 | 510 | 510 | ||
274 | 511 | def _process_new(self, node, request, status): | 511 | def _process_new(self, node, request, status): |
275 | 512 | # MAAS only cares if a NEW node is trying to commission itself. Ignore | ||
276 | 513 | # other signals. | ||
277 | 514 | if status != SIGNAL_STATUS.COMMISSIONING: | 512 | if status != SIGNAL_STATUS.COMMISSIONING: |
278 | 513 | # MAAS only cares if a NEW node is trying to commission itself. | ||
279 | 514 | # Ignore other signals. | ||
280 | 515 | return None | 515 | return None |
281 | 516 | 516 | ||
282 | 517 | # Check if the node currently has a pending or running commissioning | 517 | # Check if the node currently has a pending or running commissioning |
283 | @@ -525,9 +525,6 @@ class VersionIndexHandler(MetadataViewHandler): | |||
284 | 525 | node, ['none']) | 525 | node, ['none']) |
285 | 526 | node.current_commissioning_script_set = script_set | 526 | node.current_commissioning_script_set = script_set |
286 | 527 | 527 | ||
287 | 528 | node.min_hwe_kernel = Config.objects.get_config( | ||
288 | 529 | 'default_min_hwe_kernel') | ||
289 | 530 | |||
290 | 531 | return NODE_STATUS.COMMISSIONING | 528 | return NODE_STATUS.COMMISSIONING |
291 | 532 | 529 | ||
292 | 533 | def _process_testing(self, node, request, status): | 530 | def _process_testing(self, node, request, status): |
293 | @@ -1155,7 +1152,10 @@ class EnlistUserDataHandler(OperationsHandler): | |||
294 | 1155 | return HttpResponse( | 1152 | return HttpResponse( |
295 | 1156 | generate_user_data_for_status( | 1153 | generate_user_data_for_status( |
296 | 1157 | None, NODE_STATUS.NEW, rack_controller=rack_controller, | 1154 | None, NODE_STATUS.NEW, rack_controller=rack_controller, |
298 | 1158 | request=request), | 1155 | request=request, extra_content={ |
299 | 1156 | 'enlist_commissioning': Config.objects.get_config( | ||
300 | 1157 | 'enlist_commissioning'), | ||
301 | 1158 | }), | ||
302 | 1159 | content_type="text/plain") | 1159 | content_type="text/plain") |
303 | 1160 | 1160 | ||
304 | 1161 | 1161 | ||
305 | diff --git a/src/metadataserver/tests/test_api.py b/src/metadataserver/tests/test_api.py | |||
306 | index 2e7b6cb..68d8b2f 100644 | |||
307 | --- a/src/metadataserver/tests/test_api.py | |||
308 | +++ b/src/metadataserver/tests/test_api.py | |||
309 | @@ -47,7 +47,6 @@ from maasserver.exceptions import ( | |||
310 | 47 | Unauthorized, | 47 | Unauthorized, |
311 | 48 | ) | 48 | ) |
312 | 49 | from maasserver.models import ( | 49 | from maasserver.models import ( |
313 | 50 | Config, | ||
314 | 51 | NodeMetadata, | 50 | NodeMetadata, |
315 | 52 | Event, | 51 | Event, |
316 | 53 | SSHKey, | 52 | SSHKey, |
317 | @@ -2546,8 +2545,6 @@ class TestNewAPI(MAASServerTestCase): | |||
318 | 2546 | factory.make_Script(script_type=SCRIPT_TYPE.COMMISSIONING) | 2545 | factory.make_Script(script_type=SCRIPT_TYPE.COMMISSIONING) |
319 | 2547 | factory.make_Script( | 2546 | factory.make_Script( |
320 | 2548 | script_type=SCRIPT_TYPE.TESTING, tags=['commissioning']) | 2547 | script_type=SCRIPT_TYPE.TESTING, tags=['commissioning']) |
321 | 2549 | min_hwe_kernel = factory.make_name('hwe_kernel') | ||
322 | 2550 | Config.objects.set_config('default_min_hwe_kernel', min_hwe_kernel) | ||
323 | 2551 | 2548 | ||
324 | 2552 | client = make_node_client(node) | 2549 | client = make_node_client(node) |
325 | 2553 | response = call_signal(client, status=SIGNAL_STATUS.COMMISSIONING) | 2550 | response = call_signal(client, status=SIGNAL_STATUS.COMMISSIONING) |
326 | @@ -2560,7 +2557,6 @@ class TestNewAPI(MAASServerTestCase): | |||
327 | 2560 | [script.name for script in node.current_commissioning_script_set]) | 2557 | [script.name for script in node.current_commissioning_script_set]) |
328 | 2561 | self.assertIsNone(node.current_testing_script_set) | 2558 | self.assertIsNone(node.current_testing_script_set) |
329 | 2562 | self.assertEqual(NODE_STATUS.COMMISSIONING, node.status) | 2559 | self.assertEqual(NODE_STATUS.COMMISSIONING, node.status) |
330 | 2563 | self.assertEqual(min_hwe_kernel, node.min_hwe_kernel) | ||
331 | 2564 | 2560 | ||
332 | 2565 | def test_signal_commissioning_only_creates_scriptsets_when_needed(self): | 2561 | def test_signal_commissioning_only_creates_scriptsets_when_needed(self): |
333 | 2566 | # This happens when commissioning is started by the user with correct | 2562 | # This happens when commissioning is started by the user with correct |
334 | diff --git a/src/metadataserver/user_data/templates/enlistment.template b/src/metadataserver/user_data/templates/enlistment.template | |||
335 | index f389108..726be19 100644 | |||
336 | --- a/src/metadataserver/user_data/templates/enlistment.template | |||
337 | +++ b/src/metadataserver/user_data/templates/enlistment.template | |||
338 | @@ -48,7 +48,7 @@ main() { | |||
339 | 48 | # already exists and is not in a NEW state this will fail. | 48 | # already exists and is not in a NEW state this will fail. |
340 | 49 | output=$(maas-enlist --quite --serverurl "{{server_url}}" \ | 49 | output=$(maas-enlist --quite --serverurl "{{server_url}}" \ |
341 | 50 | ${power_params:+--power-params "${power_params}" \ | 50 | ${power_params:+--power-params "${power_params}" \ |
343 | 51 | --power-type "${power_type}"}) | 51 | --power-type "${power_type}"}{{if enlist_commissioning}} --commission{{endif}}) |
344 | 52 | ret=$? | 52 | ret=$? |
345 | 53 | echo $output | jq . | 53 | echo $output | jq . |
346 | 54 | if [ $ret -ne 0 ]; then | 54 | if [ $ret -ne 0 ]; then |
347 | @@ -57,6 +57,7 @@ main() { | |||
348 | 57 | exit 1 | 57 | exit 1 |
349 | 58 | fi | 58 | fi |
350 | 59 | 59 | ||
351 | 60 | {{if enlist_commissioning}} | ||
352 | 60 | # Reload cloud-init preseed using the system_id to get OAUTH credentials. | 61 | # Reload cloud-init preseed using the system_id to get OAUTH credentials. |
353 | 61 | system_id=$(echo $output | jq -r .system_id) | 62 | system_id=$(echo $output | jq -r .system_id) |
354 | 62 | mv ${CRED_CFG} ${CRED_CFG}.orig | 63 | mv ${CRED_CFG} ${CRED_CFG}.orig |
355 | @@ -65,6 +66,7 @@ main() { | |||
356 | 65 | signal COMMISSIONING "Enlistment complete, starting commissioning" | 66 | signal COMMISSIONING "Enlistment complete, starting commissioning" |
357 | 66 | 67 | ||
358 | 67 | maas-run-remote-scripts "--config=${CRED_CFG}" "${TEMP_D}" | 68 | maas-run-remote-scripts "--config=${CRED_CFG}" "${TEMP_D}" |
359 | 69 | {{endif}} | ||
360 | 68 | } | 70 | } |
361 | 69 | 71 | ||
362 | 70 | ### begin writing files ### | 72 | ### begin writing files ### |
363 | @@ -85,6 +87,7 @@ add_bin "maas-wedge-autodetect" <<"END_MAAS_WEDGE_AUTODETECT" | |||
364 | 85 | {{maas_wedge_autodetect_sh}} | 87 | {{maas_wedge_autodetect_sh}} |
365 | 86 | END_MAAS_WEDGE_AUTODETECT | 88 | END_MAAS_WEDGE_AUTODETECT |
366 | 87 | 89 | ||
367 | 90 | {{if enlist_commissioning}} | ||
368 | 88 | add_bin "maas_api_helper.py" <<"END_MAAS_API_HELPER" | 91 | add_bin "maas_api_helper.py" <<"END_MAAS_API_HELPER" |
369 | 89 | {{maas_api_helper_py}} | 92 | {{maas_api_helper_py}} |
370 | 90 | END_MAAS_API_HELPER | 93 | END_MAAS_API_HELPER |
371 | @@ -96,6 +99,7 @@ END_MAAS_SIGNAL | |||
372 | 96 | add_bin "maas-run-remote-scripts" <<"END_MAAS_RUN_REMOTE_SCRIPTS" | 99 | add_bin "maas-run-remote-scripts" <<"END_MAAS_RUN_REMOTE_SCRIPTS" |
373 | 97 | {{maas_run_remote_scripts_py}} | 100 | {{maas_run_remote_scripts_py}} |
374 | 98 | END_MAAS_RUN_REMOTE_SCRIPTS | 101 | END_MAAS_RUN_REMOTE_SCRIPTS |
375 | 102 | {{endif}} | ||
376 | 99 | 103 | ||
377 | 100 | add_bin "maas-enlist" <<"END_MAAS_ENLIST" | 104 | add_bin "maas-enlist" <<"END_MAAS_ENLIST" |
378 | 101 | {{maas_enlist_sh}} | 105 | {{maas_enlist_sh}} |
379 | diff --git a/src/metadataserver/user_data/templates/snippets/maas_enlist.sh b/src/metadataserver/user_data/templates/snippets/maas_enlist.sh | |||
380 | index 394b0bd..895c0d8 100644 | |||
381 | --- a/src/metadataserver/user_data/templates/snippets/maas_enlist.sh | |||
382 | +++ b/src/metadataserver/user_data/templates/snippets/maas_enlist.sh | |||
383 | @@ -2,7 +2,7 @@ | |||
384 | 2 | # | 2 | # |
385 | 3 | # maas-enlist: MAAS Enlistment Tool | 3 | # maas-enlist: MAAS Enlistment Tool |
386 | 4 | # | 4 | # |
388 | 5 | # Copyright (C) 2014-2016 Canonical Ltd. | 5 | # Copyright (C) 2014-2018 Canonical Ltd. |
389 | 6 | # | 6 | # |
390 | 7 | # Authors: Andres Rodriguez <andres.rodriguez@canonical.com> | 7 | # Authors: Andres Rodriguez <andres.rodriguez@canonical.com> |
391 | 8 | # | 8 | # |
392 | @@ -107,6 +107,7 @@ enlist_node() { | |||
393 | 107 | hostname="${5}" | 107 | hostname="${5}" |
394 | 108 | power_type="${6}" | 108 | power_type="${6}" |
395 | 109 | power_params="${7}" | 109 | power_params="${7}" |
396 | 110 | commission="${8}" | ||
397 | 110 | 111 | ||
398 | 111 | local macparms="" | 112 | local macparms="" |
399 | 112 | macparms=$(get_mac_address_curl_parms "$mac") | 113 | macparms=$(get_mac_address_curl_parms "$mac") |
400 | @@ -119,6 +120,7 @@ enlist_node() { | |||
401 | 119 | --data-urlencode "subarchitecture=${subarch}" \ | 120 | --data-urlencode "subarchitecture=${subarch}" \ |
402 | 120 | --data-urlencode "power_type=${power_type}" \ | 121 | --data-urlencode "power_type=${power_type}" \ |
403 | 121 | --data-urlencode "power_parameters=${power_params}" \ | 122 | --data-urlencode "power_parameters=${power_params}" \ |
404 | 123 | --data-urlencode "commission=${commission}" \ | ||
405 | 122 | ${macparms} \ | 124 | ${macparms} \ |
406 | 123 | "${serverurl}" | 125 | "${serverurl}" |
407 | 124 | 126 | ||
408 | @@ -171,6 +173,8 @@ Usage: ${0##*/} [ options ] | |||
409 | 171 | -e | --exists checks if the machine already exists in MAAS | 173 | -e | --exists checks if the machine already exists in MAAS |
410 | 172 | -w | --in-action checks if the machine already exists in MAAS in a 'in-progress' | 174 | -w | --in-action checks if the machine already exists in MAAS in a 'in-progress' |
411 | 173 | action like 'deploying' or 'commissioning'. | 175 | action like 'deploying' or 'commissioning'. |
412 | 176 | -c | --commission tell MAAS when creating a new machine to set the status to | ||
413 | 177 | 'commissioning'. | ||
414 | 174 | --subarch subarchitecture of the node to register | 178 | --subarch subarchitecture of the node to register |
415 | 175 | 179 | ||
416 | 176 | Example: | 180 | Example: |
417 | @@ -181,8 +185,8 @@ EOF | |||
418 | 181 | 185 | ||
419 | 182 | bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || Error "$@"; exit 1; } | 186 | bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || Error "$@"; exit 1; } |
420 | 183 | 187 | ||
423 | 184 | short_opts="hs:n:i:a:t:p:ewq" | 188 | short_opts="hs:n:i:a:t:p:ewqc" |
424 | 185 | long_opts="help,serverurl:,hostname:,interface:,arch:,subarch:,power-type:,power-params:,exists,in-action,quite" | 189 | long_opts="help,serverurl:,hostname:,interface:,arch:,subarch:,power-type:,power-params:,exists,in-action,quite,commission" |
425 | 186 | getopt_out=$(getopt --name "${0##*/}" \ | 190 | getopt_out=$(getopt --name "${0##*/}" \ |
426 | 187 | --options "${short_opts}" --long "${long_opts}" -- "$@") && | 191 | --options "${short_opts}" --long "${long_opts}" -- "$@") && |
427 | 188 | eval set -- "${getopt_out}" || | 192 | eval set -- "${getopt_out}" || |
428 | @@ -202,6 +206,7 @@ while [ $# -ne 0 ]; do | |||
429 | 202 | -e|--exists) check_exists=true;; | 206 | -e|--exists) check_exists=true;; |
430 | 203 | -w|--in-action) check_action_in_progress=true;; | 207 | -w|--in-action) check_action_in_progress=true;; |
431 | 204 | -q|--quite) quite=true;; | 208 | -q|--quite) quite=true;; |
432 | 209 | -c|--commission) commission=true;; | ||
433 | 205 | --) shift; break;; | 210 | --) shift; break;; |
434 | 206 | esac | 211 | esac |
435 | 207 | shift; | 212 | shift; |
436 | @@ -268,5 +273,5 @@ elif [ "$check_action_in_progress" = true ]; then | |||
437 | 268 | check_node "$protocol://$servername/$api_url" "${mac_addrs}" "is_action_in_progress" | 273 | check_node "$protocol://$servername/$api_url" "${mac_addrs}" "is_action_in_progress" |
438 | 269 | exit $? | 274 | exit $? |
439 | 270 | else | 275 | else |
441 | 271 | enlist_node "$protocol://$servername/$api_url" "${mac_addrs}" "$arch" "$subarch" "$hostname" "$power_type" "$power_parameters" | 276 | enlist_node "$protocol://$servername/$api_url" "${mac_addrs}" "$arch" "$subarch" "$hostname" "$power_type" "$power_parameters" "$commission" |
442 | 272 | fi | 277 | fi |
443 | diff --git a/src/metadataserver/user_data/tests/test_generate_user_data.py b/src/metadataserver/user_data/tests/test_generate_user_data.py | |||
444 | index 3632799..4b51a79 100644 | |||
445 | --- a/src/metadataserver/user_data/tests/test_generate_user_data.py | |||
446 | +++ b/src/metadataserver/user_data/tests/test_generate_user_data.py | |||
447 | @@ -26,7 +26,8 @@ class TestGenerateUserData(MAASServerTestCase): | |||
448 | 26 | # both definitions and use of various commands in python. | 26 | # both definitions and use of various commands in python. |
449 | 27 | rack = factory.make_RackController() | 27 | rack = factory.make_RackController() |
450 | 28 | user_data = generate_user_data_for_status( | 28 | user_data = generate_user_data_for_status( |
452 | 29 | None, NODE_STATUS.NEW, rack_controller=rack) | 29 | None, NODE_STATUS.NEW, rack_controller=rack, |
453 | 30 | extra_content={'enlist_commissioning': True}) | ||
454 | 30 | parsed_data = email.message_from_string(user_data.decode("utf-8")) | 31 | parsed_data = email.message_from_string(user_data.decode("utf-8")) |
455 | 31 | self.assertTrue(parsed_data.is_multipart()) | 32 | self.assertTrue(parsed_data.is_multipart()) |
456 | 32 | 33 |
Approved in https:/ /code.launchpad .net/~ltrager/ maas/+git/ maas/+merge/ 360849