Skip to content

Commit 04f357a

Browse files
authored
Fix #206 and #201 Warn about GOSC DNS failures on Ubuntu and default gateway failures (#227)
* Fix #206 and #201 Warn about GOSC DNS failures on Ubuntu and default gateway failures Signed-off-by: Qi Zhang <[email protected]>
1 parent 07d64ae commit 04f357a

File tree

10 files changed

+148
-92
lines changed

10 files changed

+148
-92
lines changed

common/vm_add_serial_port.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#
1010
- name: "Set default serial port output file"
1111
set_fact:
12-
vm_serial_port_file_path: "{{ vm_files_path_ds }}/serial-{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}.log"
12+
vm_serial_port_file_path: "{{ vm_files_path_ds.strip('\\/') }}/serial-{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}.log"
1313
when: vm_serial_port_file_path is undefined or not vm_serial_port_file_path
1414

1515
- name: "Add a serial port using output file"

common/vm_remove_serial_port.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
# Parameter:
66
# vm_serial_port_file_path: The serial port output file on datastore.
77

8+
# Before removing serial port, remove the serial port output file
9+
- include_tasks: esxi_check_delete_datastore_file.yml
10+
vars:
11+
file_in_datastore: "{{ datastore }}"
12+
file_in_datastore_path: "{{ vm_serial_port_file_path.split(']')[-1].strip(' ') }}"
13+
file_in_datastore_ops: "absent"
14+
file_in_datastore_failed_ignore: True
15+
816
- name: "Remove a serial port using output file"
917
vmware_guest_serial_port:
1018
hostname: "{{ vsphere_host_name }}"

linux/deploy_vm/deploy_vm_from_iso.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@
172172
when: guest_os_ansible_distribution == "Ubuntu"
173173

174174
- include_tasks: ../../common/vm_remove_serial_port.yml
175+
176+
- fail:
177+
msg: "Failed to remove serial port from VM"
178+
when: >
179+
remove_serial_port is undefined or
180+
remove_serial_port.changed is undefined or
181+
not remove_serial_port.changed
182+
175183
- include_tasks: ../../common/vm_set_power_state.yml
176184
vars:
177185
vm_power_state_set: 'powered-on'

linux/guest_customization/check_dns.yml

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,9 @@
4444
src_path: "/tmp/resolvectl_dns.txt"
4545
dest_path: "{{ current_test_log_folder }}/resolvectl_dns.txt"
4646

47-
- name: "Get output of 'resolvectl dns'"
48-
command: cat "{{ current_test_log_folder }}/resolvectl_dns.txt"
49-
register: dns_servers
50-
5147
- name: "Set fact of guest DNS servers"
5248
set_fact:
53-
guest_dns_servers: "{{ dns_servers.stdout_lines | select('match', '^Link') |
54-
regex_findall('\\b(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\b') }}"
49+
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') }}"
5550
when: resolvectl_dns_result | bool
5651

5752
# Run command 'resolvectl domain' to get DNS servers
@@ -72,14 +67,9 @@
7267
src_path: "/tmp/resolvectl_domain.txt"
7368
dest_path: "{{ current_test_log_folder }}/resolvectl_domain.txt"
7469

75-
- name: "Get output of 'resolvectl domain'"
76-
command: cat "{{ current_test_log_folder }}/resolvectl_domain.txt"
77-
register: dns_domains
78-
7970
- name: "Set fact of guest DNS searching domains"
8071
set_fact:
81-
guest_dns_search: "{{ dns_domains.stdout_lines | select('match', '^Link') |
82-
regex_findall('\\b(?:[a-zA-Z0-9-]{1,}\\.){1,}[a-zA-Z0-9-]{1,}\\b') }}"
72+
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') }}"
8373
when: resolvectl_domain_result | bool
8474
when: resolvectl_status_result
8575

@@ -101,27 +91,14 @@
10191
src_path: "/tmp/resolv.conf"
10292
dest_path: "{{ current_test_log_folder }}/etc/resolv.conf"
10393

104-
- name: "Get DNS servers from /etc/resolv.conf"
105-
shell: cat "{{ current_test_log_folder }}/etc/resolv.conf" | grep -i "^nameserver\s*" | awk '{print $2}'
106-
register: dns_servers
107-
108-
- name: "Get guest DNS servers from shell command output"
109-
set_fact:
110-
guest_dns_servers: "{{ dns_servers.stdout_lines }}"
111-
112-
- name: "Get DNS search domains from /etc/resolv.conf"
113-
shell: cat "{{ current_test_log_folder }}/etc/resolv.conf" | grep -i "^search" | awk '{i=2;while(i<=NF) {print $i; i++ }}'
114-
register: dns_search
115-
116-
- name: "Save guest DNS search list to tmp variable"
94+
- name: "Get content of /etc/resolv.conf in guest OS"
11795
set_fact:
118-
tmp_dns_search: "{{ dns_search.stdout_lines }}"
96+
guest_resolv_conf: "{{ lookup('file', current_test_log_folder ~ '/etc/resolv.conf').split('\n') }}"
11997

