feat: backend executor implement

This commit is contained in:
2026-08-16 17:12:06 +08:00
parent 390e0565d3
commit 7755da72e7
31 changed files with 2762 additions and 184 deletions
+27 -21
View File
@@ -40,40 +40,46 @@ type Mount struct {
// ContainerSpec contains every property controlled by the backend executor.
type ContainerSpec struct {
Name string
ImageReference string
Platform Platform
Environment []string
Labels map[string]string
NetworkMode string
RestartPolicy RestartPolicy
Mounts []Mount
Name string
ImageReference string
Platform Platform
Environment []string
Labels map[string]string
NetworkMode string
RestartPolicy RestartPolicy
Mounts []Mount
User string
StopTimeoutSeconds int
}
// Container is the runtime state required for idempotent inspection.
type Container struct {
ID string
Name string
ImageID string
ImageReference string
Platform string
Running bool
Dead bool
Status string
Environment []string
Labels map[string]string
NetworkMode string
RestartPolicy RestartPolicy
Mounts []Mount
ID string
Name string
ImageID string
ImageReference string
Platform string
Running bool
Dead bool
Status string
Environment []string
Labels map[string]string
NetworkMode string
RestartPolicy RestartPolicy
Mounts []Mount
User string
StopTimeoutSeconds int
}
// Engine is the smallest container runtime API required by an update executor.
type Engine interface {
Ping(context.Context) error
PullImage(context.Context, string) error
LoadImage(context.Context, io.Reader) error
InspectImage(context.Context, string) (Image, error)
CreateContainer(context.Context, ContainerSpec) (Container, error)
StartContainer(context.Context, string) error
StopContainer(context.Context, string) error
InspectContainer(context.Context, string) (Container, error)
RemoveContainer(context.Context, string, bool) error
Close() error
+28 -2
View File
@@ -37,6 +37,18 @@ func (e *MobyEngine) Ping(ctx context.Context) error {
return nil
}
func (e *MobyEngine) PullImage(ctx context.Context, imageReference string) error {
response, err := e.client.ImagePull(ctx, imageReference, client.ImagePullOptions{})
if err != nil {
return fmt.Errorf("pull image %s: %w", imageReference, err)
}
defer response.Close()
if err := decodeImageLoadResponse(response); err != nil {
return fmt.Errorf("pull image %s response: %w", imageReference, err)
}
return nil
}
func (e *MobyEngine) LoadImage(ctx context.Context, input io.Reader) error {
if input == nil {
return errors.New("image archive reader is required")
@@ -99,10 +111,13 @@ func (e *MobyEngine) CreateContainer(ctx context.Context, spec ContainerSpec) (C
ReadOnly: item.ReadOnly,
})
}
stopTimeout := spec.StopTimeoutSeconds
result, err := e.client.ContainerCreate(ctx, client.ContainerCreateOptions{
Config: &container.Config{
Env: append([]string(nil), spec.Environment...),
Labels: cloneMap(spec.Labels),
Env: append([]string(nil), spec.Environment...),
Labels: cloneMap(spec.Labels),
User: spec.User,
StopTimeout: &stopTimeout,
},
HostConfig: &container.HostConfig{
NetworkMode: container.NetworkMode(spec.NetworkMode),
@@ -133,6 +148,13 @@ func (e *MobyEngine) StartContainer(ctx context.Context, idOrName string) error
return nil
}
func (e *MobyEngine) StopContainer(ctx context.Context, idOrName string) error {
if _, err := e.client.ContainerStop(ctx, idOrName, client.ContainerStopOptions{}); err != nil {
return engineError("stop container", err)
}
return nil
}
func (e *MobyEngine) InspectContainer(ctx context.Context, idOrName string) (Container, error) {
result, err := e.client.ContainerInspect(ctx, idOrName, client.ContainerInspectOptions{})
if err != nil {
@@ -154,6 +176,10 @@ func (e *MobyEngine) InspectContainer(ctx context.Context, idOrName string) (Con
record.ImageReference = response.Config.Image
record.Environment = append([]string(nil), response.Config.Env...)
record.Labels = cloneMap(response.Config.Labels)
record.User = response.Config.User
if response.Config.StopTimeout != nil {
record.StopTimeoutSeconds = *response.Config.StopTimeout
}
}
if response.HostConfig != nil {
record.NetworkMode = string(response.HostConfig.NetworkMode)