Configure CaaS SR-IOV and provider networks
[ta/infra-ansible.git] / roles / baremetal_provision / tasks / ironic_nodes_deploy.yml
1 ---
2
3 # Copyright 2019 Nokia
4
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Block traffic during nodes power on/off so that possible old deployment
18 # clients cannot connect new deployment services (like mysql)  and ruin
19 # the installation.
20 - name: Block traffic on infra_internal
21   iptables:
22     state: present
23     action: insert
24     chain: INPUT
25     jump: REJECT
26     in_interface: "{{ networking['infra_internal']['interface'] }}"
27   when:
28     - installation_phase == "provisioning-started"
29     - not virtual_env
30   run_once: true
31
32 - name: Power off nodes
33   environment:
34     OS_AUTH_TOKEN: "fake-token"
35     IRONIC_URL: "{{ ironic_service_adminurl }}"
36   command: "/usr/bin/ironic node-set-power-state {{baremetal_ironic_node_id.uuid}} off"
37   when:
38     - not virtual_env
39     - installation_phase == "provisioning-started"
40   retries: 5
41   delay: 10
42
43 - name: Power off nodes
44   command: "openstack --os-cloud default baremetal node power off {{baremetal_ironic_node_id.uuid}}"
45   when:
46     - not virtual_env
47     - installation_phase != "provisioning-started"
48   retries: 5
49   delay: 10
50
51 - name: Ensure nodes are powered off
52   environment:
53     OS_AUTH_TOKEN: "fake-token"
54     IRONIC_URL: "{{ ironic_service_adminurl }}"
55   os_node_power_check:
56     auth:
57     auth_type: 'None'
58     ironic_url: "{{ ironic_service_adminurl }}"
59     nodes_details:
60       - "{{ baremetal_ironic_node_id }}"
61     power_state: 'power off'
62   until: power_pending_list | length == 0
63   retries: 30
64   delay: 6
65   when:
66     - not virtual_env
67     - installation_phase == "provisioning-started"
68   #no_log: True
69
70 - name: Ensure nodes are powered off
71   os_node_power_check:
72     cloud: default
73     auth_type: password
74     ironic_url: "{{ ironic_service_adminurl }}"
75     nodes_details:
76       - "{{ baremetal_ironic_node_id }}"
77     power_state: 'power off'
78     endpoint_type: internal
79   until: power_pending_list | length == 0
80   retries: 30
81   delay: 6
82   when:
83     - not virtual_env
84     - installation_phase != "provisioning-started"
85   #no_log: True
86
87 # Sleep to make sure power is off
88 - name: Sleep for 15 seconds
89   pause:
90     seconds: 15
91   when: not virtual_env
92
93 - name: Create config-drive directories for all nodes
94   file:
95     path: "/var/lib/ironic/confdrive/{{baremetal_ironic_node_id.name}}/openstack/latest/"
96     state: "directory"
97     owner: "ironic"
98     group: "ironic"
99     mode: "0775"
100
101 - name: Generate config-drive files
102   config_template:
103     src: "{{item.src}}"
104     dest: "/var/lib/ironic/confdrive/{{baremetal_ironic_node_id.name}}/openstack/latest/{{item.dest}}"
105     owner: "ironic"
106     group: "ironic"
107     mode: "0644"
108     config_type: "{{item.config_type}}"
109   with_items:
110     - "{{ config_drive_templates }}"
111
112 - name: Stat config-drive files to check if they exists
113   stat:
114     path: "/var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64"
115   register: confdrive_stat
116
117 - name: Prepare Config-drive ISO file
118   shell: |
119     # Generated ISO
120     genisoimage -o /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso -ldots -allow-lowercase -allow-multidot -l -publisher 'ironicclient-configdrive 0.1' -quiet -J -r -V config-2 /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}
121     # Zip it!
122     gzip /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso
123     # Encode it to base64
124     base64 -w 0 /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso.gz > /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64
125     chown ironic:ironic /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso.gz
126     chown ironic:ironic /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64
127     chmod o+r /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.iso.gz
128     chmod o+r /var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64
129   when: not confdrive_stat.stat.exists
130
131 - name: Remove os_net_config temp files
132   file:
133     dest: "/tmp/{{baremetal_ironic_node_id.name}}_config.yaml"
134     state: absent
135
136 - name: Calculate md5sum of Golden image
137   stat:
138     path: "/opt/images/guest-image.img"
139     get_md5: yes
140   register: golden_img_md5sum
141   run_once: true
142
143 - name: Enable traffic on infra_internal
144   iptables:
145     state: absent
146     chain: INPUT
147     jump: REJECT
148     in_interface: "{{ networking['infra_internal']['interface'] }}"
149   when:
150     - installation_phase == "provisioning-started"
151     - not virtual_env
152   run_once: true
153
154 - set_fact:
155     initiator_host: "{{ lookup('file', '/etc/hostname') }}"
156
157 - set_fact:
158     initiator_host_ip: "{{ hostvars[initiator_host]['networking']['infra_internal']['ip'] }}"
159
160 - name: Configure Baremetal deployment
161   environment:
162     OS_AUTH_TOKEN: "fake-token"
163     IRONIC_URL: "{{ ironic_service_adminurl }}"
164   os_ironic_node:
165     auth:
166     auth_type: 'None'
167     ironic_url: "{{ ironic_service_adminurl }}"
168     uuid: "{{baremetal_ironic_node_id.uuid}}"
169     deploy: False
170     state: present
171     power: absent
172     maintenance: False
173     instance_info:
174       root_gb: 10
175       image_source: "http://{{initiator_host_ip}}:{{golden_image_http_port}}/guest-image.img"
176       image_checksum: "{{golden_img_md5sum.stat.md5}}"
177   when:
178     - installation_phase == "provisioning-started"
179
180 - name: Configure Baremetal deployment
181   os_ironic_node:
182     cloud: default
183     endpoint_type: internal
184     auth_type: password
185     uuid: "{{baremetal_ironic_node_id.uuid}}"
186     deploy: False
187     state: present
188     power: absent
189     maintenance: False
190     instance_info:
191       root_gb: 10
192       image_source: "http://{{initiator_host_ip}}:{{golden_image_http_port}}/guest-image.img"
193       image_checksum: "{{golden_img_md5sum.stat.md5}}"
194   when:
195     - installation_phase != "provisioning-started"
196
197 - name: Start Baremetal deployment
198   environment:
199     OS_AUTH_TOKEN: "fake-token"
200     IRONIC_URL: "{{ ironic_service_adminurl }}"
201   os_ironic_node:
202     auth:
203     auth_type: 'None'
204     ironic_url: "{{ ironic_service_adminurl }}"
205     deploy: True
206     power: present
207     config_drive: "{{lookup('file', '/var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64')}}"
208     uuid: "{{baremetal_ironic_node_id.uuid}}"
209     instance_info:
210       root_gb: 10
211       image_source: "http://{{initiator_host_ip}}:{{golden_image_http_port}}/guest-image.img"
212       image_checksum: "{{golden_img_md5sum.stat.md5}}"
213   when:
214     - installation_phase == "provisioning-started"
215
216 - name: Start Baremetal deployment
217   os_ironic_node:
218     cloud: default
219     endpoint_type: internal
220     auth_type: password
221     deploy: True
222     power: present
223     config_drive: "{{lookup('file', '/var/lib/ironic/confdrive/{{ baremetal_ironic_node_id.name }}.base64')}}"
224     uuid: "{{baremetal_ironic_node_id.uuid}}"
225     instance_info:
226       root_gb: 10
227       image_source: "http://{{initiator_host_ip}}:{{golden_image_http_port}}/guest-image.img"
228       image_checksum: "{{golden_img_md5sum.stat.md5}}"
229   when:
230     - installation_phase != "provisioning-started"
231
232 - name: Verify node provisioning state. Waiting for 60mins max.
233   environment:
234     OS_AUTH_TOKEN: "fake-token"
235     IRONIC_URL: "{{ ironic_service_adminurl }}"
236   os_node_provision_check:
237     auth:
238     auth_type: 'None'
239     ironic_url: "{{ ironic_service_adminurl }}"
240     nodes_details:
241       - "{{baremetal_ironic_node_id}}"
242   register: baremetal_ironic_node_provisionin_results
243   until: provision_pending_list | length == 0
244   retries: 360
245   delay: 10
246   when:
247     - installation_phase == "provisioning-started"
248
249 - name: Checking for any deployment failures
250   fail:
251     msg: "One or more nodes failed in deployment. {{baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] }}"
252   when:
253     - installation_phase == "provisioning-started"
254     - baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] | length > 0
255
256 - name: Verify node provisioning state. Waiting for 60mins max.
257   os_node_provision_check:
258     cloud: default
259     endpoint_type: internal
260     auth_type: password
261     nodes_details:
262       - "{{baremetal_ironic_node_id}}"
263   register: baremetal_ironic_node_provisionin_results
264   until: provision_pending_list | length == 0
265   retries: 360
266   delay: 10
267   when:
268     - installation_phase != "provisioning-started"
269
270 - name: Checking for any deployment failures
271   fail:
272     msg: "One or more nodes failed in deployment. {{baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] }}"
273   when:
274     - installation_phase != "provisioning-started"
275     - baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] | length > 0
276
277 - set_fact:
278     net_conn_details: "{{ ironic_node_details.driver_info.power.os_net_config | json_query('network_config[*].addresses[0].ip_netmask') |  ipaddr('address') }}"
279   when: ironic_node_details.driver_info.power.os_net_config.network_config[0].type != 'ovs_bridge'
280   no_log: True
281
282 - set_fact:
283     net_conn_details: "{{ ironic_node_details.driver_info.power.os_net_config | json_query('network_config[*].members[*].addresses[0].ip_netmask')|first | ipaddr('address') }}"
284   when: ironic_node_details.driver_info.power.os_net_config.network_config[0].type == 'ovs_bridge'
285   no_log: True
286
287 # JanneS: until looping is a fix for the problem in wait_for module; it does not catch socket error in recv if peer closes the connection.
288 - name: Verify remote node ssh ports active. Waiting for 60mins max.
289   wait_for:
290      host: "{{ net_conn_details[0] }}"
291      port: 22
292      search_regex: OpenSSH
293      sleep: 5
294      timeout: 3600
295   register: remote_success
296   until: remote_success | success
297   retries: 3
298
299 - name: Wait for remote node ssh login. Waiting for 10mins max.
300   become: "{{ users.admin_user_name }}"
301   local_action: shell ssh -oBatchMode=yes -4 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null {{ net_conn_details[0] }} "echo success"
302   register: user_enabled
303   until: user_enabled.stdout.find("success") != -1
304   retries: 90
305   delay: 10