120-
# In Amazon Linux 2 guest, a period after each DNS search domain would be added, so remove it
121-
- name: "Get guest DNS search list"
98+
- name: "Get guest DNS servers and search domains from /etc/resolv.conf"
12299
set_fact:
123-
guest_dns_search: "{{ guest_dns_search + [item | regex_replace('\\.$','')] }}"
124-
with_items: "{{ tmp_dns_search }}"
100+
guest_dns_servers: "{{ guest_resolv_conf | select('match', '^nameserver\\s*') | map('regex_replace', 'nameserver\\s*', '') }}"
101+
guest_dns_search: "{{ guest_resolv_conf | select('match', '^search\\s*') | join('\\n') | regex_replace('^search\\s*', '') | split() | map('regex_replace', '\\.$', '') }}"
125102
when:
126103
- not resolvectl_status_result
127104
- guest_os_ansible_distribution != 'Ubuntu'
@@ -143,21 +120,15 @@
143120
operation: "fetch_file"
144121
src_path: "/tmp/systemd_resolve_status"
145122
dest_path: "{{ current_test_log_folder }}/systemd_resolve_status.txt"
146-
- name: "Get DNS servers from command systemd-resolve"
147-
shell: cat "{{ current_test_log_folder }}/systemd_resolve_status.txt" | sed -n '/DNS Servers/,/DNS Domain/p' | head -n -1
148-
register: dns_servers
149-
- name: "Set fact of DNS servers from shell command output"
123+
124+
- name: "Set fact of guest systemd resolve status"
150125
set_fact:
151-
guest_dns_servers: "{{ (guest_dns_servers + [item.strip().split(':')[1].strip()]) if 'DNS Servers' in item else (guest_dns_servers + [item.strip()]) }}"
152-
with_items: "{{ dns_servers.stdout_lines }}"
126+
guest_resolve_status: "{{ lookup('file', current_test_log_folder ~ '/systemd_resolve_status.txt') | regex_replace('\\n\\s*','\\n') }}"
153127

154-
- name: "Get DNS search domains from command systemd-resolve"
155-
shell: cat "{{ current_test_log_folder }}/systemd_resolve_status.txt" | sed -n '/DNS Domain/,/DNSSEC NTA/p' | head -n -1
156-
register: dns_domains
157-
- name: "Set fact of DNS search domains from shell command output"
128+
- name: "Set fact of DNS servers and search domains from systemd resolve status"
158129
set_fact:
159-
guest_dns_search: "{{ (guest_dns_search + [item.strip().split(':')[1].strip()]) if 'DNS Domain' in item else (guest_dns_search + [item.strip()]) }}"
160-
with_items: "{{ dns_domains.stdout_lines }}"
130+
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', '') }}"
131+
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', '') }}"
161132
when: systemd_resolve_result
162133
when:
163134
- not resolvectl_status_result
@@ -207,6 +178,11 @@
207178
gosc_check_error_msg: "VM DNS servers are {{ guest_dns_servers }}, not expected DNS servers {{ linux_gosc_spec['dns_servers'] }}"
208179

209180
# Check guest DNS search domains
181+
- debug:
182+
msg:
183+
- "The expected search domains: {{ linux_gosc_spec['dns_suffix'] }}"
184+
- "The actual DNS search domains got in guest: {{ guest_dns_search }}"
185+
210186
- name: "Check DNS search domains are customized"
211187
set_fact:
212188
dns_suffix_success: "{{ linux_gosc_spec['dns_suffix'] | difference(guest_dns_search) | length == 0 }}"

linux/guest_customization/check_etc_hosts.yml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
etc_hosts_success: False
1010
expected_ips: ['::1']
1111
ipv6_hostname_check: False
12+
actual_ips: []
1213

1314
- include_tasks: ../../common/vm_guest_file_operation.yml
1415
vars:
@@ -17,12 +18,13 @@
1718
dest_path: "{{ hosts_file_path }}"
1819

