94 lines
3.4 KiB
Go
94 lines
3.4 KiB
Go
//go:build proxyctl_process_test
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"os"
|
|
"os/user"
|
|
"path/filepath"
|
|
"strconv"
|
|
|
|
"proxyctl/internal/profile"
|
|
"proxyctl/internal/target"
|
|
)
|
|
|
|
type processResetTarget struct{ marker string }
|
|
|
|
func (t processResetTarget) ID() string { return "docker-daemon-test" }
|
|
func (t processResetTarget) Description() target.Description {
|
|
if os.Getenv("PROXYCTL_PROCESS_TEST_MUTATION_FIFO") != "" {
|
|
return target.Description{Name: "Blocking mutation Target"}
|
|
}
|
|
return target.Description{Name: "Docker daemon"}
|
|
}
|
|
func (t processResetTarget) Availability(context.Context) target.Availability {
|
|
return target.Availability{Available: true, Evidence: "isolated process fixture"}
|
|
}
|
|
func (t processResetTarget) Inspect(context.Context, *profile.Profile) target.Inspection {
|
|
if os.Getenv("PROXYCTL_PROCESS_TEST_MUTATION_FIFO") != "" {
|
|
return target.Inspection{State: target.Disabled, Evidence: "ready for isolated blocked mutation"}
|
|
}
|
|
if _, err := os.Stat(t.marker); err == nil {
|
|
return target.Inspection{State: target.Disabled, Evidence: "isolated managed configuration removed"}
|
|
}
|
|
return target.Inspection{State: target.Drifted, Evidence: "isolated recovery metadata exists"}
|
|
}
|
|
func (t processResetTarget) Confirmation(bool) string {
|
|
if os.Getenv("PROXYCTL_PROCESS_TEST_MUTATION_FIFO") != "" {
|
|
return ""
|
|
}
|
|
return "Docker will restart immediately. This may disrupt running containers and other work."
|
|
}
|
|
func (t processResetTarget) SetDesired(ctx context.Context, enabled bool, active *profile.Profile) target.OperationResult {
|
|
if fifo := os.Getenv("PROXYCTL_PROCESS_TEST_MUTATION_FIFO"); fifo != "" {
|
|
started := os.Getenv("PROXYCTL_PROCESS_TEST_MUTATION_STARTED")
|
|
if err := os.WriteFile(started, []byte("started\n"), 0o600); err != nil {
|
|
return target.OperationResult{Inspection: t.Inspect(ctx, active), Err: err}
|
|
}
|
|
release, err := os.Open(fifo)
|
|
if err == nil {
|
|
var signal [1]byte
|
|
_, err = release.Read(signal[:])
|
|
_ = release.Close()
|
|
}
|
|
state := target.Disabled
|
|
if enabled {
|
|
state = target.Enabled
|
|
}
|
|
return target.OperationResult{Inspection: target.Inspection{State: state, Evidence: "isolated mutation completed"}, Err: err}
|
|
}
|
|
err := os.WriteFile(t.marker, []byte("reset\n"), 0o600)
|
|
return target.OperationResult{Inspection: t.Inspect(context.Background(), nil), Err: err}
|
|
}
|
|
|
|
// This file is compiled only into the process-smoke binary. It gives that real
|
|
// executable an identity whose home is inside the test sandbox and omits
|
|
// production system Targets, so no command can reach developer or host state.
|
|
func init() {
|
|
processProductionTargets = func(profile.IdentityEnvironment) ([]target.Target, error) {
|
|
home := os.Getenv("PROXYCTL_PROCESS_TEST_HOME")
|
|
return []target.Target{processResetTarget{marker: filepath.Join(home, "reset-mutation-marker")}}, nil
|
|
}
|
|
processCurrentUser = func() (profile.UserIdentity, error) {
|
|
home := os.Getenv("PROXYCTL_PROCESS_TEST_HOME")
|
|
if home == "" {
|
|
return profile.UserIdentity{}, errors.New("PROXYCTL_PROCESS_TEST_HOME is required by proxyctl_process_test builds")
|
|
}
|
|
current, err := user.Current()
|
|
if err != nil {
|
|
return profile.UserIdentity{}, err
|
|
}
|
|
uid, err := strconv.Atoi(current.Uid)
|
|
if err != nil {
|
|
return profile.UserIdentity{}, err
|
|
}
|
|
gid, err := strconv.Atoi(current.Gid)
|
|
if err != nil {
|
|
return profile.UserIdentity{}, err
|
|
}
|
|
return profile.UserIdentity{Username: current.Username, HomeDir: home, UID: uid, GID: gid}, nil
|
|
}
|
|
}
|