Playbook #1

/root/kubeinit/ci/builds/6mbKNrxD/0/kubeinit/kubeinit/kubeinit-aux/kubeinit/playbook.yml

Report Status CLI Date Duration Controller User Versions Hosts Plays Tasks Results Files Records
26 Oct 2023 16:01:52 +0000 01:07:59.06 nyctea root Ansible 2.15.2 ara 1.6.1 (client), 1.6.1 (server) Python 3.11.4 6 6 846 846 50 1

File: /root/.ansible/collections/ansible_collections/kubeinit/kubeinit/roles/kubeinit_libvirt/tasks/deploy_windows_guest.yml

---
# Copyright kubeinit contributors
# All Rights Reserved.
#
# 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.

- name: Deploy a Windows server guest
  block:
    - name: Print Windows EULA so users accept it
      ansible.builtin.debug:
        msg: |
          *********************************************************************************************************************
          * Please read: https://docs.microsoft.com/en-us/legal/windows-server/system-insights-eula                           *
          *********************************************************************************************************************
          * MICROSOFT.WINDOWSSERVER.SYSTEMINSIGHTS                                                                            *
          * These license terms are an agreement between you and Microsoft Corporation (or one of its affiliates).            *
          * They apply to the software named above and any Microsoft services or software updates (except to the              *
          * extent such services or updates are accompanied by new or additional terms, in which case those                   *
          * different terms apply prospectively and do not alter your or Microsoft's rights relating to pre-updated           *
          * software or services).                                                                                            *
          * IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. *
          *********************************************************************************************************************
          * If you do not comply with these license terms, please stop this deployment right now.                             *
          *********************************************************************************************************************

    - name: Wait 1 minute for displaying the EULA text
      ansible.builtin.pause:
        minutes: 1

    - name: Remove old disk images
      ansible.builtin.file:
        path: "{{ kubeinit_libvirt_target_image_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}.qcow2"
        state: absent

    - name: Create the config data folder
      ansible.builtin.file:
        path: "{{ kubeinit_libvirt_hypervisor_tmp_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}/config/"
        state: directory
        mode: 0775
        recurse: yes

    - name: Create the config data folder template
      ansible.builtin.template:
        src: "autounattend.xml.j2"
        dest: "{{ kubeinit_libvirt_hypervisor_tmp_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}/config/autounattend.xml"
        mode: "0644"

    - name: Render the authorized keys file
      ansible.builtin.template:
        src: "authorized_keys.j2"
        dest: "{{ kubeinit_libvirt_hypervisor_tmp_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}/config/authorized_keys"
        mode: "0644"

    - name: Render the setup scripts
      ansible.builtin.template:
        src: "{{ item }}.j2"
        dest: "{{ kubeinit_libvirt_hypervisor_tmp_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}/config/{{ item }}"
        mode: "0644"
      loop:
        - SetNet.ps1
        - Install-Openssh.ps1
        - PrepareRequirements.ps1
        - Install-Containerd.ps1
        - PrepareNode.ps1
        - PrepareFlannel.ps1

    - name: Create the .iso disk with the install assets
      ansible.builtin.shell: |
        # We create an iso file with the config unnatended data
        mkisofs -o {{ kubeinit_libvirt_target_image_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}_config.iso -r -J {{ kubeinit_libvirt_hypervisor_tmp_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}/config/
      args:
        executable: /bin/bash
      register: _result
      changed_when: "_result.rc == 0"

    - name: Create a qcow empty disk to install the OS
      ansible.builtin.shell: |
        # We create the server disk image
        qemu-img create -f qcow2 {{ kubeinit_libvirt_target_image_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}.qcow2 {{ hostvars[kubeinit_deployment_node_name].disk }}
      args:
        executable: /bin/bash
      register: _result
      changed_when: "_result.rc == 0"

    - name: Install Windows
      ansible.builtin.shell: |
        virt-install \
          --name={{ hostvars[kubeinit_deployment_node_name].guest_name }} \
          --memory memory={{ hostvars[kubeinit_deployment_node_name].ram|int // 1024 }} \
          --vcpus={{ hostvars[kubeinit_deployment_node_name].vcpus }},maxvcpus={{ hostvars[kubeinit_deployment_node_name].maxvcpus }} \
          --network network={{ kubeinit_cluster_hostvars.network_name }},mac={{ hostvars[kubeinit_deployment_node_name].mac }},virtualport.parameters.interfaceid={{ hostvars[kubeinit_deployment_node_name].interfaceid }},target.dev=veth0-{{ hostvars[kubeinit_deployment_node_name].ansible_host | ansible.utils.ip4_hex }},model=virtio \
          --disk path={{ kubeinit_libvirt_target_image_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}.qcow2,format=qcow2,bus=virtio \
          --cdrom {{ kubeinit_libvirt_target_image_dir }}/SERVER_EVAL_x64FRE_en-us.iso \
          --disk path={{ kubeinit_libvirt_target_image_dir }}/{{ kubeinit_libvirt_virtio_image_name }},device=cdrom \
          --disk path={{ kubeinit_libvirt_target_image_dir }}/{{ hostvars[kubeinit_deployment_node_name].guest_name }}_config.iso,device=cdrom \
          --os-variant win2k8 \
          --vnc \
          --autostart \
          --console pty \
          --connect qemu:///system \
          --import \
          --noautoconsole
      args:
        executable: /bin/bash
      register: _result
      changed_when: "_result.rc == 0"

    - name: "Wait until is running {{ hostvars[kubeinit_deployment_node_name].guest_name }}"
      community.libvirt.virt:
        command: list_vms
        state: running
      register: _result
      retries: 30
      delay: 10
      until: hostvars[kubeinit_deployment_node_name].guest_name in _result.list_vms

    - name: "Wait until setup finish and the guest is shut down for {{ hostvars[kubeinit_deployment_node_name].guest_name }}"
      community.libvirt.virt:
        command: list_vms
        state: shutdown
      register: _result
      retries: 100
      delay: 10
      until: hostvars[kubeinit_deployment_node_name].guest_name in _result.list_vms

    - name: "Re-start {{ hostvars[kubeinit_deployment_node_name].guest_name }}"
      community.libvirt.virt:
        name: "{{ hostvars[kubeinit_deployment_node_name].guest_name }}"
        state: running

    - name: "Wait until is running {{ hostvars[kubeinit_deployment_node_name].guest_name }}"
      community.libvirt.virt:
        command: list_vms
        state: running
      register: _result
      retries: 30
      delay: 10
      until: hostvars[kubeinit_deployment_node_name].guest_name in _result.list_vms

    - name: Show some information for connecting with VNC
      ansible.builtin.debug:
        msg: |
          Make sure the VNC session is up and running with:
          virsh vncdisplay {{ hostvars[kubeinit_deployment_node_name].guest_name }}
          Create a tunnel from your machine to the hypervisor hosting the Windows guest
          ssh root@tyto -L 5900:127.0.0.1:5900
          from your machine connect to the VNC server at 127.0.0.1

    - name: "Make sure we can execute SSH remote commands in {{ hostvars[kubeinit_deployment_node_name].guest_name }}"
      ansible.builtin.shell: |
        set -o pipefail
        ssh {{ hostvars[kubeinit_deployment_node_name].ansible_ssh_common_args }} \
            {{ _param_guest_user | default('root') }}@{{ hostvars[kubeinit_deployment_node_name].ansible_host }} 'echo connected' || true
      args:
        executable: /bin/bash
      register: _result
      retries: 60
      delay: 10
      until: "'connected' in _result.stdout"
      changed_when: "_result.rc == 0"

  delegate_to: "{{ kubeinit_deployment_delegate }}"

- name: Configure common requirements in Windows guests
  block:
    - name: Make sure there is enough RAM for Windows computes
      ansible.builtin.assert:
        that:
          - compute_node_ram_size | int >= 16777216
        fail_msg: "'compute_node_ram_size' must be greater than 16777216, that is, 16GB RAM"
        success_msg: "'compute_node_ram_size' is more than 16GB RAM, OK"

    - name: Ping
      ansible.windows.win_ping:

    - name: Create the k folder
      ansible.windows.win_file:
        path: C:\k
        state: directory

    - name: Copy all the ISO resources to a writable folder
      ansible.windows.win_copy:
        src: F:\
        dest: C:\k
        remote_src: yes

    - name: Install KB5012637
      ansible.windows.win_powershell:
        script: |
          $patchFile = "windows10.0-kb5012637-x64_6a7459b60e226b0ad0d30b34a4be069bee4d2867.msu"
          $url = "https://catalog.s.download.windowsupdate.com/c/msdownload/update/software/updt/2022/04/$patchFile"
          $dest = "C:\Windows\Temp\$patchFile"
          Invoke-WebRequest -Uri $url -OutFile $dest
          # Install the patch, bypassing any prompts
          cmd.exe /c wusa.exe $dest /quiet /norestart
      register: _result
      changed_when: "_result.host_err == ''"

    - name: Enable the required container features and required modules
      ansible.windows.win_powershell:
        script: |
          Install-WindowsFeature Containers
          Install-WindowsFeature Hyper-V
          Install-WindowsFeature Hyper-V-PowerShell
      register: _result
      changed_when: "_result.host_err == ''"

    - name: Reboot the server after installing the new features
      # This might take a lot of time depending on updates,
      # and finishing to enable the container features.
      ansible.windows.win_reboot:
        reboot_timeout: 3600

    - name: Configure Overlay HNSNetwork for the overlay network
      # This task MUST be executed after the initial guest reboot
      ansible.windows.win_powershell:
        script: |
          # We do this when there is no network created, this will create a network glitch
          # as there must be created a new virtual switch where each pod will be connected to
          # Note: RDP connection will hiccup when running this command (New-HNSNetwork).
          New-Item C:\k -Force -ItemType Directory | Out-Null
          curl.exe --silent --fail -Lo C:\k\hns.psm1 https://github.com/Microsoft/SDN/raw/master/Kubernetes/windows/hns.psm1
          Import-Module "c:\k\hns.psm1"
          # There is no need to remove the nhs nets as this is a new environment
          # get-hnsnetwork | remove-hnsnetwork
          New-HNSNetwork -Type "Overlay" `
                         -AddressPrefix "10.244.0.0/16" `
                         -Gateway "10.244.0.1" `
                         -Name "vxlan0" `
                         -AdapterName "$((Get-NetAdapter -Physical).Name)" `
                         -SubnetPolicies @(@{Type = "VSID"; VSID = 4096; }) `
                         -Verbose
          # This task will make Ansible to hang, there is a connection hiccup
          # and then we are not able to continue, so we trigger this as async
          # and then we ping again the machine to see we can communicate over SSH
      async: 60
      poll: 0

    - name: Ping
      ansible.windows.win_ping:
  # TODO:FIXME: The following variables should be
  # added as group vars for those compute nodes which the
  # os is equals to 'windows'
  # TODO:FIXME: The usage of ansible_shell_type might
  # be different depending on the win_* task, the
  # supported values are [cmd | powershell]
  vars:
    ansible_shell_type: 'cmd'
    ansible_remote_tmp: 'C:\Windows\Temp'
  delegate_to: "{{ kubeinit_deployment_node_name }}"

# TODO:FIXME: Do we need a Windows gather facts?
# - name: Gather guest network facts
#   block:
#     - name: Gather network and host facts for guest
#       ansible.builtin.include_role:
#         name: kubeinit.kubeinit.kubeinit_prepare
#         tasks_from: gather_host_facts.yml
#         public: yes
#       vars:
#         _param_gather_host: "{{ kubeinit_deployment_node_name }}"
#   tags: omit_from_grapher