Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] Add new test case windows_online_updates_install #594

Merged
merged 22 commits into from
Jul 3, 2024
Merged
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
14 changes: 13 additions & 1 deletion vars/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -382,11 +382,23 @@ windows_nfs_msu_path: ''
# The use name and password for accessing above Windows shared folder.
# windows_nfs_username: "CHANGEME"
# windows_nfs_password: "CHANGEME"

# A list of update titles or KB numbers that can be used to specify which updates are to be excluded from
# online Windows Updates installation. Online Windows Updates is executed before offline .msu file installation.
# The list is comma separated string. E.g. "KB12344, KB2343, kB567"
# The list is comma separated string. E.g. "KB12344, KB2343, kB567".
# This paramter can also be used in below test case "windows_online_updates_install".
windows_updates_reject_list: ''

# 8. windows_online_updates_install
# For Windows testing only.
# The expected build number of guest OS after installing Windows online updates.
# When this paramter is set to a valid build number, then after installing Windows updates, will check
# if guest OS build number is the same as or newer than this expected one. If this parameter is not set,
# will not check guest OS build number after installing Windows online updates in this test case.
# It must be set as a major build numner or a major build number with a minor build number,
# e.g., '22000', '22000.1', '22000.1234'.
# windows_updated_build_num: ''

#####################################
# GOS related parameters
#####################################
Expand Down
1 change: 1 addition & 0 deletions windows/gosv_testcase_list.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# SPDX-License-Identifier: BSD-2-Clause
---
- import_playbook: deploy_vm/deploy_vm.yml
- import_playbook: windows_online_updates_install/windows_online_updates_install.yml
- import_playbook: check_inbox_driver/check_inbox_driver.yml
- import_playbook: wintools_complete_install_verify/wintools_complete_install_verify.yml
- import_playbook: windows_update_install/windows_update_install.yml
Expand Down
6 changes: 5 additions & 1 deletion windows/setup/test_setup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,12 @@
- name: "Print VM guest IP address"
ansible.builtin.debug: var=vm_guest_ip

# Windows Update will cause OS poweroff or restart taking a long time,
# or GOSC test cases failure, here try to pause Windows Update 7 days
- name: "Pause Windows Update"
include_tasks: ../utils/win_pause_windows_update.yml
include_tasks: ../utils/win_pause_resume_win_update.yml
vars:
win_update_ops: 'pause'
when: not base_snapshot_exists

- name: "Get VMware Tools status"
Expand Down
41 changes: 41 additions & 0 deletions windows/utils/scripts/resume_windows_update.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Copyright 2024 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
#
# Script to remove pausing Windows Update config from registry
#
$win_pause_update_reg_path = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings"
$win_exclude_driver_update = 'ExcludeWUDriversInQualityUpdate'
$win_policy_current = "HKLM:\SOFTWARE\Microsoft\PolicyManager\current\device\Update"
$win_policy_update = "HKLM:\SOFTWARE\Microsoft\PolicyManager\default\Update"
$win_policy_windows_update = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$win_pause_config = @('PauseUpdatesStartTime', 'PauseUpdatesExpiryTime', 'PauseFeatureUpdatesStartTime', 'PauseFeatureUpdatesEndTime', 'PauseQualityUpdatesStartTime', 'PauseQualityUpdatesEndTime', $win_exclude_driver_update)

