diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container.go | 5 | ||||
-rw-r--r-- | libpod/container_inspect.go | 3 | ||||
-rw-r--r-- | libpod/define/podstate.go | 19 | ||||
-rw-r--r-- | libpod/oci_conmon_linux.go | 13 | ||||
-rw-r--r-- | libpod/options.go | 21 | ||||
-rw-r--r-- | libpod/pod_status.go | 59 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 41 | ||||
-rw-r--r-- | libpod/runtime_pod.go | 28 |
8 files changed, 177 insertions, 12 deletions
diff --git a/libpod/container.go b/libpod/container.go index b3cb6334a..f29cebf20 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -373,8 +373,11 @@ type ContainerConfig struct { // Time container was created CreatedTime time.Time `json:"createdTime"` // NoCgroups indicates that the container will not create CGroups. It is - // incompatible with CgroupParent. + // incompatible with CgroupParent. Deprecated in favor of CgroupsMode. NoCgroups bool `json:"noCgroups,omitempty"` + // CgroupsMode indicates how the container will create cgroups + // (disabled, no-conmon, enabled). It supersedes NoCgroups. + CgroupsMode string `json:"cgroupsMode,omitempty"` // Cgroup parent of the container CgroupParent string `json:"cgroupParent"` // LogPath log location diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go index 01f2d93bd..641bc8a91 100644 --- a/libpod/container_inspect.go +++ b/libpod/container_inspect.go @@ -1014,6 +1014,9 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named hostConfig.ShmSize = c.config.ShmSize hostConfig.Runtime = "oci" + // Default CPUShares is 1024, but we may overwrite below. + hostConfig.CpuShares = 1024 + // This is very expensive to initialize. // So we don't want to initialize it unless we absolutely have to - IE, // there are things that require a major:minor to path translation. diff --git a/libpod/define/podstate.go b/libpod/define/podstate.go new file mode 100644 index 000000000..2b59aabfb --- /dev/null +++ b/libpod/define/podstate.go @@ -0,0 +1,19 @@ +package define + +const ( + // PodStateCreated indicates the pod is created but has not been started + PodStateCreated = "Created" + // PodStateErrored indicates the pod is in an errored state where + // information about it can no longer be retrieved + PodStateErrored = "Error" + // PodStateExited indicates the pod ran but has been stopped + PodStateExited = "Exited" + // PodStatePaused indicates the pod has been paused + PodStatePaused = "Paused" + // PodStateRunning indicates that one or more of the containers in + // the pod is running + PodStateRunning = "Running" + // PodStateStopped indicates all of the containers belonging to the pod + // are stopped. + PodStateStopped = "Stopped" +) diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index 0e8a64865..722012386 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -1425,11 +1425,22 @@ func startCommandGivenSelinux(cmd *exec.Cmd) error { // it then signals for conmon to start by sending nonse data down the start fd func (r *ConmonOCIRuntime) moveConmonToCgroupAndSignal(ctr *Container, cmd *exec.Cmd, startFd *os.File) error { mustCreateCgroup := true - // If cgroup creation is disabled - just signal. + if ctr.config.NoCgroups { mustCreateCgroup = false } + // If cgroup creation is disabled - just signal. + switch ctr.config.CgroupsMode { + case "disabled", "no-conmon": + mustCreateCgroup = false + } + + // $INVOCATION_ID is set by systemd when running as a service. + if os.Getenv("INVOCATION_ID") != "" { + mustCreateCgroup = false + } + if mustCreateCgroup { cgroupParent := ctr.CgroupParent() if r.cgroupManager == define.SystemdCgroupsManager { diff --git a/libpod/options.go b/libpod/options.go index 8bc5a541d..593037382 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -1078,25 +1078,26 @@ func WithLogTag(tag string) CtrCreateOption { } -// WithNoCgroups disables the creation of CGroups for the new container. -func WithNoCgroups() CtrCreateOption { +// WithCgroupsMode disables the creation of CGroups for the conmon process. +func WithCgroupsMode(mode string) CtrCreateOption { return func(ctr *Container) error { if ctr.valid { return define.ErrCtrFinalized } - if ctr.config.CgroupParent != "" { - return errors.Wrapf(define.ErrInvalidArg, "NoCgroups conflicts with CgroupParent") - } - - if ctr.config.PIDNsCtr != "" { - return errors.Wrapf(define.ErrInvalidArg, "NoCgroups requires a private PID namespace and cannot be used when PID namespace is shared with another container") + switch mode { + case "disabled": + ctr.config.NoCgroups = true + ctr.config.CgroupsMode = mode + case "enabled", "no-conmon": + ctr.config.CgroupsMode = mode + default: + return errors.Wrapf(define.ErrInvalidArg, "Invalid cgroup mode %q", mode) } - ctr.config.NoCgroups = true - return nil } + } // WithCgroupParent sets the Cgroup Parent of the new container. diff --git a/libpod/pod_status.go b/libpod/pod_status.go new file mode 100644 index 000000000..3a44c4457 --- /dev/null +++ b/libpod/pod_status.go @@ -0,0 +1,59 @@ +package libpod + +import "github.com/containers/libpod/libpod/define" + +// GetPodStatus determines the status of the pod based on the +// statuses of the containers in the pod. +// Returns a string representation of the pod status +func (p *Pod) GetPodStatus() (string, error) { + ctrStatuses, err := p.Status() + if err != nil { + return define.PodStateErrored, err + } + return CreatePodStatusResults(ctrStatuses) +} + +func CreatePodStatusResults(ctrStatuses map[string]define.ContainerStatus) (string, error) { + ctrNum := len(ctrStatuses) + if ctrNum == 0 { + return define.PodStateCreated, nil + } + statuses := map[string]int{ + define.PodStateStopped: 0, + define.PodStateRunning: 0, + define.PodStatePaused: 0, + define.PodStateCreated: 0, + define.PodStateErrored: 0, + } + for _, ctrStatus := range ctrStatuses { + switch ctrStatus { + case define.ContainerStateExited: + fallthrough + case define.ContainerStateStopped: + statuses[define.PodStateStopped]++ + case define.ContainerStateRunning: + statuses[define.PodStateRunning]++ + case define.ContainerStatePaused: + statuses[define.PodStatePaused]++ + case define.ContainerStateCreated, define.ContainerStateConfigured: + statuses[define.PodStateCreated]++ + default: + statuses[define.PodStateErrored]++ + } + } + + switch { + case statuses[define.PodStateRunning] > 0: + return define.PodStateRunning, nil + case statuses[define.PodStatePaused] == ctrNum: + return define.PodStatePaused, nil + case statuses[define.PodStateStopped] == ctrNum: + return define.PodStateExited, nil + case statuses[define.PodStateStopped] > 0: + return define.PodStateStopped, nil + case statuses[define.PodStateErrored] > 0: + return define.PodStateErrored, nil + default: + return define.PodStateCreated, nil + } +} diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index de7cfd3b8..e8952967d 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -836,3 +836,44 @@ func (r *Runtime) GetLatestContainer() (*Container, error) { } return ctrs[lastCreatedIndex], nil } + +// PruneContainers removes stopped and exited containers from localstorage. A set of optional filters +// can be provided to be more granular. +func (r *Runtime) PruneContainers(filterFuncs []ContainerFilter) (map[string]int64, map[string]error, error) { + pruneErrors := make(map[string]error) + prunedContainers := make(map[string]int64) + // We add getting the exited and stopped containers via a filter + containerStateFilter := func(c *Container) bool { + if c.PodID() != "" { + return false + } + state, err := c.State() + if err != nil { + logrus.Error(err) + return false + } + if state == define.ContainerStateStopped || state == define.ContainerStateExited { + return true + } + return false + } + filterFuncs = append(filterFuncs, containerStateFilter) + delContainers, err := r.GetContainers(filterFuncs...) + if err != nil { + return nil, nil, err + } + for _, c := range delContainers { + ctr := c + size, err := ctr.RWSize() + if err != nil { + pruneErrors[ctr.ID()] = err + continue + } + err = r.RemoveContainer(context.Background(), ctr, false, false) + pruneErrors[ctr.ID()] = err + if err != nil { + prunedContainers[ctr.ID()] = size + } + } + return prunedContainers, pruneErrors, nil +} diff --git a/libpod/runtime_pod.go b/libpod/runtime_pod.go index 66f9b10c9..e1dc31391 100644 --- a/libpod/runtime_pod.go +++ b/libpod/runtime_pod.go @@ -182,3 +182,31 @@ func (r *Runtime) GetRunningPods() ([]*Pod, error) { } return runningPods, nil } + +// PrunePods removes unused pods and their containers from local storage. +// If force is given, then running pods are also included in the pruning. +func (r *Runtime) PrunePods() (map[string]error, error) { + response := make(map[string]error) + states := []string{define.PodStateStopped, define.PodStateExited} + filterFunc := func(p *Pod) bool { + state, _ := p.GetPodStatus() + for _, status := range states { + if state == status { + return true + } + } + return false + } + pods, err := r.Pods(filterFunc) + if err != nil { + return nil, err + } + if len(pods) < 1 { + return response, nil + } + for _, pod := range pods { + err := r.removePod(context.TODO(), pod, true, false) + response[pod.ID()] = err + } + return response, nil +} |