env/windows-arm64/azure: add stage zero loop script

Add a wrapper script that loops forever executing the boostrap stage0
buildlet executable (needed for proper reverse builder functionality)
Update startup script to download script during setup and run at login.

Updates golang/go#57408.

Change-Id: Ie77c37462a32ae259e443f2dc9996ab11a631082
Reviewed-on: https://go-review.googlesource.com/c/build/+/461097
Reviewed-by: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
diff --git a/env/windows-arm64/azure/README.md b/env/windows-arm64/azure/README.md
index f72e245..ca96e0f 100644
--- a/env/windows-arm64/azure/README.md
+++ b/env/windows-arm64/azure/README.md
@@ -24,7 +24,7 @@
 
 ## VM strategy for Azure
 
-At the moment, windows-arm64 Azure VMs are configured as reverse builders, and they are set up with no public IP address and no exposed ports. To interact with the VMs directly (e.g. to log in and poke around) it is recommended to use the Azure "bastion" feature, which provides RDP-like access to VMs from within the portal.
+At the moment, windows-arm64 Azure VMs are configured as reverse builders, and they are set up with no public IP address and no exposed ports. To interact with the VMs directly (e.g. to log in and poke around) it is recommended to use the Azure "bastion" feature, which provides RDP-like access to VMs from within the portal.  If you need to log in, use the account "gopheradmin" (password in Valentine). You can also run PowerShell scripts on the deployed VMs via "az vm run-command invoke --command-id=RunPowerShellScript ... --scripts @scriptpath" to perform upkeep operations.
 
 ## Deployment VM creation
 
diff --git a/env/windows-arm64/azure/startup.ps1 b/env/windows-arm64/azure/startup.ps1
index 2726812..b28c7bc 100644
--- a/env/windows-arm64/azure/startup.ps1
+++ b/env/windows-arm64/azure/startup.ps1
@@ -105,6 +105,11 @@
 mkdir $builder_dir
 Get-FileFromUrl -URL 'https://storage.googleapis.com/go-builder-data/buildlet-stage0.windows-arm64' -Output $bootstrap_exe_path
 
+# Download stage zero loop script.
+Write-Host "downloading loop script"
+$loop_script_path = "$builder_dir\windows-arm64-stage0-loop.bat"
+Get-FileFromUrl -URL 'https://storage.googleapis.com/go-builder-data/windows-arm64-stage0-loop.bat' -Output $loop_script_path
+
 # Install the OpenSSH Client
 Add-WindowsCapability -Online -Name OpenSSH.Client
 # Install the OpenSSH Server
@@ -149,9 +154,9 @@
 # this setting needs to persist across reboots.
 [Environment]::SetEnvironmentVariable('GO_BUILDER_ENV', 'host-windows11-arm64-azure', [System.EnvironmentVariableTarget]::Machine)
 
-# Run the bootstrap program on login
+# Run the bootstrap loop script on login
 Write-Host "setting stage0 to run on start"
-$bootstrap_cmd = "cmd /k ""cd $builder_dir && $bootstrap_exe_path"""
+$bootstrap_cmd = "cmd /k ""cd $builder_dir && windows-arm64-stage0-loop.bat"""
 New-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "Buildlet" -PropertyType ExpandString -Value $bootstrap_cmd -Force
 
 # Setup autologon and reboot
diff --git a/env/windows-arm64/azure/windows-arm64-stage0-loop.bat b/env/windows-arm64/azure/windows-arm64-stage0-loop.bat
new file mode 100644
index 0000000..2bd4595
--- /dev/null
+++ b/env/windows-arm64/azure/windows-arm64-stage0-loop.bat
@@ -0,0 +1,13 @@
+
+rem This simple script loops forever, invoking the stage0 buildlet.
+rem When stage0 runs, it will download a new copy of the main
+rem buildlet and execute it.
+
+:loop
+
+@echo Invoking bootstrap.exe at %date% %time% on %computername%
+
+C:\golang\bootstrap.exe
+
+goto loop
+