golang.org/x/build@v0.0.0-20240506185731-218518f32b70/env/windows-arm64/azure/startup.ps1 (about) 1 # Copyright 2022 The Go Authors. All rights reserved. 2 # Use of this source code is governed by a BSD-style 3 # license that can be found in the LICENSE file. 4 5 Set-StrictMode -Version Latest 6 7 # Helpers 8 function Test-RegistryKeyExists($path, $name) 9 { 10 $key = Get-Item -LiteralPath $path -ErrorAction SilentlyContinue 11 ($key -and $null -ne $key.GetValue($name, $null)) -ne $false 12 } 13 14 function Get-FileFromUrl( 15 [string] $URL, 16 [string] $Output) 17 { 18 Add-Type -AssemblyName "System.Net.Http" 19 20 $client = New-Object System.Net.Http.HttpClient 21 $request = New-Object System.Net.Http.HttpRequestMessage -ArgumentList @([System.Net.Http.HttpMethod]::Get, $URL) 22 $responseMsg = $client.SendAsync($request) 23 $responseMsg.Wait() 24 25 if (!$responseMsg.IsCanceled) 26 { 27 $response = $responseMsg.Result 28 if ($response.IsSuccessStatusCode) 29 { 30 $downloadedFileStream = [System.IO.File]::Create($Output) 31 $copyStreamOp = $response.Content.CopyToAsync($downloadedFileStream) 32 $copyStreamOp.Wait() 33 $downloadedFileStream.Close() 34 if ($copyStreamOp.Exception -ne $null) 35 { 36 throw $copyStreamOp.Exception 37 } 38 } 39 } 40 } 41 42 # https://social.technet.microsoft.com/Forums/ie/en-US/29508e4e-a2b5-42eb-9729-6eca473716ae/disabling-password-complexity-via-command?forum=ITCG 43 function Disable-PasswordComplexity 44 { 45 param() 46 47 $secEditPath = [System.Environment]::ExpandEnvironmentVariables("%SystemRoot%\system32\secedit.exe") 48 $tempFile = [System.IO.Path]::GetTempFileName() 49 50 $exportArguments = '/export /cfg "{0}" /quiet' -f $tempFile 51 $importArguments = '/configure /db secedit.sdb /cfg "{0}" /quiet' -f $tempFile 52 53 Start-Process -FilePath $secEditPath -ArgumentList $exportArguments -Wait 54 55 $currentConfig = Get-Content -Path $tempFile 56 57 $currentConfig = $currentConfig -replace 'PasswordComplexity = .', 'PasswordComplexity = 0' 58 $currentConfig = $currentConfig -replace 'MinimumPasswordLength = .', 'MinimumPasswordLength = 0' 59 $currentConfig | Out-File -FilePath $tempFile 60 61 Start-Process -FilePath $secEditPath -ArgumentList $importArguments -Wait 62 63 Remove-Item -Path .\secedit.sdb 64 Remove-Item -Path $tempFile 65 } 66 67 function Add-Path($Path) { 68 $Path = [Environment]::GetEnvironmentVariable("PATH") + [IO.Path]::PathSeparator + $Path 69 [Environment]::SetEnvironmentVariable( "PATH", $Path ) 70 } 71 72 # Wait till network comes up 73 while(-Not (Test-NetConnection 8.8.8.8 -Port 53 | ? { $_.TcpTestSucceeded })) { 74 Write-Host "waiting for network (external network) to come up" 75 sleep 3 76 } 77 78 # Disable password complexity, automatic updates, windows firewall, error reporting, and UAC 79 # 80 # - Update can interrupt the builds 81 # - We don't care about security since this isn't going to be Internet-facing 82 # - No ports will ever be accessible externally 83 # - We can be trusted to run as a real Administrator 84 Write-Host "disabling security features" 85 New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate" 86 New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" 87 New-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU" -Name NoAutoUpdate -Value 1 -Force | Out-Null 88 New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" -Name Disabled -Value 1 -Force | Out-Null 89 New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting" -Name DontShowUI -Value 1 -Force | Out-Null 90 New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system" -Name EnableLUA -PropertyType DWord -Value 0 -Force | Out-Null 91 netsh advfirewall set allprofiles state off 92 netsh firewall set opmode mode=disable profile=ALL 93 Set-MpPreference -DisableRealtimeMonitoring $true 94 95 # Disable unwanted services 96 Write-Host "disabling unused services" 97 Set-Service -Name 'NlaSvc' -StartupType 'Disabled' 98 Set-Service -Name 'LanmanServer' -StartupType 'Disabled' 99 Set-Service -Name 'BITS' -StartupType 'Disabled' 100 Set-Service -Name 'DPS' -StartupType 'Disabled' 101 Set-Service -Name 'MSDTC' -StartupType 'Disabled' 102 Set-Service -Name 'IKEEXT' -StartupType 'Disabled' 103 Set-Service -Name 'RemoteRegistry' -StartupType 'Disabled' 104 Set-Service -Name 'lmhosts' -StartupType 'Disabled' 105 Set-Service -Name 'WSearch' -StartupType 'Disabled' 106 Stop-Service -Name 'WSearch' 107 108 $builder_dir = "C:\golang" 109 mkdir $builder_dir 110 111 # Download bootstrapswarm.exe 112 $bootstrapswarm_exe_path = "$builder_dir\bootstrapswarm.exe" 113 Write-Host "downloading bootstrapswarm to $bootstrapswarm_exe_path" 114 Get-FileFromUrl -URL 'https://storage.googleapis.com/go-builder-data/windows-arm64-bootstrapswarm.exe' -Output $bootstrapswarm_exe_path 115 dir $bootstrapswarm_exe_path 116 117 # Download luci_machine_tokend.exe 118 $tokend_exe_path = "$builder_dir\luci_machine_tokend.exe" 119 Write-Host "downloading luci_machine_tokend to $tokend_exe_path" 120 Get-FileFromUrl -URL 'https://storage.googleapis.com/go-builder-data/windows-arm64-luci_machine_tokend.exe' -Output $tokend_exe_path 121 dir $tokend_exe_path 122 123 # Install the OpenSSH Client 124 Add-WindowsCapability -Online -Name OpenSSH.Client 125 # Install the OpenSSH Server 126 Add-WindowsCapability -Online -Name OpenSSH.Server 127 128 Start-Service sshd 129 # OPTIONAL but recommended: 130 Set-Service -Name sshd -StartupType 'Automatic' 131 132 # Note: in previous versions of this script, we would download and install 133 # C/C++ compilers (https://storage.googleapis.com/go-builder-data/llvm-mingw-20220323-ucrt-aarch64.tar.gz), however in the LUCI case, compilers will be 134 # installed on the fly via CIPD. 135 136 # Download and install Visual Studio Build Tools (MSVC) 137 # https://docs.microsoft.com/en-us/visualstudio/install/build-tools-container 138 Write-Host "downloading Visual Studio Build Tools" 139 $vs_buildtools = "$builder_dir\vs_buildtools.exe" 140 Get-FileFromUrl -URL "https://aka.ms/vs/16/release/vs_buildtools.exe" -Output "$vs_buildtools" 141 142 Write-Host "installing Visual Studio Build Tools" 143 $dep_dir = "C:\godep" 144 mkdir $dep_dir 145 & $vs_buildtools --quiet --wait --norestart --nocache --installPath "$dep_dir\vs" --all --add Microsoft.VisualStudio.Component.VC.Tools.ARM64 --add Microsoft.VisualStudio.Component.VC.Tools.ARM 146 147 # Download and install the root certificate used for crypto/x509 testing 148 Write-Host "downloading crypto/x509 test root" 149 $test_root = "$builder_dir\test_root.pem" 150 Get-FileFromUrl -URL "https://storage.googleapis.com/go-builder-data/platform_root_cert.pem" -Output "$test_root" 151 152 Write-Host "installing crypto/x509 test root" 153 Import-Certificate -FilePath "$test_root" -CertStoreLocation "Cert:\LocalMachine\Root" 154 155 # Install chocolatey, so as to install python via choco (preferred since 156 # it makes python available for all users). 157 Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) 158 159 # Install python 160 choco install python -y --version=3.11.3 161 162 # We need this module as well. Python dirs are not yet in our path, so 163 # insert them before this call. 164 Add-Path C:\Python311 165 Add-Path C:\Python311\Scripts 166 pip install pywin32 167 168 # "bootstrapswarm" requires that "python3" be on the path, not just "python", 169 # and annoyingly, choco only installed python.exe. Create a symbolic link 170 # by hand. 171 $here = Get-Location 172 Set-Location C:\Python311 173 New-Item -ItemType SymbolicLink -Path "python3.exe" -Target "python.exe" 174 Set-Location $here 175 176 # Create a tokend user (needs to be distinct from the swarming user). 177 Write-Host "creating tokend user" 178 $tokend_user = "tokend" 179 $tokend_password = "tokend" 180 net user $tokend_user $tokend_password /ADD 181 net localgroup administrators $tokend_user /ADD 182 Set-LocalUser -Name $tokend_user -PasswordNeverExpires $true 183 184 # Create swarming user 185 Write-Host "creating swarming user" 186 $swarming_user = "swarming" 187 $swarming_password = "swarming" 188 net user $swarming_user $swarming_password /ADD 189 net localgroup administrators $swarming_user /ADD 190 Set-LocalUser -Name $swarming_user -PasswordNeverExpires $true 191 192 # We need a swarming work directory in C:\b -- create that dir and 193 # make it owned by swarming. 194 $swarming_workdir = "C:\b" 195 mkdir $swarming_workdir 196 icacls $swarming_workdir /setowner swarming 197 198 # Download LUCI bot cert and place in proper location 199 $cert_dir = "C:\tokend" 200 mkdir $cert_dir 201 $cert_file = "$cert_dir\windows-arm64-azure-cert.txt" 202 Write-Host "downloading LUCI bot cert to $cert_file" 203 Get-FileFromUrl -URL "https://storage.googleapis.com/go-builder-data/windows-arm64-azure-1702406379-cert.txt" -Output "$cert_file" 204 dir $cert_file 205 206 # Note: the private key will live in C:\tokend\windows-arm64-azure-key.txt, 207 # however we'll distribute that to the builder in a separate step. 208 209 # Update ACLs on the cert/key to make them owned and readable only 210 # by tokend. [NB: many unsuccessful attempts at doing this in powershell, 211 # down down into cmd instead]. 212 icacls $cert_file /setowner tokend 213 icacls $cert_file /deny swarming:r 214 215 # Set GO_BUILDER_NAME environment variable. 216 [Environment]::SetEnvironmentVariable('GO_BUILDER_NAME', 'windows-arm64-azure', [System.EnvironmentVariableTarget]::Machine) 217 218 # Tell the swarming bot not to reboot this machine. This appears to be 219 # needed to avoid having to re-disable anti-tamper security measures. 220 [Environment]::SetEnvironmentVariable('SWARMING_NEVER_REBOOT', 'true', [System.EnvironmentVariableTarget]::Machine) 221 222 # Path to the token.json file. Written by tokend, read by swarming. 223 $token_file = "$builder_dir\token.json" 224 225 # Set LUCI_MACHINE_TOKEN environment variable. 226 [Environment]::SetEnvironmentVariable('LUCI_MACHINE_TOKEN', "$token_file", [System.EnvironmentVariableTarget]::Machine) 227 228 # Create a tiny bat file that invokes tokend. This is mainly to 229 # avoid quoting problems when creating our scheduled task below, but 230 # also to log the date/time of the run for debugging purposes. 231 # *Important*: request ASCII content; without this we get UTF-16, 232 # which (ironically) can't be digested by windows 'cmd'. 233 $run_tokend_batfile = "$builder_dir\runtokend.bat" 234 $key_file = "$cert_dir\windows-arm64-azure-key.txt" 235 $cmd = "$tokend_exe_path -backend luci-token-server.appspot.com -cert-pem $cert_file -pkey-pem $key_file -token-file=$token_file" 236 $cmd | Out-File -Encoding ascii $run_tokend_batfile 237 Add-Content -Encoding ascii -Path $run_tokend_batfile -Value "echo %date% %time% >> $cert_dir\lastrun.txt" 238 239 # Create a scheduled task to run 'luci_machine_tokend.exe' every 10 240 # minutes to regenerate token.json. Note that this scheduled task 241 # has to be run even when user "tokend" is not logged in, which requires 242 # a bit of extra work (via -LogonType option to New-ScheduledTaskPrincipal). 243 $task_action = New-ScheduledTaskAction -Execute $run_tokend_batfile 244 $task_trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Minutes 10) 245 $task_settings = New-ScheduledTaskSettingsSet -MultipleInstances Parallel 246 $principal = New-ScheduledTaskPrincipal -LogonType ServiceAccount -UserID "NT AUTHORITY\SYSTEM" -RunLevel Highest 247 $task = New-ScheduledTask -Action $task_action -Trigger $task_trigger -Settings $task_settings -Principal $principal 248 Register-ScheduledTask -TaskName 'Token Generator' -InputObject $task 249 250 # Run the swarming loop script on login 251 Write-Host "setting bootstrapswarm to run on start" 252 $bootstrap_cmd = "cmd /k $builder_dir\windows-arm64-bootstrapswarm-loop.bat" 253 New-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "Swarming" -PropertyType ExpandString -Value "$bootstrap_cmd" -Force 254 255 # Setup autologon and reboot 256 $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" 257 if ((Test-RegistryKeyExists $RegPath "DefaultUsername") -eq $false) { 258 Write-Host "configuring auto login" 259 Remove-ItemProperty -Path 'HKLM:SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name 'AutoLogonCount' -Force | Out-Null 260 Set-ItemProperty $RegPath "AutoAdminLogon" -Value "1" -type String 261 Set-ItemProperty $RegPath "DefaultUsername" -Value "$swarming_user" -type String 262 Set-ItemProperty $RegPath "DefaultPassword" -Value "$swarming_password" -type String 263 Set-ItemProperty $RegPath "LogonCount" -Value "99999999" -type String 264 Write-Host "rebooting" 265 shutdown /r /t 0 266 }