mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-09-17 23:22:27 +02:00
90 lines
2.4 KiB
Go
90 lines
2.4 KiB
Go
// Package processguard provides OS containment and out-of-process crash cleanup.
|
|
// It is intentionally independent of the Agent/MCP packages so it can be
|
|
// cross-compiled and exercised without starting the application.
|
|
package processguard
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os/exec"
|
|
"sync"
|
|
)
|
|
|
|
type Options struct {
|
|
Mode string `yaml:"mode" json:"mode"` // auto, required, process_group
|
|
CgroupRoot string `yaml:"cgroup_root" json:"cgroup_root"`
|
|
MaxProcesses int `yaml:"max_processes" json:"max_processes"`
|
|
MemoryMaxBytes int64 `yaml:"memory_max_bytes" json:"memory_max_bytes"`
|
|
CPUQuotaMicros int64 `yaml:"cpu_quota_micros" json:"cpu_quota_micros"` // per 100000 us
|
|
}
|
|
|
|
// Prepared commands must call Commit after Start and always call Dispose.
|
|
// Commit releases the Unix fallback launch gate only after watchdog ownership
|
|
// is acknowledged. Strong backends assign containment atomically at creation.
|
|
type Launch struct {
|
|
Commit func() error
|
|
Dispose func()
|
|
}
|
|
|
|
type Group interface {
|
|
Name() string
|
|
Prepare(*exec.Cmd) (*Launch, error)
|
|
Release(int) error
|
|
Close(context.Context) error
|
|
}
|
|
|
|
var configured = struct {
|
|
sync.RWMutex
|
|
opts Options
|
|
}{opts: Options{Mode: "auto", MaxProcesses: 256, MemoryMaxBytes: 2 << 30}}
|
|
|
|
func normalize(o Options) (Options, error) {
|
|
if o.Mode == "" {
|
|
o.Mode = "auto"
|
|
}
|
|
if o.Mode != "auto" && o.Mode != "required" && o.Mode != "process_group" {
|
|
return o, fmt.Errorf("invalid process isolation mode %q", o.Mode)
|
|
}
|
|
if o.MaxProcesses == 0 {
|
|
o.MaxProcesses = 256
|
|
}
|
|
if o.MemoryMaxBytes == 0 {
|
|
o.MemoryMaxBytes = 2 << 30
|
|
}
|
|
if o.MaxProcesses < 1 || o.MaxProcesses > 65535 || o.MemoryMaxBytes < 0 || o.CPUQuotaMicros < 0 {
|
|
return o, fmt.Errorf("invalid process isolation resource limits")
|
|
}
|
|
return o, nil
|
|
}
|
|
|
|
// Configure validates deployment before accepting any tasks. An explicit root
|
|
// or required mode fails closed; it never silently falls back after an error.
|
|
func Configure(o Options) error {
|
|
var err error
|
|
o, err = normalize(o)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err = configurePlatform(&o); err != nil {
|
|
return err
|
|
}
|
|
configured.Lock()
|
|
configured.opts = o
|
|
configured.Unlock()
|
|
return nil
|
|
}
|
|
func New(id string) (Group, error) {
|
|
configured.RLock()
|
|
o := configured.opts
|
|
configured.RUnlock()
|
|
return NewWithOptions(id, o)
|
|
}
|
|
func NewWithOptions(id string, o Options) (Group, error) {
|
|
var err error
|
|
o, err = normalize(o)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return newPlatformGroup(id, o)
|
|
}
|