아바타 저장소 승격 계약을 완성
This commit is contained in:
parent
ac9b702688
commit
ccdcfcd2f5
36 changed files with 14734 additions and 222 deletions
220
scripts/public-runtime-task-maintenance.ps1
Normal file
220
scripts/public-runtime-task-maintenance.ps1
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
$taskDefinitionCutoverContract = Join-Path $PSScriptRoot "public-runtime-task-definition-cutover.ps1"
|
||||
if (-not (Test-Path -LiteralPath $taskDefinitionCutoverContract -PathType Leaf)) {
|
||||
throw "Public runtime task definition cutover contract is unavailable"
|
||||
}
|
||||
. $taskDefinitionCutoverContract
|
||||
|
||||
function Assert-PublicRuntimeTasksDisabledAndIdle {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][object[]]$Snapshot,
|
||||
[int]$TimeoutSec = 30
|
||||
)
|
||||
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
do {
|
||||
$allDisabledAndIdle = $true
|
||||
foreach ($entry in @($Snapshot)) {
|
||||
if (-not [bool]$entry.exists) {
|
||||
$unexpectedTask = Get-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction SilentlyContinue
|
||||
if ($null -ne $unexpectedTask) {
|
||||
throw "A coordinated public runtime task appeared during maintenance: $($entry.task_name)"
|
||||
}
|
||||
continue
|
||||
}
|
||||
$task = Get-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction Stop
|
||||
if ([bool]$task.Settings.Enabled -or [string]$task.State -eq "Running") {
|
||||
$allDisabledAndIdle = $false
|
||||
break
|
||||
}
|
||||
}
|
||||
if ($allDisabledAndIdle) {
|
||||
return
|
||||
}
|
||||
Start-Sleep -Milliseconds 250
|
||||
} while ((Get-Date) -lt $deadline)
|
||||
|
||||
throw "Public runtime scheduled tasks did not become disabled and idle"
|
||||
}
|
||||
|
||||
function Get-PublicRuntimeTaskMaintenanceState {
|
||||
param([Parameter(Mandatory = $true)][object[]]$Snapshot)
|
||||
|
||||
$allDisabledAndIdle = $true
|
||||
$restoredToSnapshot = $true
|
||||
$verified = $true
|
||||
foreach ($entry in @($Snapshot)) {
|
||||
if (-not [bool]$entry.exists) {
|
||||
try {
|
||||
$unexpectedTask = Get-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction SilentlyContinue
|
||||
if ($null -ne $unexpectedTask) {
|
||||
$allDisabledAndIdle = $false
|
||||
$restoredToSnapshot = $false
|
||||
}
|
||||
} catch {
|
||||
$verified = $false
|
||||
$allDisabledAndIdle = $false
|
||||
$restoredToSnapshot = $false
|
||||
}
|
||||
continue
|
||||
}
|
||||
try {
|
||||
$task = Get-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction Stop
|
||||
$isEnabled = [bool]$task.Settings.Enabled
|
||||
$isRunning = [string]$task.State -eq "Running"
|
||||
if ($isEnabled -or $isRunning) {
|
||||
$allDisabledAndIdle = $false
|
||||
}
|
||||
if ($isEnabled -ne [bool]$entry.was_enabled) {
|
||||
$restoredToSnapshot = $false
|
||||
}
|
||||
} catch {
|
||||
$verified = $false
|
||||
$allDisabledAndIdle = $false
|
||||
$restoredToSnapshot = $false
|
||||
}
|
||||
}
|
||||
|
||||
return [pscustomobject][ordered]@{
|
||||
verified = $verified
|
||||
all_disabled_and_idle = $allDisabledAndIdle
|
||||
restored_to_snapshot = $restoredToSnapshot
|
||||
}
|
||||
}
|
||||
|
||||
function Suspend-PublicRuntimeTasks {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][object[]]$Snapshot,
|
||||
[int]$TimeoutSec = 30
|
||||
)
|
||||
|
||||
foreach ($entry in @($Snapshot)) {
|
||||
if (-not [bool]$entry.exists) {
|
||||
continue
|
||||
}
|
||||
Disable-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction Stop `
|
||||
| Out-Null
|
||||
}
|
||||
Assert-PublicRuntimeTasksDisabledAndIdle `
|
||||
-Snapshot $Snapshot `
|
||||
-TimeoutSec $TimeoutSec
|
||||
}
|
||||
|
||||
function Enter-PublicRuntimeTaskMaintenance {
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string[]]$TaskNames,
|
||||
[int]$TimeoutSec = 30
|
||||
)
|
||||
|
||||
$snapshot = @()
|
||||
try {
|
||||
# 모든 원상복구 정보를 먼저 캡처한다. disable 도중 두 번째 task에서 오류가 나도
|
||||
# 첫 번째 task를 포함한 완전한 snapshot으로 되돌릴 수 있어야 한다.
|
||||
foreach ($taskName in @($TaskNames | Sort-Object -Unique)) {
|
||||
if ([string]::IsNullOrWhiteSpace($taskName)) {
|
||||
throw "Public runtime scheduled task name is empty"
|
||||
}
|
||||
$task = Get-ScheduledTask `
|
||||
-TaskName $taskName `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction SilentlyContinue
|
||||
if ($null -eq $task) {
|
||||
$snapshot += [pscustomobject][ordered]@{
|
||||
task_name = $taskName
|
||||
exists = $false
|
||||
was_enabled = $false
|
||||
}
|
||||
continue
|
||||
}
|
||||
$wasEnabled = [bool]$task.Settings.Enabled
|
||||
$snapshot += [pscustomobject][ordered]@{
|
||||
task_name = $taskName
|
||||
exists = $true
|
||||
was_enabled = $wasEnabled
|
||||
}
|
||||
}
|
||||
|
||||
$result = @($snapshot)
|
||||
Suspend-PublicRuntimeTasks `
|
||||
-Snapshot $result `
|
||||
-TimeoutSec $TimeoutSec
|
||||
return $result
|
||||
} catch {
|
||||
foreach ($entry in @($snapshot)) {
|
||||
if ([bool]$entry.exists -and [bool]$entry.was_enabled) {
|
||||
Enable-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction SilentlyContinue `
|
||||
| Out-Null
|
||||
}
|
||||
}
|
||||
foreach ($entry in @($snapshot)) {
|
||||
if (-not [bool]$entry.exists) {
|
||||
continue
|
||||
}
|
||||
$task = Get-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction Stop
|
||||
if ([bool]$task.Settings.Enabled -ne [bool]$entry.was_enabled) {
|
||||
throw "Public runtime task maintenance entry rollback failed: $($entry.task_name)"
|
||||
}
|
||||
}
|
||||
throw
|
||||
}
|
||||
}
|
||||
|
||||
function Exit-PublicRuntimeTaskMaintenance {
|
||||
param([Parameter(Mandatory = $true)][object[]]$Snapshot)
|
||||
|
||||
try {
|
||||
foreach ($entry in @($Snapshot)) {
|
||||
if (-not [bool]$entry.exists -or -not [bool]$entry.was_enabled) {
|
||||
continue
|
||||
}
|
||||
Enable-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction Stop `
|
||||
| Out-Null
|
||||
}
|
||||
|
||||
foreach ($entry in @($Snapshot)) {
|
||||
if (-not [bool]$entry.exists -or -not [bool]$entry.was_enabled) {
|
||||
continue
|
||||
}
|
||||
$task = Get-ScheduledTask `
|
||||
-TaskName ([string]$entry.task_name) `
|
||||
-TaskPath "\" `
|
||||
-ErrorAction Stop
|
||||
if (-not [bool]$task.Settings.Enabled) {
|
||||
throw "Public runtime scheduled task was not re-enabled: $($entry.task_name)"
|
||||
}
|
||||
}
|
||||
$restoredTruth = Get-PublicRuntimeTaskMaintenanceState -Snapshot $Snapshot
|
||||
if (
|
||||
-not [bool]$restoredTruth.verified -or
|
||||
-not [bool]$restoredTruth.restored_to_snapshot
|
||||
) {
|
||||
throw "Public runtime scheduled task set drifted during maintenance"
|
||||
}
|
||||
} catch {
|
||||
Suspend-PublicRuntimeTasks -Snapshot $Snapshot -TimeoutSec 30
|
||||
throw
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue