diff options
Diffstat (limited to 'libpod/runtime_ctr.go')
-rw-r--r-- | libpod/runtime_ctr.go | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index a169d30f7..633d26fe1 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -8,20 +8,17 @@ import ( "strings" "time" + config2 "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" "github.com/containers/libpod/pkg/rootless" "github.com/containers/storage/pkg/stringid" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" - opentracing "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) -// CtrRemoveTimeout is the default number of seconds to wait after stopping a container -// before sending the kill signal -const CtrRemoveTimeout = 10 - // Contains the public Runtime API for containers // A CtrCreateOption is a functional option which alters the Container created @@ -38,7 +35,7 @@ func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options .. r.lock.Lock() defer r.lock.Unlock() if !r.valid { - return nil, ErrRuntimeStopped + return nil, config2.ErrRuntimeStopped } return r.newContainer(ctx, rSpec, options...) } @@ -48,7 +45,7 @@ func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config r.lock.Lock() defer r.lock.Unlock() if !r.valid { - return nil, ErrRuntimeStopped + return nil, config2.ErrRuntimeStopped } ctr, err := r.initContainerVariables(rSpec, config) @@ -60,7 +57,7 @@ func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConfig) (c *Container, err error) { if rSpec == nil { - return nil, errors.Wrapf(ErrInvalidArg, "must provide a valid runtime spec to create container") + return nil, errors.Wrapf(config2.ErrInvalidArg, "must provide a valid runtime spec to create container") } ctr := new(Container) ctr.config = new(ContainerConfig) @@ -93,7 +90,7 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf ctr.state.BindMounts = make(map[string]string) - ctr.config.StopTimeout = CtrRemoveTimeout + ctr.config.StopTimeout = config2.CtrRemoveTimeout ctr.config.OCIRuntime = r.defaultOCIRuntime.name @@ -136,8 +133,16 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai ctr.config.LockID = ctr.lock.ID() logrus.Debugf("Allocated lock %d for container %s", ctr.lock.ID(), ctr.ID()) + defer func() { + if err != nil { + if err2 := ctr.lock.Free(); err2 != nil { + logrus.Errorf("Error freeing lock for container after creation failed: %v", err2) + } + } + }() + ctr.valid = true - ctr.state.State = ContainerStateConfigured + ctr.state.State = config2.ContainerStateConfigured ctr.runtime = r if ctr.config.OCIRuntime == "" { @@ -145,7 +150,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai } else { ociRuntime, ok := r.ociRuntimes[ctr.config.OCIRuntime] if !ok { - return nil, errors.Wrapf(ErrInvalidArg, "requested OCI runtime %s is not available", ctr.config.OCIRuntime) + return nil, errors.Wrapf(config2.ErrInvalidArg, "requested OCI runtime %s is not available", ctr.config.OCIRuntime) } ctr.ociRuntime = ociRuntime } @@ -178,14 +183,14 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID()) } if podCgroup == "" { - return nil, errors.Wrapf(ErrInternal, "pod %s cgroup is not set", pod.ID()) + return nil, errors.Wrapf(config2.ErrInternal, "pod %s cgroup is not set", pod.ID()) } ctr.config.CgroupParent = podCgroup } else { ctr.config.CgroupParent = CgroupfsDefaultCgroupParent } } else if strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") { - return nil, errors.Wrapf(ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs") + return nil, errors.Wrapf(config2.ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs") } case SystemdCgroupsManager: if ctr.config.CgroupParent == "" { @@ -195,14 +200,16 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID()) } ctr.config.CgroupParent = podCgroup + } else if rootless.IsRootless() { + ctr.config.CgroupParent = SystemdDefaultRootlessCgroupParent } else { ctr.config.CgroupParent = SystemdDefaultCgroupParent } } else if len(ctr.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") { - return nil, errors.Wrapf(ErrInvalidArg, "did not receive systemd slice as cgroup parent when using systemd to manage cgroups") + return nil, errors.Wrapf(config2.ErrInvalidArg, "did not receive systemd slice as cgroup parent when using systemd to manage cgroups") } default: - return nil, errors.Wrapf(ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.CgroupManager) + return nil, errors.Wrapf(config2.ErrInvalidArg, "unsupported CGroup manager: %s - cannot validate cgroup parent", r.config.CgroupManager) } if ctr.restoreFromCheckpoint { @@ -242,7 +249,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (c *Contai if err == nil { // The volume exists, we're good continue - } else if errors.Cause(err) != ErrNoSuchVolume { + } else if errors.Cause(err) != config2.ErrNoSuchVolume { return nil, errors.Wrapf(err, "error retrieving named volume %s for new container", vol.Name) } @@ -356,7 +363,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, } if !r.valid { - return ErrRuntimeStopped + return config2.ErrRuntimeStopped } // Update the container to get current state @@ -372,7 +379,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, } } - if c.state.State == ContainerStatePaused { + if c.state.State == config2.ContainerStatePaused { if err := c.ociRuntime.killContainer(c, 9); err != nil { return err } @@ -386,7 +393,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, } // Check that the container's in a good state to be removed - if c.state.State == ContainerStateRunning { + if c.state.State == config2.ContainerStateRunning { if err := c.ociRuntime.stopContainer(c, c.StopTimeout()); err != nil { return errors.Wrapf(err, "cannot remove container %s as it could not be stopped", c.ID()) } @@ -414,7 +421,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, } if len(deps) != 0 { depsStr := strings.Join(deps, ", ") - return errors.Wrapf(ErrCtrExists, "container %s has dependent containers which must be removed before it: %s", c.ID(), depsStr) + return errors.Wrapf(config2.ErrCtrExists, "container %s has dependent containers which must be removed before it: %s", c.ID(), depsStr) } } @@ -424,22 +431,17 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, // If we're removing the pod, the container will be evicted // from the state elsewhere if !removePod { - if err := r.state.RemoveContainerFromPod(pod, c); err != nil { - if cleanupErr == nil { - cleanupErr = err - } else { - logrus.Errorf("removing container from pod: %v", err) - } - } - } - } else { - if err := r.state.RemoveContainer(c); err != nil { if cleanupErr == nil { cleanupErr = err } else { - logrus.Errorf("removing container: %v", err) + logrus.Errorf("removing container from pod: %v", err) } } + } else { + if err := r.state.RemoveContainer(c); err != nil { + cleanupErr = err + } + logrus.Errorf("removing container: %v", err) } // Set container as invalid so it can no longer be used @@ -466,8 +468,8 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, // Delete the container. // Not needed in Configured and Exited states, where the container // doesn't exist in the runtime - if c.state.State != ContainerStateConfigured && - c.state.State != ContainerStateExited { + if c.state.State != config2.ContainerStateConfigured && + c.state.State != config2.ContainerStateExited { if err := c.delete(ctx); err != nil { if cleanupErr == nil { cleanupErr = err @@ -497,7 +499,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, if !volume.IsCtrSpecific() { continue } - if err := runtime.removeVolume(ctx, volume, false); err != nil && err != ErrNoSuchVolume && err != ErrVolumeBeingUsed { + if err := runtime.removeVolume(ctx, volume, false); err != nil && err != config2.ErrNoSuchVolume && err != config2.ErrVolumeBeingUsed { logrus.Errorf("cleanup volume (%s): %v", v, err) } } @@ -512,7 +514,7 @@ func (r *Runtime) GetContainer(id string) (*Container, error) { defer r.lock.RUnlock() if !r.valid { - return nil, ErrRuntimeStopped + return nil, config2.ErrRuntimeStopped } return r.state.Container(id) @@ -524,7 +526,7 @@ func (r *Runtime) HasContainer(id string) (bool, error) { defer r.lock.RUnlock() if !r.valid { - return false, ErrRuntimeStopped + return false, config2.ErrRuntimeStopped } return r.state.HasContainer(id) @@ -537,7 +539,7 @@ func (r *Runtime) LookupContainer(idOrName string) (*Container, error) { defer r.lock.RUnlock() if !r.valid { - return nil, ErrRuntimeStopped + return nil, config2.ErrRuntimeStopped } return r.state.LookupContainer(idOrName) } @@ -551,7 +553,7 @@ func (r *Runtime) GetContainers(filters ...ContainerFilter) ([]*Container, error defer r.lock.RUnlock() if !r.valid { - return nil, ErrRuntimeStopped + return nil, config2.ErrRuntimeStopped } ctrs, err := r.state.AllContainers() @@ -584,7 +586,7 @@ func (r *Runtime) GetAllContainers() ([]*Container, error) { func (r *Runtime) GetRunningContainers() ([]*Container, error) { running := func(c *Container) bool { state, _ := c.State() - return state == ContainerStateRunning + return state == config2.ContainerStateRunning } return r.GetContainers(running) } @@ -612,7 +614,7 @@ func (r *Runtime) GetLatestContainer() (*Container, error) { return nil, errors.Wrapf(err, "unable to find latest container") } if len(ctrs) == 0 { - return nil, ErrNoSuchCtr + return nil, config2.ErrNoSuchCtr } for containerIndex, ctr := range ctrs { createdTime := ctr.config.CreatedTime |