Skip to content

Commit

Permalink
[Linux] Fix v3.1 regression test issues for deploy_vm, GOSC and waiti…
Browse files Browse the repository at this point in the history
…ng ESXi portgroup (#541)

Signed-off-by: Qi Zhang <[email protected]>
  • Loading branch information
keirazhang authored Jan 31, 2024
1 parent 4efd99c commit 63e75c6
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 66 deletions.
2 changes: 1 addition & 1 deletion autoinstall/FreeBSD/13/installerconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export ZFSBOOT_BOOT_TYPE="BIOS"

#!/bin/sh
# Set hostname
sysrc hostname="FreeBSD-{{ hostname_timestamp }}"
sysrc hostname="FreeBSD-{{ current_test_timestamp }}"

# Set Time Zone to UTC
echo "Setting Time Zone to UTC ..."
Expand Down
2 changes: 1 addition & 1 deletion autoinstall/FreeBSD/14/installerconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export ZFSBOOT_BOOT_TYPE="BIOS"

#!/bin/sh
# Set hostname
sysrc hostname="FreeBSD-{{ hostname_timestamp }}"
sysrc hostname="FreeBSD-{{ current_test_timestamp }}"

# Set Time Zone to UTC
echo "Setting Time Zone to UTC ..."
Expand Down
7 changes: 4 additions & 3 deletions common/esxi_wait_portgroup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
until:
- portgroup_facts is defined
- portgroup_facts.hosts_portgroup_info is defined
- portgroup_facts.hosts_portgroup_info[esxi_hostname] is defined
- portgroup_facts.hosts_portgroup_info[esxi_hostname] | length > 0
- (portgroup_facts.hosts_portgroup_info[esxi_hostname] | selectattr('portgroup', 'equalto', wait_for_portgroup_name)) | length != 0
- portgroup_facts.hosts_portgroup_info | length == 1
- (portgroup_facts.hosts_portgroup_info |
dict2items | map(attribute='value') | flatten |
selectattr('portgroup', 'equalto', wait_for_portgroup_name)) | length != 0
ignore_errors: true
register: portgroup_facts

Expand Down
6 changes: 3 additions & 3 deletions linux/deploy_vm/deploy_vm_from_ova.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@
- name: "Get VM info"
include_tasks: ../../common/vm_get_vm_info.yml

- name: "Get VM's primary network adapter MAC address"
include_tasks: ../../common/vm_wait_primary_nic_mac.yml

- name: "Try to get OS type from guest info"
include_tasks: get_ova_guest_os_type.yml

Expand Down Expand Up @@ -90,9 +93,6 @@
- name: "Add a serial port for VM"
include_tasks: ../../common/vm_add_serial_port.yml

- name: "Get VM's primary network adapter MAC address"
include_tasks: ../../common/vm_wait_primary_nic_mac.yml

- name: "Reconfigure VM with cloud-init"
include_tasks: reconfigure_vm_with_cloudinit.yml
when: ova_guest_os_type in ['photon', 'ubuntu', 'amazon']
Expand Down
141 changes: 83 additions & 58 deletions linux/guest_customization/check_dns.yml
Original file line number Diff line number Diff line change
@@ -1,91 +1,105 @@
# Copyright 2021-2023 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
- name: "Initilize DNS configuration check results"
- name: "Initilize facts of guest OS resolvectl command and DNS configuration check results"
ansible.builtin.set_fact:
guest_resolvectl_cmd: "/usr/bin/resolvectl"
dns_servers_success: false
dns_suffix_success: false
guest_dns_servers: []
guest_dns_search: []

# Try to use command 'resolvectl' to get DNS status
- include_tasks: ../../common/vm_shell_in_guest.yml
- name: "Test '{{ guest_resolvectl_cmd }} status' command in guest OS"
include_tasks: ../../common/vm_shell_in_guest.yml
vars:
vm_shell_cmd: "/usr/bin/resolvectl"
vm_shell_cmd: "{{ guest_resolvectl_cmd }}"
vm_shell_args: "status"
vm_shell_out: "/tmp/resolvectl_status.txt"
- name: "Set fact of the 'resolvectl status' command result"

- name: "Set fact of '{{ guest_resolvectl_cmd }} status' command result"
ansible.builtin.set_fact:
resolvectl_status_result: "{{ false if vm_shell_result.exit_code is undefined or vm_shell_result.exit_code != 0 else true }}"
resolvectl_status_result: "{{ vm_shell_result.exit_code is defined and vm_shell_result.exit_code == 0 }}"

# If 'resolvectl' command succeed
- block:
- include_tasks: ../../common/vm_guest_file_operation.yml
# Guest OS has /usr/bin/resolvectl command
- name: "Get DNS servers and search domains for {{ guest_os_ansible_distribution }}"
when: resolvectl_status_result
block:
- name: "Fetch the output file of '{{ guest_resolvectl_cmd }} status'"
include_tasks: ../../common/vm_guest_file_operation.yml
vars:
operation: "fetch_file"
src_path: "/tmp/resolvectl_status.txt"
dest_path: "{{ current_test_log_folder }}/resolvectl_status.txt"

# Run command 'resolvectl dns' to get DNS servers
- include_tasks: ../../common/vm_shell_in_guest.yml
- name: "Run command '{{ guest_resolvectl_cmd }} dns' to get DNS servers"
include_tasks: ../../common/vm_shell_in_guest.yml
vars:
vm_shell_cmd: "/usr/bin/resolvectl"
vm_shell_cmd: "{{ guest_resolvectl_cmd }}"
vm_shell_args: "dns"
vm_shell_out: "/tmp/resolvectl_dns.txt"

- name: "Set fact of the 'resolvectl dns' command result"
- name: "Set fact of '{{ guest_resolvectl_cmd }} dns' command result"
ansible.builtin.set_fact:
resolvectl_dns_result: "{{ false if vm_shell_result.exit_code is undefined or vm_shell_result.exit_code != 0 else true }}"
resolvectl_dns_result: "{{ vm_shell_result.exit_code is defined and vm_shell_result.exit_code == 0 }}"

- block:
- include_tasks: ../../common/vm_guest_file_operation.yml
- name: "Get DNS servers for {{ guest_os_ansible_distribution }}"
when: resolvectl_dns_result
block:
- name: "Fetch the output file of '{{ guest_resolvectl_cmd }} dns'"
include_tasks: ../../common/vm_guest_file_operation.yml
vars:
operation: "fetch_file"
src_path: "/tmp/resolvectl_dns.txt"
dest_path: "{{ current_test_log_folder }}/resolvectl_dns.txt"

- name: "Set fact of guest DNS servers"
- name: "Set fact of DNS servers for {{ guest_os_ansible_distribution }}"
ansible.builtin.set_fact:
guest_dns_servers: "{{ lookup('file', current_test_log_folder ~ '/resolvectl_dns.txt').split('\n') | select('match', '^link', ignorecase=True) | regex_findall('\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b') }}"
when: resolvectl_dns_result | bool
guest_dns_servers: "{{ lookup('file', current_test_log_folder ~ '/resolvectl_dns.txt') | regex_search('link[^:]*:[\\d\\s\\.]+', ignorecase=True) | regex_findall('\\b(?:\\d{1,3}\\.){3}\\d{1,3}\\b') }}"

# Run command 'resolvectl domain' to get DNS servers
- include_tasks: ../../common/vm_shell_in_guest.yml
- name: "Run command '{{ guest_resolvectl_cmd }} domain' to get DNS search domains"
include_tasks: ../../common/vm_shell_in_guest.yml
vars:
vm_shell_cmd: "/usr/bin/resolvectl"
vm_shell_cmd: "{{ guest_resolvectl_cmd }}"
vm_shell_args: "domain"
vm_shell_out: "/tmp/resolvectl_domain.txt"

- name: "Set fact of the 'resolvectl domain' command result"
- name: "Set fact of '{{ guest_resolvectl_cmd }} domain' command result"
ansible.builtin.set_fact:
resolvectl_domain_result: "{{ false if vm_shell_result.exit_code is undefined or vm_shell_result.exit_code != 0 else true }}"
resolvectl_domain_result: "{{ vm_shell_result.exit_code is defined and vm_shell_result.exit_code == 0 }}"

- block:
- include_tasks: ../../common/vm_guest_file_operation.yml
- name: "Get DNS search domains for {{ guest_os_ansible_distribution }}"
when: resolvectl_domain_result
block:
- name: "Fetch the output file of '{{ guest_resolvectl_cmd }} domain'"
include_tasks: ../../common/vm_guest_file_operation.yml
vars:
operation: "fetch_file"
src_path: "/tmp/resolvectl_domain.txt"
dest_path: "{{ current_test_log_folder }}/resolvectl_domain.txt"

- name: "Set fact of guest DNS searching domains"
- name: "Set fact of DNS search domains for {{ guest_os_ansible_distribution }}"
ansible.builtin.set_fact:
guest_dns_search: "{{ lookup('file', current_test_log_folder ~ '/resolvectl_domain.txt').split('\n') | select('match', '^link', ignorecase=True) | regex_findall('\\b(?:[a-zA-Z0-9-]{1,}\\.){1,}[a-zA-Z0-9-]{1,}\\b') }}"
when: resolvectl_domain_result | bool
when: resolvectl_status_result
guest_dns_search: "{{ lookup('file', current_test_log_folder ~ '/resolvectl_domain.txt') | regex_search('link[^:]*:[^:]+', ignorecase=True) | regex_findall('\\b(?:[\\w-]{1,}\\.){1,}[\\w-]{1,}\\b') }}"

# If 'resolvectl' command failed and guest OS is not Ubuntu
# Try to get DNS servers and DNS search domains from /etc/resolv.conf
- block:
# In SLES 15, /etc/resolv.conf is a symbolic link. But after cloud-initGOSC,
- name: "Get DNS servers and search domains for {{ guest_os_ansible_distribution }}"
when:
- not resolvectl_status_result
- guest_os_ansible_distribution != 'Ubuntu'
block:
# In SLES 15, /etc/resolv.conf is a symbolic link. But after cloud-init GOSC,
# it will be overwritten to a file. Here we get content in /etc/resolv.conf
# in case the file is overwritten
- include_tasks: ../../common/vm_shell_in_guest.yml
- name: "Dump content of /etc/resolv.conf"
include_tasks: ../../common/vm_shell_in_guest.yml
vars:
vm_shell_cmd: "/usr/bin/cat"
vm_shell_args: "/etc/resolv.conf"
vm_shell_out: "/tmp/resolv.conf"

- include_tasks: ../../common/vm_guest_file_operation.yml
- name: "Fetch the copy file of /etc/resolv.conf"
include_tasks: ../../common/vm_guest_file_operation.yml
vars:
operation: "fetch_file"
src_path: "/tmp/resolv.conf"
Expand All @@ -95,26 +109,32 @@
ansible.builtin.set_fact:
guest_resolv_conf: "{{ lookup('file', current_test_log_folder ~ '/etc/resolv.conf').split('\n') }}"

- name: "Get guest DNS servers and search domains from /etc/resolv.conf"
- name: "Get DNS servers and search domains from /etc/resolv.conf"
ansible.builtin.set_fact:
guest_dns_servers: "{{ guest_resolv_conf | select('match', '^nameserver\\s*') | map('regex_replace', 'nameserver\\s*', '') }}"
guest_dns_search: "{{ guest_resolv_conf | select('match', '^search\\s*') | join('\\n') | regex_replace('^search\\s*', '') | split() | map('regex_replace', '\\.$', '') }}"
when:
- not resolvectl_status_result
- guest_os_ansible_distribution != 'Ubuntu'

# If 'resolvectl' command failed and guest OS is Ubuntu
# For Ubuntu 18.04.4 or later guest, try to use systemd-resolve command
- block:
- include_tasks: ../../common/vm_shell_in_guest.yml
- name: "Get DNS servers and search domains for {{ guest_os_ansible_distribution }}"
when:
- not resolvectl_status_result
- guest_os_ansible_distribution == 'Ubuntu'
block:
- name: "Run command '/usr/bin/systemd-resolve --status' to get DNS servers and search domains"
include_tasks: ../../common/vm_shell_in_guest.yml
vars:
vm_shell_cmd: "/usr/bin/systemd-resolve"
vm_shell_args: "--status"
vm_shell_out: "/tmp/systemd_resolve_status.txt"
- name: "Set fact of the systemd-resolve command result"

- name: "Set fact of '/usr/bin/systemd-resolve --status' command result"
ansible.builtin.set_fact:
systemd_resolve_result: "{{ false if vm_shell_result.exit_code is undefined or vm_shell_result.exit_code != 0 else true }}"
- block:
systemd_resolve_result: "{{ vm_shell_result.exit_code is defined and vm_shell_result.exit_code == 0 }}"

- name: "Get DNS servers and search domains from systemd-resolve status"
when: systemd_resolve_result
block:
- include_tasks: ../../common/vm_guest_file_operation.yml
vars:
operation: "fetch_file"
Expand All @@ -129,10 +149,6 @@
ansible.builtin.set_fact:
guest_dns_servers: "{{ guest_resolve_status | regex_search('DNS Servers:\\s*(([0-9]+\\.){3}([0-9]+)\\n?)+') | regex_replace('DNS Servers:\\s*', '') | split('\\n') | reject('equalto', '') }}"
guest_dns_search: "{{ guest_resolve_status | regex_search('DNS Domain:\\s*(([0-9a-zA-Z_\\-]+\\.){1,}([0-9a-zA-Z_\\-]+)\\n?)+') | regex_replace('DNS Domain:\\s*', '') | split('\\n') | reject('equalto', '') }}"
when: systemd_resolve_result
when:
- not resolvectl_status_result
- guest_os_ansible_distribution == 'Ubuntu'

- name: "Set fact of the expected DNS servers after GOSC"
ansible.builtin.set_fact:
Expand All @@ -143,24 +159,28 @@
# Please refer to this issue: https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1892447
# File: https://github.com/canonical/cloud-init/blob/master/cloudinit/distros/parsers/resolv_conf.py
#
- block:
- name: "Get DNS servers and search domains for {{ guest_os_ansible_distribution }}"
when:
- dns_servers_before_gosc is defined
- enable_cloudinit_gosc is defined and enable_cloudinit_gosc
- linux_gosc_spec['dns_servers'] | difference(guest_dns_servers) | length != 0
block:
- name: "Set fact of the combination of DNS servers list before GOSC and the configured list"
ansible.builtin.set_fact:
tmp_dns_server_list: "{{ (dns_servers_before_gosc + linux_gosc_spec['dns_servers']) | unique }}"

- name: "Set fact of the expected DNS servers"
ansible.builtin.set_fact:
expected_dns_servers: "{{ dns_servers_before_gosc }}"
when: tmp_dns_server_list | length == dns_servers_before_gosc | length

- name: "Set fact of the expected DNS servers"
ansible.builtin.set_fact:
expected_dns_servers: "{{ tmp_dns_server_list[:3] if tmp_dns_server_list | length > 3 else tmp_dns_server_list }}"
when: tmp_dns_server_list | length > dns_servers_before_gosc | length
when:
- dns_servers_before_gosc is defined
- enable_cloudinit_gosc is defined and enable_cloudinit_gosc
- linux_gosc_spec['dns_servers'] | difference(guest_dns_servers) | length != 0

- ansible.builtin.debug:
- name: "Display the expected and actual DNS servers"
ansible.builtin.debug:
msg:
- "The expected DNS servers: {{ expected_dns_servers }}"
- "The actual DNS servers got in guest: {{ guest_dns_servers }}"
Expand All @@ -169,27 +189,32 @@
- name: "Check guest DNS servers are customized"
ansible.builtin.set_fact:
dns_servers_success: "{{ expected_dns_servers | difference(guest_dns_servers) | length == 0 }}"

- name: "Print DNS servers check result"
ansible.builtin.debug: var=dns_servers_success

- include_tasks: set_gosc_validation_result.yml
- name: "Set GOSC validation result for checking DNS servers"
include_tasks: set_gosc_validation_result.yml
vars:
gosc_check_item: "dns_servers_success"
gosc_check_error_msg: "VM DNS servers are {{ guest_dns_servers }}, not expected DNS servers {{ linux_gosc_spec['dns_servers'] }}"

# Check guest DNS search domains
- ansible.builtin.debug:
- name: "Display the expected and actual DNS search domains"
ansible.builtin.debug:
msg:
- "The expected search domains: {{ linux_gosc_spec['dns_suffix'] }}"
- "The expected DNS search domains: {{ linux_gosc_spec['dns_suffix'] }}"
- "The actual DNS search domains got in guest: {{ guest_dns_search }}"

- name: "Check DNS search domains are customized"
ansible.builtin.set_fact:
dns_suffix_success: "{{ linux_gosc_spec['dns_suffix'] | difference(guest_dns_search) | length == 0 }}"

- name: "Print DNS suffix check result"
ansible.builtin.debug: var=dns_suffix_success

- include_tasks: set_gosc_validation_result.yml
- name: "Set GOSC validation result for checking DNS search domains"
include_tasks: set_gosc_validation_result.yml
vars:
gosc_check_item: "dns_suffix_success"
gosc_check_error_msg: "VM DNS domain search domains are {{ guest_dns_search }} not expected search domains {{ linux_gosc_spec['dns_suffix'] }}"
gosc_check_error_msg: "VM DNS domain search domains are {{ guest_dns_search }}, not expected search domains {{ linux_gosc_spec['dns_suffix'] }}"

0 comments on commit 63e75c6

Please sign in to comment.