115 lines
3.0 KiB
Go
115 lines
3.0 KiB
Go
package miner
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
// EnvironmentProbes captures host capabilities that drive tier selection.
|
|
type EnvironmentProbes struct {
|
|
Docker bool `json:"docker"`
|
|
WSL bool `json:"wsl"`
|
|
PowerShell bool `json:"pwsh"`
|
|
DotNet bool `json:"dotnet"`
|
|
GPU bool `json:"gpu"`
|
|
AVBlocksExe bool `json:"av_blocks_exe"`
|
|
WebView2 bool `json:"webview2"`
|
|
}
|
|
|
|
// probeExecCommand is exec.Command; tests override via SetProbeExecCommand.
|
|
var probeExecCommand = exec.Command
|
|
|
|
// SetProbeExecCommand restores the default when fn is nil.
|
|
func SetProbeExecCommand(fn func(name string, args ...string) *exec.Cmd) {
|
|
if fn == nil {
|
|
probeExecCommand = exec.Command
|
|
return
|
|
}
|
|
probeExecCommand = fn
|
|
}
|
|
|
|
// gpuProbeFn reports discrete GPU presence; tests inject via SetGPUProbe.
|
|
var gpuProbeFn = defaultGPUProbe
|
|
|
|
// SetGPUProbe restores the default when fn is nil.
|
|
func SetGPUProbe(fn func() bool) {
|
|
if fn == nil {
|
|
gpuProbeFn = defaultGPUProbe
|
|
return
|
|
}
|
|
gpuProbeFn = fn
|
|
}
|
|
|
|
func defaultGPUProbe() bool {
|
|
return false
|
|
}
|
|
|
|
// ProbeEnvironment gathers tier eligibility signals from the local host.
|
|
func ProbeEnvironment(runtimeFn func() ContainerRuntimeInfo) EnvironmentProbes {
|
|
if runtimeFn == nil {
|
|
runtimeFn = RuntimeDetector
|
|
}
|
|
rt := runtimeFn()
|
|
p := EnvironmentProbes{
|
|
Docker: rt.Available,
|
|
GPU: gpuProbeFn(),
|
|
}
|
|
if runtime.GOOS == "windows" {
|
|
wsl := WSLDetector()
|
|
p.WSL = wsl.Available
|
|
p.PowerShell = probePowerShell()
|
|
p.DotNet = probeDotNet()
|
|
p.WebView2 = probeWebView2()
|
|
p.AVBlocksExe = inferAVBlocksExe()
|
|
} else if runtime.GOOS == "linux" {
|
|
p.PowerShell = commandOK("pwsh", "--version") || commandOK("powershell", "--version")
|
|
p.DotNet = commandOK("dotnet", "--version")
|
|
}
|
|
return p
|
|
}
|
|
|
|
func inferAVBlocksExe() bool {
|
|
if v := strings.TrimSpace(os.Getenv("AETHERFORGE_AV_BLOCKS_EXE")); v == "1" || strings.EqualFold(v, "true") {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func probeWSL() bool {
|
|
return commandOK("wsl", "--status") || commandOK("wsl", "-l", "-q")
|
|
}
|
|
|
|
func probePowerShell() bool {
|
|
return commandOK("pwsh", "-NoLogo", "-NoProfile", "-Command", "$PSVersionTable.PSVersion.Major") ||
|
|
commandOK("powershell", "-NoLogo", "-NoProfile", "-Command", "$PSVersionTable.PSVersion.Major")
|
|
}
|
|
|
|
func probeDotNet() bool {
|
|
return commandOK("dotnet", "--version")
|
|
}
|
|
|
|
func probeWebView2() bool {
|
|
paths := []string{
|
|
os.Getenv("ProgramFiles") + `\Microsoft\EdgeWebView\Application`,
|
|
os.Getenv("ProgramFiles(x86)") + `\Microsoft\EdgeWebView\Application`,
|
|
}
|
|
for _, base := range paths {
|
|
if base == `\Microsoft\EdgeWebView\Application` {
|
|
continue
|
|
}
|
|
if info, err := os.Stat(base); err == nil && info.IsDir() {
|
|
return true
|
|
}
|
|
}
|
|
return commandOK("reg", "query", `HKLM\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}`)
|
|
}
|
|
|
|
func commandOK(name string, args ...string) bool {
|
|
cmd := probeExecCommand(name, args...)
|
|
cmd.Stdout = nil
|
|
cmd.Stderr = nil
|
|
return cmd.Run() == nil
|
|
}
|