202 lines
8.1 KiB
PowerShell
202 lines
8.1 KiB
PowerShell
# Typed MinerOps miner-control execution. Loaded by MinerOpsAgentService.ps1.
|
|
|
|
function Get-MinerOpsAgentVersion {
|
|
$versionPath = Join-Path $PSScriptRoot "VERSION"
|
|
if (Test-Path $versionPath) {
|
|
return ([string](Get-Content $versionPath -Raw)).Trim()
|
|
}
|
|
return "unknown"
|
|
}
|
|
|
|
function Get-MinerOpsControlCredentials {
|
|
$config = Read-AgentConfig
|
|
$account = ([string]$config.api3_account).Trim()
|
|
$password = [string]$config.api3_password
|
|
$port = 4433
|
|
if ($config.api3_port) {
|
|
try { $port = [int]$config.api3_port } catch { $port = 4433 }
|
|
}
|
|
return @{
|
|
available = (-not [string]::IsNullOrWhiteSpace($account)) -and
|
|
(-not [string]::IsNullOrWhiteSpace($password))
|
|
account = $account
|
|
password = $password
|
|
port = $port
|
|
}
|
|
}
|
|
|
|
function Invoke-MinerOpsControlApi3Command {
|
|
param(
|
|
[Parameter(Mandatory=$true)][string]$IpAddress,
|
|
[Parameter(Mandatory=$true)][string]$Command,
|
|
[object]$Param = $null
|
|
)
|
|
$credentials = Get-MinerOpsControlCredentials
|
|
if (-not $credentials.available) { throw "credentials_missing" }
|
|
|
|
$saltInfo = Get-MinerOpsApi3Salt -IpAddress $IpAddress -Port $credentials.port
|
|
$timestamp = [int64][DateTimeOffset]::UtcNow.ToUnixTimeSeconds()
|
|
$token = Get-MinerOpsApi3Token -Command $Command -Password $credentials.password `
|
|
-Salt ([string]$saltInfo.salt) -Timestamp $timestamp
|
|
$payload = @{
|
|
cmd = $Command
|
|
ts = $timestamp
|
|
token = $token
|
|
account = $credentials.account
|
|
}
|
|
if ($null -ne $Param) { $payload["param"] = $Param }
|
|
$response = Invoke-MinerOpsApi3Payload -IpAddress $IpAddress `
|
|
-Port $credentials.port -Payload $payload
|
|
if ([int]$response.response.code -ne 0) { throw "command_rejected" }
|
|
return $response
|
|
}
|
|
|
|
function New-MinerOpsControlResult {
|
|
param(
|
|
[bool]$Accepted,
|
|
[bool]$VerificationAttempted,
|
|
[string]$VerificationStatus,
|
|
[string]$ObservedMode = "",
|
|
[string]$FailureCode = "",
|
|
[string]$QueueStatus = "completed"
|
|
)
|
|
return [ordered]@{
|
|
schema_version = 1
|
|
command_accepted = $Accepted
|
|
verification_attempted = $VerificationAttempted
|
|
verification_status = $VerificationStatus
|
|
observed_service_state = $null
|
|
observed_performance_mode = if ($ObservedMode) { $ObservedMode } else { $null }
|
|
failure_code = if ($FailureCode) { $FailureCode } else { $null }
|
|
_queue_status = $QueueStatus
|
|
}
|
|
}
|
|
|
|
function Run-MinerControlCommand {
|
|
param([Parameter(Mandatory=$true)][object]$Payload)
|
|
|
|
try {
|
|
if ($Payload -is [string]) { $Payload = $Payload | ConvertFrom-Json }
|
|
$action = ([string]$Payload.action).Trim().ToLower()
|
|
$ipAddress = ([string]$Payload.ip_address).Trim()
|
|
$requested = ([string]$Payload.requested_value).Trim().ToLower()
|
|
if (-not $requested -and $Payload.performance_mode) {
|
|
$requested = ([string]$Payload.performance_mode).Trim().ToLower()
|
|
}
|
|
if ($action -notin @("suspend", "resume", "performance_mode")) {
|
|
return New-MinerOpsControlResult -Accepted $false `
|
|
-VerificationAttempted $false -VerificationStatus "unavailable" `
|
|
-FailureCode "invalid_action" -QueueStatus "failed"
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($ipAddress)) {
|
|
return New-MinerOpsControlResult -Accepted $false `
|
|
-VerificationAttempted $false -VerificationStatus "unavailable" `
|
|
-FailureCode "target_missing" -QueueStatus "failed"
|
|
}
|
|
$credentials = Get-MinerOpsControlCredentials
|
|
if (-not $credentials.available) {
|
|
return New-MinerOpsControlResult -Accepted $false `
|
|
-VerificationAttempted $false -VerificationStatus "unavailable" `
|
|
-FailureCode "credentials_missing" -QueueStatus "failed"
|
|
}
|
|
|
|
if ($action -eq "performance_mode") {
|
|
if ($requested -notin @("low", "normal", "high")) {
|
|
return New-MinerOpsControlResult -Accepted $false `
|
|
-VerificationAttempted $false -VerificationStatus "unavailable" `
|
|
-FailureCode "invalid_mode" -QueueStatus "failed"
|
|
}
|
|
Invoke-MinerOpsControlApi3Command -IpAddress $ipAddress `
|
|
-Command "set.miner.power_mode" -Param $requested | Out-Null
|
|
|
|
$observed = ""
|
|
$readUnavailable = $false
|
|
for ($attempt = 1; $attempt -le 3; $attempt++) {
|
|
try {
|
|
$read = Invoke-MinerOpsControlApi3Command -IpAddress $ipAddress `
|
|
-Command "get.miner.setting"
|
|
$candidate = ([string]$read.response.msg.'power-mode').Trim().ToLower()
|
|
if ($candidate -in @("low", "normal", "high")) {
|
|
$observed = $candidate
|
|
if ($observed -eq $requested) {
|
|
return New-MinerOpsControlResult -Accepted $true `
|
|
-VerificationAttempted $true -VerificationStatus "confirmed" `
|
|
-ObservedMode $observed
|
|
}
|
|
}
|
|
} catch {
|
|
if ($_.Exception.Message -match "unsupported|unknown_command") {
|
|
$readUnavailable = $true
|
|
break
|
|
}
|
|
}
|
|
if ($attempt -lt 3) { Start-Sleep -Milliseconds 750 }
|
|
}
|
|
if ($readUnavailable) {
|
|
return New-MinerOpsControlResult -Accepted $true `
|
|
-VerificationAttempted $true -VerificationStatus "unavailable"
|
|
}
|
|
if ($observed) {
|
|
return New-MinerOpsControlResult -Accepted $true `
|
|
-VerificationAttempted $true `
|
|
-VerificationStatus "verification_failed" -ObservedMode $observed
|
|
}
|
|
return New-MinerOpsControlResult -Accepted $true `
|
|
-VerificationAttempted $true -VerificationStatus "unconfirmed"
|
|
}
|
|
|
|
$serviceAction = if ($action -eq "suspend") { "stop" } else { "start" }
|
|
Invoke-MinerOpsControlApi3Command -IpAddress $ipAddress `
|
|
-Command "set.miner.service" -Param $serviceAction | Out-Null
|
|
return New-MinerOpsControlResult -Accepted $true `
|
|
-VerificationAttempted $false -VerificationStatus "unconfirmed"
|
|
} catch {
|
|
$failure = if ($_.Exception.Message -eq "credentials_missing") {
|
|
"credentials_missing"
|
|
} else { "write_rejected" }
|
|
return New-MinerOpsControlResult -Accepted $false `
|
|
-VerificationAttempted $false -VerificationStatus "unavailable" `
|
|
-FailureCode $failure -QueueStatus "failed"
|
|
}
|
|
}
|
|
|
|
function Send-AgentCommandResult {
|
|
param(
|
|
[string]$CommandId,
|
|
[string]$Status,
|
|
[object]$ResultPayload = $null,
|
|
[string]$ErrorMessage = $null
|
|
)
|
|
if ($ResultPayload -and $ResultPayload._queue_status) {
|
|
$Status = [string]$ResultPayload._queue_status
|
|
$ResultPayload.Remove("_queue_status")
|
|
$ErrorMessage = if ($ResultPayload.failure_code) {
|
|
[string]$ResultPayload.failure_code
|
|
} else { $null }
|
|
}
|
|
$body = [ordered]@{
|
|
command_id = $CommandId
|
|
status = $Status
|
|
result_payload = $ResultPayload
|
|
error_message = $ErrorMessage
|
|
}
|
|
return Invoke-AgentApi -Method "POST" -Path "/api/agent/commands/result" -Body $body
|
|
}
|
|
|
|
function Send-AgentCheckin {
|
|
$config = Read-AgentConfig
|
|
$credentials = Get-MinerOpsControlCredentials
|
|
$body = [ordered]@{
|
|
agent_id = [string]$config.agent_id
|
|
site_id = [string]$config.site_id
|
|
site_name = [string]$config.site_name
|
|
hostname = $env:COMPUTERNAME
|
|
version = Get-MinerOpsAgentVersion
|
|
ip_address = ""
|
|
control_available = [bool]$credentials.available
|
|
control_unavailable_reason = if ($credentials.available) { $null } else { "credentials_missing" }
|
|
local_time = (Get-Date).ToString("o")
|
|
}
|
|
return Invoke-AgentApi -Method "POST" -Path "/api/agent/checkin" -Body $body
|
|
}
|