X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=roles%2Fbaremetal_provision%2Ftasks%2Fironic_nodes_deploy.yml;fp=roles%2Fbaremetal_provision%2Ftasks%2Fironic_nodes_deploy.yml;h=cb5ba958d475f97365156a4497564e5a329ae4db;hb=74a49ba6ef2ea715fa492db0bcd85c30398688e8;hp=0000000000000000000000000000000000000000;hpb=a936af362724cca0c5dc2c424902d398f9833410;p=ta%2Finfra-ansible.git diff --git a/roles/baremetal_provision/tasks/ironic_nodes_deploy.yml b/roles/baremetal_provision/tasks/ironic_nodes_deploy.yml new file mode 100644 index 0000000..cb5ba95 --- /dev/null +++ b/roles/baremetal_provision/tasks/ironic_nodes_deploy.yml @@ -0,0 +1,338 @@ +--- + +# Copyright 2019 Nokia + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Block traffic during nodes power on/off so that possible old deployment +# clients cannot connect new deployment services (like mysql) and ruin +# the installation. +- name: Block traffic on infra_internal + iptables: + state: present + action: insert + chain: INPUT + jump: REJECT + in_interface: "{{ networking['infra_internal']['interface'] }}" + when: + - installation_phase == "provisioning-started" + +- name: Power off nodes + environment: + OS_AUTH_TOKEN: "fake-token" + IRONIC_URL: "{{ ironic_service_adminurl }}" + command: "/usr/bin/ironic node-set-power-state {{item.uuid}} off" + with_items: "{{ baremetal_ironic_nodes_ids }}" + when: + - not virtual_env + - installation_phase == "provisioning-started" + retries: 5 + delay: 10 + loop_control: + label: "{{ item.name }}" + +- name: Power off nodes + command: "openstack --os-cloud default baremetal node power off {{item.uuid}}" + with_items: "{{ baremetal_ironic_nodes_ids }}" + when: + - not virtual_env + - installation_phase != "provisioning-started" + retries: 5 + delay: 10 + loop_control: + label: "{{ item.name }}" + +- name: Ensure nodes are powered off + environment: + OS_AUTH_TOKEN: "fake-token" + IRONIC_URL: "{{ ironic_service_adminurl }}" + os_node_power_check: + auth: + auth_type: 'None' + ironic_url: "{{ ironic_service_adminurl }}" + nodes_details: "{{ baremetal_ironic_nodes_ids }}" + power_state: 'power off' + until: power_pending_list | length == 0 + retries: 30 + delay: 6 + when: + - not virtual_env and baremetal_ironic_nodes_ids | length > 0 + - installation_phase == "provisioning-started" + no_log: True + +- name: Ensure nodes are powered off + os_node_power_check: + cloud: default + auth_type: password + ironic_url: "{{ ironic_service_adminurl }}" + nodes_details: "{{ baremetal_ironic_nodes_ids }}" + power_state: 'power off' + endpoint_type: internal + until: power_pending_list | length == 0 + retries: 30 + delay: 6 + when: + - not virtual_env and baremetal_ironic_nodes_ids | length > 0 + - installation_phase != "provisioning-started" + no_log: True + +# Sleep to make sure power is off +- name: Sleep for 15 seconds + pause: + seconds: 15 + when: not virtual_env and baremetal_ironic_nodes_ids | length > 0 + +- name: Create config-drive directories for all nodes + file: + path: "/var/lib/ironic/confdrive/{{item.name}}/openstack/latest/" + state: "directory" + owner: "ironic" + group: "ironic" + with_items: "{{ baremetal_ironic_nodes_ids }}" + loop_control: + label: "{{ item.name }}" + +- name: Generate config-drive files + config_template: + src: "{{ item[1].src }}" + dest: "/var/lib/ironic/confdrive/{{item[0].name}}/openstack/latest/{{ item[1].dest }}" + owner: "ironic" + group: "ironic" + mode: "0644" + config_type: "{{ item[1].config_type }}" + with_nested: + - "{{ baremetal_ironic_nodes_ids }}" + - "{{ config_drive_templates }}" + loop_control: + label: "{{ item[0].name }}" + +- name: Stat config-drive files to check if they exists + stat: + path: "/var/lib/ironic/confdrive/{{ item.name }}.base64" + register: confdrive_stat + with_items: "{{ baremetal_ironic_nodes_ids }}" + +- name: Prepare Config-drive ISO file + shell: | + # Generated ISO + genisoimage -o /var/lib/ironic/confdrive/{{ item.item.name }}.iso -ldots -allow-lowercase -allow-multidot -l -publisher 'ironicclient-configdrive 0.1' -quiet -J -r -V config-2 /var/lib/ironic/confdrive/{{ item.item.name }} + # Zip it! + gzip /var/lib/ironic/confdrive/{{ item.item.name }}.iso + # Encode it to base64 + base64 -w 0 /var/lib/ironic/confdrive/{{ item.item.name }}.iso.gz > /var/lib/ironic/confdrive/{{ item.item.name }}.base64 + when: not item.stat.exists + with_items: "{{confdrive_stat.results}}" + +- name: Remove os_net_config temp files + file: + dest: "/tmp/{{item.name}}_config.yaml" + state: absent + with_items: "{{ baremetal_ironic_nodes }}" + loop_control: + label: "{{ item.name }}" + +- name: Calculate md5sum of Golden image + stat: + path: "/opt/images/guest-image.img" + get_md5: yes + register: golden_img_md5sum + when: baremetal_ironic_nodes_ids | length > 0 + +- name: Enable traffic on infra_internal + iptables: + state: absent + chain: INPUT + jump: REJECT + in_interface: "{{ networking['infra_internal']['interface'] }}" + when: + - installation_phase == "provisioning-started" + +- name: Configure Baremetal deployment + environment: + OS_AUTH_TOKEN: "fake-token" + IRONIC_URL: "{{ ironic_service_adminurl }}" + os_ironic_node: + auth: + auth_type: 'None' + ironic_url: "{{ ironic_service_adminurl }}" + uuid: "{{item.uuid}}" + deploy: False + state: present + power: absent + maintenance: False + instance_info: + root_gb: 10 + image_source: "http://{{ansible_host}}:{{golden_image_http_port}}/guest-image.img" + image_checksum: "{{golden_img_md5sum.stat.md5}}" + with_items: "{{ baremetal_ironic_nodes_ids }}" + loop_control: + label: "{{ item.name }}" + when: + - installation_phase == "provisioning-started" + +- name: Configure Baremetal deployment + os_ironic_node: + cloud: default + endpoint_type: internal + auth_type: password + uuid: "{{item.uuid}}" + deploy: False + state: present + power: absent + maintenance: False + instance_info: + root_gb: 10 + image_source: "http://{{ansible_host}}:{{golden_image_http_port}}/guest-image.img" + image_checksum: "{{golden_img_md5sum.stat.md5}}" + with_items: "{{ baremetal_ironic_nodes_ids }}" + loop_control: + label: "{{ item.name }}" + when: + - installation_phase != "provisioning-started" + +- name: Start Baremetal deployment + environment: + OS_AUTH_TOKEN: "fake-token" + IRONIC_URL: "{{ ironic_service_adminurl }}" + os_ironic_node: + auth: + auth_type: 'None' + ironic_url: "{{ ironic_service_adminurl }}" + deploy: True + power: present + config_drive: "{{lookup('file', '/var/lib/ironic/confdrive/{{ item.name }}.base64')}}" + uuid: "{{item.uuid}}" + instance_info: + root_gb: 10 + image_source: "http://{{ansible_host}}:{{golden_image_http_port}}/guest-image.img" + image_checksum: "{{golden_img_md5sum.stat.md5}}" + with_items: "{{ baremetal_ironic_nodes_ids }}" + loop_control: + label: "{{ item.name }}" + when: + - installation_phase == "provisioning-started" + +- name: Start Baremetal deployment + os_ironic_node: + cloud: default + endpoint_type: internal + auth_type: password + deploy: True + power: present + config_drive: "{{lookup('file', '/var/lib/ironic/confdrive/{{ item.name }}.base64')}}" + uuid: "{{item.uuid}}" + instance_info: + root_gb: 10 + image_source: "http://{{ansible_host}}:{{golden_image_http_port}}/guest-image.img" + image_checksum: "{{golden_img_md5sum.stat.md5}}" + with_items: "{{ baremetal_ironic_nodes_ids }}" + loop_control: + label: "{{ item.name }}" + when: + - installation_phase != "provisioning-started" + +- name: Verify node provisioning state. Waiting for 60mins max. + environment: + OS_AUTH_TOKEN: "fake-token" + IRONIC_URL: "{{ ironic_service_adminurl }}" + os_node_provision_check: + auth: + auth_type: 'None' + ironic_url: "{{ ironic_service_adminurl }}" + nodes_details: "{{baremetal_ironic_nodes_ids}}" + register: baremetal_ironic_node_provisionin_results + until: provision_pending_list | length == 0 + retries: 360 + delay: 10 + when: + - installation_phase == "provisioning-started" + +- name: Checking for any deployment failures + fail: + msg: "One or more nodes failed in deployment. {{baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] }}" + when: + - installation_phase == "provisioning-started" + - baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] | length > 0 + +- name: Verify node provisioning state. Waiting for 60mins max. + os_node_provision_check: + cloud: default + endpoint_type: internal + auth_type: password + nodes_details: "{{baremetal_ironic_nodes_ids}}" + register: baremetal_ironic_node_provisionin_results + until: provision_pending_list | length == 0 + retries: 360 + delay: 10 + when: + - installation_phase != "provisioning-started" + +- name: Checking for any deployment failures + fail: + msg: "One or more nodes failed in deployment. {{baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] }}" + when: + - installation_phase != "provisioning-started" + - baremetal_ironic_node_provisionin_results['ansible_facts']['provision_failed_list'] | length > 0 + +# 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. +- name: Verify remote node ssh ports active. Waiting for 60mins max. + wait_for: + host: "{{ item.node_ip[0] }}" + port: 22 + search_regex: OpenSSH + sleep: 5 + timeout: 3600 + register: remote_success + until: remote_success | success + retries: 3 + with_items: "{{net_conn_details}}" + +- name: Wait for remote node ssh login. Waiting for 10mins max. + become: "{{ ansible_env.SUDO_USER }}" + local_action: shell ssh -oBatchMode=yes -4 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null {{ item.node_ip[0] }} "echo success" + register: user_enabled + with_items: "{{net_conn_details}}" + until: user_enabled.stdout.find("success") != -1 + retries: 90 + delay: 10 + +- name: Set Ironic maintenance mode to all nodes. + os_ironic_node: + cloud: default + endpoint_type: internal + auth_type: password + uuid: "{{item.name}}" + maintenance: True + deploy: False + with_items: "{{ baremetal_ironic_nodes }}" + loop_control: + label: "{{ item.name }}" + when: + - installation_phase != "provisioning-started" + +- name: Set Ironic maintenance mode to all nodes. + environment: + OS_AUTH_TOKEN: "fake-token" + IRONIC_URL: "{{ ironic_service_adminurl }}" + os_ironic_node: + auth: + auth_type: 'None' + ironic_url: "{{ ironic_service_adminurl }}" + uuid: "{{item.name}}" + maintenance: True + deploy: False + with_items: "{{ baremetal_ironic_nodes }}" + loop_control: + label: "{{ item.name }}" + when: + - installation_phase == "provisioning-started"