summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/boltdb_state.go2
-rw-r--r--libpod/common/common.go6
-rw-r--r--libpod/container_api.go6
-rw-r--r--libpod/container_exec.go56
-rw-r--r--libpod/container_internal.go23
-rw-r--r--libpod/container_internal_linux.go14
-rw-r--r--libpod/container_path_resolution.go1
-rw-r--r--libpod/define/containerstate.go1
-rw-r--r--libpod/doc.go11
-rw-r--r--libpod/events/config.go2
-rw-r--r--libpod/events/events.go2
-rw-r--r--libpod/events/logfile.go5
-rw-r--r--libpod/networking_linux.go4
-rw-r--r--libpod/networking_machine.go15
-rw-r--r--libpod/networking_slirp4netns.go7
-rw-r--r--libpod/oci_conmon_exec_linux.go7
-rw-r--r--libpod/oci_conmon_linux.go15
-rw-r--r--libpod/pod.go9
-rw-r--r--libpod/runtime_ctr.go1
-rw-r--r--libpod/runtime_pod_linux.go3
-rw-r--r--libpod/stats.go22
-rw-r--r--libpod/volume.go12
22 files changed, 144 insertions, 80 deletions
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go
index 6389431ab..9745121c7 100644
--- a/libpod/boltdb_state.go
+++ b/libpod/boltdb_state.go
@@ -366,7 +366,7 @@ func (s *BoltState) GetDBConfig() (*DBConfig, error) {
err = db.View(func(tx *bolt.Tx) error {
configBucket, err := getRuntimeConfigBucket(tx)
if err != nil {
- return nil
+ return err
}
// Some of these may be nil
diff --git a/libpod/common/common.go b/libpod/common/common.go
index 93a736af2..34cabeadc 100644
--- a/libpod/common/common.go
+++ b/libpod/common/common.go
@@ -1,16 +1,16 @@
package common
-// IsTrue determines whether the given string equals "true"
+// IsTrue determines whether the given string equals "true".
func IsTrue(str string) bool {
return str == "true"
}
-// IsFalse determines whether the given string equals "false"
+// IsFalse determines whether the given string equals "false".
func IsFalse(str string) bool {
return str == "false"
}
-// IsValidBool determines whether the given string equals "true" or "false"
+// IsValidBool determines whether the given string equals "true" or "false".
func IsValidBool(str string) bool {
return IsTrue(str) || IsFalse(str)
}
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 03b3dcc04..0b6139335 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -921,7 +921,11 @@ func (c *Container) Stat(ctx context.Context, containerPath string) (*define.Fil
if err != nil {
return nil, err
}
- defer c.unmount(false)
+ defer func() {
+ if err := c.unmount(false); err != nil {
+ logrus.Errorf("Unmounting container %s: %v", c.ID(), err)
+ }
+ }()
}
info, _, _, err := c.stat(ctx, mountPoint, containerPath)
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index d1c190905..140267f28 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -341,22 +341,60 @@ func (c *Container) ExecStartAndAttach(sessionID string, streams *define.AttachS
}
lastErr = tmpErr
- exitCode, err := c.readExecExitCode(session.ID())
- if err != nil {
+ exitCode, exitCodeErr := c.readExecExitCode(session.ID())
+
+ // Lock again.
+ // Important: we must lock and sync *before* the above error is handled.
+ // We need info from the database to handle the error.
+ if !c.batched {
+ c.lock.Lock()
+ }
+ // We can't reuse the old exec session (things may have changed from
+ // other use, the container was unlocked).
+ // So re-sync and get a fresh copy.
+ // If we can't do this, no point in continuing, any attempt to save
+ // would write garbage to the DB.
+ if err := c.syncContainer(); err != nil {
+ if errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved) {
+ // We can't save status, but since the container has
+ // been entirely removed, we don't have to; exit cleanly
+ return lastErr
+ }
if lastErr != nil {
logrus.Errorf("Container %s exec session %s error: %v", c.ID(), session.ID(), lastErr)
}
- lastErr = err
- }
+ return errors.Wrapf(err, "error syncing container %s state to update exec session %s", c.ID(), sessionID)
+ }
+
+ // Now handle the error from readExecExitCode above.
+ if exitCodeErr != nil {
+ newSess, ok := c.state.ExecSessions[sessionID]
+ if !ok {
+ // The exec session was removed entirely, probably by
+ // the cleanup process. When it did so, it should have
+ // written an event with the exit code.
+ // Given that, there's nothing more we can do.
+ logrus.Infof("Container %s exec session %s already removed", c.ID(), session.ID())
+ return lastErr
+ }
- logrus.Debugf("Container %s exec session %s completed with exit code %d", c.ID(), session.ID(), exitCode)
+ if newSess.State == define.ExecStateStopped {
+ // Exec session already cleaned up.
+ // Exit code should be recorded, so it's OK if we were
+ // not able to read it.
+ logrus.Infof("Container %s exec session %s already cleaned up", c.ID(), session.ID())
+ return lastErr
+ }
- // Lock again
- if !c.batched {
- c.lock.Lock()
+ if lastErr != nil {
+ logrus.Errorf("Container %s exec session %s error: %v", c.ID(), session.ID(), lastErr)
+ }
+ lastErr = exitCodeErr
}
- if err := writeExecExitCode(c, session.ID(), exitCode); err != nil {
+ logrus.Debugf("Container %s exec session %s completed with exit code %d", c.ID(), session.ID(), exitCode)
+
+ if err := justWriteExecExitCode(c, session.ID(), exitCode); err != nil {
if lastErr != nil {
logrus.Errorf("Container %s exec session %s error: %v", c.ID(), session.ID(), lastErr)
}
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index 3c21cade8..0db59f2fe 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -99,15 +99,8 @@ func (c *Container) rootFsSize() (int64, error) {
// rwSize gets the size of the mutable top layer of the container.
func (c *Container) rwSize() (int64, error) {
if c.config.Rootfs != "" {
- var size int64
- err := filepath.Walk(c.config.Rootfs, func(path string, info os.FileInfo, err error) error {
- if err != nil {
- return err
- }
- size += info.Size()
- return nil
- })
- return size, err
+ size, err := util.SizeOfPath(c.config.Rootfs)
+ return int64(size), err
}
container, err := c.runtime.store.Container(c.ID())
@@ -1087,13 +1080,6 @@ func (c *Container) init(ctx context.Context, retainRetries bool) error {
// With the spec complete, do an OCI create
if _, err = c.ociRuntime.CreateContainer(c, nil); err != nil {
- // Fedora 31 is carrying a patch to display improved error
- // messages to better handle the V2 transition. This is NOT
- // upstream in any OCI runtime.
- // TODO: Remove once runc supports cgroupsv2
- if strings.Contains(err.Error(), "this version of runc doesn't work on cgroups v2") {
- logrus.Errorf("Oci runtime %q does not support Cgroups V2: use system migrate to mitigate", c.ociRuntime.Name())
- }
return err
}
@@ -1268,7 +1254,10 @@ func (c *Container) start() error {
}
}
- if c.config.HealthCheckConfig != nil {
+ // Check if healthcheck is not nil and --no-healthcheck option is not set.
+ // If --no-healthcheck is set Test will be always set to `[NONE]` so no need
+ // to update status in such case.
+ if c.config.HealthCheckConfig != nil && !(len(c.config.HealthCheckConfig.Test) == 1 && c.config.HealthCheckConfig.Test[0] == "NONE") {
if err := c.updateHealthStatus(define.HealthCheckStarting); err != nil {
logrus.Error(err)
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 75250b9b1..11ca169ca 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -968,6 +968,16 @@ func (c *Container) mountNotifySocket(g generate.Generator) error {
// systemd expects to have /run, /run/lock and /tmp on tmpfs
// It also expects to be able to write to /sys/fs/cgroup/systemd and /var/log/journal
func (c *Container) setupSystemd(mounts []spec.Mount, g generate.Generator) error {
+ var containerUUIDSet bool
+ for _, s := range c.config.Spec.Process.Env {
+ if strings.HasPrefix(s, "container_uuid=") {
+ containerUUIDSet = true
+ break
+ }
+ }
+ if !containerUUIDSet {
+ g.AddProcessEnv("container_uuid", c.ID()[:32])
+ }
options := []string{"rw", "rprivate", "nosuid", "nodev"}
for _, dest := range []string{"/run", "/run/lock"} {
if MountExists(mounts, dest) {
@@ -2587,7 +2597,7 @@ func (c *Container) generateUserGroupEntry(addedGID int) (string, int, error) {
gid, err := strconv.ParseUint(group, 10, 32)
if err != nil {
- return "", 0, nil
+ return "", 0, nil // nolint: nilerr
}
if addedGID != 0 && addedGID == int(gid) {
@@ -2740,7 +2750,7 @@ func (c *Container) generateUserPasswdEntry(addedUID int) (string, int, int, err
// If a non numeric User, then don't generate passwd
uid, err := strconv.ParseUint(userspec, 10, 32)
if err != nil {
- return "", 0, 0, nil
+ return "", 0, 0, nil // nolint: nilerr
}
if addedUID != 0 && int(uid) == addedUID {
diff --git a/libpod/container_path_resolution.go b/libpod/container_path_resolution.go
index 7db23b783..80a3749f5 100644
--- a/libpod/container_path_resolution.go
+++ b/libpod/container_path_resolution.go
@@ -1,4 +1,3 @@
-// +linux
package libpod
import (
diff --git a/libpod/define/containerstate.go b/libpod/define/containerstate.go
index 23ba1f451..9ad3aec08 100644
--- a/libpod/define/containerstate.go
+++ b/libpod/define/containerstate.go
@@ -138,7 +138,6 @@ type ContainerStats struct {
CPU float64
CPUNano uint64
CPUSystemNano uint64
- DataPoints int64
SystemNano uint64
MemUsage uint64
MemLimit uint64
diff --git a/libpod/doc.go b/libpod/doc.go
new file mode 100644
index 000000000..948153181
--- /dev/null
+++ b/libpod/doc.go
@@ -0,0 +1,11 @@
+// The libpod library is not stable and we do not support use cases outside of
+// this repository. The API can change at any time even with patch releases.
+//
+// If you need a stable interface Podman provides a HTTP API which follows semver,
+// please see https://docs.podman.io/en/latest/markdown/podman-system-service.1.html
+// to start the api service and https://docs.podman.io/en/latest/_static/api.html
+// for the API reference.
+//
+// We also provide stable go bindings to talk to the api service from another go
+// program, see the pkg/bindings directory.
+package libpod
diff --git a/libpod/events/config.go b/libpod/events/config.go
index d88d7b6e3..188d15578 100644
--- a/libpod/events/config.go
+++ b/libpod/events/config.go
@@ -162,6 +162,8 @@ const (
Refresh Status = "refresh"
// Remove ...
Remove Status = "remove"
+ // Rename indicates that a container was renamed
+ Rename Status = "rename"
// Renumber indicates that lock numbers were reallocated at user
// request.
Renumber Status = "renumber"
diff --git a/libpod/events/events.go b/libpod/events/events.go
index 16dd6424e..d7bba7295 100644
--- a/libpod/events/events.go
+++ b/libpod/events/events.go
@@ -188,6 +188,8 @@ func StringToStatus(name string) (Status, error) {
return Refresh, nil
case Remove.String():
return Remove, nil
+ case Rename.String():
+ return Rename, nil
case Renumber.String():
return Renumber, nil
case Restart.String():
diff --git a/libpod/events/logfile.go b/libpod/events/logfile.go
index be2aaacca..76173cde9 100644
--- a/libpod/events/logfile.go
+++ b/libpod/events/logfile.go
@@ -9,6 +9,7 @@ import (
"github.com/containers/podman/v4/pkg/util"
"github.com/containers/storage/pkg/lockfile"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// EventLogFile is the structure for event writing to a logfile. It contains the eventer
@@ -59,7 +60,9 @@ func (e EventLogFile) Read(ctx context.Context, options ReadOptions) error {
}
go func() {
time.Sleep(time.Until(untilTime))
- t.Stop()
+ if err := t.Stop(); err != nil {
+ logrus.Errorf("Stopping logger: %v", err)
+ }
}()
}
funcDone := make(chan bool)
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index d2d1e12cb..db36ac75d 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -1002,7 +1002,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
}
}
// do not propagate error inspecting a joined network ns
- logrus.Errorf("Error inspecting network namespace: %s of container %s: %v", networkNSPath, c.ID(), err)
+ logrus.Errorf("Inspecting network namespace: %s of container %s: %v", networkNSPath, c.ID(), err)
}
// We can't do more if the network is down.
@@ -1149,7 +1149,7 @@ func (c *Container) inspectJoinedNetworkNS(networkns string) (q types.StatusBloc
// result
func resultToBasicNetworkConfig(result types.StatusBlock) (define.InspectBasicNetworkConfig, error) {
config := define.InspectBasicNetworkConfig{}
- interfaceNames := make([]string, len(result.Interfaces))
+ interfaceNames := make([]string, 0, len(result.Interfaces))
for interfaceName := range result.Interfaces {
interfaceNames = append(interfaceNames, interfaceName)
}
diff --git a/libpod/networking_machine.go b/libpod/networking_machine.go
index ca759b893..d2a6b7cfa 100644
--- a/libpod/networking_machine.go
+++ b/libpod/networking_machine.go
@@ -11,6 +11,7 @@ import (
"net/http"
"strconv"
"strings"
+ "time"
"github.com/containers/common/libnetwork/types"
"github.com/sirupsen/logrus"
@@ -36,7 +37,18 @@ func requestMachinePorts(expose bool, ports []types.PortMapping) error {
url = url + "unexpose"
}
ctx := context.Background()
- client := &http.Client{}
+ client := &http.Client{
+ Transport: &http.Transport{
+ // make sure to not set a proxy here so explicitly ignore the proxy
+ // since we want to talk directly to gvproxy
+ // https://github.com/containers/podman/issues/13628
+ Proxy: nil,
+ MaxIdleConns: 50,
+ IdleConnTimeout: 30 * time.Second,
+ TLSHandshakeTimeout: 10 * time.Second,
+ ExpectContinueTimeout: 1 * time.Second,
+ },
+ }
buf := new(bytes.Buffer)
for num, port := range ports {
protocols := strings.Split(port.Protocol, ",")
@@ -78,7 +90,6 @@ func requestMachinePorts(expose bool, ports []types.PortMapping) error {
}
func makeMachineRequest(ctx context.Context, client *http.Client, url string, buf io.Reader) error {
- //var buf io.ReadWriter
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, buf)
if err != nil {
return err
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index a7a002657..3f6c4bef2 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -216,8 +216,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
var err error
path, err = exec.LookPath("slirp4netns")
if err != nil {
- logrus.Errorf("Could not find slirp4netns, the network namespace won't be configured: %v", err)
- return nil
+ return fmt.Errorf("could not find slirp4netns, the network namespace can't be configured: %w", err)
}
}
@@ -338,7 +337,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
return err
}
- // wait until slirp4nets is ready before reseting this value
+ // wait until slirp4nets is ready before resetting this value
slirpReadyWg.Wait()
return ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644)
})
@@ -662,7 +661,7 @@ func (r *Runtime) setupRootlessPortMappingViaSlirp(ctr *Container, cmd *exec.Cmd
return errors.Wrapf(err, "error parsing error status from slirp4netns")
}
if e, found := y["error"]; found {
- return errors.Errorf("error from slirp4netns while setting up port redirection: %v", e)
+ return errors.Errorf("from slirp4netns while setting up port redirection: %v", e)
}
}
logrus.Debug("slirp4netns port-forwarding setup via add_hostfwd is ready")
diff --git a/libpod/oci_conmon_exec_linux.go b/libpod/oci_conmon_exec_linux.go
index aa970bbde..65123b37e 100644
--- a/libpod/oci_conmon_exec_linux.go
+++ b/libpod/oci_conmon_exec_linux.go
@@ -758,11 +758,14 @@ func prepareProcessExec(c *Container, options *ExecOptions, env []string, sessio
} else {
pspec.Capabilities.Bounding = ctrSpec.Process.Capabilities.Bounding
}
+
+ // Always unset the inheritable capabilities similarly to what the Linux kernel does
+ // They are used only when using capabilities with uid != 0.
+ pspec.Capabilities.Inheritable = []string{}
+
if execUser.Uid == 0 {
pspec.Capabilities.Effective = pspec.Capabilities.Bounding
- pspec.Capabilities.Inheritable = pspec.Capabilities.Bounding
pspec.Capabilities.Permitted = pspec.Capabilities.Bounding
- pspec.Capabilities.Ambient = pspec.Capabilities.Bounding
} else {
if user == c.config.User {
pspec.Capabilities.Effective = ctrSpec.Process.Capabilities.Effective
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 735b1f09b..38bf85834 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -750,7 +750,7 @@ func openControlFile(ctr *Container, parentDir string) (*os.File, error) {
for i := 0; i < 600; i++ {
controlFile, err := os.OpenFile(controlPath, unix.O_WRONLY|unix.O_NONBLOCK, 0)
if err == nil {
- return controlFile, err
+ return controlFile, nil
}
if !isRetryable(err) {
return nil, errors.Wrapf(err, "could not open ctl file for terminal resize for container %s", ctr.ID())
@@ -1015,7 +1015,8 @@ func (r *ConmonOCIRuntime) getLogTag(ctr *Container) (string, error) {
}
data, err := ctr.inspectLocked(false)
if err != nil {
- return "", nil
+ // FIXME: this error should probably be returned
+ return "", nil // nolint: nilerr
}
tmpl, err := template.New("container").Parse(logTag)
if err != nil {
@@ -1371,7 +1372,7 @@ func (r *ConmonOCIRuntime) sharedConmonArgs(ctr *Container, cuuid, bundlePath, p
case define.JSONLogging:
fallthrough
//lint:ignore ST1015 the default case has to be here
- default: //nolint-stylecheck
+ default: //nolint:stylecheck
// No case here should happen except JSONLogging, but keep this here in case the options are extended
logrus.Errorf("%s logging specified but not supported. Choosing k8s-file logging instead", ctr.LogDriver())
fallthrough
@@ -1586,17 +1587,19 @@ func readConmonPipeData(runtimeName string, pipe *os.File, ociLog string) (int,
var si *syncInfo
rdr := bufio.NewReader(pipe)
b, err := rdr.ReadBytes('\n')
- if err != nil {
+ // ignore EOF here, error is returned even when data was read
+ // if it is no valid json unmarshal will fail below
+ if err != nil && !errors.Is(err, io.EOF) {
ch <- syncStruct{err: err}
}
if err := json.Unmarshal(b, &si); err != nil {
- ch <- syncStruct{err: err}
+ ch <- syncStruct{err: fmt.Errorf("conmon bytes %q: %w", string(b), err)}
return
}
ch <- syncStruct{si: si}
}()
- data := -1
+ data := -1 //nolint: wastedassign
select {
case ss := <-ch:
if ss.err != nil {
diff --git a/libpod/pod.go b/libpod/pod.go
index 6273ff247..ed2d97b37 100644
--- a/libpod/pod.go
+++ b/libpod/pod.go
@@ -422,10 +422,6 @@ type PodContainerStats struct {
// GetPodStats returns the stats for each of its containers
func (p *Pod) GetPodStats(previousContainerStats map[string]*define.ContainerStats) (map[string]*define.ContainerStats, error) {
- var (
- ok bool
- prevStat *define.ContainerStats
- )
p.lock.Lock()
defer p.lock.Unlock()
@@ -438,10 +434,7 @@ func (p *Pod) GetPodStats(previousContainerStats map[string]*define.ContainerSta
}
newContainerStats := make(map[string]*define.ContainerStats)
for _, c := range containers {
- if prevStat, ok = previousContainerStats[c.ID()]; !ok {
- prevStat = &define.ContainerStats{}
- }
- newStats, err := c.GetContainerStats(prevStat)
+ newStats, err := c.GetContainerStats(previousContainerStats[c.ID()])
// If the container wasn't running, don't include it
// but also suppress the error
if err != nil && errors.Cause(err) != define.ErrCtrStateInvalid {
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index fc1a688fb..8c3d283a5 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -155,6 +155,7 @@ func (r *Runtime) RenameContainer(ctx context.Context, ctr *Container, newName s
return nil, err
}
+ ctr.newContainerEvent(events.Rename)
return ctr, nil
}
diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go
index 230491c1a..2bbccfdf6 100644
--- a/libpod/runtime_pod_linux.go
+++ b/libpod/runtime_pod_linux.go
@@ -6,6 +6,7 @@ package libpod
import (
"context"
"fmt"
+ "os"
"path"
"path/filepath"
"strings"
@@ -239,7 +240,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
// Don't try if we failed to retrieve the cgroup
if err == nil {
- if err := conmonCgroup.Update(resLimits); err != nil {
+ if err := conmonCgroup.Update(resLimits); err != nil && !os.IsNotExist(err) {
logrus.Warnf("Error updating pod %s conmon cgroup PID limit: %v", p.ID(), err)
}
}
diff --git a/libpod/stats.go b/libpod/stats.go
index b5d39240d..25baa378d 100644
--- a/libpod/stats.go
+++ b/libpod/stats.go
@@ -14,7 +14,9 @@ import (
"github.com/pkg/errors"
)
-// GetContainerStats gets the running stats for a given container
+// GetContainerStats gets the running stats for a given container.
+// The previousStats is used to correctly calculate cpu percentages. You
+// should pass nil if there is no previous stat for this container.
func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*define.ContainerStats, error) {
stats := new(define.ContainerStats)
stats.ContainerID = c.ID()
@@ -36,6 +38,14 @@ func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*de
return stats, define.ErrCtrStateInvalid
}
+ if previousStats == nil {
+ previousStats = &define.ContainerStats{
+ // if we have no prev stats use the container start time as prev time
+ // otherwise we cannot correctly calculate the CPU percentage
+ SystemNano: uint64(c.state.StartedTime.UnixNano()),
+ }
+ }
+
cgroupPath, err := c.cGroupPath()
if err != nil {
return nil, err
@@ -67,8 +77,8 @@ func (c *Container) GetContainerStats(previousStats *define.ContainerStats) (*de
stats.Duration = cgroupStats.CPU.Usage.Total
stats.UpTime = time.Duration(stats.Duration)
stats.CPU = calculateCPUPercent(cgroupStats, previousCPU, now, previousStats.SystemNano)
- stats.AvgCPU = calculateAvgCPU(stats.CPU, previousStats.AvgCPU, previousStats.DataPoints)
- stats.DataPoints = previousStats.DataPoints + 1
+ // calc the average cpu usage for the time the container is running
+ stats.AvgCPU = calculateCPUPercent(cgroupStats, 0, now, uint64(c.state.StartedTime.UnixNano()))
stats.MemUsage = cgroupStats.Memory.Usage.Usage
stats.MemLimit = c.getMemLimit()
stats.MemPerc = (float64(stats.MemUsage) / float64(stats.MemLimit)) * 100
@@ -146,9 +156,3 @@ func calculateBlockIO(stats *cgroups.Metrics) (read uint64, write uint64) {
}
return
}
-
-// calculateAvgCPU calculates the avg CPU percentage given the previous average and the number of data points.
-func calculateAvgCPU(statsCPU float64, prevAvg float64, prevData int64) float64 {
- avgPer := ((prevAvg * float64(prevData)) + statsCPU) / (float64(prevData) + 1)
- return avgPer
-}
diff --git a/libpod/volume.go b/libpod/volume.go
index f79ceaa87..bffafdc15 100644
--- a/libpod/volume.go
+++ b/libpod/volume.go
@@ -1,13 +1,12 @@
package libpod
import (
- "os"
- "path/filepath"
"time"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/lock"
"github.com/containers/podman/v4/libpod/plugin"
+ "github.com/containers/podman/v4/pkg/util"
)
// Volume is a libpod named volume.
@@ -93,14 +92,7 @@ func (v *Volume) Name() string {
// Returns the size on disk of volume
func (v *Volume) Size() (uint64, error) {
- var size uint64
- err := filepath.Walk(v.config.MountPoint, func(path string, info os.FileInfo, err error) error {
- if err == nil && !info.IsDir() {
- size += (uint64)(info.Size())
- }
- return err
- })
- return size, err
+ return util.SizeOfPath(v.config.MountPoint)
}
// Driver retrieves the volume's driver.