Fix our Buildkite Windows VMs *once and for all*.
diff --git a/buildkite/setup-windows-manual.ps1 b/buildkite/setup-windows-manual.ps1
index 4036cb0..87ba0c6 100755
--- a/buildkite/setup-windows-manual.ps1
+++ b/buildkite/setup-windows-manual.ps1
@@ -228,16 +228,6 @@
& "${android_sdk_root}\tools\bin\sdkmanager.bat" "platforms;android-27"
& "${android_sdk_root}\tools\bin\sdkmanager.bat" "extras;android;m2repository"
-## Create an unprivileged user that we'll run the Buildkite agent as.
-$buildkite_username = "buildkite"
-Write-Host "Creating ${buildkite_username} user..."
-# The password used here is not relevant for security, as the server is behind a
-# firewall blocking all incoming access and locally we run the CI jobs as that
-# user anyway.
-$buildkite_password = ConvertTo-SecureString "b@1ldk1te" -AsPlainText -Force
-New-LocalUser -Name $buildkite_username -Password $buildkite_password -UserMayNotChangePassword
-$buildkite_credential = New-Object System.Management.Automation.PSCredential $buildkite_username, $buildkite_password
-
## Download and install the Buildkite agent.
Write-Host "Downloading Buildkite agent..."
$buildkite_agent_version = "3.0-beta.39"
@@ -269,30 +259,31 @@
"@
[System.IO.File]::WriteAllLines("${buildkite_agent_root}\hooks\environment.bat", $buildkite_environment_hook)
-Write-Host "Creating Buildkite agent wrapper script..."
-$buildkite_service = @"
-Write-Host "Buildkite agent wrapper starting..."
+## Create an unprivileged user that we'll run the Buildkite agent as.
+# The password used here is not relevant for security, as the server is behind a
+# firewall blocking all incoming access and locally we run the CI jobs as that
+# user anyway.
+Write-Host "Creating Buildkite service user..."
+$buildkite_username = "buildkite"
+$buildkite_password = "Bu1ldk1t3"
+$buildkite_secure_password = ConvertTo-SecureString $buildkite_password -AsPlainText -Force
+New-LocalUser -Name $buildkite_username -Password $buildkite_secure_password -UserMayNotChangePassword
+
+## Create the Buildkite Monitor script.
+Write-Host "Creating Buildkite Monitor script..."
+$buildkite_monitor_script = @"
`$ErrorActionPreference = "Stop"
`$ConfirmPreference = "None"
-
-`$buildkite_agent_root = "${buildkite_agent_root}"
`$buildkite_username = "${buildkite_username}"
-`$buildkite_password = ConvertTo-SecureString "b@1ldk1te" -AsPlainText -Force
-`$buildkite_credential = New-Object System.Management.Automation.PSCredential ``
- `${buildkite_username}, `${buildkite_password}
-function Bazel-Clean {
- Write-Host "Terminating all processes belonging to the `${buildkite_username} user..."
- & taskkill /FI "username eq `${buildkite_username}" /T /F
- Start-Sleep -Seconds 1
+Write-Host "Terminating all processes belonging to the `${buildkite_username} user..."
+& taskkill /FI "username eq `${buildkite_username}" /T /F
+Start-Sleep -Seconds 1
- Write-Host "Recreating fresh temporary directory D:\temp..."
- Remove-Item -Recurse -Force "D:\temp"
- New-Item -Type Directory "D:\temp"
- Add-NTFSAccess -Path "D:\temp" -Account BUILTIN\Users -AccessRights Write
-}
-
-Bazel-Clean
+Write-Host "Recreating fresh temporary directory D:\temp..."
+Remove-Item -Recurse -Force "D:\temp"
+New-Item -Type Directory "D:\temp"
+Add-NTFSAccess -Path "D:\temp" -Account BUILTIN\Users -AccessRights Write
Write-Host "Deleting home directory of the `${buildkite_username} user..."
Get-CimInstance Win32_UserProfile | Where LocalPath -EQ "C:\Users\`${buildkite_username}" | Remove-CimInstance
@@ -301,47 +292,55 @@
}
Write-Host "Starting Buildkite agent as user `${buildkite_username}..."
-Start-Process -FilePath "buildkite-agent.exe" -ArgumentList "start" ``
- -Credential `${buildkite_credential} -WorkingDirectory "C:\buildkite" ``
- -RedirectStandardError "buildkite.err.log" ``
- -RedirectStandardOutput "buildkite.out.log" ``
- -Wait
+& nssm start "buildkite-agent"
-Bazel-Clean
+Write-Host "Waiting for Buildkite agent to exit..."
+While ((Get-Service "buildkite-agent").Status -eq "Running") { Start-Sleep -Seconds 1 }
-Write-Host "buildkite-agent has exited."
+Write-Host "Buildkite agent has exited."
"@
-[System.IO.File]::WriteAllLines("${buildkite_agent_root}\buildkite-service.ps1", $buildkite_service)
+[System.IO.File]::WriteAllLines("${buildkite_agent_root}\buildkite-monitor.ps1", $buildkite_monitor_script)
## Allow the Buildkite agent to store SSH host keys in this folder.
Write-Host "Creating C:\buildkite\.ssh folder..."
New-Item "c:\buildkite\.ssh" -ItemType "directory"
Add-NTFSAccess -Path "c:\buildkite\.ssh" -Account BUILTIN\Users -AccessRights Write
+Write-Host "Creating C:\buildkite\logs folder..."
+New-Item "c:\buildkite\logs" -ItemType "directory"
+Add-NTFSAccess -Path "c:\buildkite\logs" -Account BUILTIN\Users -AccessRights Write
+
## Create a service for the Buildkite agent.
-# Some hints: https://gist.github.com/fdstevex/52da0d7e5892fe2965eae105b8cf3883
-# https://github.com/buildkite/agent/issues/329
-# https://github.com/kohsuke/winsw
-Write-Host "Creating Buildkite agent service..."
-$winsw_url = "https://github.com/kohsuke/winsw/releases/download/winsw-v2.1.2/WinSW.NET4.exe"
-$winsw = "${buildkite_agent_root}\buildkite-service.exe"
-(New-Object Net.WebClient).DownloadFile($winsw_url, $winsw)
-$winsw_config = @"
-<configuration>
- <id>buildkite-service</id>
- <name>Buildkite agent</name>
- <description>The Buildkite CI agent.</description>
- <executable>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</executable>
- <executable>%BASE%\buildkite-service.ps1</executable>
- <startmode>Manual</startmode>
- <onfailure action="restart" delay="10 sec"/>
-</configuration>
-"@
-[System.IO.File]::WriteAllLines("${buildkite_agent_root}\buildkite-service.xml", $winsw_config)
-& $winsw install
+& choco install nssm
+
+Write-Host "Creating Buildkite Monitor service..."
+nssm install "buildkite-monitor" `
+ "c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
+ "c:\buildkite\buildkite-monitor.ps1"
+nssm set "buildkite-monitor" "AppDirectory" "c:\buildkite"
+nssm set "buildkite-monitor" "DisplayName" "Buildkite Monitor"
+nssm set "buildkite-monitor" "Start" "SERVICE_DEMAND_START"
+nssm set "buildkite-monitor" "AppExit" "Default" "Restart"
+nssm set "buildkite-monitor" "AppRestartDelay" "3000"
+nssm set "buildkite-monitor" "AppStdout" "c:\buildkite\logs\buildkite-monitor.log"
+nssm set "buildkite-monitor" "AppStderr" "c:\buildkite\logs\buildkite-monitor.log"
+nssm set "buildkite-monitor" "AppRotateFiles" "1"
+
+Write-Host "Creating Buildkite Agent service..."
+nssm install "buildkite-agent" `
+ "c:\buildkite\buildkite-agent.exe" `
+ "start"
+nssm set "buildkite-agent" "AppDirectory" "c:\buildkite"
+nssm set "buildkite-agent" "DisplayName" "Buildkite Agent"
+nssm set "buildkite-agent" "Start" "SERVICE_DEMAND_START"
+nssm set "buildkite-agent" "ObjectName" ".\${buildkite_username}" "$buildkite_password"
+nssm set "buildkite-agent" "AppExit" "Default" "Exit"
+nssm set "buildkite-agent" "AppStdout" "c:\buildkite\logs\buildkite-agent.log"
+nssm set "buildkite-agent" "AppStderr" "c:\buildkite\logs\buildkite-agent.log"
+nssm set "buildkite-agent" "AppRotateFiles" "1"
Write-Host "All done, adding GCESysprep to RunOnce and rebooting..."
-Set-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "GCESysprep" -Value "C:\Program Files\Google\Compute Engine\sysprep\gcesysprep.bat"
+Set-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "GCESysprep" -Value "c:\Program Files\Google\Compute Engine\sysprep\gcesysprep.bat"
Restart-Computer
'@
diff --git a/buildkite/setup-windows.ps1 b/buildkite/setup-windows.ps1
index 6e0789b..b7ee08f 100755
--- a/buildkite/setup-windows.ps1
+++ b/buildkite/setup-windows.ps1
@@ -227,16 +227,6 @@
& "${android_sdk_root}\tools\bin\sdkmanager.bat" "platforms;android-27"
& "${android_sdk_root}\tools\bin\sdkmanager.bat" "extras;android;m2repository"
-## Create an unprivileged user that we'll run the Buildkite agent as.
-$buildkite_username = "buildkite"
-Write-Host "Creating ${buildkite_username} user..."
-# The password used here is not relevant for security, as the server is behind a
-# firewall blocking all incoming access and locally we run the CI jobs as that
-# user anyway.
-$buildkite_password = ConvertTo-SecureString "b@1ldk1te" -AsPlainText -Force
-New-LocalUser -Name $buildkite_username -Password $buildkite_password -UserMayNotChangePassword
-$buildkite_credential = New-Object System.Management.Automation.PSCredential $buildkite_username, $buildkite_password
-
## Download and install the Buildkite agent.
Write-Host "Downloading Buildkite agent..."
$buildkite_agent_version = "3.0-beta.39"
@@ -268,30 +258,31 @@
"@
[System.IO.File]::WriteAllLines("${buildkite_agent_root}\hooks\environment.bat", $buildkite_environment_hook)
-Write-Host "Creating Buildkite agent wrapper script..."
-$buildkite_service = @"
-Write-Host "Buildkite agent wrapper starting..."
+## Create an unprivileged user that we'll run the Buildkite agent as.
+# The password used here is not relevant for security, as the server is behind a
+# firewall blocking all incoming access and locally we run the CI jobs as that
+# user anyway.
+Write-Host "Creating Buildkite service user..."
+$buildkite_username = "buildkite"
+$buildkite_password = "Bu1ldk1t3"
+$buildkite_secure_password = ConvertTo-SecureString $buildkite_password -AsPlainText -Force
+New-LocalUser -Name $buildkite_username -Password $buildkite_secure_password -UserMayNotChangePassword
+
+## Create the Buildkite Monitor script.
+Write-Host "Creating Buildkite Monitor script..."
+$buildkite_monitor_script = @"
`$ErrorActionPreference = "Stop"
`$ConfirmPreference = "None"
-
-`$buildkite_agent_root = "${buildkite_agent_root}"
`$buildkite_username = "${buildkite_username}"
-`$buildkite_password = ConvertTo-SecureString "b@1ldk1te" -AsPlainText -Force
-`$buildkite_credential = New-Object System.Management.Automation.PSCredential ``
- `${buildkite_username}, `${buildkite_password}
-function Bazel-Clean {
- Write-Host "Terminating all processes belonging to the `${buildkite_username} user..."
- & taskkill /FI "username eq `${buildkite_username}" /T /F
- Start-Sleep -Seconds 1
+Write-Host "Terminating all processes belonging to the `${buildkite_username} user..."
+& taskkill /FI "username eq `${buildkite_username}" /T /F
+Start-Sleep -Seconds 1
- Write-Host "Recreating fresh temporary directory D:\temp..."
- Remove-Item -Recurse -Force "D:\temp"
- New-Item -Type Directory "D:\temp"
- Add-NTFSAccess -Path "D:\temp" -Account BUILTIN\Users -AccessRights Write
-}
-
-Bazel-Clean
+Write-Host "Recreating fresh temporary directory D:\temp..."
+Remove-Item -Recurse -Force "D:\temp"
+New-Item -Type Directory "D:\temp"
+Add-NTFSAccess -Path "D:\temp" -Account BUILTIN\Users -AccessRights Write
Write-Host "Deleting home directory of the `${buildkite_username} user..."
Get-CimInstance Win32_UserProfile | Where LocalPath -EQ "C:\Users\`${buildkite_username}" | Remove-CimInstance
@@ -300,45 +291,57 @@
}
Write-Host "Starting Buildkite agent as user `${buildkite_username}..."
-Start-Process -FilePath "buildkite-agent.exe" -ArgumentList "start" ``
- -Credential `${buildkite_credential} -WorkingDirectory "C:\buildkite" ``
- -RedirectStandardError "buildkite.err.log" ``
- -RedirectStandardOutput "buildkite.out.log" ``
- -Wait
+& nssm start "buildkite-agent"
-Bazel-Clean
+Write-Host "Waiting for Buildkite agent to exit..."
+While ((Get-Service "buildkite-agent").Status -eq "Running") { Start-Sleep -Seconds 1 }
-Write-Host "buildkite-agent has exited."
+Write-Host "Buildkite agent has exited."
"@
-[System.IO.File]::WriteAllLines("${buildkite_agent_root}\buildkite-service.ps1", $buildkite_service)
+[System.IO.File]::WriteAllLines("${buildkite_agent_root}\buildkite-monitor.ps1", $buildkite_monitor_script)
## Allow the Buildkite agent to store SSH host keys in this folder.
Write-Host "Creating C:\buildkite\.ssh folder..."
New-Item "c:\buildkite\.ssh" -ItemType "directory"
Add-NTFSAccess -Path "c:\buildkite\.ssh" -Account BUILTIN\Users -AccessRights Write
+Write-Host "Creating C:\buildkite\logs folder..."
+New-Item "c:\buildkite\logs" -ItemType "directory"
+Add-NTFSAccess -Path "c:\buildkite\logs" -Account BUILTIN\Users -AccessRights Write
+
## Create a service for the Buildkite agent.
-# Some hints: https://gist.github.com/fdstevex/52da0d7e5892fe2965eae105b8cf3883
-# https://github.com/buildkite/agent/issues/329
-# https://github.com/kohsuke/winsw
-Write-Host "Creating Buildkite agent service..."
-$winsw_url = "https://github.com/kohsuke/winsw/releases/download/winsw-v2.1.2/WinSW.NET4.exe"
-$winsw = "${buildkite_agent_root}\buildkite-service.exe"
-(New-Object Net.WebClient).DownloadFile($winsw_url, $winsw)
-$winsw_config = @"
-<configuration>
- <id>buildkite-service</id>
- <name>Buildkite agent</name>
- <description>The Buildkite CI agent.</description>
- <executable>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</executable>
- <executable>%BASE%\buildkite-service.ps1</executable>
- <startmode>Manual</startmode>
- <onfailure action="restart" delay="10 sec"/>
-</configuration>
-"@
-[System.IO.File]::WriteAllLines("${buildkite_agent_root}\buildkite-service.xml", $winsw_config)
-& $winsw install
+& choco install nssm
+
+Write-Host "Creating Buildkite Monitor service..."
+nssm install "buildkite-monitor" `
+ "c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" `
+ "c:\buildkite\buildkite-monitor.ps1"
+nssm set "buildkite-monitor" "AppDirectory" "c:\buildkite"
+nssm set "buildkite-monitor" "DisplayName" "Buildkite Monitor"
+nssm set "buildkite-monitor" "Start" "SERVICE_DEMAND_START"
+nssm set "buildkite-monitor" "AppExit" "Default" "Restart"
+nssm set "buildkite-monitor" "AppRestartDelay" "3000"
+nssm set "buildkite-monitor" "AppStdout" "c:\buildkite\logs\buildkite-monitor.log"
+nssm set "buildkite-monitor" "AppStderr" "c:\buildkite\logs\buildkite-monitor.log"
+nssm set "buildkite-monitor" "AppRotateFiles" "1"
+nssm set "buildkite-monitor" "AppRotateSeconds" 86400
+nssm set "buildkite-monitor" "AppRotateBytes" 1048576
+
+Write-Host "Creating Buildkite Agent service..."
+nssm install "buildkite-agent" `
+ "c:\buildkite\buildkite-agent.exe" `
+ "start"
+nssm set "buildkite-agent" "AppDirectory" "c:\buildkite"
+nssm set "buildkite-agent" "DisplayName" "Buildkite Agent"
+nssm set "buildkite-agent" "Start" "SERVICE_DEMAND_START"
+nssm set "buildkite-agent" "ObjectName" ".\${buildkite_username}" "$buildkite_password"
+nssm set "buildkite-agent" "AppExit" "Default" "Exit"
+nssm set "buildkite-agent" "AppStdout" "c:\buildkite\logs\buildkite-agent.log"
+nssm set "buildkite-agent" "AppStderr" "c:\buildkite\logs\buildkite-agent.log"
+nssm set "buildkite-agent" "AppRotateFiles" "1"
+nssm set "buildkite-agent" "AppRotateSeconds" 86400
+nssm set "buildkite-agent" "AppRotateBytes" 1048576
Write-Host "All done, adding GCESysprep to RunOnce and rebooting..."
-Set-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "GCESysprep" -Value "C:\Program Files\Google\Compute Engine\sysprep\gcesysprep.bat"
+Set-ItemProperty "HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce" -Name "GCESysprep" -Value "c:\Program Files\Google\Compute Engine\sysprep\gcesysprep.bat"
Restart-Computer
diff --git a/buildkite/startup-windows.ps1 b/buildkite/startup-windows.ps1
index 8524e76..e21a567 100755
--- a/buildkite/startup-windows.ps1
+++ b/buildkite/startup-windows.ps1
@@ -66,7 +66,7 @@
[System.IO.File]::WriteAllLines("${buildkite_agent_root}\buildkite-agent.cfg", $buildkite_agent_config)
# Start the Buildkite agent service.
-if ( $(hostname) -match 'buildkite-' ) {
- Write-Host "Starting Buildkite agent..."
- & net start buildkite-service
+if ($(hostname) -match 'buildkite-') {
+ Write-Host "Starting Buildkite Monitor..."
+ & nssm start buildkite-monitor
}