summaryrefslogtreecommitdiff
path: root/pkg/specgen/generate/container.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/specgen/generate/container.go')
-rw-r--r--pkg/specgen/generate/container.go159
1 files changed, 87 insertions, 72 deletions
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 3d70571d5..df27f225b 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -5,6 +5,7 @@ import (
"github.com/containers/image/v5/manifest"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/image"
ann "github.com/containers/libpod/pkg/annotations"
envLib "github.com/containers/libpod/pkg/env"
"github.com/containers/libpod/pkg/signal"
@@ -13,91 +14,103 @@ import (
"golang.org/x/sys/unix"
)
-func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) error {
- // If a rootfs is used, then there is no image data
- if s.ContainerStorageConfig.Rootfs != "" {
- return nil
- }
-
- newImage, err := r.ImageRuntime().NewFromLocal(s.Image)
- if err != nil {
- return err
- }
-
- _, mediaType, err := newImage.Manifest(ctx)
- if err != nil {
- return err
- }
-
- if s.HealthConfig == nil && mediaType == manifest.DockerV2Schema2MediaType {
- s.HealthConfig, err = newImage.GetHealthCheck(ctx)
+// Fill any missing parts of the spec generator (e.g. from the image).
+// Returns a set of warnings or any fatal error that occurred.
+func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) ([]string, error) {
+ var (
+ newImage *image.Image
+ err error
+ )
+
+ // Only add image configuration if we have an image
+ if s.Image != "" {
+ newImage, err = r.ImageRuntime().NewFromLocal(s.Image)
if err != nil {
- return err
+ return nil, err
}
- }
- // Image stop signal
- if s.StopSignal == nil {
- stopSignal, err := newImage.StopSignal(ctx)
+ _, mediaType, err := newImage.Manifest(ctx)
if err != nil {
- return err
+ return nil, err
}
- if stopSignal != "" {
- sig, err := signal.ParseSignalNameOrNumber(stopSignal)
+
+ if s.HealthConfig == nil && mediaType == manifest.DockerV2Schema2MediaType {
+ s.HealthConfig, err = newImage.GetHealthCheck(ctx)
if err != nil {
- return err
+ return nil, err
+ }
+ }
+
+ // Image stop signal
+ if s.StopSignal == nil {
+ stopSignal, err := newImage.StopSignal(ctx)
+ if err != nil {
+ return nil, err
+ }
+ if stopSignal != "" {
+ sig, err := signal.ParseSignalNameOrNumber(stopSignal)
+ if err != nil {
+ return nil, err
+ }
+ s.StopSignal = &sig
}
- s.StopSignal = &sig
}
}
rtc, err := r.GetConfig()
if err != nil {
- return err
+ return nil, err
}
// Get Default Environment
defaultEnvs, err := envLib.ParseSlice(rtc.Containers.Env)
if err != nil {
- return errors.Wrap(err, "Env fields in containers.conf failed to parse")
+ return nil, errors.Wrap(err, "Env fields in containers.conf failed to parse")
}
- // Image envs from the image if they don't exist
- // already, overriding the default environments
- imageEnvs, err := newImage.Env(ctx)
- if err != nil {
- return err
- }
+ var envs map[string]string
- envs, err := envLib.ParseSlice(imageEnvs)
- if err != nil {
- return errors.Wrap(err, "Env fields from image failed to parse")
- }
- s.Env = envLib.Join(envLib.Join(defaultEnvs, envs), s.Env)
+ if newImage != nil {
+ // Image envs from the image if they don't exist
+ // already, overriding the default environments
+ imageEnvs, err := newImage.Env(ctx)
+ if err != nil {
+ return nil, err
+ }
- labels, err := newImage.Labels(ctx)
- if err != nil {
- return err
+ envs, err = envLib.ParseSlice(imageEnvs)
+ if err != nil {
+ return nil, errors.Wrap(err, "Env fields from image failed to parse")
+ }
}
- // labels from the image that dont exist already
- if len(labels) > 0 && s.Labels == nil {
- s.Labels = make(map[string]string)
- }
- for k, v := range labels {
- if _, exists := s.Labels[k]; !exists {
- s.Labels[k] = v
+ s.Env = envLib.Join(envLib.Join(defaultEnvs, envs), s.Env)
+
+ // Labels and Annotations
+ annotations := make(map[string]string)
+ if newImage != nil {
+ labels, err := newImage.Labels(ctx)
+ if err != nil {
+ return nil, err
}
- }
- // annotations
+ // labels from the image that dont exist already
+ if len(labels) > 0 && s.Labels == nil {
+ s.Labels = make(map[string]string)
+ }
+ for k, v := range labels {
+ if _, exists := s.Labels[k]; !exists {
+ s.Labels[k] = v
+ }
+ }
- // Add annotations from the image
- annotations, err := newImage.Annotations(ctx)
- if err != nil {
- return err
- }
- for k, v := range annotations {
- annotations[k] = v
+ // Add annotations from the image
+ imgAnnotations, err := newImage.Annotations(ctx)
+ if err != nil {
+ return nil, err
+ }
+ for k, v := range imgAnnotations {
+ annotations[k] = v
+ }
}
// in the event this container is in a pod, and the pod has an infra container
@@ -121,40 +134,42 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat
s.Annotations = annotations
// workdir
- workingDir, err := newImage.WorkingDir(ctx)
- if err != nil {
- return err
- }
- if len(s.WorkDir) < 1 && len(workingDir) > 1 {
- s.WorkDir = workingDir
+ if newImage != nil {
+ workingDir, err := newImage.WorkingDir(ctx)
+ if err != nil {
+ return nil, err
+ }
+ if len(s.WorkDir) < 1 && len(workingDir) > 1 {
+ s.WorkDir = workingDir
+ }
}
if len(s.SeccompProfilePath) < 1 {
p, err := libpod.DefaultSeccompPath()
if err != nil {
- return err
+ return nil, err
}
s.SeccompProfilePath = p
}
- if len(s.User) == 0 {
+ if len(s.User) == 0 && newImage != nil {
s.User, err = newImage.User(ctx)
if err != nil {
- return err
+ return nil, err
}
}
if err := finishThrottleDevices(s); err != nil {
- return err
+ return nil, err
}
// Unless already set via the CLI, check if we need to disable process
// labels or set the defaults.
if len(s.SelinuxOpts) == 0 {
if err := setLabelOpts(s, r, s.PidNS, s.IpcNS); err != nil {
- return err
+ return nil, err
}
}
- return nil
+ return verifyContainerResources(s)
}
// finishThrottleDevices takes the temporary representation of the throttle