1920
- name: "Get IP bindings for hostname {{ linux_gosc_spec['hostname'] }} in /etc/hosts"
20-
shell: grep "{{ linux_gosc_spec['hostname'] }}.{{ linux_gosc_spec['domain'] }} *{{ linux_gosc_spec['hostname'] }}" {{ hosts_file_path }} | awk '{print $1}'
21-
changed_when: False
22-
register: etc_hosts_result
23-
- name: "Save hostname binding list"
2421
set_fact:
25-
actual_ips: "{{ etc_hosts_result.stdout_lines }}"
22+
guest_host_ip_bindings: "{{ lookup('file', hosts_file_path).split('\n') | select('match', '.*\\s*' ~ linux_gosc_spec['hostname'] ~ '.' ~ linux_gosc_spec['domain'] ~ ' *' ~ linux_gosc_spec['hostname']) }}"
23+
24+
- name: "Set fact of hostnam and IP binding"
25+
set_fact:
26+
actual_ips: "{{ guest_host_ip_bindings | map('regex_replace', '\\s*' ~ linux_gosc_spec['hostname'] ~ '.*', '') }}"
27+
when: guest_host_ip_bindings | length > 0
2628

2729
# Perl GOSC:
2830
# 1. When ip assignment is dhcp, hostname will be bound to 127.0.1.1 and ::1

linux/guest_customization/check_hostname_and_domain.yml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
---
44
- name: "Initialize hostname and domain check result"
55
set_fact:
6+
guest_hostname: ""
7+
guest_dns_domain: ""
68
hostname_success: ""
79
dns_domain_success: ""
810

@@ -27,14 +29,13 @@
2729
dest_path: "{{ current_test_log_folder }}/hostname_f.txt"
2830

2931
- name: "Get guest FQDN"
30-
command: cat "{{ current_test_log_folder }}/hostname_f.txt"
31-
changed_when: False
32-
register: result
32+
set_fact:
33+
guest_fqdn: "{{ lookup('file', current_test_log_folder ~ '/hostname_f.txt') }}"
3334

34-
- name: "Save hostname and domain check result"
35+
- name: "Set fact of guest OS hostname and domain"
3536
set_fact:
36-
guest_hostname: "{{ result.stdout.split('.')[0] }}"
37-
guest_dns_domain: "{{ result.stdout.split('.')[1:] | join('.') }}"
37+
guest_hostname: "{{ guest_fqdn.split('.')[0] }}"
38+
guest_dns_domain: "{{ (guest_fqdn.split('.')[1:] | join('.')) if guest_fqdn.split('.') | length > 1 else '' }}"
3839

3940
# Check hostname
4041
- name: Check guest hostname is customized

linux/guest_customization/check_network_config.yml

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
---
44
- name: "Initialize GOSC network check result"
55
set_fact:
6+
ip_command: "{{ '/usr/sbin/ip' if guest_os_ansible_distribution != 'Ubuntu' else '/sbin/ip' }}"
7+
guest_iface_name: ""
8+
guest_ipv4_address: ""
9+
guest_ipv4_netmask: ""
10+
guest_ipv4_gateway: ""
611
guest_ipv4_success: ""
712
guest_netmask_success: ""
813
guest_gateway_success: ""
9-
ip_command: "/usr/sbin/ip"
10-
11-
- name: "Set fact of ip command when guest OS is Ubuntu"
12-
set_fact:
13-
ip_command: "/sbin/ip"
14-
when: guest_os_ansible_distribution in ["Ubuntu"]
1514

1615
# Get IP address and netmask
1716
- include_tasks: ../../common/vm_shell_in_guest.yml
@@ -27,15 +26,15 @@
2726
dest_path: "{{ current_test_log_folder }}/ip_addr_show.txt"
2827

2928
- name: "Get IPv4 address"
30-
shell: cat "{{ current_test_log_folder }}/ip_addr_show.txt" | grep -v lo | grep -v virbr | awk '{print $1, $2, $3}'
31-
changed_when: False
32-
register: result
29+
set_fact:
30+
guest_ip_addr_show: "{{ lookup('file', current_test_log_folder ~ '/ip_addr_show.txt').split('\n') | select('search', '^e(n|th).*') }}"
3331

34-
- name: "Save GOSC network facts from command output"
32+
- name: "Set facts of guest network interface names and IPv4 address"
3533
set_fact:
36-
guest_iface_name: "{{ result.stdout.split(' ')[0] }}"
37-
guest_ipv4_address: "{{ result.stdout.split(' ')[-1] | ipaddr('address') }}"
38-
guest_ipv4_netmask: "{{ result.stdout.split(' ')[-1] | ipaddr('netmask') }}"
34+
guest_iface_name: "{{ guest_ip_addr_show[0].split()[0] }}"
35+
guest_ipv4_address: "{{ guest_ip_addr_show[0] | regex_search('(\\d+\\.){3}(\\d+)/(\\d+)') | ipaddr('address') }}"
36+
guest_ipv4_netmask: "{{ guest_ip_addr_show[0] | regex_search('(\\d+\\.){3}(\\d+)/(\\d+)') | ipaddr('netmask') }}"
37+
when: guest_ip_addr_show | length > 0
3938

