package task import ( "time" "github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb" "github.com/moby/buildkit/frontend/dockerfile/shell" specs "github.com/opencontainers/image-spec/specs-go/v1" ) // ImageConfig defines the execution parameters which should be used as a base when running a container using an image. type ImageConfig struct { // [Image Spec](https://github.com/opencontainers/image-spec/blob/main/specs-go/v1/config.go) // User defines the username or UID which the process in the container should run as. User string `json:"user,omitempty"` // ExposedPorts a set of ports to expose from a container running this image. ExposedPorts map[string]struct{} `json:"expose,omitempty"` // Env is a list of environment variables to be used in a container. Env map[string]string `json:"env,omitempty"` // Entrypoint defines a list of arguments to use as the command to execute when the container starts. Entrypoint []string `json:"entrypoint,omitempty"` // Cmd defines the default arguments to the entrypoint of the container. Cmd []string `json:"cmd,omitempty"` // Volumes is a set of directories describing where the process is likely write data specific to a container instance. Volumes map[string]struct{} `json:"volume,omitempty"` // WorkingDir sets the current working directory of the entrypoint process in the container. WorkingDir string `json:"workdir,omitempty"` // Labels contains arbitrary metadata for the container. Labels map[string]string `json:"label,omitempty"` // StopSignal contains the system call signal that will be sent to the container to exit. StopSignal string `json:"stopsignal,omitempty"` // [Docker Superset](https://github.com/moby/buildkit/blob/master/frontend/dockerfile/dockerfile2llb/image.go) Healthcheck *HealthConfig `json:"healthcheck,omitempty"` // Healthcheck describes how to check the container is healthy ArgsEscaped bool `json:"argsescaped,omitempty"` // True if command is already escaped (Windows specific) OnBuild []string `json:"onbuild,omitempty"` // ONBUILD metadata that were defined on the image Dockerfile StopTimeout *int `json:"stoptimeout,omitempty"` // Timeout (in seconds) to stop a container Shell []string `json:"shell,omitempty"` // Shell for shell-form of RUN, CMD, ENTRYPOINT } // HealthConfig holds configuration settings for the HEALTHCHECK feature. type HealthConfig struct { // Test is the test to perform to check that the container is healthy. // An empty slice means to inherit the default. // The options are: // {} : inherit healthcheck // {"NONE"} : disable healthcheck // {"CMD", args...} : exec arguments directly // {"CMD-SHELL", command} : run command with system's default shell Test []string `json:"test,omitempty"` // Zero means to inherit. Durations are expressed as integer nanoseconds. Interval time.Duration `json:"interval,omitempty"` // Interval is the time to wait between checks. Timeout time.Duration `json:"timeout,omitempty"` // Timeout is the time to wait before considering the check to have hung. StartPeriod time.Duration `json:"startperiod,omitempty"` // The start period for the container to initialize before the retries starts to count down. // Retries is the number of consecutive failures needed to consider a container as unhealthy. // Zero means inherit. Retries int `json:"retries,omitempty"` } func (ic ImageConfig) ToSpec() dockerfile2llb.ImageConfig { cfg := dockerfile2llb.ImageConfig{} cfg.User = ic.User cfg.ExposedPorts = ic.ExposedPorts cfg.Env = envToSpec(ic.Env) cfg.Entrypoint = ic.Entrypoint cfg.Cmd = ic.Cmd cfg.Volumes = ic.Volumes cfg.WorkingDir = ic.WorkingDir cfg.Labels = ic.Labels cfg.StopSignal = ic.StopSignal cfg.Healthcheck = ic.Healthcheck.ToSpec() cfg.ArgsEscaped = ic.ArgsEscaped cfg.OnBuild = ic.OnBuild cfg.StopTimeout = ic.StopTimeout cfg.Shell = ic.Shell return cfg } func ConvertImageConfig(spec dockerfile2llb.ImageConfig) ImageConfig { cfg := ImageConfig{} cfg.User = spec.User cfg.ExposedPorts = spec.ExposedPorts cfg.Env = shell.BuildEnvs(spec.Env) cfg.Entrypoint = spec.Entrypoint cfg.Cmd = spec.Cmd cfg.Volumes = spec.Volumes cfg.WorkingDir = spec.WorkingDir cfg.Labels = spec.Labels cfg.StopSignal = spec.StopSignal cfg.Healthcheck = ConvertHealthConfig(spec.Healthcheck) cfg.ArgsEscaped = spec.ArgsEscaped cfg.OnBuild = spec.OnBuild cfg.StopTimeout = spec.StopTimeout cfg.Shell = spec.Shell return cfg } func envToSpec(env map[string]string) []string { envs := []string{} for k, v := range env { envs = append(envs, k+"="+v) } return envs } func (hc *HealthConfig) ToSpec() *dockerfile2llb.HealthConfig { if hc == nil { return nil } cfg := dockerfile2llb.HealthConfig{} cfg.Test = hc.Test cfg.Interval = hc.Interval cfg.Timeout = hc.Timeout cfg.StartPeriod = hc.StartPeriod cfg.Retries = hc.Retries return &cfg } func ConvertHealthConfig(spec *dockerfile2llb.HealthConfig) *HealthConfig { if spec == nil { return nil } cfg := HealthConfig{} cfg.Test = spec.Test cfg.Interval = spec.Interval cfg.Timeout = spec.Timeout cfg.StartPeriod = spec.StartPeriod cfg.Retries = spec.Retries return &cfg } func NewImage(config ImageConfig, platform specs.Platform) dockerfile2llb.Image { return dockerfile2llb.Image{ Config: config.ToSpec(), Image: specs.Image{ Architecture: platform.Architecture, OS: platform.OS, }, Variant: platform.Variant, } }