summaryrefslogtreecommitdiff
path: root/pkg/domain
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/domain')
-rw-r--r--pkg/domain/entities/engine_container.go1
-rw-r--r--pkg/domain/entities/manifest.go1
-rw-r--r--pkg/domain/entities/pods.go48
-rw-r--r--pkg/domain/infra/abi/manifest.go1
-rw-r--r--pkg/domain/infra/abi/pods.go25
-rw-r--r--pkg/domain/infra/abi/pods_stats.go85
-rw-r--r--pkg/domain/infra/tunnel/manifest.go1
-rw-r--r--pkg/domain/infra/tunnel/pods.go4
8 files changed, 161 insertions, 5 deletions
diff --git a/pkg/domain/entities/engine_container.go b/pkg/domain/entities/engine_container.go
index 8c5bc3058..502279bcf 100644
--- a/pkg/domain/entities/engine_container.go
+++ b/pkg/domain/entities/engine_container.go
@@ -53,6 +53,7 @@ type ContainerEngine interface {
PodRestart(ctx context.Context, namesOrIds []string, options PodRestartOptions) ([]*PodRestartReport, error)
PodRm(ctx context.Context, namesOrIds []string, options PodRmOptions) ([]*PodRmReport, error)
PodStart(ctx context.Context, namesOrIds []string, options PodStartOptions) ([]*PodStartReport, error)
+ PodStats(ctx context.Context, namesOrIds []string, options PodStatsOptions) ([]*PodStatsReport, error)
PodStop(ctx context.Context, namesOrIds []string, options PodStopOptions) ([]*PodStopReport, error)
PodTop(ctx context.Context, options PodTopOptions) (*StringSliceReport, error)
PodUnpause(ctx context.Context, namesOrIds []string, options PodunpauseOptions) ([]*PodUnpauseReport, error)
diff --git a/pkg/domain/entities/manifest.go b/pkg/domain/entities/manifest.go
index a9c961f9d..7316735b0 100644
--- a/pkg/domain/entities/manifest.go
+++ b/pkg/domain/entities/manifest.go
@@ -10,6 +10,7 @@ type ManifestAddOptions struct {
Arch string `json:"arch" schema:"arch"`
Features []string `json:"features" schema:"features"`
Images []string `json:"images" schema:"images"`
+ OS string `json:"os" schema:"os"`
OSVersion string `json:"os_version" schema:"os_version"`
Variant string `json:"variant" schema:"variant"`
}
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index aa1445a6a..a4896ce4d 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -1,6 +1,7 @@
package entities
import (
+ "errors"
"strings"
"time"
@@ -188,3 +189,50 @@ type PodInspectOptions struct {
type PodInspectReport struct {
*define.InspectPodData
}
+
+// PodStatsOptions are options for the pod stats command.
+type PodStatsOptions struct {
+ // All - provide stats for all running pods.
+ All bool
+ // Latest - provide stats for the latest pod.
+ Latest bool
+}
+
+// PodStatsReport includes pod-resource statistics data.
+type PodStatsReport struct {
+ CPU string
+ MemUsage string
+ Mem string
+ NetIO string
+ BlockIO string
+ PIDS string
+ Pod string
+ CID string
+ Name string
+}
+
+// ValidatePodStatsOptions validates the specified slice and options. Allows
+// for sharing code in the front- and the back-end.
+func ValidatePodStatsOptions(args []string, options *PodStatsOptions) error {
+ num := 0
+ if len(args) > 0 {
+ num++
+ }
+ if options.All {
+ num++
+ }
+ if options.Latest {
+ num++
+ }
+ switch num {
+ case 0:
+ // Podman v1 compat: if nothing's specified get all running
+ // pods.
+ options.All = true
+ return nil
+ case 1:
+ return nil
+ default:
+ return errors.New("--all, --latest and arguments cannot be used together")
+ }
+}
diff --git a/pkg/domain/infra/abi/manifest.go b/pkg/domain/infra/abi/manifest.go
index 27d4bf9a5..88331f96c 100644
--- a/pkg/domain/infra/abi/manifest.go
+++ b/pkg/domain/infra/abi/manifest.go
@@ -79,6 +79,7 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd
Arch: opts.Arch,
Features: opts.Features,
Images: opts.Images,
+ OS: opts.OS,
OSVersion: opts.OSVersion,
Variant: opts.Variant,
}
diff --git a/pkg/domain/infra/abi/pods.go b/pkg/domain/infra/abi/pods.go
index c4ae9efbf..7c06f9a4e 100644
--- a/pkg/domain/infra/abi/pods.go
+++ b/pkg/domain/infra/abi/pods.go
@@ -145,7 +145,7 @@ func (ic *ContainerEngine) PodStop(ctx context.Context, namesOrIds []string, opt
reports []*entities.PodStopReport
)
pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
- if err != nil {
+ if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchPod) {
return nil, err
}
for _, p := range pods {
@@ -180,6 +180,7 @@ func (ic *ContainerEngine) PodRestart(ctx context.Context, namesOrIds []string,
errs, err := p.Restart(ctx)
if err != nil {
report.Errs = []error{err}
+ reports = append(reports, &report)
continue
}
if len(errs) > 0 {
@@ -207,6 +208,7 @@ func (ic *ContainerEngine) PodStart(ctx context.Context, namesOrIds []string, op
errs, err := p.Start(ctx)
if err != nil {
report.Errs = []error{err}
+ reports = append(reports, &report)
continue
}
if len(errs) > 0 {
@@ -226,7 +228,7 @@ func (ic *ContainerEngine) PodRm(ctx context.Context, namesOrIds []string, optio
reports []*entities.PodRmReport
)
pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
- if err != nil {
+ if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchPod) {
return nil, err
}
for _, p := range pods {
@@ -234,6 +236,7 @@ func (ic *ContainerEngine) PodRm(ctx context.Context, namesOrIds []string, optio
err := ic.Libpod.RemovePod(ctx, p, true, options.Force)
if err != nil {
report.Err = err
+ reports = append(reports, &report)
continue
}
reports = append(reports, &report)
@@ -292,9 +295,12 @@ func (ic *ContainerEngine) PodTop(ctx context.Context, options entities.PodTopOp
func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOptions) ([]*entities.ListPodsReport, error) {
var (
+ err error
filters []libpod.PodFilter
+ pds []*libpod.Pod
reports []*entities.ListPodsReport
)
+
for k, v := range options.Filters {
for _, filter := range v {
f, err := lpfilters.GeneratePodFilterFunc(k, filter)
@@ -305,10 +311,19 @@ func (ic *ContainerEngine) PodPs(ctx context.Context, options entities.PodPSOpti
}
}
- pds, err := ic.Libpod.Pods(filters...)
- if err != nil {
- return nil, err
+ if options.Latest {
+ pod, err := ic.Libpod.GetLatestPod()
+ if err != nil {
+ return nil, err
+ }
+ pds = append(pds, pod)
+ } else {
+ pds, err = ic.Libpod.Pods(filters...)
+ if err != nil {
+ return nil, err
+ }
}
+
for _, p := range pds {
var lpcs []*entities.ListPodContainer
status, err := p.GetPodStatus()
diff --git a/pkg/domain/infra/abi/pods_stats.go b/pkg/domain/infra/abi/pods_stats.go
new file mode 100644
index 000000000..a41c01da0
--- /dev/null
+++ b/pkg/domain/infra/abi/pods_stats.go
@@ -0,0 +1,85 @@
+package abi
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/pkg/cgroups"
+ "github.com/containers/libpod/pkg/domain/entities"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/docker/go-units"
+ "github.com/pkg/errors"
+)
+
+// PodStats implements printing stats about pods.
+func (ic *ContainerEngine) PodStats(ctx context.Context, namesOrIds []string, options entities.PodStatsOptions) ([]*entities.PodStatsReport, error) {
+ // Cgroups v2 check for rootless.
+ if rootless.IsRootless() {
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return nil, err
+ }
+ if !unified {
+ return nil, errors.New("pod stats is not supported in rootless mode without cgroups v2")
+ }
+ }
+ // Get the (running) pods and convert them to the entities format.
+ pods, err := getPodsByContext(options.All, options.Latest, namesOrIds, ic.Libpod)
+ if err != nil {
+ return nil, errors.Wrap(err, "unable to get list of pods")
+ }
+ return ic.podsToStatsReport(pods)
+}
+
+// podsToStatsReport converts a slice of pods into a corresponding slice of stats reports.
+func (ic *ContainerEngine) podsToStatsReport(pods []*libpod.Pod) ([]*entities.PodStatsReport, error) {
+ reports := []*entities.PodStatsReport{}
+ for i := range pods { // Access by index to prevent potential loop-variable leaks.
+ podStats, err := pods[i].GetPodStats(nil)
+ if err != nil {
+ return nil, err
+ }
+ podID := pods[i].ID()[:12]
+ for j := range podStats {
+ r := entities.PodStatsReport{
+ CPU: floatToPercentString(podStats[j].CPU),
+ MemUsage: combineHumanValues(podStats[j].MemUsage, podStats[j].MemLimit),
+ Mem: floatToPercentString(podStats[j].MemPerc),
+ NetIO: combineHumanValues(podStats[j].NetInput, podStats[j].NetOutput),
+ BlockIO: combineHumanValues(podStats[j].BlockInput, podStats[j].BlockOutput),
+ PIDS: pidsToString(podStats[j].PIDs),
+ CID: podStats[j].ContainerID[:12],
+ Name: podStats[j].Name,
+ Pod: podID,
+ }
+ reports = append(reports, &r)
+ }
+ }
+
+ return reports, nil
+}
+
+func combineHumanValues(a, b uint64) string {
+ if a == 0 && b == 0 {
+ return "-- / --"
+ }
+ return fmt.Sprintf("%s / %s", units.HumanSize(float64(a)), units.HumanSize(float64(b)))
+}
+
+func floatToPercentString(f float64) string {
+ strippedFloat, err := libpod.RemoveScientificNotationFromFloat(f)
+ if err != nil || strippedFloat == 0 {
+ // If things go bazinga, return a safe value
+ return "--"
+ }
+ return fmt.Sprintf("%.2f", strippedFloat) + "%"
+}
+
+func pidsToString(pid uint64) string {
+ if pid == 0 {
+ // If things go bazinga, return a safe value
+ return "--"
+ }
+ return fmt.Sprintf("%d", pid)
+}
diff --git a/pkg/domain/infra/tunnel/manifest.go b/pkg/domain/infra/tunnel/manifest.go
index 338256530..18b400533 100644
--- a/pkg/domain/infra/tunnel/manifest.go
+++ b/pkg/domain/infra/tunnel/manifest.go
@@ -41,6 +41,7 @@ func (ir *ImageEngine) ManifestAdd(ctx context.Context, opts entities.ManifestAd
Arch: opts.Arch,
Features: opts.Features,
Images: opts.Images,
+ OS: opts.OS,
OSVersion: opts.OSVersion,
Variant: opts.Variant,
}
diff --git a/pkg/domain/infra/tunnel/pods.go b/pkg/domain/infra/tunnel/pods.go
index e7641c077..c193c6752 100644
--- a/pkg/domain/infra/tunnel/pods.go
+++ b/pkg/domain/infra/tunnel/pods.go
@@ -211,3 +211,7 @@ func (ic *ContainerEngine) PodInspect(ctx context.Context, options entities.PodI
}
return pods.Inspect(ic.ClientCxt, options.NameOrID)
}
+
+func (ic *ContainerEngine) PodStats(ctx context.Context, namesOrIds []string, options entities.PodStatsOptions) ([]*entities.PodStatsReport, error) {
+ return pods.Stats(ic.ClientCxt, namesOrIds, options)
+}