mirror of
https://github.com/fscotto/infra.git
synced 2026-05-30 15:39:58 +00:00
Remove Spotify and simplify Windows winget flow
This commit is contained in:
@@ -29,9 +29,6 @@ windows_winget_packages:
|
|||||||
name: Windows Terminal
|
name: Windows Terminal
|
||||||
- id: Postman.Postman
|
- id: Postman.Postman
|
||||||
name: Postman
|
name: Postman
|
||||||
- id: Spotify.Spotify
|
|
||||||
name: Spotify
|
|
||||||
scope: user
|
|
||||||
- id: Telegram.TelegramDesktop
|
- id: Telegram.TelegramDesktop
|
||||||
name: Telegram Desktop
|
name: Telegram Desktop
|
||||||
|
|
||||||
|
|||||||
@@ -128,116 +128,15 @@
|
|||||||
script: |
|
script: |
|
||||||
$packageId = '{{ item.id }}'
|
$packageId = '{{ item.id }}'
|
||||||
$packageName = '{{ item.name | default(item.id) }}'
|
$packageName = '{{ item.name | default(item.id) }}'
|
||||||
$packageScope = '{{ item.scope | default('' ) }}'
|
$installed = & winget list --id $packageId --exact --accept-source-agreements --disable-interactivity 2>$null
|
||||||
$packageIdRegex = [regex]::Escape($packageId)
|
if ($LASTEXITCODE -eq 0 -and $installed -match [regex]::Escape($packageId)) {
|
||||||
$installArgs = @(
|
$Ansible.Changed = $false
|
||||||
'install'
|
return
|
||||||
'--id', $packageId
|
|
||||||
'--exact'
|
|
||||||
'--silent'
|
|
||||||
'--accept-package-agreements'
|
|
||||||
'--accept-source-agreements'
|
|
||||||
'--disable-interactivity'
|
|
||||||
)
|
|
||||||
|
|
||||||
if (-not [string]::IsNullOrWhiteSpace($packageScope)) {
|
|
||||||
$installArgs += @('--scope', $packageScope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($packageScope -ne 'user') {
|
& winget install --id $packageId --exact --silent --accept-package-agreements --accept-source-agreements --disable-interactivity
|
||||||
$installed = & winget list --id $packageId --exact --accept-source-agreements --disable-interactivity 2>$null
|
if ($LASTEXITCODE -ne 0) {
|
||||||
if ($LASTEXITCODE -eq 0 -and $installed -match $packageIdRegex) {
|
throw "Failed to install $packageName with winget"
|
||||||
$Ansible.Changed = $false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($packageScope -eq 'user') {
|
|
||||||
$interactiveUser = (Get-CimInstance Win32_ComputerSystem).UserName
|
|
||||||
if ([string]::IsNullOrWhiteSpace($interactiveUser)) {
|
|
||||||
throw "Failed to install $packageName with winget: no interactive Windows user session is available for a user-scoped install."
|
|
||||||
}
|
|
||||||
|
|
||||||
$taskName = "AnsibleWinget-$($packageId -replace '[^A-Za-z0-9.-]', '-')"
|
|
||||||
$taskScriptPath = Join-Path $env:TEMP "$taskName.ps1"
|
|
||||||
$stdoutPath = Join-Path $env:TEMP "$taskName.stdout.log"
|
|
||||||
$stderrPath = Join-Path $env:TEMP "$taskName.stderr.log"
|
|
||||||
$resultPath = Join-Path $env:TEMP "$taskName.result.json"
|
|
||||||
$quotedArgs = ($installArgs | ForEach-Object { '"' + ($_ -replace '"', '""') + '"' }) -join ', '
|
|
||||||
$taskScript = @(
|
|
||||||
"`$ErrorActionPreference = 'Stop'",
|
|
||||||
"function Test-PackageInstalled {",
|
|
||||||
" `$installed = & winget.exe list --id '$packageId' --exact --accept-source-agreements --disable-interactivity 2>`$null",
|
|
||||||
" return (`$LASTEXITCODE -eq 0 -and `$installed -match '$packageIdRegex')",
|
|
||||||
"}",
|
|
||||||
"`$result = @{ changed = `$false; installed = `$false }",
|
|
||||||
"if (-not (Test-PackageInstalled)) {",
|
|
||||||
"`$installArgs = @($quotedArgs)",
|
|
||||||
"`$process = Start-Process -FilePath 'winget.exe' -ArgumentList `$installArgs -Wait -PassThru -NoNewWindow -RedirectStandardOutput '$stdoutPath' -RedirectStandardError '$stderrPath'",
|
|
||||||
" if (`$process.ExitCode -ne 0) { exit `$process.ExitCode }",
|
|
||||||
" `$deadline = (Get-Date).AddMinutes(2)",
|
|
||||||
" do {",
|
|
||||||
" Start-Sleep -Seconds 2",
|
|
||||||
" `$result.installed = Test-PackageInstalled",
|
|
||||||
" } while ((Get-Date) -lt `$deadline -and -not `$result.installed)",
|
|
||||||
" if (-not `$result.installed) { throw 'Package was not detected after the user-scoped install completed.' }",
|
|
||||||
" `$result.changed = `$true",
|
|
||||||
"}",
|
|
||||||
"else {",
|
|
||||||
" `$result.installed = `$true",
|
|
||||||
"}",
|
|
||||||
"`$result | ConvertTo-Json -Compress | Set-Content -Path '$resultPath' -Encoding Ascii"
|
|
||||||
) -join [Environment]::NewLine
|
|
||||||
|
|
||||||
Set-Content -Path $taskScriptPath -Value $taskScript -Encoding Ascii
|
|
||||||
|
|
||||||
try {
|
|
||||||
$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$taskScriptPath`""
|
|
||||||
$principal = New-ScheduledTaskPrincipal -UserId $interactiveUser -LogonType InteractiveToken -RunLevel Limited
|
|
||||||
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -StartWhenAvailable
|
|
||||||
|
|
||||||
Register-ScheduledTask -TaskName $taskName -Action $action -Principal $principal -Settings $settings -Force | Out-Null
|
|
||||||
Start-ScheduledTask -TaskName $taskName
|
|
||||||
|
|
||||||
$deadline = (Get-Date).AddMinutes(10)
|
|
||||||
do {
|
|
||||||
Start-Sleep -Seconds 2
|
|
||||||
$task = Get-ScheduledTask -TaskName $taskName
|
|
||||||
$taskInfo = Get-ScheduledTaskInfo -TaskName $taskName
|
|
||||||
} while ((Get-Date) -lt $deadline -and ($task.State -ne 'Ready' -or $taskInfo.LastRunTime -eq [datetime]::MinValue))
|
|
||||||
|
|
||||||
if ($task.State -ne 'Ready' -or $taskInfo.LastRunTime -eq [datetime]::MinValue) {
|
|
||||||
throw "Failed to install $packageName with winget: timed out waiting for the user-scoped scheduled task to finish."
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($taskInfo.LastTaskResult -ne 0) {
|
|
||||||
$stderr = if (Test-Path $stderrPath) { Get-Content -Path $stderrPath -Raw } else { '' }
|
|
||||||
$stdout = if (Test-Path $stdoutPath) { Get-Content -Path $stdoutPath -Raw } else { '' }
|
|
||||||
throw "Failed to install $packageName with winget. Exit code: $($taskInfo.LastTaskResult). Stdout: $stdout Stderr: $stderr"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (-not (Test-Path $resultPath)) {
|
|
||||||
throw "Failed to install $packageName with winget: no result file was produced by the user-scoped scheduled task."
|
|
||||||
}
|
|
||||||
|
|
||||||
$result = Get-Content -Path $resultPath -Raw | ConvertFrom-Json
|
|
||||||
if (-not $result.installed) {
|
|
||||||
throw "Failed to install $packageName with winget: the package is still not detected after the user-scoped install task finished."
|
|
||||||
}
|
|
||||||
|
|
||||||
$Ansible.Changed = [bool]$result.changed
|
|
||||||
return
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
|
|
||||||
Remove-Item -Path $taskScriptPath, $stdoutPath, $stderrPath, $resultPath -Force -ErrorAction SilentlyContinue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
& winget @installArgs
|
|
||||||
if ($LASTEXITCODE -ne 0) {
|
|
||||||
throw "Failed to install $packageName with winget"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$Ansible.Changed = $true
|
$Ansible.Changed = $true
|
||||||
|
|||||||
Reference in New Issue
Block a user