automation: transition to Windows Server 2022
Let's keep our Windows build environment modern by upgrading to the
latest OS.
As part of the upgrade, we pick up a migration to EC2Launch Version 2.
This has a different config mechanism. So we need to port how we manage
the administrator password.
As part of migrating to the new YAML/JSON config file mechanism, we move
the code to the powershell script that is run when the instance first
launches. This ensures that the config is retained during the reboot we
perform as part of building the Windows AMI.
The motivation for this is I'm currently unable to build the Windows
2019 AMI due to an issue installing OpenSSH. This _just works_ on
Windows Server 2022. I have no clue what the root cause is. I think
it might have something to do with Microsoft not publishing the files
in the right location.
Differential Revision: https://phab.mercurial-scm.org/D12630
--- a/contrib/automation/hgautomation/aws.py Fri Jun 03 20:25:06 2022 -0700
+++ b/contrib/automation/hgautomation/aws.py Sat Jun 04 11:18:32 2022 -0700
@@ -59,7 +59,7 @@
UBUNTU_ACCOUNT_ID = '099720109477'
-WINDOWS_BASE_IMAGE_NAME = 'Windows_Server-2019-English-Full-Base-*'
+WINDOWS_BASE_IMAGE_NAME = 'Windows_Server-2022-English-Full-Base-*'
KEY_PAIRS = {
@@ -174,6 +174,23 @@
net user Administrator "%s"
wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
+# And set it via EC2Launch so it persists across reboots.
+$config = & $env:ProgramFiles\Amazon\EC2Launch\EC2Launch.exe get-agent-config --format json | ConvertFrom-Json
+$config | ConvertTo-Json -Depth 6 | Out-File -encoding UTF8 $env:ProgramData/Amazon/EC2Launch/config/agent-config.yml
+$setAdminAccount = @"
+{
+ "task": "setAdminAccount",
+ "inputs": {
+ "password": {
+ "type": "static",
+ "data": "%s"
+ }
+ }
+}
+"@
+$config.config | %%{if($_.stage -eq 'preReady'){$_.tasks += (ConvertFrom-Json -InputObject $setAdminAccount)}}
+$config | ConvertTo-Json -Depth 6 | Out-File -encoding UTF8 $env:ProgramData/Amazon/EC2Launch/config/agent-config.yml
+
# First, make sure WinRM can't be connected to
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block
@@ -752,7 +769,7 @@
)
if bootstrap:
- config['UserData'] = WINDOWS_USER_DATA % password
+ config['UserData'] = WINDOWS_USER_DATA % (password, password)
with temporary_ec2_instances(c.ec2resource, config) as instances:
wait_for_ip_addresses(instances)
@@ -1173,28 +1190,16 @@
with INSTALL_WINDOWS_DEPENDENCIES.open('r', encoding='utf-8') as fh:
commands.extend(l.rstrip() for l in fh)
- # Schedule run of EC2Launch on next boot. This ensures that UserData
- # is executed.
- # We disable setComputerName because it forces a reboot.
- # We set an explicit admin password because this causes UserData to run
- # as Administrator instead of System.
- commands.extend(
- [
- r'''Set-Content -Path C:\ProgramData\Amazon\EC2-Windows\Launch\Config\LaunchConfig.json '''
- r'''-Value '{"setComputerName": false, "setWallpaper": true, "addDnsSuffixList": true, '''
- r'''"extendBootVolumeSize": true, "handleUserData": true, '''
- r'''"adminPasswordType": "Specify", "adminPassword": "%s"}' '''
- % c.automation.default_password(),
- r'C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 '
- r'–Schedule',
- ]
- )
-
# Disable Windows Defender when bootstrapping because it just slows
# things down.
commands.insert(0, 'Set-MpPreference -DisableRealtimeMonitoring $true')
commands.append('Set-MpPreference -DisableRealtimeMonitoring $false')
+ # Trigger shutdown to prepare for imaging.
+ commands.append(
+ 'Stop-Computer -ComputerName localhost',
+ )
+
# Compute a deterministic fingerprint to determine whether image needs
# to be regenerated.
fingerprint = resolve_fingerprint(