Merge pull request #1505 from helderco/image-config
Make env in ImageConfig a map
This commit is contained in:
commit
7788b9f2f3
@ -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