Skip to content

Commit

Permalink
Move ImageConfig struct into image.go file.
Browse files Browse the repository at this point in the history
I expect to start moving these structs into separate files just to help
organize things better.
Since I'm messing with this now, now seemed like a good time to do this
one.

Signed-off-by: Brian Goff <[email protected]>
  • Loading branch information
cpuguy83 committed Feb 29, 2024
1 parent 2299813 commit 88e1cac
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 49 deletions.
4 changes: 3 additions & 1 deletion frontend/mariner2/handle_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,12 @@ func buildImageConfig(ctx context.Context, spec *dalec.Spec, target string, clie
return nil, fmt.Errorf("error unmarshalling image config: %w", err)
}

if err := dalec.MergeImageConfig(&img, mergeSpecImage(spec, targetKey)); err != nil {
cfg := img.Config
if err := dalec.MergeImageConfig(&cfg, mergeSpecImage(spec, targetKey)); err != nil {
return nil, err
}

img.Config = cfg
return &img, nil
}

Expand Down
58 changes: 48 additions & 10 deletions image.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,48 @@ import (
"github.com/pkg/errors"
)

// ImageConfig is the configuration for the output image.
// When the target output is a container image, this is used to configure the image.
type ImageConfig struct {
// Entrypoint sets the image's "entrypoint" field.
// This is used to control the default command to run when the image is run.
Entrypoint string `yaml:"entrypoint,omitempty" json:"entrypoint,omitempty"`
// Cmd sets the image's "cmd" field.
// When entrypoint is set, this is used as the default arguments to the entrypoint.
// When entrypoint is not set, this is used as the default command to run.
Cmd string `yaml:"cmd,omitempty" json:"cmd,omitempty"`
// Env is the list of environment variables to set in the image.
Env []string `yaml:"env,omitempty" json:"env,omitempty"`
// Labels is the list of labels to set in the image metadata.
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
// Volumes is the list of volumes for the image.
// Volumes instruct the runtime to bypass the any copy-on-write filesystems and mount the volume directly to the container.
Volumes map[string]struct{} `yaml:"volumes,omitempty" json:"volumes,omitempty"`
// WorkingDir is the working directory to set in the image.
// This sets the directory the container will start in.
WorkingDir string `yaml:"working_dir,omitempty" json:"working_dir,omitempty"`
// StopSignal is the signal to send to the container to stop it.
// This is used to stop the container gracefully.
StopSignal string `yaml:"stop_signal,omitempty" json:"stop_signal,omitempty" jsonschema:"example=SIGTERM"`
// Base is the base image to use for the output image.
// This only affects the output image, not the intermediate build image.
Base string `yaml:"base,omitempty" json:"base,omitempty"`

// Post is the post install configuration for the image.
// This allows making additional modifications to the container rootfs after the package(s) are installed.
//
// Use this to perform actions that would otherwise require additional tooling inside the container that is not relavent to
// the resulting container and makes a post-install script as part of the package unnecessary.
Post *PostInstall `yaml:"post,omitempty" json:"post,omitempty"`

// User is the that the image should run as.
User string `yaml:"user,omitempty" json:"user,omitempty"`
}

// MergeImageConfig copies the fields from the source [ImageConfig] into the destination [image.Image].
// If a field is not set in the source, it is not modified in the destination.
// Envs from [ImageConfig] are merged into the destination [image.Image] and take precedence.
func MergeImageConfig(dst *image.Image, src *ImageConfig) error {
func MergeImageConfig(dst *image.ImageConfig, src *ImageConfig) error {
if src == nil {
return nil
}
Expand All @@ -19,45 +57,45 @@ func MergeImageConfig(dst *image.Image, src *ImageConfig) error {
if err != nil {
return errors.Wrap(err, "error splitting entrypoint into args")
}
dst.Config.Entrypoint = split
dst.Entrypoint = split
// Reset cmd as this may be totally invalid now
// This is the same behavior as the Dockerfile frontend
dst.Config.Cmd = nil
dst.Cmd = nil
}
if src.Cmd != "" {
split, err := shlex.Split(src.Cmd)
if err != nil {
return errors.Wrap(err, "error splitting cmd into args")
}
dst.Config.Cmd = split
dst.Cmd = split
}

if len(src.Env) > 0 {
// Env is append only
// If the env var already exists, replace it
envIdx := make(map[string]int)
for i, env := range dst.Config.Env {
for i, env := range dst.Env {
envIdx[env] = i
}

for _, env := range src.Env {
if idx, ok := envIdx[env]; ok {
dst.Config.Env[idx] = env
dst.Env[idx] = env
} else {
dst.Config.Env = append(dst.Config.Env, env)
dst.Env = append(dst.Env, env)
}
}
}

if src.WorkingDir != "" {
dst.Config.WorkingDir = src.WorkingDir
dst.WorkingDir = src.WorkingDir
}
if src.StopSignal != "" {
dst.Config.StopSignal = src.StopSignal
dst.StopSignal = src.StopSignal
}

if src.User != "" {
dst.Config.User = src.User
dst.User = src.User
}

return nil
Expand Down
38 changes: 0 additions & 38 deletions spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,44 +149,6 @@ func (a *Artifacts) IsEmpty() bool {
return true
}

// ImageConfig is the configuration for the output image.
// When the target output is a container image, this is used to configure the image.
type ImageConfig struct {
// Entrypoint sets the image's "entrypoint" field.
// This is used to control the default command to run when the image is run.
Entrypoint string `yaml:"entrypoint,omitempty" json:"entrypoint,omitempty"`
// Cmd sets the image's "cmd" field.
// When entrypoint is set, this is used as the default arguments to the entrypoint.
// When entrypoint is not set, this is used as the default command to run.
Cmd string `yaml:"cmd,omitempty" json:"cmd,omitempty"`
// Env is the list of environment variables to set in the image.
Env []string `yaml:"env,omitempty" json:"env,omitempty"`
// Labels is the list of labels to set in the image metadata.
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
// Volumes is the list of volumes for the image.
// Volumes instruct the runtime to bypass the any copy-on-write filesystems and mount the volume directly to the container.
Volumes map[string]struct{} `yaml:"volumes,omitempty" json:"volumes,omitempty"`
// WorkingDir is the working directory to set in the image.
// This sets the directory the container will start in.
WorkingDir string `yaml:"working_dir,omitempty" json:"working_dir,omitempty"`
// StopSignal is the signal to send to the container to stop it.
// This is used to stop the container gracefully.
StopSignal string `yaml:"stop_signal,omitempty" json:"stop_signal,omitempty" jsonschema:"example=SIGTERM"`
// Base is the base image to use for the output image.
// This only affects the output image, not the intermediate build image.
Base string `yaml:"base,omitempty" json:"base,omitempty"`

// Post is the post install configuration for the image.
// This allows making additional modifications to the container rootfs after the package(s) are installed.
//
// Use this to perform actions that would otherwise require additional tooling inside the container that is not relavent to
// the resulting container and makes a post-install script as part of the package unnecessary.
Post *PostInstall `yaml:"post,omitempty" json:"post,omitempty"`

// User is the that the image should run as.
User string `yaml:"user,omitempty" json:"user,omitempty"`
}

// PostInstall is the post install configuration for the image.
type PostInstall struct {
// Symlinks is the list of symlinks to create in the container rootfs after the package(s) are installed.
Expand Down

0 comments on commit 88e1cac

Please sign in to comment.