If (Test-Path -Path $win_pause_update_reg_path)
{
foreach ($item in $win_pause_config)
{
if ((Get-Item -Path $win_pause_update_reg_path).Property -contains $item)
{
Write-Host "Remove $win_pause_update_reg_path\$item"
Remove-ItemProperty -Path $win_pause_update_reg_path -Name $item -Force
}
}
}
If ((Test-Path -Path $win_policy_current) -and `
((Get-Item -Path $win_policy_current).Property -contains $win_exclude_driver_update))
{
Write-Host "Remove $win_policy_current\$win_exclude_driver_update"
Remove-ItemProperty -Path $win_policy_current -Name $win_exclude_driver_update -Force
}
If ((Test-Path -Path $win_policy_update) -and `
((Get-Item -Path $win_policy_update).Property -contains $win_exclude_driver_update))
{
Write-Host "Remove $win_policy_update\$win_exclude_driver_update"
Remove-ItemProperty -Path $win_policy_update -Name $win_exclude_driver_update -Force
}
If ((Test-Path -Path $win_policy_windows_update) -and `
((Get-Item -Path $win_policy_windows_update).Property -contains $win_exclude_driver_update))
{
Write-Host "Remove $win_policy_windows_update\$win_exclude_driver_update"
Remove-ItemProperty -Path $win_policy_windows_update -Name $win_exclude_driver_update -Force
}
64 changes: 64 additions & 0 deletions windows/utils/win_get_online_updates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Copyright 2024 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Search and list the online Windows Updates in all or specified categories.
# Parameters:
# win_updates_categories (optional): a list of categories to get updates from.
# Some possible categories are: Application, Connectors, Critical Updates, Definition Updates, Developer Kits,
# Feature Packs, Guidance, Security Updates, Service Packs, Tools, Update Rollups, Updates and Upgrades.
# Default value is '*', means matching all categories.
# win_updates_categories_expect (optional): a list of expected update categories. If configured,
# searched online updates must contain at least one of the category in this list.
# Default value is '['']'.
# win_get_updates_retries (optional): the retry times to get expected update categories.
# Default value is 1.
# win_updates_ignore_errors (optional): whether to ignore errors in searching and checking
# Windows online updates, default is false.
# win_updates_log_file (optional): the log file path for Windows Update in guest OS.
# Default is 'C:\win_updates_log.txt'.
#
Tomorrow9 marked this conversation as resolved.
Show resolved Hide resolved
- name: "Initialize the facts of getting Windows online updates"
ansible.builtin.set_fact:
win_updates_categories: "{{ win_updates_categories | default('*') }}"
win_updates_categories_expect: "{{ win_updates_categories_expect | default(['']) }}"
win_updates_ignore_errors: "{{ win_updates_ignore_errors | default(false) }}"
win_updates_log_file: "{{ win_updates_log_file | default('C:\\win_updates_log.txt') }}"

- name: "Set 'win_get_updates_retries' to 1 by default"
ansible.builtin.set_fact:
win_get_updates_retries: 1
when: win_get_updates_retries is undefined

- name: "Get the list of available Windows online updates"
ansible.windows.win_updates:
server_selection: "windows_update"
category_names: "{{ win_updates_categories }}"
log_path: "{{ win_updates_log_file }}"
skip_optional: true
state: "searched"
delegate_to: "{{ vm_guest_ip }}"
register: win_get_updates_result
ignore_errors: true
retries: "{{ win_get_updates_retries | int }}"
delay: 10
until:
- win_get_updates_result.found_update_count is defined
Tomorrow9 marked this conversation as resolved.
Show resolved Hide resolved
- win_get_updates_result.found_update_count | int != 0
- win_get_updates_result.updates is defined
- win_get_updates_result.updates | length != 0
- (win_get_updates_result.updates.values() | map(attribute='categories') | flatten | unique + ['']) | intersect(win_updates_categories_expect) | length != 0

- name: "Print the result of searching Windows online updates"
ansible.builtin.debug: var=win_get_updates_result
when: enable_debug

- name: "Check getting Windows online updates result"
ansible.builtin.fail:
msg: >-
Failed to search Windows online updates containing specified categories:
{{ win_updates_categories_expect }} after {{ win_get_updates_retries }} retries,
with errors: {{ win_get_updates_result.stderr | default('') }}
when:
- not win_updates_ignore_errors
- win_get_updates_result.failed is defined
- win_get_updates_result.failed
103 changes: 38 additions & 65 deletions windows/utils/win_install_online_updates.yml
Original file line number Diff line number Diff line change
@@ -1,82 +1,55 @@
# Copyright 2023-2024 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Search and install Windows Updates in specified categories,
# and skip optional ones in Windows guest OS.
# Parameter:
# win_updates_category_names(optional): A list of categories to install updates from.
# Some possible categories are: Application, Connectors, Critical Updates, Definition Updates, Developer Kits,
# Feature Packs, Guidance, Security Updates, Service Packs, Tools, Update Rollups, Updates, and Upgrades.
# Default value is *. The value * will match all categories
# win_updates_reject_list(optional): A list of update titles or KB numbers that can be used to specify
# which updates are to be excluded from installation.
# win_updates_ignore_errors: Ignore errors when checking and installing Windows Updates. Default is false.
# Install Windows online updates in specified categories, skip optional
# ones or in a reject list in Windows guest OS.
# Parameters:
# win_updates_categories (optional): A list of categories to install updates from.
# Some possible categories are: Application, Connectors, Critical Updates,
# Definition Updates, Developer Kits, Feature Packs, Guidance, Security Updates,
# Service Packs, Tools, Update Rollups, Updates and Upgrades.
# Default value is '*', which matches all categories.
# win_updates_reject_list (optional): A list of update titles or KB numbers that
# can be used to specify which updates are to be excluded from installation.
# win_updates_ignore_errors (optional): Whether to ignore errors when installing
# Windows updates. Default is false.
# win_updates_log_file (optional): The log file path for Windows Update in guest OS.
# Default is 'C:\win_updates_log.txt'.
# Return:
# win_updates_log_file: Windows Updates install log file path.
# win_online_updates_succeed: Windows Updates install result indicator.
# win_online_updates_installed: Indicates if there are Windows online updates
# installed and the installed count is the same as the found count.
#
- name: "Set fact of Windows Updates install log path and initialize online update status"
- name: "Set fact and initialize Windows online updates install parameters"
ansible.builtin.set_fact:
win_updates_log_file: "C:\\win_updates_log.txt"
win_online_updates_succeed: false
win_updates_log_file: "{{ win_updates_log_file | default('C:\\win_updates_log.txt') }}"
win_online_updates_installed: false

- name: "Get the list of available Windows Updates"
- name: "Install Windows online updates"
ansible.windows.win_updates:
server_selection: "windows_update"
category_names: "{{ win_updates_category_names | default('*') }}"
category_names: "{{ win_updates_categories | default('*') }}"
reject_list: "{{ win_updates_reject_list | default('') }}"
log_path: "{{ win_updates_log_file }}"
skip_optional: true
state: "searched"
state: "installed"
reboot: true
reboot_timeout: 2700
delegate_to: "{{ vm_guest_ip }}"
register: win_updates_list
register: win_updates_install_result
ignore_errors: "{{ win_updates_ignore_errors | default(false) }}"
- name: "Print the list of Windows Updates"
ansible.builtin.debug: var=win_updates_list

- name: "Install Windows Updates when updates found"
when:
- win_updates_list.failed is defined
- not win_updates_list.failed
- win_updates_list.found_update_count is defined
- win_updates_list.found_update_count | int != 0
- win_updates_list.updates is defined
- win_updates_list.updates | length != 0
block:
- name: "Install Windows Updates"
ansible.windows.win_updates:
server_selection: "windows_update"
category_names: "{{ win_updates_category_names | default('*') }}"
reject_list: "{{ win_updates_reject_list | default('') }}"
log_path: "{{ win_updates_log_file }}"
skip_optional: true
state: "installed"
reboot: true
reboot_timeout: 2700
delegate_to: "{{ vm_guest_ip }}"
register: win_updates_install_result
ignore_errors: "{{ win_updates_ignore_errors | default(false) }}"
- name: "Print Windows Updates install result"
debug: var=win_updates_install_result

- name: "No need to install Windows Updates"
ansible.builtin.debug:
msg: "Will not execute Windows Updates installation task due to no update found or search failed."
when: >
(win_updates_list.found_update_count is undefined) or
(win_updates_list.found_update_count | int == 0)
- name: "Print Windows online updates install result"
debug: var=win_updates_install_result
when: enable_debug

- name: "Set Windows Updates installation status"
- name: "Set fact of Windows online updates install status"
ansible.builtin.set_fact:
win_online_updates_succeed: |-
{%- if win_updates_list.failed is defined and not win_updates_list.failed and
win_updates_list.found_update_count | int == 0 -%}
true
{%- elif win_updates_install_result is defined and win_updates_install_result.installed_update_count is defined and
win_updates_install_result.found_update_count | int == win_updates_install_result.installed_update_count | int -%}
true
{%- else -%}
false
{%- endif -%}
win_online_updates_installed: true
when:
- win_updates_install_result.found_update_count is defined
- win_updates_install_result.found_update_count | int != 0
Tomorrow9 marked this conversation as resolved.
Show resolved Hide resolved
- win_updates_install_result.installed_update_count is defined
- win_updates_install_result.found_update_count | int == win_updates_install_result.installed_update_count | int

- name: "Display Windows Updates installation status"
ansible.builtin.debug: var=win_online_updates_succeed
- name: "Display Windows online updates install status"
ansible.builtin.debug: var=win_online_updates_installed
53 changes: 53 additions & 0 deletions windows/utils/win_pause_resume_win_update.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copyright 2024 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Disable Windows auto update and pause Windows Update 7 days,
# or delete this pauing Windows Update config in registry to
# resume Windows Update.
# Paramters:
# win_update_ops: valid values are 'pause' or 'resume'.
#
- name: "Check required parameter"
ansible.builtin.assert:
that:
- win_update_ops is defined
- win_update_ops in ['pause', 'resume']
fail_msg: >-
Parameter 'win_update_ops': {{ win_update_ops | default('') }} is not set correctly,
valid value is 'pause' or 'resume'.

- name: "Set fact of the PowerShell script name"
ansible.builtin.set_fact:
win_update_script: "{{ win_update_ops }}_windows_update.ps1"

- name: "Set fact of the PowerShell script local and remote paths"
ansible.builtin.set_fact:
local_ps_file: "scripts/{{ win_update_script }}"
remote_ps_file: "C:\\{{ win_update_script }}"

- name: "Copy PowerShell script from local to guest OS"
include_tasks: win_copy_file_from_local.yml
vars:
src_path_local: "{{ local_ps_file }}"
dest_path_remote: "C:\\"

- name: "Get PowerShell script existence state in guest OS"
include_tasks: win_check_file_exist.yml
vars:
win_check_file_exist_file: "{{ remote_ps_file }}"
Tomorrow9 marked this conversation as resolved.
Show resolved Hide resolved
- name: "Make sure PowerShell script exists in guest OS"
ansible.builtin.assert:
that:
- win_check_file_exist_result is defined
- win_check_file_exist_result | bool
fail_msg: "PowerShell script is not found in guest OS in this path: {{ remote_ps_file }}"

# Pause Windows Update is not a demand task, so ignore errors
- name: "Execute {{ win_update_ops }} Windows Update PowerShell script in guest OS"
ansible.windows.win_command: "powershell.exe -ExecutionPolicy bypass -File {{ remote_ps_file }}"
delegate_to: "{{ vm_guest_ip }}"
ignore_errors: "{{ win_update_ops == 'pause' }}"
register: win_update_ops_result
- name: "Display the PowerShell script execute result"
ansible.builtin.debug: var=win_update_ops_result
when: enable_debug
36 changes: 0 additions & 36 deletions windows/utils/win_pause_windows_update.yml

This file was deleted.

Loading