comparison contrib/automation/hgautomation/aws.py @ 49402:f1dcddb7f328 stable

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
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 04 Jun 2022 11:18:32 -0700
parents 5c8148cd7f13
children 3e84e001b6c1
comparison
equal deleted inserted replaced
49401:ef40864bc074 49402:f1dcddb7f328
57 DEBIAN_ACCOUNT_ID = '379101102735' 57 DEBIAN_ACCOUNT_ID = '379101102735'
58 DEBIAN_ACCOUNT_ID_2 = '136693071363' 58 DEBIAN_ACCOUNT_ID_2 = '136693071363'
59 UBUNTU_ACCOUNT_ID = '099720109477' 59 UBUNTU_ACCOUNT_ID = '099720109477'
60 60
61 61
62 WINDOWS_BASE_IMAGE_NAME = 'Windows_Server-2019-English-Full-Base-*' 62 WINDOWS_BASE_IMAGE_NAME = 'Windows_Server-2022-English-Full-Base-*'
63 63
64 64
65 KEY_PAIRS = { 65 KEY_PAIRS = {
66 'automation', 66 'automation',
67 } 67 }
172 172
173 # Set administrator password 173 # Set administrator password
174 net user Administrator "%s" 174 net user Administrator "%s"
175 wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE 175 wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
176 176
177 # And set it via EC2Launch so it persists across reboots.
178 $config = & $env:ProgramFiles\Amazon\EC2Launch\EC2Launch.exe get-agent-config --format json | ConvertFrom-Json
179 $config | ConvertTo-Json -Depth 6 | Out-File -encoding UTF8 $env:ProgramData/Amazon/EC2Launch/config/agent-config.yml
180 $setAdminAccount = @"
181 {
182 "task": "setAdminAccount",
183 "inputs": {
184 "password": {
185 "type": "static",
186 "data": "%s"
187 }
188 }
189 }
190 "@
191 $config.config | %%{if($_.stage -eq 'preReady'){$_.tasks += (ConvertFrom-Json -InputObject $setAdminAccount)}}
192 $config | ConvertTo-Json -Depth 6 | Out-File -encoding UTF8 $env:ProgramData/Amazon/EC2Launch/config/agent-config.yml
193
177 # First, make sure WinRM can't be connected to 194 # First, make sure WinRM can't be connected to
178 netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block 195 netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block
179 196
180 # Delete any existing WinRM listeners 197 # Delete any existing WinRM listeners
181 winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null 198 winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null
750 'Tags': [{'Key': 'Name', 'Value': 'hg-temp-windows'}], 767 'Tags': [{'Key': 'Name', 'Value': 'hg-temp-windows'}],
751 } 768 }
752 ) 769 )
753 770
754 if bootstrap: 771 if bootstrap:
755 config['UserData'] = WINDOWS_USER_DATA % password 772 config['UserData'] = WINDOWS_USER_DATA % (password, password)
756 773
757 with temporary_ec2_instances(c.ec2resource, config) as instances: 774 with temporary_ec2_instances(c.ec2resource, config) as instances:
758 wait_for_ip_addresses(instances) 775 wait_for_ip_addresses(instances)
759 776
760 print('waiting for Windows Remote Management service...') 777 print('waiting for Windows Remote Management service...')
1171 ] 1188 ]
1172 1189
1173 with INSTALL_WINDOWS_DEPENDENCIES.open('r', encoding='utf-8') as fh: 1190 with INSTALL_WINDOWS_DEPENDENCIES.open('r', encoding='utf-8') as fh:
1174 commands.extend(l.rstrip() for l in fh) 1191 commands.extend(l.rstrip() for l in fh)
1175 1192
1176 # Schedule run of EC2Launch on next boot. This ensures that UserData
1177 # is executed.
1178 # We disable setComputerName because it forces a reboot.
1179 # We set an explicit admin password because this causes UserData to run
1180 # as Administrator instead of System.
1181 commands.extend(
1182 [
1183 r'''Set-Content -Path C:\ProgramData\Amazon\EC2-Windows\Launch\Config\LaunchConfig.json '''
1184 r'''-Value '{"setComputerName": false, "setWallpaper": true, "addDnsSuffixList": true, '''
1185 r'''"extendBootVolumeSize": true, "handleUserData": true, '''
1186 r'''"adminPasswordType": "Specify", "adminPassword": "%s"}' '''
1187 % c.automation.default_password(),
1188 r'C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 '
1189 r'–Schedule',
1190 ]
1191 )
1192
1193 # Disable Windows Defender when bootstrapping because it just slows 1193 # Disable Windows Defender when bootstrapping because it just slows
1194 # things down. 1194 # things down.
1195 commands.insert(0, 'Set-MpPreference -DisableRealtimeMonitoring $true') 1195 commands.insert(0, 'Set-MpPreference -DisableRealtimeMonitoring $true')
1196 commands.append('Set-MpPreference -DisableRealtimeMonitoring $false') 1196 commands.append('Set-MpPreference -DisableRealtimeMonitoring $false')
1197
1198 # Trigger shutdown to prepare for imaging.
1199 commands.append(
1200 'Stop-Computer -ComputerName localhost',
1201 )
1197 1202
1198 # Compute a deterministic fingerprint to determine whether image needs 1203 # Compute a deterministic fingerprint to determine whether image needs
1199 # to be regenerated. 1204 # to be regenerated.
1200 fingerprint = resolve_fingerprint( 1205 fingerprint = resolve_fingerprint(
1201 { 1206 {