diff options
Diffstat (limited to 'vcpkg/scripts/azure-pipelines/windows/create-image.ps1')
| -rw-r--r-- | vcpkg/scripts/azure-pipelines/windows/create-image.ps1 | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/vcpkg/scripts/azure-pipelines/windows/create-image.ps1 b/vcpkg/scripts/azure-pipelines/windows/create-image.ps1 new file mode 100644 index 0000000..d4e02b2 --- /dev/null +++ b/vcpkg/scripts/azure-pipelines/windows/create-image.ps1 @@ -0,0 +1,287 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: MIT +# + +<# +.SYNOPSIS +Creates a Windows virtual machine image, set up for vcpkg's CI. + +.DESCRIPTION +create-image.ps1 creates an Azure Windows VM image, set up for vcpkg's CI system. + +This script assumes you have installed Azure tools into PowerShell by following the instructions +at https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-3.6.1 +or are running from Azure Cloud Shell. +#> + +$Location = 'westus3' +$DatePrefixComponent = Get-Date -Format 'yyyy-MM-dd' +$Prefix = "Win-$DatePrefixComponent" +$GalleryImageVersion = $DatePrefixComponent.Replace('-','.') +$VMSize = 'Standard_D8ads_v5' +$ProtoVMName = 'PROTOTYPE' +$WindowsServerSku = '2025-datacenter-azure-edition' +$ErrorActionPreference = 'Stop' + +$ProgressActivity = 'Creating Windows Image' +$TotalProgress = 18 +$CurrentProgress = 1 + +# Assigning this to another variable helps when running the commands in this script manually for +# debugging +$Root = $PSScriptRoot + +<# +.SYNOPSIS +Generates a random password. + +.DESCRIPTION +New-Password generates a password, randomly, of length $Length, containing +only alphanumeric characters, underscore, and dash. + +.PARAMETER Length +The length of the returned password. +#> +function New-Password { + Param ([int] $Length = 32) + $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-" + if ($alphabet.Length -ne 64) { + throw 'Bad alphabet length' + } + + $result = New-Object SecureString + for ($idx = 0; $idx -lt $Length; $idx++) { + $result.AppendChar($alphabet[(Get-SecureRandom -Maximum $alphabet.Length)]) + } + + return $result +} + +<# +.SYNOPSIS +Waits for the shutdown of the specified resource. + +.DESCRIPTION +Wait-Shutdown takes a VM, and checks if there's a 'PowerState/stopped' +code; if there is, it returns. If there isn't, it waits ten seconds and +tries again. + +.PARAMETER ResourceGroupName +The name of the resource group to look up the VM in. + +.PARAMETER Name +The name of the virtual machine to wait on. +#> +function Wait-Shutdown { + [CmdletBinding()] + Param([string]$ResourceGroupName, [string]$Name) + + Write-Host "Waiting for $Name to stop..." + while ($true) { + $Vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $Name -Status + $highestStatus = $Vm.Statuses.Count + for ($idx = 0; $idx -lt $highestStatus; $idx++) { + if ($Vm.Statuses[$idx].Code -eq 'PowerState/stopped') { + return + } + } + + Write-Host "... not stopped yet, sleeping for 10 seconds" + Start-Sleep -Seconds 10 + } +} + + +$AdminPW = New-Password +$Credential = New-Object System.Management.Automation.PSCredential ("AdminUser", $AdminPW) + +$VirtualNetwork = Get-AzVirtualNetwork -ResourceGroupName 'vcpkg-image-minting' -Name 'vcpkg-image-minting-wus3' +$Subnet = $VirtualNetwork.Subnets | Where-Object -Property 'Name' -EQ -Value 'image-minting' | Select-Object -First 1 + +#################################################################################################### +Write-Progress ` + -Activity $ProgressActivity ` + -Status 'Creating prototype VM' ` + -PercentComplete (100 / $TotalProgress * $CurrentProgress++) + +$NicName = $Prefix + 'NIC' +$Nic = New-AzNetworkInterface ` + -Name $NicName ` + -ResourceGroupName 'vcpkg-image-minting' ` + -Location $Location ` + -Subnet $Subnet ` + -EnableAcceleratedNetworking + +$VM = New-AzVMConfig -Name $ProtoVMName -VMSize $VMSize -SecurityType TrustedLaunch -IdentityType SystemAssigned +$VM = Set-AzVMOperatingSystem ` + -VM $VM ` + -Windows ` + -ComputerName $ProtoVMName ` + -Credential $Credential ` + -ProvisionVMAgent + +$VM = Add-AzVMNetworkInterface -VM $VM -Id $Nic.Id +$VM = Set-AzVMOSDisk -VM $VM -StorageAccountType 'Premium_LRS' -CreateOption 'FromImage' +$VM = Set-AzVMSourceImage ` + -VM $VM ` + -PublisherName 'MicrosoftWindowsServer' ` + -Offer 'WindowsServer' ` + -Skus $WindowsServerSku ` + -Version latest + +$VM = Set-AzVMBootDiagnostic -VM $VM -Disable +New-AzVm ` + -ResourceGroupName 'vcpkg-image-minting' ` + -Location $Location ` + -VM $VM + +$VMCreated = Get-AzVM -ResourceGroupName 'vcpkg-image-minting' -Name $ProtoVMName +$VMCreatedOsDisk = $VMCreated.StorageProfile.OsDisk.Name + +#################################################################################################### +Write-Progress ` + -Activity $ProgressActivity ` + -Status 'Minting token for vcpkg-image-minting storage account' ` + -PercentComplete (100 / $TotalProgress * $CurrentProgress++) + +$VcpkgImageMintingAccount = Get-AzStorageAccount -ResourceGroupName 'vcpkg-image-minting' -Name 'vcpkgimageminting' + +$AssetStorageContext = New-AzStorageContext -StorageAccountName 'vcpkgimageminting' -UseConnectedAccount +$StartTime = Get-Date +$ExpiryTime = $StartTime.AddHours(4) +$AssetsSas = New-AzStorageContainerSASToken -Name 'assets' -Permission r -StartTime $StartTime -ExpiryTime $ExpiryTime -Context $AssetStorageContext + +#################################################################################################### +function Invoke-ScriptWithPrefix { + param( + [string]$ScriptName, + [switch]$SkipSas + ) + + Write-Progress ` + -Activity $ProgressActivity ` + -Status "Running provisioning script $ScriptName in VM" ` + -PercentComplete (100 / $TotalProgress * $CurrentProgress++) + + $UtilityPrefixContent = Get-Content "$Root\utility-prefix.ps1" -Encoding utf8NoBOM -Raw + + $tempScriptFilename = "$env:TEMP\temp-script.txt" + try { + $script = Get-Content "$Root\$ScriptName" -Encoding utf8NoBOM -Raw +$replacement = @" +if (Test-Path "`$PSScriptRoot/utility-prefix.ps1") { + . "`$PSScriptRoot/utility-prefix.ps1" +} +"@ + $script = $script.Replace($replacement, $UtilityPrefixContent); + Set-Content -Path $tempScriptFilename -Value $script -Encoding utf8NoBOM + + $parameter = $null + if (-not $SkipSas) { + $parameter = @{SasToken = "`"$AssetsSas`"";} + } + + $InvokeResult = Invoke-AzVMRunCommand ` + -ResourceGroupName 'vcpkg-image-minting' ` + -VMName $ProtoVMName ` + -CommandId 'RunPowerShellScript' ` + -ScriptPath $tempScriptFilename ` + -Parameter $parameter + + Write-Host "$ScriptName output: $($InvokeResult.value.Message)" + } finally { + Remove-Item $tempScriptFilename -Force + } +} + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-tlssettings.ps1' -SkipSas +Write-Host 'Waiting 1 minute for VM to reboot...' +Start-Sleep -Seconds 60 + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-visual-studio.ps1' + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-mpi.ps1' + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-cuda.ps1' + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-cudnn.ps1' + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-inteloneapi.ps1' + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-pwsh.ps1' + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-azure-cli.ps1' + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-azcopy.ps1' + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'deploy-settings.txt' -SkipSas +Restart-AzVM -ResourceGroupName 'vcpkg-image-minting' -Name $ProtoVMName + +#################################################################################################### +Invoke-ScriptWithPrefix -ScriptName 'sysprep.ps1' + +#################################################################################################### +Write-Progress ` + -Activity $ProgressActivity ` + -Status 'Waiting for VM to shut down' ` + -PercentComplete (100 / $TotalProgress * $CurrentProgress++) + +Wait-Shutdown -ResourceGroupName 'vcpkg-image-minting' -Name $ProtoVMName + +#################################################################################################### +Write-Progress ` + -Activity $ProgressActivity ` + -Status 'Converting VM to Image' ` + -PercentComplete (100 / $TotalProgress * $CurrentProgress++) + +Stop-AzVM ` + -ResourceGroupName 'vcpkg-image-minting' ` + -Name $ProtoVMName ` + -Force + +Set-AzVM ` + -ResourceGroupName 'vcpkg-image-minting' ` + -Name $ProtoVMName ` + -Generalized + +$westus3Location = @{Name = 'West US 3';} +$westusLocation = @{Name = 'West US';} + +New-AzGalleryImageVersion ` + -ResourceGroupName 'vcpkg-image-minting' ` + -GalleryName 'vcpkg_gallery_wus3' ` + -GalleryImageDefinitionName 'PrWinWus3-TrustedLaunch' ` + -Name $GalleryImageVersion ` + -Location $Location ` + -SourceImageVMId $VMCreated.ID ` + -ReplicaCount 1 ` + -StorageAccountType 'Premium_LRS' ` + -PublishingProfileExcludeFromLatest ` + -TargetRegion @($westus3Location, $westusLocation) + +#################################################################################################### +Write-Progress ` + -Activity $ProgressActivity ` + -Status 'Deleting unused temporary resources' ` + -PercentComplete (100 / $TotalProgress * $CurrentProgress++) + +Remove-AzVM -Id $VMCreated.ID -Force +Remove-AzDisk -ResourceGroupName 'vcpkg-image-minting' -Name $VMCreatedOsDisk -Force +Remove-AzNetworkInterface -ResourceGroupName 'vcpkg-image-minting' -Name $NicName -Force + +#################################################################################################### +Write-Progress -Activity $ProgressActivity -Completed +Write-Host "Generated Image: $GalleryImageVersion" +Write-Host 'Finished!' + +$AdminPW.Dispose() |