summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container.go5
-rw-r--r--libpod/container_inspect.go3
-rw-r--r--libpod/define/podstate.go19
-rw-r--r--libpod/oci_conmon_linux.go13
-rw-r--r--libpod/options.go21
-rw-r--r--libpod/pod_status.go59
-rw-r--r--libpod/runtime_ctr.go41
-rw-r--r--libpod/runtime_pod.go28
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
+}