4039
# Get default gateway
4140
- include_tasks: ../../common/vm_shell_in_guest.yml
@@ -51,12 +50,15 @@
5150
dest_path: "{{ current_test_log_folder }}/ip_route_show.txt"
5251

5352
- name: "Get default gateway"
54-
shell: cat "{{ current_test_log_folder }}/ip_route_show.txt" | grep "^default"
55-
changed_when: False
56-
register: result
57-
- name: "Save GOSC network gateway"
5853
set_fact:
59-
guest_ipv4_gateway: "{{ result.stdout.split(' ')[2] }}"
54+
guest_default_gateway: "{{ lookup('file', current_test_log_folder ~ '/ip_route_show.txt').split('\n') | select('match', '^default') }}"
55+
56+
- name: "Set fact of GOSC network gateway"
57+
set_fact:
58+
guest_ipv4_gateway: "{{ guest_default_gateway[0].split()[2] }}"
59+
when:
60+
- guest_default_gateway | length > 0
61+
- guest_default_gateway[0].split() | length >= 3
6062

6163
# Check IP address, netmaks, gateway settings for GOSC with DHCP IP
6264
- block:
@@ -186,15 +188,15 @@
186188
dest_path: "{{ current_test_log_folder }}/list_network_files.txt"
187189

188190
- name: "Look for network file on Photon OS"
189-
command: cat "{{ current_test_log_folder }}/list_network_files.txt"
190-
register: network_files
191-
191+
set_fact:
192+
guest_network_files: "{{ lookup('file', current_test_log_folder ~ '/list_network_files.txt').split('\n') }}"
192193
- include_tasks: ../../common/vm_guest_file_operation.yml
193194
vars:
194195
operation: "fetch_file"
195196
src_path: "{{ src_network_file }}"
196197
dest_path: "{{ current_test_log_folder }}{{ src_network_file }}"
197-
with_items: "{{ network_files.stdout_lines }}"
198+
with_items: "{{ guest_network_files }}"
198199
loop_control:
199200
loop_var: "src_network_file"
201+
when: guest_network_files | length > 0
200202
when: guest_os_ansible_distribution == "VMware Photon OS"

linux/guest_customization/check_timezone_and_hwclock.yml

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
---
44
- name: "Initialize timezone check result"
55
set_fact:
6+
guest_timezone: ""
67
timezone_success: ""
8+
79
- name: "Initialize hardware clock check result for perl GOSC"
810
set_fact:
11+
guest_hwclockUTC: ""
912
hwclock_success: ""
1013
when: gosc_workflow == "perl"
1114

@@ -25,12 +28,12 @@
2528
dest_path: "{{ current_test_log_folder }}/timedatectl_status.txt"
2629

2730
- name: "Get time zone from 'timedatectl status'"
28-
shell: grep -i "^ *time zone:" "{{ current_test_log_folder }}/timedatectl_status.txt" | awk '{print $3}'
29-
register: tz_result
31+
set_fact:
32+
guest_timedate_status: "{{ lookup('file', current_test_log_folder ~ '/timedatectl_status.txt') | regex_search('\\s*Time zone:\\s*[^\\n]+\\n?') }}"
3033

31-
- name: "Save guest timezone setting after GOSC"
34+
- name: "Set fact of guest time zone after GOSC"
3235
set_fact:
33-
guest_timezone: "{{ tz_result.stdout }}"
36+
guest_timezone: "{{ guest_timedate_status | regex_replace('.*\\s*Time zone:\\s*([^\\s]+)\\s*.*\\n?', '\\1')}}"
3437

3538
- block:
3639
- name: "Get hwclock from 'timedatectl status'"
@@ -61,13 +64,8 @@
6164
dest_path: "{{ current_test_log_folder }}/readlink_etc_localtime.txt"
6265

6366
- name: "Get timezone info from /etc/localtime"
64-
command: cat "{{ current_test_log_folder }}/readlink_etc_localtime.txt"
65-
register: tz_result
66-
changed_when: False
67-
68-
- name: "Save guest timezone setting after GOSC"
6967
set_fact:
70-
guest_timezone: "{{ tz_result.stdout.replace('/usr/share/zoneinfo/','') }}"
68+
guest_timezone: "{{ lookup('file', current_test_log_folder ~ '/readlink_etc_localtime.txt') | replace('/usr/share/zoneinfo/','') }}"
7169

7270
# Get hwclock by running command "hwclock -D" when test perl GOSC
7371
- block:

linux/guest_customization/linux_gosc_start.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
# Do not fail GOSC immediately if state keyword doesn't exist
4545
- include_tasks: ../../common/vm_wait_gosc_completed.yml
4646
vars:
47+
get_guest_reset_time_retries: 10
4748
check_gosc_state_keyword: False
4849

4950
# Traditional GOSC will reboot guest OS (except for Photon) after all customization done

0 commit comments

Comments
 (0)