Make env in ImageConfig a map
Fields in CUE were renamed to the lowercase version of Dockerfile instructions. There's now opportunity to make other fields simpler to use (e.g., healthcheck), this commit is focused on env. Signed-off-by: Helder Correia <174525+helderco@users.noreply.github.com>
This commit is contained in:
parent
c6d4ffb75e
commit
c276a8b8ba
@ -35,15 +35,28 @@ package engine
|
|||||||
|
|
||||||
// Container image config. See [OCI](https://www.opencontainers.org/).
|
// Container image config. See [OCI](https://www.opencontainers.org/).
|
||||||
// Spec left open on purpose to account for additional fields.
|
// Spec left open on purpose to account for additional fields.
|
||||||
// [Image Spec](https://github.com/opencontainers/image-spec/blob/main/specs-go/v1/config.go)
|
|
||||||
// [Docker Superset](https://github.com/moby/buildkit/blob/master/frontend/dockerfile/dockerfile2llb/image.go)
|
|
||||||
#ImageConfig: {
|
#ImageConfig: {
|
||||||
Env?: [...string]
|
user?: string
|
||||||
User?: string
|
expose?: [string]: {}
|
||||||
Cmd?: [...string]
|
env?: [string]: string
|
||||||
|
entrypoint?: [...string]
|
||||||
|
cmd?: [...string]
|
||||||
|
volume?: [string]: {}
|
||||||
|
workdir?: string
|
||||||
|
label?: [string]: string
|
||||||
|
healthcheck?: #HealthCheck
|
||||||
|
shell?: [...string]
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#HealthCheck: {
|
||||||
|
test?: [...string]
|
||||||
|
interval?: int
|
||||||
|
timeout?: int
|
||||||
|
startPeriod?: int
|
||||||
|
retries?: int
|
||||||
|
}
|
||||||
|
|
||||||
// Download a container image from a remote repository
|
// Download a container image from a remote repository
|
||||||
#Pull: {
|
#Pull: {
|
||||||
$dagger: task: _name: "Pull"
|
$dagger: task: _name: "Pull"
|
||||||
|
@ -126,7 +126,7 @@ func (t *dockerfileTask) Run(ctx context.Context, pctx *plancontext.Context, s s
|
|||||||
|
|
||||||
return compiler.NewValue().FillFields(map[string]interface{}{
|
return compiler.NewValue().FillFields(map[string]interface{}{
|
||||||
"output": pctx.FS.New(solvedRef).MarshalCUE(),
|
"output": pctx.FS.New(solvedRef).MarshalCUE(),
|
||||||
"config": image.Config,
|
"config": ConvertImageConfig(image.Config),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
154
plan/task/imageconfig.go
Normal file
154
plan/task/imageconfig.go
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
|
||||||
|
"github.com/moby/buildkit/frontend/dockerfile/shell"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
@ -68,6 +68,6 @@ func (c *pullTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.
|
|||||||
return compiler.NewValue().FillFields(map[string]interface{}{
|
return compiler.NewValue().FillFields(map[string]interface{}{
|
||||||
"output": fs.MarshalCUE(),
|
"output": fs.MarshalCUE(),
|
||||||
"digest": digest,
|
"digest": digest,
|
||||||
"config": image.Config,
|
"config": ConvertImageConfig(image.Config),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -56,14 +56,14 @@ func (c *pushTask) Run(ctx context.Context, pctx *plancontext.Context, s solver.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decode the image config
|
// Decode the image config
|
||||||
imageConfig := dockerfile2llb.ImageConfig{}
|
imageConfig := ImageConfig{}
|
||||||
if err := v.Lookup("config").Decode(&imageConfig); err != nil {
|
if err := v.Lookup("config").Decode(&imageConfig); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export image
|
// Export image
|
||||||
lg.Debug().Str("dest", dest.String()).Msg("export image")
|
lg.Debug().Str("dest", dest.String()).Msg("export image")
|
||||||
resp, err := s.Export(ctx, st, &dockerfile2llb.Image{Config: imageConfig}, bk.ExportEntry{
|
resp, err := s.Export(ctx, st, &dockerfile2llb.Image{Config: imageConfig.ToSpec()}, bk.ExportEntry{
|
||||||
Type: bk.ExporterImage,
|
Type: bk.ExporterImage,
|
||||||
Attrs: map[string]string{
|
Attrs: map[string]string{
|
||||||
"name": dest.String(),
|
"name": dest.String(),
|
||||||
|
@ -18,8 +18,8 @@ engine.#Plan & {
|
|||||||
"""
|
"""
|
||||||
} & {
|
} & {
|
||||||
config: {
|
config: {
|
||||||
Env: ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "test=foobar"]
|
env: test: "foobar"
|
||||||
Cmd: ["/bin/sh", "-c", "/test-cmd"]
|
cmd: ["/bin/sh", "-c", "/test-cmd"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ engine.#Plan & {
|
|||||||
// assert result
|
// assert result
|
||||||
digest: "sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
digest: "sha256:e7d88de73db3d3fd9b2d63aa7f447a10fd0220b7cbf39803c803f2af9ba256b3"
|
||||||
config: {
|
config: {
|
||||||
Env: ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"]
|
env: PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
Cmd: ["/bin/sh"]
|
cmd: ["/bin/sh"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ engine.#Plan & {
|
|||||||
// assert result
|
// assert result
|
||||||
digest: "sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060"
|
digest: "sha256:c74f1b1166784193ea6c8f9440263b9be6cae07dfe35e32a5df7a31358ac2060"
|
||||||
config: {
|
config: {
|
||||||
Env: ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"]
|
env: PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
Cmd: ["/bin/sh"]
|
cmd: ["/bin/sh"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ engine.#Plan & {
|
|||||||
push: engine.#Push & {
|
push: engine.#Push & {
|
||||||
dest: "daggerio/ci-test:\(randomString.output)"
|
dest: "daggerio/ci-test:\(randomString.output)"
|
||||||
input: randomString.image.output
|
input: randomString.image.output
|
||||||
config: Env: ["FOO=\(randomString.output)"]
|
config: env: FOO: randomString.output
|
||||||
auth: #auth
|
auth: #auth
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,9 +54,7 @@ engine.#Plan & {
|
|||||||
// check digest
|
// check digest
|
||||||
digest: strings.Split(push.result, "@")[1]
|
digest: strings.Split(push.result, "@")[1]
|
||||||
// check image config
|
// check image config
|
||||||
config: {
|
config: env: FOO: randomString.output
|
||||||
Env: ["FOO=\(randomString.output)"]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pullOutputFile: engine.#ReadFile & {
|
pullOutputFile: engine.#ReadFile & {
|
||||||
|
Reference in New Issue
Block a user