Files
sovereign_ai/SovereignAI-Starter/scripts/setup_execution_sandbox_disk.ps1

236 lines
10 KiB
PowerShell

param(
[ValidateSet('Setup', 'Mount', 'Status', 'Remove')]
[string]$Action = 'Setup',
[switch]$DirectElevated,
[switch]$ConfirmRemove
)
$ErrorActionPreference = 'Stop'
$sandboxRoot = Join-Path $env:LOCALAPPDATA 'SovereignAI\agent-sandbox'
$vhdPath = Join-Path $sandboxRoot 'execution.vhdx'
$mountPath = Join-Path $sandboxRoot 'workspace'
$volumeLabel = 'SOVEREIGNAI_EXEC'
$virtualSizeBytes = 1GB
$volumeSizeToleranceBytes = 8MB
function Test-Administrator {
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
function Invoke-DiskPartScript([string[]]$Commands) {
$scriptPath = Join-Path $env:TEMP ("SovereignAI-DiskPart-{0}.txt" -f [guid]::NewGuid().ToString('N'))
try {
Set-Content -LiteralPath $scriptPath -Value ($Commands + 'exit') -Encoding ascii
$output = & "$env:WINDIR\System32\diskpart.exe" /s $scriptPath 2>&1 | Out-String
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0 -or $output -match '(?im)^DiskPart has encountered an error') {
throw "DiskPart failed (exit $exitCode): $output"
}
return $output
} finally {
if (Test-Path -LiteralPath $scriptPath -PathType Leaf) {
Remove-Item -LiteralPath $scriptPath -Force
}
}
}
function Get-ExecutionVolume {
$volumes = @(Get-Volume -FileSystemLabel $volumeLabel -ErrorAction SilentlyContinue)
if ($volumes.Count -gt 1) { throw "More than one volume is labeled $volumeLabel; refusing to choose." }
if ($volumes.Count -eq 0) { return $null }
return $volumes[0]
}
function Assert-ExecutionVolume($Volume) {
if (-not $Volume) { throw "The expected $volumeLabel volume is not attached." }
if ($Volume.FileSystem -ne 'NTFS') { throw "Expected NTFS but found '$($Volume.FileSystem)'." }
if ($Volume.Size -gt ($virtualSizeBytes + $volumeSizeToleranceBytes) -or
$Volume.Size -lt ($virtualSizeBytes - 32MB)) {
throw "Unexpected sandbox volume size: $($Volume.Size) bytes."
}
$mountedVolumePath = (& "$env:WINDIR\System32\mountvol.exe" $mountPath /L 2>&1 | Out-String).Trim()
if ($LASTEXITCODE -ne 0 -or
-not $mountedVolumePath.Equals($Volume.Path.Trim(), [StringComparison]::OrdinalIgnoreCase)) {
throw "The sandbox mount path does not resolve to the expected VHDX volume. mountvol='$mountedVolumePath', volume='$($Volume.Path)'."
}
$diskImage = Get-DiskImage -ImagePath $vhdPath -ErrorAction SilentlyContinue
if (-not $diskImage -or -not $diskImage.Attached) {
throw 'The VHDX backing file is not attached.'
}
$disk = $diskImage | Get-Disk
if ($disk.Size -gt $virtualSizeBytes -or $disk.Size -lt ($virtualSizeBytes - 1MB)) {
throw "The VHDX virtual capacity is unexpected: $($disk.Size) bytes."
}
return [pscustomobject]@{
vhdx_path = $vhdPath
mount_path = $mountPath
virtual_size_bytes = $disk.Size
filesystem_size_bytes = $Volume.Size
filesystem = $Volume.FileSystem
filesystem_label = $Volume.FileSystemLabel
free_bytes = $Volume.SizeRemaining
attached = $diskImage.Attached
}
}
function Mount-ExecutionDisk {
if (-not (Test-Path -LiteralPath $vhdPath -PathType Leaf)) {
throw "The sandbox VHDX does not exist: $vhdPath"
}
$volume = Get-ExecutionVolume
if (-not $volume) {
Ensure-MountDirectory
$commands = @(
"select vdisk file=`"$vhdPath`"",
'attach vdisk',
'select partition 1',
"assign mount=`"$mountPath`""
)
Invoke-DiskPartScript $commands | Out-Null
$volume = Get-ExecutionVolume
}
Assert-ExecutionVolume $volume | Out-Null
return $volume
}
function Ensure-MountDirectory {
if (-not (Test-Path -LiteralPath $sandboxRoot -PathType Container)) {
New-Item -ItemType Directory -Path $sandboxRoot -Force | Out-Null
}
if (-not (Test-Path -LiteralPath $mountPath -PathType Container)) {
New-Item -ItemType Directory -Path $mountPath | Out-Null
}
$mountItem = Get-Item -LiteralPath $mountPath -Force
if (($mountItem.Attributes -band [System.IO.FileAttributes]::ReparsePoint) -ne 0) {
throw "The sandbox mount directory is unexpectedly a reparse point: $mountPath"
}
if (Get-ChildItem -LiteralPath $mountPath -Force) {
throw "The intended sandbox mount directory is not empty: $mountPath"
}
}
if ($Action -eq 'Status') {
$volume = Get-ExecutionVolume
if (-not $volume) {
[pscustomobject]@{ configured = (Test-Path -LiteralPath $vhdPath); attached = $false; vhdx_path = $vhdPath; mount_path = $mountPath } | ConvertTo-Json
exit 0
}
Assert-ExecutionVolume $volume | ConvertTo-Json -Depth 4
exit 0
}
if ($Action -eq 'Remove' -and -not $ConfirmRemove) {
throw 'Removal deletes the dedicated sandbox disk and all data stored on it. Re-run with -ConfirmRemove to proceed.'
}
if (-not $DirectElevated -and -not (Test-Administrator)) {
$powershell = Join-Path $env:WINDIR 'System32\WindowsPowerShell\v1.0\powershell.exe'
$arguments = @(
'-NoProfile',
'-ExecutionPolicy', 'Bypass',
'-File', ('"{0}"' -f $MyInvocation.MyCommand.Path),
'-Action', $Action,
'-DirectElevated'
)
if ($ConfirmRemove) { $arguments += '-ConfirmRemove' }
try {
$child = Start-Process -FilePath $powershell -ArgumentList ($arguments -join ' ') `
-Verb RunAs -WindowStyle Hidden -PassThru -Wait
} catch {
throw "Windows did not grant the required administrator token: $($_.Exception.Message)"
}
exit $child.ExitCode
}
if (-not (Test-Administrator)) { throw 'This action requires an elevated administrator token.' }
switch ($Action) {
'Setup' {
if (Test-Path -LiteralPath $vhdPath -PathType Leaf) {
$volume = Get-ExecutionVolume
if (-not $volume) {
$volume = Mount-ExecutionDisk
}
Assert-ExecutionVolume $volume | ConvertTo-Json -Depth 4
break
}
if (Test-Path -LiteralPath $vhdPath) {
throw "A non-file already occupies the expected VHDX path: $vhdPath"
}
if (Get-ExecutionVolume) {
throw "A volume labeled $volumeLabel exists but is not backed by the expected VHDX path."
}
$driveRoot = [System.IO.Path]::GetPathRoot($env:LOCALAPPDATA)
$availableBytes = [System.IO.DriveInfo]::new($driveRoot).AvailableFreeSpace
if ($availableBytes -lt (2 * $virtualSizeBytes)) {
throw "Less than 2 GiB is free on $driveRoot; refusing to create a 1 GiB sandbox disk."
}
Ensure-MountDirectory
try {
$commands = @(
"create vdisk file=`"$vhdPath`" maximum=1024 type=expandable",
"select vdisk file=`"$vhdPath`"",
'attach vdisk',
'create partition primary',
"format fs=ntfs quick label=$volumeLabel",
"assign mount=`"$mountPath`""
)
$output = Invoke-DiskPartScript $commands
$volume = Get-ExecutionVolume
Assert-ExecutionVolume $volume | ConvertTo-Json -Depth 4
Write-Host 'The VHDX has a 1 GiB virtual maximum. Its data volume is mounted only at the dedicated workspace path.'
Write-Host 'Agent command execution remains disabled until the broker and API enforce snapshots, cleanup, and per-run approval.'
} catch {
if (Test-Path -LiteralPath $vhdPath -PathType Leaf) {
try {
$mountItem = Get-Item -LiteralPath $mountPath -Force -ErrorAction SilentlyContinue
if ($mountItem -and ($mountItem.Attributes -band [System.IO.FileAttributes]::ReparsePoint)) {
& "$env:WINDIR\System32\mountvol.exe" $mountPath /D | Out-Null
if ($LASTEXITCODE -ne 0) { throw "MountVol could not remove the partial mount ($LASTEXITCODE)." }
}
Invoke-DiskPartScript @("select vdisk file=`"$vhdPath`"", 'detach vdisk') | Out-Null
Remove-Item -LiteralPath $vhdPath -Force
} catch {
Write-Warning "Automatic cleanup could not remove the failed VHDX; inspect $vhdPath. $($_.Exception.Message)"
}
}
throw
}
}
'Mount' {
$volume = Mount-ExecutionDisk
Assert-ExecutionVolume $volume | ConvertTo-Json -Depth 4
}
'Remove' {
if (-not (Test-Path -LiteralPath $vhdPath -PathType Leaf)) {
Write-Host 'No sandbox VHDX exists at the expected path.'
break
}
$resolvedRoot = [System.IO.Path]::GetFullPath($sandboxRoot).TrimEnd('\')
$resolvedVhd = [System.IO.Path]::GetFullPath($vhdPath)
if (-not $resolvedVhd.StartsWith($resolvedRoot + '\', [StringComparison]::OrdinalIgnoreCase)) {
throw "Refusing to remove a VHDX outside the dedicated sandbox directory: $resolvedVhd"
}
$volume = Get-ExecutionVolume
if ($volume) {
Assert-ExecutionVolume $volume | Out-Null
& "$env:WINDIR\System32\mountvol.exe" $mountPath /D | Out-Null
if ($LASTEXITCODE -ne 0) { throw "MountVol could not remove the sandbox mount ($LASTEXITCODE)." }
Invoke-DiskPartScript @("select vdisk file=`"$vhdPath`"", 'detach vdisk') | Out-Null
}
Remove-Item -LiteralPath $vhdPath -Force
if ((Test-Path -LiteralPath $mountPath -PathType Container) -and
-not (Get-ChildItem -LiteralPath $mountPath -Force)) {
Remove-Item -LiteralPath $mountPath -Force
}
if ((Test-Path -LiteralPath $sandboxRoot -PathType Container) -and
-not (Get-ChildItem -LiteralPath $sandboxRoot -Force)) {
Remove-Item -LiteralPath $sandboxRoot -Force
}
Write-Host 'Removed the exact dedicated execution VHDX and its mount directory.'
}
}