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  }