mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-21 19:56:33 +00:00
1ab61b0dd5
* fix(ecs): enforce or refuse container runtime fields (TFC-0040) user, mountPoints, volumesFrom, readonlyRootFilesystem, privileged, pseudoTerminal, interactive, linuxParameters, systemControls, startTimeout and stopTimeout registered successfully but were never stored, sent to the agent, enforced, or echoed back on describe. Store and echo the fields the agent can enforce (user, readonly root filesystem, privileged, pseudo terminal, interactive, systemControls, capability add/drop, start/stop timeout), apply them through containerd via OCI spec options and a graceful Stop, and refuse at RegisterTaskDefinition the fields the agent cannot honor (mountPoints, volumesFrom, linuxParameters.devices/initProcessEnabled/ sharedMemorySize/tmpfs). Refusal only triggers on a value that asks for the restriction; empty lists and false/unset flags are accepted and echoed as before. * test: move the bus wire-contract test to an external package * fix(ecs-agent): release an interactive container's stdin so its copier exits * fix(ecs): return a caller-supplied empty collection instead of omitting it
143 lines
3.4 KiB
Go
143 lines
3.4 KiB
Go
package runtime
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// FakePuller is an in-memory ImagePuller for tests and the scheduler-only build.
|
|
// It records pull requests and replays a programmed result or error.
|
|
type FakePuller struct {
|
|
mu sync.Mutex
|
|
Pulls []PullSpec
|
|
Authzd []string
|
|
Result Image
|
|
Err error
|
|
Closed bool
|
|
OnPull func(PullSpec) (Image, error)
|
|
|
|
// Run bookkeeping.
|
|
Runs []RunSpec
|
|
RunErr error
|
|
WaitCode int
|
|
WaitErr error
|
|
Waited []string
|
|
Removed []string
|
|
OnRun func(string, RunSpec) (string, error)
|
|
|
|
// Stop bookkeeping: StopTimeouts pairs the container ID with the timeout it
|
|
// was stopped with, in call order, so a test can assert both the target and
|
|
// the enforced stopTimeout without a fake containerd.
|
|
Stopped []string
|
|
StopTimeouts []time.Duration
|
|
StopErr error
|
|
|
|
// List bookkeeping: Containers is replayed by List; ListErr forces a failure;
|
|
// Listed records that List was called.
|
|
Containers []Container
|
|
ListErr error
|
|
Listed bool
|
|
}
|
|
|
|
var (
|
|
_ ImagePuller = (*FakePuller)(nil)
|
|
_ Runner = (*FakePuller)(nil)
|
|
)
|
|
|
|
// Pull records the spec, exercises the resolver, and returns the programmed
|
|
// result. If OnPull is set it takes precedence over Result/Err.
|
|
func (f *FakePuller) Pull(ctx context.Context, spec PullSpec, r Resolver) (Image, error) {
|
|
f.mu.Lock()
|
|
f.Pulls = append(f.Pulls, spec)
|
|
f.mu.Unlock()
|
|
|
|
if r != nil {
|
|
user, _, _, err := r.Authorize(ctx, spec.Ref)
|
|
if err != nil {
|
|
return Image{}, fmt.Errorf("authorize %s: %w", spec.Ref, err)
|
|
}
|
|
f.mu.Lock()
|
|
f.Authzd = append(f.Authzd, user)
|
|
f.mu.Unlock()
|
|
}
|
|
|
|
if f.OnPull != nil {
|
|
return f.OnPull(spec)
|
|
}
|
|
if f.Err != nil {
|
|
return Image{}, f.Err
|
|
}
|
|
res := f.Result
|
|
if res.Ref == "" {
|
|
res.Ref = spec.Ref
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
// Close marks the puller closed.
|
|
func (f *FakePuller) Close() error {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
f.Closed = true
|
|
return nil
|
|
}
|
|
|
|
// Run records the spec and returns id (or the programmed result/error).
|
|
func (f *FakePuller) Run(_ context.Context, id string, spec RunSpec) (string, error) {
|
|
f.mu.Lock()
|
|
f.Runs = append(f.Runs, spec)
|
|
f.mu.Unlock()
|
|
if f.OnRun != nil {
|
|
return f.OnRun(id, spec)
|
|
}
|
|
if f.RunErr != nil {
|
|
return "", f.RunErr
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
// Wait records the container ID and returns the programmed exit code/error.
|
|
func (f *FakePuller) Wait(_ context.Context, containerID string) (RunStatus, error) {
|
|
f.mu.Lock()
|
|
f.Waited = append(f.Waited, containerID)
|
|
f.mu.Unlock()
|
|
return RunStatus{ExitCode: f.WaitCode}, f.WaitErr
|
|
}
|
|
|
|
// Stop records the container ID and the timeout it was stopped with.
|
|
func (f *FakePuller) Stop(_ context.Context, containerID string, timeout time.Duration) error {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
f.Stopped = append(f.Stopped, containerID)
|
|
f.StopTimeouts = append(f.StopTimeouts, timeout)
|
|
return f.StopErr
|
|
}
|
|
|
|
// Remove records the container ID.
|
|
func (f *FakePuller) Remove(_ context.Context, containerID string) error {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
f.Removed = append(f.Removed, containerID)
|
|
return nil
|
|
}
|
|
|
|
// Waits returns a copy of the container IDs passed to Wait, for assertions.
|
|
func (f *FakePuller) Waits() []string {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
return append([]string(nil), f.Waited...)
|
|
}
|
|
|
|
// List replays the programmed container set (or error).
|
|
func (f *FakePuller) List(_ context.Context) ([]Container, error) {
|
|
f.mu.Lock()
|
|
defer f.mu.Unlock()
|
|
f.Listed = true
|
|
if f.ListErr != nil {
|
|
return nil, f.ListErr
|
|
}
|
|
return f.Containers, nil
|
|
}
|