Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions windows/guest_customization/win_gosc_verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,20 @@
include_tasks: check_runonce_command.yml
- name: "Check timezone configured"
include_tasks: check_timezone.yml
- name: "Check Windows readiness"
include_tasks: ../utils/win_check_os_readiness.yml
- name: "Get 'explorer.exe' process status"
include_tasks: ../utils/win_get_explorer_process.yml
- name: "Check 'explorer.exe' process status"
ansible.builtin.assert:
that:
- win_explorer_running
fail_msg: >
Failed to get process 'explorer.exe' in guest OS after GOSC, black screen issue may happen,
please check the screenshot or log files in the current test case log folder.

- name: "Take a screenshot after GOSC"
include_tasks: ../../common/vm_take_screenshot.yml
vars:
vm_screenshot_local_dir: "{{ current_test_log_folder }}"
vm_screenshot_local_name: "screenshot_after_gosc.png"
48 changes: 48 additions & 0 deletions windows/utils/win_check_active_update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2025 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Get these 2 processes' info to check if the Windows is actively installing or
# configuring something.
# "TiWorker.exe (Windows Modules Installer Worker)" is the primary process
# responsible for installing updates and modifying system files.
# "msiexec.exe" is the Windows Installer engine, if running as SYSTEM user (Session 0),
# it means a background installation (like a driver or managed app) is happening.
#
- name: "Set facts of the commands for checking Windows status"
ansible.builtin.set_fact:
check_tiworker: "Get-Process TiWorker -ErrorAction SilentlyContinue | Format-List -Property *"
check_msiexec: "Get-Process msiexec -IncludeUserName -ErrorAction SilentlyContinue | Where-Object {$_.UserName -match 'SYSTEM'} | Format-List -Property *"

- name: "Get 'TiWorker.exe' process info"
include_tasks: win_execute_cmd.yml
vars:
win_powershell_cmd: "{{ check_tiworker }}"
win_execute_cmd_ignore_error: true

- name: "Save the result of getting 'TiWorker.exe' process info"
ansible.builtin.set_fact:
check_tiworker_result: "{{ win_powershell_cmd_output }}"

- name: "Get 'msiexec.exe' process info"
include_tasks: win_execute_cmd.yml
vars:
win_powershell_cmd: "{{ check_msiexec }}"
win_execute_cmd_ignore_error: true

- name: "Save the result of getting 'msiexec.exe' process info"
ansible.builtin.set_fact:
check_msiexec_result: "{{ win_powershell_cmd_output }}"

- name: "Set fact of Windows is actively installing updates"
ansible.builtin.set_fact:
os_in_active_updates: true
when: >
(check_tiworker_result.rc is defined and check_tiworker_result.rc == 0) or
(check_msiexec_result.stdout is defined and check_msiexec_result.stdout | length != 0)

- name: "Set fact of Windows is not actively installing updates"
ansible.builtin.set_fact:
os_in_active_updates: false
when:
- check_tiworker_result.rc is defined and check_tiworker_result.rc != 0
- check_msiexec_result.stdout is defined and check_msiexec_result.stdout | length == 0
45 changes: 45 additions & 0 deletions windows/utils/win_check_os_readiness.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright 2025 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Check Windows system readiness after booting up
#
- name: "Initialize the readiness of Windows"
ansible.builtin.set_fact:
os_in_active_updates: false

- name: "Retry to check if Windows is actively installing updates"
include_tasks: win_check_active_update.yml
loop: "{{ range(1, 11) | list }}"
loop_control:
pause: 3
break_when:
- os_in_active_updates

- name: "Debug message"
ansible.builtin.debug:
msg: "Not get the processes that can indicating the Windows is actively installing updates in 30s."
when: not os_in_active_updates

- name: "Debug message"
ansible.builtin.debug:
msg: "Windows guest OS is actively installing updates or configuring something."
when: os_in_active_updates

