102 lines
2.5 KiB
Go
102 lines
2.5 KiB
Go
// Package supervisor defines the narrow process-control seam shared by the
|
|
// client runtime and platform implementations. It intentionally contains no
|
|
// operating-system handles or process APIs.
|
|
package supervisor
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
rvboxv1 "github.com/rvbox/rvbox/gen/go/rvbox/v1"
|
|
"github.com/rvbox/rvbox/internal/domain"
|
|
)
|
|
|
|
var (
|
|
ErrInvalidStartSpec = errors.New("invalid supervisor start specification")
|
|
ErrUnsupported = errors.New("supervisor operation is unsupported")
|
|
)
|
|
|
|
type SignalKind uint8
|
|
|
|
const (
|
|
SignalTerm SignalKind = iota + 1
|
|
SignalKill
|
|
)
|
|
|
|
// StartSpec is already validated at the protocol boundary. The supervisor
|
|
// still checks the identity/revision/source invariants because it is a second
|
|
// durability boundary and may be called after a restart.
|
|
type StartSpec struct {
|
|
IssueUUID domain.UUID
|
|
CommandRevision uint64
|
|
Execution *rvboxv1.ExecutionSpec
|
|
WorkingDirectory string
|
|
Environment map[string]string
|
|
ExecutionProfiles []string
|
|
}
|
|
|
|
func (spec StartSpec) Validate() error {
|
|
if _, err := domain.ParseUUIDv7(spec.IssueUUID.String()); err != nil || spec.CommandRevision == 0 || spec.Execution == nil || spec.Execution.Source == nil {
|
|
return ErrInvalidStartSpec
|
|
}
|
|
if spec.WorkingDirectory == "" {
|
|
return ErrInvalidStartSpec
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// EffectiveIdentity is immutable process evidence captured before launch.
|
|
// Empty user/session fields mean a Session 0 service context.
|
|
type EffectiveIdentity struct {
|
|
Context string
|
|
SessionID uint32
|
|
UserSID string
|
|
LogonSID string
|
|
Elevated bool
|
|
Integrity string
|
|
}
|
|
|
|
type Process interface {
|
|
IssueUUID() domain.UUID
|
|
Identity() EffectiveIdentity
|
|
Wait(context.Context) (ExitStatus, error)
|
|
WriteStdin(context.Context, []byte, bool) error
|
|
CloseStdin(context.Context) error
|
|
}
|
|
|
|
type ExitStatus struct {
|
|
Code int32
|
|
Signaled bool
|
|
Signal SignalKind
|
|
StartedAt time.Time
|
|
FinishedAt time.Time
|
|
OutputDrained bool
|
|
Output bool
|
|
}
|
|
|
|
type SignalOutcome struct {
|
|
Delivered bool
|
|
Escalated bool
|
|
Detail string
|
|
ObservedAt time.Time
|
|
}
|
|
|
|
type ResourceSnapshot struct {
|
|
CPUTime time.Duration
|
|
ResidentBytes uint64
|
|
IOReadBytes uint64
|
|
IOWriteBytes uint64
|
|
ProcessCount uint64
|
|
ObservedAt time.Time
|
|
Complete bool
|
|
Detail string
|
|
}
|
|
|
|
type Supervisor interface {
|
|
Start(context.Context, StartSpec) (Process, error)
|
|
Signal(context.Context, Process, SignalKind) (SignalOutcome, error)
|
|
Snapshot(context.Context, Process) (ResourceSnapshot, error)
|
|
StopAll(context.Context) error
|
|
}
|