- name: "Wait for Windows updates installation completes"
when: os_in_active_updates
block:
- name: "Retry to check if Windows completes installing updates"
include_tasks: win_check_active_update.yml
loop: "{{ range(1, 201) | list }}"
loop_control:
pause: 3
break_when:
- not os_in_active_updates
- name: "Debug message"
ansible.builtin.debug:
msg: "Still can get the processes that indicating the Windows is actively installing updates in 600s."
when: os_in_active_updates
- name: "Debug message"
ansible.builtin.debug:
msg: "Windows guest OS completes the updates install."
when: not os_in_active_updates
35 changes: 35 additions & 0 deletions windows/utils/win_get_explorer_process.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2025 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Description:
# Get process 'explorer.exe' in Windows guest OS to check
# if there is black screen issue occurs.
# Parameters:
# win_get_explorer_timeout: the retry time in seconds to get
# the status of process 'explorer.exe'.
# Return:
# win_explorer_running: true or false. Whether the process
# 'explorer.exe' is running in guest OS.
#
- name: "Initialize the status of process 'explorer.exe'"
ansible.builtin.set_fact:
win_explorer_running: false

- name: "Wait for 'explorer.exe' process starting"
ansible.windows.win_shell: 'Get-Process -Name explorer'
delegate_to: "{{ vm_guest_ip }}"
register: get_service_status
delay: 5
retries: "{{ (win_get_explorer_timeout | default(300) / 5) | round | int }}"
until:
- get_service_status.rc is defined
- get_service_status.rc == 0
ignore_errors: true
ignore_unreachable: true

- name: "Set fact of the status of process 'explorer.exe'"
ansible.builtin.set_fact:
win_explorer_running: true
when:
- win_powershell_cmd_output.rc is defined
- win_powershell_cmd_output.rc == 0
42 changes: 22 additions & 20 deletions windows/utils/win_wait_service_status.yml
Original file line number Diff line number Diff line change
@@ -1,39 +1,41 @@
# Copyright 2022-2024 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Retry to get serivce status in Windows guest OS until it's running
# Retry to get serivce status in Windows guest OS until it reaches the expected state.
# Parameters:
# win_service_name: the service name
# win_service_name: the service name to getting status.
# win_wait_service_state (optional): the state of the service, e.g., 'Stopped', 'Running'.
# Default value is 'Running'.
# win_wait_service_timeout (optional): the timeout in seconds to wait for service state.
# Default value is 60s.
#
- name: "Check required parameter"
ansible.builtin.fail:
msg: "win_service_name must be defined before get service status"
when: win_service_name is undefined or not win_service_name
ansible.builtin.assert:
that:
- win_service_name is defined
- win_service_name | length > 0
msg: "Parameter 'win_service_name' must be defined before get service status."

- name: "Check specified service '{{ win_service_name }}' status in Windows"
ansible.windows.win_shell: 'get-service -Name {{ win_service_name }} | foreach {$_.Status}'
delay: 5
retries: 10
ansible.windows.win_shell: 'Get-Service -Name {{ win_service_name }} | foreach {$_.Status}'
delegate_to: "{{ vm_guest_ip }}"
register: get_service_status
delay: 5
retries: "{{ (win_wait_service_timeout | default(60) / 5) | round | int }}"
until:
- get_service_status is defined
- get_service_status.stdout_lines is defined
- get_service_status.stdout_lines | length != 0
- get_service_status.stdout_lines[0] == 'Running'
- get_service_status.stdout_lines | length == 1
- get_service_status.stdout_lines[0] == win_wait_service_state | default('Running')
ignore_errors: true
ignore_unreachable: true

- name: "Check service '{{ win_service_name }}' status in Windows"
ansible.builtin.assert:
that:
- get_service_status is defined
- get_service_status.stdout_lines is defined
- get_service_status.stdout_lines | length != 0
- get_service_status.stdout_lines[0] == 'Running'
- get_service_status.failed is defined
- not get_service_status.failed
fail_msg: >-
Windows service '{{ win_service_name }}' status is not running after 50 seconds.
Current service status is '{{ get_service_status.stdout_lines[0] | default("") }}'.

- name: "Display the PowerShell command result"
ansible.builtin.debug: var=get_service_status
when: enable_debug is defined and enable_debug
Windows service '{{ win_service_name }}' status is not {{ win_wait_service_state | default('Running') }}
after {{ win_wait_service_timeout | default(60) }} seconds.
Get service status in guest OS '{{ get_service_status.stdout_lines | default("") }}'.