libpod/runtime: switch to golang native error wrapping

We now use the golang error wrapping format specifier `%w` instead of
the deprecated github.com/pkg/errors package.

[NO NEW TESTS NEEDED]

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
This commit is contained in:
Sascha Grunert
2022-06-30 16:47:21 +02:00
parent 3e8ab31239
commit 597de7a083
19 changed files with 391 additions and 318 deletions

View File

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
@ -40,7 +41,6 @@ import (
"github.com/containers/storage/pkg/unshare" "github.com/containers/storage/pkg/unshare"
"github.com/docker/docker/pkg/namesgenerator" "github.com/docker/docker/pkg/namesgenerator"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -146,7 +146,7 @@ func SetXdgDirs() error {
} }
} }
if err := os.Setenv("XDG_RUNTIME_DIR", runtimeDir); err != nil { if err := os.Setenv("XDG_RUNTIME_DIR", runtimeDir); err != nil {
return errors.Wrapf(err, "cannot set XDG_RUNTIME_DIR") return fmt.Errorf("cannot set XDG_RUNTIME_DIR: %w", err)
} }
if rootless.IsRootless() && os.Getenv("DBUS_SESSION_BUS_ADDRESS") == "" { if rootless.IsRootless() && os.Getenv("DBUS_SESSION_BUS_ADDRESS") == "" {
@ -163,7 +163,7 @@ func SetXdgDirs() error {
return err return err
} }
if err := os.Setenv("XDG_CONFIG_HOME", cfgHomeDir); err != nil { if err := os.Setenv("XDG_CONFIG_HOME", cfgHomeDir); err != nil {
return errors.Wrapf(err, "cannot set XDG_CONFIG_HOME") return fmt.Errorf("cannot set XDG_CONFIG_HOME: %w", err)
} }
} }
return nil return nil
@ -214,7 +214,7 @@ func newRuntimeFromConfig(conf *config.Config, options ...RuntimeOption) (*Runti
// Overwrite config with user-given configuration options // Overwrite config with user-given configuration options
for _, opt := range options { for _, opt := range options {
if err := opt(runtime); err != nil { if err := opt(runtime); err != nil {
return nil, errors.Wrapf(err, "error configuring runtime") return nil, fmt.Errorf("error configuring runtime: %w", err)
} }
} }
@ -225,12 +225,12 @@ func newRuntimeFromConfig(conf *config.Config, options ...RuntimeOption) (*Runti
} }
os.Exit(1) os.Exit(1)
return nil return nil
}); err != nil && errors.Cause(err) != shutdown.ErrHandlerExists { }); err != nil && !errors.Is(err, shutdown.ErrHandlerExists) {
logrus.Errorf("Registering shutdown handler for libpod: %v", err) logrus.Errorf("Registering shutdown handler for libpod: %v", err)
} }
if err := shutdown.Start(); err != nil { if err := shutdown.Start(); err != nil {
return nil, errors.Wrapf(err, "error starting shutdown signal handler") return nil, fmt.Errorf("error starting shutdown signal handler: %w", err)
} }
if err := makeRuntime(runtime); err != nil { if err := makeRuntime(runtime); err != nil {
@ -256,10 +256,10 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) {
lockPath := filepath.Join(runtime.config.Engine.TmpDir, "locks") lockPath := filepath.Join(runtime.config.Engine.TmpDir, "locks")
manager, err = lock.OpenFileLockManager(lockPath) manager, err = lock.OpenFileLockManager(lockPath)
if err != nil { if err != nil {
if os.IsNotExist(errors.Cause(err)) { if errors.Is(err, os.ErrNotExist) {
manager, err = lock.NewFileLockManager(lockPath) manager, err = lock.NewFileLockManager(lockPath)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to get new file lock manager") return nil, fmt.Errorf("failed to get new file lock manager: %w", err)
} }
} else { } else {
return nil, err return nil, err
@ -275,19 +275,19 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) {
manager, err = lock.OpenSHMLockManager(lockPath, runtime.config.Engine.NumLocks) manager, err = lock.OpenSHMLockManager(lockPath, runtime.config.Engine.NumLocks)
if err != nil { if err != nil {
switch { switch {
case os.IsNotExist(errors.Cause(err)): case errors.Is(err, os.ErrNotExist):
manager, err = lock.NewSHMLockManager(lockPath, runtime.config.Engine.NumLocks) manager, err = lock.NewSHMLockManager(lockPath, runtime.config.Engine.NumLocks)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed to get new shm lock manager") return nil, fmt.Errorf("failed to get new shm lock manager: %w", err)
} }
case errors.Cause(err) == syscall.ERANGE && runtime.doRenumber: case errors.Is(err, syscall.ERANGE) && runtime.doRenumber:
logrus.Debugf("Number of locks does not match - removing old locks") logrus.Debugf("Number of locks does not match - removing old locks")
// ERANGE indicates a lock numbering mismatch. // ERANGE indicates a lock numbering mismatch.
// Since we're renumbering, this is not fatal. // Since we're renumbering, this is not fatal.
// Remove the earlier set of locks and recreate. // Remove the earlier set of locks and recreate.
if err := os.Remove(filepath.Join("/dev/shm", lockPath)); err != nil { if err := os.Remove(filepath.Join("/dev/shm", lockPath)); err != nil {
return nil, errors.Wrapf(err, "error removing libpod locks file %s", lockPath) return nil, fmt.Errorf("error removing libpod locks file %s: %w", lockPath, err)
} }
manager, err = lock.NewSHMLockManager(lockPath, runtime.config.Engine.NumLocks) manager, err = lock.NewSHMLockManager(lockPath, runtime.config.Engine.NumLocks)
@ -299,7 +299,7 @@ func getLockManager(runtime *Runtime) (lock.Manager, error) {
} }
} }
default: default:
return nil, errors.Wrapf(define.ErrInvalidArg, "unknown lock type %s", runtime.config.Engine.LockType) return nil, fmt.Errorf("unknown lock type %s: %w", runtime.config.Engine.LockType, define.ErrInvalidArg)
} }
return manager, nil return manager, nil
} }
@ -315,17 +315,17 @@ func makeRuntime(runtime *Runtime) (retErr error) {
runtime.conmonPath = cPath runtime.conmonPath = cPath
if runtime.noStore && runtime.doReset { if runtime.noStore && runtime.doReset {
return errors.Wrapf(define.ErrInvalidArg, "cannot perform system reset if runtime is not creating a store") return fmt.Errorf("cannot perform system reset if runtime is not creating a store: %w", define.ErrInvalidArg)
} }
if runtime.doReset && runtime.doRenumber { if runtime.doReset && runtime.doRenumber {
return errors.Wrapf(define.ErrInvalidArg, "cannot perform system reset while renumbering locks") return fmt.Errorf("cannot perform system reset while renumbering locks: %w", define.ErrInvalidArg)
} }
// Make the static files directory if it does not exist // Make the static files directory if it does not exist
if err := os.MkdirAll(runtime.config.Engine.StaticDir, 0700); err != nil { if err := os.MkdirAll(runtime.config.Engine.StaticDir, 0700); err != nil {
// The directory is allowed to exist // The directory is allowed to exist
if !os.IsExist(err) { if !errors.Is(err, os.ErrExist) {
return errors.Wrap(err, "error creating runtime static files directory") return fmt.Errorf("error creating runtime static files directory: %w", err)
} }
} }
@ -337,9 +337,9 @@ func makeRuntime(runtime *Runtime) (retErr error) {
// package. // package.
switch runtime.config.Engine.StateType { switch runtime.config.Engine.StateType {
case config.InMemoryStateStore: case config.InMemoryStateStore:
return errors.Wrapf(define.ErrInvalidArg, "in-memory state is currently disabled") return fmt.Errorf("in-memory state is currently disabled: %w", define.ErrInvalidArg)
case config.SQLiteStateStore: case config.SQLiteStateStore:
return errors.Wrapf(define.ErrInvalidArg, "SQLite state is currently disabled") return fmt.Errorf("SQLite state is currently disabled: %w", define.ErrInvalidArg)
case config.BoltDBStateStore: case config.BoltDBStateStore:
dbPath := filepath.Join(runtime.config.Engine.StaticDir, "bolt_state.db") dbPath := filepath.Join(runtime.config.Engine.StaticDir, "bolt_state.db")
@ -349,7 +349,7 @@ func makeRuntime(runtime *Runtime) (retErr error) {
} }
runtime.state = state runtime.state = state
default: default:
return errors.Wrapf(define.ErrInvalidArg, "unrecognized state type passed (%v)", runtime.config.Engine.StateType) return fmt.Errorf("unrecognized state type passed (%v): %w", runtime.config.Engine.StateType, define.ErrInvalidArg)
} }
// Grab config from the database so we can reset some defaults // Grab config from the database so we can reset some defaults
@ -369,7 +369,7 @@ func makeRuntime(runtime *Runtime) (retErr error) {
} }
} }
return errors.Wrapf(err, "error retrieving runtime configuration from database") return fmt.Errorf("error retrieving runtime configuration from database: %w", err)
} }
runtime.mergeDBConfig(dbConfig) runtime.mergeDBConfig(dbConfig)
@ -412,7 +412,7 @@ func makeRuntime(runtime *Runtime) (retErr error) {
} }
if err := runtime.state.SetNamespace(runtime.config.Engine.Namespace); err != nil { if err := runtime.state.SetNamespace(runtime.config.Engine.Namespace); err != nil {
return errors.Wrapf(err, "error setting libpod namespace in state") return fmt.Errorf("error setting libpod namespace in state: %w", err)
} }
logrus.Debugf("Set libpod namespace to %q", runtime.config.Engine.Namespace) logrus.Debugf("Set libpod namespace to %q", runtime.config.Engine.Namespace)
@ -468,16 +468,16 @@ func makeRuntime(runtime *Runtime) (retErr error) {
// Create the tmpDir // Create the tmpDir
if err := os.MkdirAll(runtime.config.Engine.TmpDir, 0751); err != nil { if err := os.MkdirAll(runtime.config.Engine.TmpDir, 0751); err != nil {
// The directory is allowed to exist // The directory is allowed to exist
if !os.IsExist(err) { if !errors.Is(err, os.ErrExist) {
return errors.Wrap(err, "error creating tmpdir") return fmt.Errorf("error creating tmpdir: %w", err)
} }
} }
// Create events log dir // Create events log dir
if err := os.MkdirAll(filepath.Dir(runtime.config.Engine.EventsLogFilePath), 0700); err != nil { if err := os.MkdirAll(filepath.Dir(runtime.config.Engine.EventsLogFilePath), 0700); err != nil {
// The directory is allowed to exist // The directory is allowed to exist
if !os.IsExist(err) { if !errors.Is(err, os.ErrExist) {
return errors.Wrap(err, "error creating events dirs") return fmt.Errorf("error creating events dirs: %w", err)
} }
} }
@ -514,7 +514,7 @@ func makeRuntime(runtime *Runtime) (retErr error) {
} else { } else {
ociRuntime, ok := runtime.ociRuntimes[runtime.config.Engine.OCIRuntime] ociRuntime, ok := runtime.ociRuntimes[runtime.config.Engine.OCIRuntime]
if !ok { if !ok {
return errors.Wrapf(define.ErrInvalidArg, "default OCI runtime %q not found", runtime.config.Engine.OCIRuntime) return fmt.Errorf("default OCI runtime %q not found: %w", runtime.config.Engine.OCIRuntime, define.ErrInvalidArg)
} }
runtime.defaultOCIRuntime = ociRuntime runtime.defaultOCIRuntime = ociRuntime
} }
@ -523,19 +523,19 @@ func makeRuntime(runtime *Runtime) (retErr error) {
// Do we have at least one valid OCI runtime? // Do we have at least one valid OCI runtime?
if len(runtime.ociRuntimes) == 0 { if len(runtime.ociRuntimes) == 0 {
return errors.Wrapf(define.ErrInvalidArg, "no OCI runtime has been configured") return fmt.Errorf("no OCI runtime has been configured: %w", define.ErrInvalidArg)
} }
// Do we have a default runtime? // Do we have a default runtime?
if runtime.defaultOCIRuntime == nil { if runtime.defaultOCIRuntime == nil {
return errors.Wrapf(define.ErrInvalidArg, "no default OCI runtime was configured") return fmt.Errorf("no default OCI runtime was configured: %w", define.ErrInvalidArg)
} }
// Make the per-boot files directory if it does not exist // Make the per-boot files directory if it does not exist
if err := os.MkdirAll(runtime.config.Engine.TmpDir, 0755); err != nil { if err := os.MkdirAll(runtime.config.Engine.TmpDir, 0755); err != nil {
// The directory is allowed to exist // The directory is allowed to exist
if !os.IsExist(err) { if !errors.Is(err, os.ErrExist) {
return errors.Wrapf(err, "error creating runtime temporary files directory") return fmt.Errorf("error creating runtime temporary files directory: %w", err)
} }
} }
@ -556,7 +556,7 @@ func makeRuntime(runtime *Runtime) (retErr error) {
runtimeAliveFile := filepath.Join(runtime.config.Engine.TmpDir, "alive") runtimeAliveFile := filepath.Join(runtime.config.Engine.TmpDir, "alive")
aliveLock, err := storage.GetLockfile(runtimeAliveLock) aliveLock, err := storage.GetLockfile(runtimeAliveLock)
if err != nil { if err != nil {
return errors.Wrapf(err, "error acquiring runtime init lock") return fmt.Errorf("error acquiring runtime init lock: %w", err)
} }
// Acquire the lock and hold it until we return // Acquire the lock and hold it until we return
// This ensures that no two processes will be in runtime.refresh at once // This ensures that no two processes will be in runtime.refresh at once
@ -586,7 +586,7 @@ func makeRuntime(runtime *Runtime) (retErr error) {
aliveLock.Unlock() // Unlock to avoid deadlock as BecomeRootInUserNS will reexec. aliveLock.Unlock() // Unlock to avoid deadlock as BecomeRootInUserNS will reexec.
pausePid, err := util.GetRootlessPauseProcessPidPathGivenDir(runtime.config.Engine.TmpDir) pausePid, err := util.GetRootlessPauseProcessPidPathGivenDir(runtime.config.Engine.TmpDir)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get pause process pid file path") return fmt.Errorf("could not get pause process pid file path: %w", err)
} }
became, ret, err := rootless.BecomeRootInUserNS(pausePid) became, ret, err := rootless.BecomeRootInUserNS(pausePid)
if err != nil { if err != nil {
@ -607,10 +607,10 @@ func makeRuntime(runtime *Runtime) (retErr error) {
// This will trigger on first use as well, but refreshing an // This will trigger on first use as well, but refreshing an
// empty state only creates a single file // empty state only creates a single file
// As such, it's not really a performance concern // As such, it's not really a performance concern
if os.IsNotExist(err) { if errors.Is(err, os.ErrNotExist) {
doRefresh = true doRefresh = true
} else { } else {
return errors.Wrapf(err, "error reading runtime status file %s", runtimeAliveFile) return fmt.Errorf("error reading runtime status file %s: %w", runtimeAliveFile, err)
} }
} }
@ -704,14 +704,14 @@ func findConmon(conmonPaths []string) (string, error) {
} }
if foundOutdatedConmon { if foundOutdatedConmon {
return "", errors.Wrapf(define.ErrConmonOutdated, return "", fmt.Errorf(
"please update to v%d.%d.%d or later", "please update to v%d.%d.%d or later: %w",
conmonMinMajorVersion, conmonMinMinorVersion, conmonMinPatchVersion) conmonMinMajorVersion, conmonMinMinorVersion, conmonMinPatchVersion, define.ErrConmonOutdated)
} }
return "", errors.Wrapf(define.ErrInvalidArg, return "", fmt.Errorf(
"could not find a working conmon binary (configured options: %v)", "could not find a working conmon binary (configured options: %v): %w",
conmonPaths) conmonPaths, define.ErrInvalidArg)
} }
// probeConmon calls conmon --version and verifies it is a new enough version for // probeConmon calls conmon --version and verifies it is a new enough version for
@ -728,11 +728,11 @@ func probeConmon(conmonBinary string) error {
matches := r.FindStringSubmatch(out.String()) matches := r.FindStringSubmatch(out.String())
if len(matches) != 4 { if len(matches) != 4 {
return errors.Wrap(err, define.ErrConmonVersionFormat) return fmt.Errorf("%v: %w", define.ErrConmonVersionFormat, err)
} }
major, err := strconv.Atoi(matches[1]) major, err := strconv.Atoi(matches[1])
if err != nil { if err != nil {
return errors.Wrap(err, define.ErrConmonVersionFormat) return fmt.Errorf("%v: %w", define.ErrConmonVersionFormat, err)
} }
if major < conmonMinMajorVersion { if major < conmonMinMajorVersion {
return define.ErrConmonOutdated return define.ErrConmonOutdated
@ -743,7 +743,7 @@ func probeConmon(conmonBinary string) error {
minor, err := strconv.Atoi(matches[2]) minor, err := strconv.Atoi(matches[2])
if err != nil { if err != nil {
return errors.Wrap(err, define.ErrConmonVersionFormat) return fmt.Errorf("%v: %w", define.ErrConmonVersionFormat, err)
} }
if minor < conmonMinMinorVersion { if minor < conmonMinMinorVersion {
return define.ErrConmonOutdated return define.ErrConmonOutdated
@ -754,7 +754,7 @@ func probeConmon(conmonBinary string) error {
patch, err := strconv.Atoi(matches[3]) patch, err := strconv.Atoi(matches[3])
if err != nil { if err != nil {
return errors.Wrap(err, define.ErrConmonVersionFormat) return fmt.Errorf("%v: %w", define.ErrConmonVersionFormat, err)
} }
if patch < conmonMinPatchVersion { if patch < conmonMinPatchVersion {
return define.ErrConmonOutdated return define.ErrConmonOutdated
@ -798,7 +798,7 @@ func (r *Runtime) GetConfig() (*config.Config, error) {
// Copy so the caller won't be able to modify the actual config // Copy so the caller won't be able to modify the actual config
if err := JSONDeepCopy(rtConfig, config); err != nil { if err := JSONDeepCopy(rtConfig, config); err != nil {
return nil, errors.Wrapf(err, "error copying config") return nil, fmt.Errorf("error copying config: %w", err)
} }
return config, nil return config, nil
@ -909,7 +909,7 @@ func (r *Runtime) Shutdown(force bool) error {
// Note that the libimage runtime shuts down the store. // Note that the libimage runtime shuts down the store.
if err := r.libimageRuntime.Shutdown(force); err != nil { if err := r.libimageRuntime.Shutdown(force); err != nil {
lastError = errors.Wrapf(err, "error shutting down container storage") lastError = fmt.Errorf("error shutting down container storage: %w", err)
} }
} }
if err := r.state.Close(); err != nil { if err := r.state.Close(); err != nil {
@ -941,15 +941,15 @@ func (r *Runtime) refresh(alivePath string) error {
// Containers, pods, and volumes must also reacquire their locks. // Containers, pods, and volumes must also reacquire their locks.
ctrs, err := r.state.AllContainers() ctrs, err := r.state.AllContainers()
if err != nil { if err != nil {
return errors.Wrapf(err, "error retrieving all containers from state") return fmt.Errorf("error retrieving all containers from state: %w", err)
} }
pods, err := r.state.AllPods() pods, err := r.state.AllPods()
if err != nil { if err != nil {
return errors.Wrapf(err, "error retrieving all pods from state") return fmt.Errorf("error retrieving all pods from state: %w", err)
} }
vols, err := r.state.AllVolumes() vols, err := r.state.AllVolumes()
if err != nil { if err != nil {
return errors.Wrapf(err, "error retrieving all volumes from state") return fmt.Errorf("error retrieving all volumes from state: %w", err)
} }
// No locks are taken during pod, volume, and container refresh. // No locks are taken during pod, volume, and container refresh.
// Furthermore, the pod/volume/container refresh() functions are not // Furthermore, the pod/volume/container refresh() functions are not
@ -977,7 +977,7 @@ func (r *Runtime) refresh(alivePath string) error {
// Create a file indicating the runtime is alive and ready // Create a file indicating the runtime is alive and ready
file, err := os.OpenFile(alivePath, os.O_RDONLY|os.O_CREATE, 0644) file, err := os.OpenFile(alivePath, os.O_RDONLY|os.O_CREATE, 0644)
if err != nil { if err != nil {
return errors.Wrap(err, "error creating runtime status file") return fmt.Errorf("error creating runtime status file: %w", err)
} }
defer file.Close() defer file.Close()
@ -998,13 +998,13 @@ func (r *Runtime) generateName() (string, error) {
// Make sure container with this name does not exist // Make sure container with this name does not exist
if _, err := r.state.LookupContainer(name); err == nil { if _, err := r.state.LookupContainer(name); err == nil {
continue continue
} else if errors.Cause(err) != define.ErrNoSuchCtr { } else if !errors.Is(err, define.ErrNoSuchCtr) {
return "", err return "", err
} }
// Make sure pod with this name does not exist // Make sure pod with this name does not exist
if _, err := r.state.LookupPod(name); err == nil { if _, err := r.state.LookupPod(name); err == nil {
continue continue
} else if errors.Cause(err) != define.ErrNoSuchPod { } else if !errors.Is(err, define.ErrNoSuchPod) {
return "", err return "", err
} }
return name, nil return name, nil
@ -1203,7 +1203,7 @@ func (r *Runtime) getVolumePlugin(name string) (*plugin.VolumePlugin, error) {
pluginPath, ok := r.config.Engine.VolumePlugins[name] pluginPath, ok := r.config.Engine.VolumePlugins[name]
if !ok { if !ok {
return nil, errors.Wrapf(define.ErrMissingPlugin, "no volume plugin with name %s available", name) return nil, fmt.Errorf("no volume plugin with name %s available: %w", name, define.ErrMissingPlugin)
} }
return plugin.GetVolumePlugin(name, pluginPath) return plugin.GetVolumePlugin(name, pluginPath)

View File

@ -1,11 +1,12 @@
package libpod package libpod
import ( import (
"errors"
"fmt"
"time" "time"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -38,7 +39,7 @@ func (r *Runtime) ListStorageContainers() ([]*StorageContainer, error) {
// Look up if container is in state // Look up if container is in state
hasCtr, err := r.state.HasContainer(ctr.ID) hasCtr, err := r.state.HasContainer(ctr.ID)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error looking up container %s in state", ctr.ID) return nil, fmt.Errorf("error looking up container %s in state: %w", ctr.ID, err)
} }
storageCtr.PresentInLibpod = hasCtr storageCtr.PresentInLibpod = hasCtr
@ -60,20 +61,20 @@ func (r *Runtime) StorageContainer(idOrName string) (*storage.Container, error)
func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error { func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error {
targetID, err := r.store.Lookup(idOrName) targetID, err := r.store.Lookup(idOrName)
if err != nil { if err != nil {
if errors.Cause(err) == storage.ErrLayerUnknown { if errors.Is(err, storage.ErrLayerUnknown) {
return errors.Wrapf(define.ErrNoSuchCtr, "no container with ID or name %q found", idOrName) return fmt.Errorf("no container with ID or name %q found: %w", idOrName, define.ErrNoSuchCtr)
} }
return errors.Wrapf(err, "error looking up container %q", idOrName) return fmt.Errorf("error looking up container %q: %w", idOrName, err)
} }
// Lookup returns an ID but it's not guaranteed to be a container ID. // Lookup returns an ID but it's not guaranteed to be a container ID.
// So we can still error here. // So we can still error here.
ctr, err := r.store.Container(targetID) ctr, err := r.store.Container(targetID)
if err != nil { if err != nil {
if errors.Cause(err) == storage.ErrContainerUnknown { if errors.Is(err, storage.ErrContainerUnknown) {
return errors.Wrapf(define.ErrNoSuchCtr, "%q does not refer to a container", idOrName) return fmt.Errorf("%q does not refer to a container: %w", idOrName, define.ErrNoSuchCtr)
} }
return errors.Wrapf(err, "error retrieving container %q", idOrName) return fmt.Errorf("error retrieving container %q: %w", idOrName, err)
} }
// Error out if the container exists in libpod // Error out if the container exists in libpod
@ -82,13 +83,13 @@ func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error {
return err return err
} }
if exists { if exists {
return errors.Wrapf(define.ErrCtrExists, "refusing to remove %q as it exists in libpod as container %s", idOrName, ctr.ID) return fmt.Errorf("refusing to remove %q as it exists in libpod as container %s: %w", idOrName, ctr.ID, define.ErrCtrExists)
} }
if !force { if !force {
timesMounted, err := r.store.Mounted(ctr.ID) timesMounted, err := r.store.Mounted(ctr.ID)
if err != nil { if err != nil {
if errors.Cause(err) == storage.ErrContainerUnknown { if errors.Is(err, storage.ErrContainerUnknown) {
// Container was removed from under us. // Container was removed from under us.
// It's gone, so don't bother erroring. // It's gone, so don't bother erroring.
logrus.Infof("Storage for container %s already removed", ctr.ID) logrus.Infof("Storage for container %s already removed", ctr.ID)
@ -97,7 +98,7 @@ func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error {
logrus.Warnf("Checking if container %q is mounted, attempting to delete: %v", idOrName, err) logrus.Warnf("Checking if container %q is mounted, attempting to delete: %v", idOrName, err)
} }
if timesMounted > 0 { if timesMounted > 0 {
return errors.Wrapf(define.ErrCtrStateInvalid, "container %q is mounted and cannot be removed without using force", idOrName) return fmt.Errorf("container %q is mounted and cannot be removed without using force: %w", idOrName, define.ErrCtrStateInvalid)
} }
} else if _, err := r.store.Unmount(ctr.ID, true); err != nil { } else if _, err := r.store.Unmount(ctr.ID, true); err != nil {
if errors.Is(err, storage.ErrContainerUnknown) { if errors.Is(err, storage.ErrContainerUnknown) {
@ -109,12 +110,12 @@ func (r *Runtime) RemoveStorageContainer(idOrName string, force bool) error {
} }
if err := r.store.DeleteContainer(ctr.ID); err != nil { if err := r.store.DeleteContainer(ctr.ID); err != nil {
if errors.Cause(err) == storage.ErrNotAContainer || errors.Cause(err) == storage.ErrContainerUnknown { if errors.Is(err, storage.ErrNotAContainer) || errors.Is(err, storage.ErrContainerUnknown) {
// Container again gone, no error // Container again gone, no error
logrus.Infof("Storage for container %s already removed", ctr.ID) logrus.Infof("Storage for container %s already removed", ctr.ID)
return nil return nil
} }
return errors.Wrapf(err, "error removing storage for container %q", idOrName) return fmt.Errorf("error removing storage for container %q: %w", idOrName, err)
} }
return nil return nil

View File

@ -2,6 +2,7 @@ package libpod
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"os" "os"
"path" "path"
@ -26,7 +27,6 @@ import (
"github.com/docker/go-units" "github.com/docker/go-units"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate" "github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -86,7 +86,7 @@ func (r *Runtime) RestoreContainer(ctx context.Context, rSpec *spec.Spec, config
ctr, err := r.initContainerVariables(rSpec, config) ctr, err := r.initContainerVariables(rSpec, config)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error initializing container variables") return nil, fmt.Errorf("error initializing container variables: %w", err)
} }
// For an imported checkpoint no one has ever set the StartedTime. Set it now. // For an imported checkpoint no one has ever set the StartedTime. Set it now.
ctr.state.StartedTime = time.Now() ctr.state.StartedTime = time.Now()
@ -126,7 +126,7 @@ func (r *Runtime) RenameContainer(ctx context.Context, ctr *Container, newName s
// the config was re-written. // the config was re-written.
newConf, err := r.state.GetContainerConfig(ctr.ID()) newConf, err := r.state.GetContainerConfig(ctr.ID())
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error retrieving container %s configuration from DB to remove", ctr.ID()) return nil, fmt.Errorf("error retrieving container %s configuration from DB to remove: %w", ctr.ID(), err)
} }
ctr.config = newConf ctr.config = newConf
@ -143,7 +143,7 @@ func (r *Runtime) RenameContainer(ctx context.Context, ctr *Container, newName s
// Set config back to the old name so reflect what is actually // Set config back to the old name so reflect what is actually
// present in the DB. // present in the DB.
ctr.config.Name = oldName ctr.config.Name = oldName
return nil, errors.Wrapf(err, "error renaming container %s", ctr.ID()) return nil, fmt.Errorf("error renaming container %s: %w", ctr.ID(), err)
} }
// Step 3: rename the container in c/storage. // Step 3: rename the container in c/storage.
@ -162,7 +162,7 @@ func (r *Runtime) RenameContainer(ctx context.Context, ctr *Container, newName s
func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConfig) (*Container, error) { func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConfig) (*Container, error) {
if rSpec == nil { if rSpec == nil {
return nil, errors.Wrapf(define.ErrInvalidArg, "must provide a valid runtime spec to create container") return nil, fmt.Errorf("must provide a valid runtime spec to create container: %w", define.ErrInvalidArg)
} }
ctr := new(Container) ctr := new(Container)
ctr.config = new(ContainerConfig) ctr.config = new(ContainerConfig)
@ -172,7 +172,7 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
ctr.config.ID = stringid.GenerateNonCryptoID() ctr.config.ID = stringid.GenerateNonCryptoID()
size, err := units.FromHumanSize(r.config.Containers.ShmSize) size, err := units.FromHumanSize(r.config.Containers.ShmSize)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "converting containers.conf ShmSize %s to an int", r.config.Containers.ShmSize) return nil, fmt.Errorf("converting containers.conf ShmSize %s to an int: %w", r.config.Containers.ShmSize, err)
} }
ctr.config.ShmSize = size ctr.config.ShmSize = size
ctr.config.NoShm = false ctr.config.NoShm = false
@ -184,7 +184,7 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
// This is a restore from an imported checkpoint // This is a restore from an imported checkpoint
ctr.restoreFromCheckpoint = true ctr.restoreFromCheckpoint = true
if err := JSONDeepCopy(config, ctr.config); err != nil { if err := JSONDeepCopy(config, ctr.config); err != nil {
return nil, errors.Wrapf(err, "error copying container config for restore") return nil, fmt.Errorf("error copying container config for restore: %w", err)
} }
// If the ID is empty a new name for the restored container was requested // If the ID is empty a new name for the restored container was requested
if ctr.config.ID == "" { if ctr.config.ID == "" {
@ -224,12 +224,12 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ..
ctr, err = r.initContainerVariables(rSpec, nil) ctr, err = r.initContainerVariables(rSpec, nil)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error initializing container variables") return nil, fmt.Errorf("error initializing container variables: %w", err)
} }
for _, option := range options { for _, option := range options {
if err := option(ctr); err != nil { if err := option(ctr); err != nil {
return nil, errors.Wrapf(err, "error running container create option") return nil, fmt.Errorf("error running container create option: %w", err)
} }
} }
@ -248,7 +248,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
if opts.InterfaceName != "" { if opts.InterfaceName != "" {
// check that no name is assigned to more than network // check that no name is assigned to more than network
if cutil.StringInSlice(opts.InterfaceName, usedIfNames) { if cutil.StringInSlice(opts.InterfaceName, usedIfNames) {
return nil, errors.Errorf("network interface name %q is already assigned to another network", opts.InterfaceName) return nil, fmt.Errorf("network interface name %q is already assigned to another network", opts.InterfaceName)
} }
usedIfNames = append(usedIfNames, opts.InterfaceName) usedIfNames = append(usedIfNames, opts.InterfaceName)
} }
@ -296,7 +296,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
// Allocate a lock for the container // Allocate a lock for the container
lock, err := r.lockManager.AllocateLock() lock, err := r.lockManager.AllocateLock()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error allocating lock for new container") return nil, fmt.Errorf("error allocating lock for new container: %w", err)
} }
ctr.lock = lock ctr.lock = lock
ctr.config.LockID = ctr.lock.ID() ctr.config.LockID = ctr.lock.ID()
@ -319,7 +319,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
} else { } else {
ociRuntime, ok := r.ociRuntimes[ctr.config.OCIRuntime] ociRuntime, ok := r.ociRuntimes[ctr.config.OCIRuntime]
if !ok { if !ok {
return nil, errors.Wrapf(define.ErrInvalidArg, "requested OCI runtime %s is not available", ctr.config.OCIRuntime) return nil, fmt.Errorf("requested OCI runtime %s is not available: %w", ctr.config.OCIRuntime, define.ErrInvalidArg)
} }
ctr.ociRuntime = ociRuntime ctr.ociRuntime = ociRuntime
} }
@ -327,7 +327,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
// Check NoCgroups support // Check NoCgroups support
if ctr.config.NoCgroups { if ctr.config.NoCgroups {
if !ctr.ociRuntime.SupportsNoCgroups() { if !ctr.ociRuntime.SupportsNoCgroups() {
return nil, errors.Wrapf(define.ErrInvalidArg, "requested OCI runtime %s is not compatible with NoCgroups", ctr.ociRuntime.Name()) return nil, fmt.Errorf("requested OCI runtime %s is not compatible with NoCgroups: %w", ctr.ociRuntime.Name(), define.ErrInvalidArg)
} }
} }
@ -336,7 +336,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
// Get the pod from state // Get the pod from state
pod, err = r.state.Pod(ctr.config.Pod) pod, err = r.state.Pod(ctr.config.Pod)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "cannot add container %s to pod %s", ctr.ID(), ctr.config.Pod) return nil, fmt.Errorf("cannot add container %s to pod %s: %w", ctr.ID(), ctr.config.Pod, err)
} }
} }
@ -350,14 +350,14 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
if pod != nil && pod.config.UsePodCgroup && !ctr.IsInfra() { if pod != nil && pod.config.UsePodCgroup && !ctr.IsInfra() {
podCgroup, err := pod.CgroupPath() podCgroup, err := pod.CgroupPath()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID()) return nil, fmt.Errorf("error retrieving pod %s cgroup: %w", pod.ID(), err)
} }
expectPodCgroup, err := ctr.expectPodCgroup() expectPodCgroup, err := ctr.expectPodCgroup()
if err != nil { if err != nil {
return nil, err return nil, err
} }
if expectPodCgroup && podCgroup == "" { if expectPodCgroup && podCgroup == "" {
return nil, errors.Wrapf(define.ErrInternal, "pod %s cgroup is not set", pod.ID()) return nil, fmt.Errorf("pod %s cgroup is not set: %w", pod.ID(), define.ErrInternal)
} }
canUseCgroup := !rootless.IsRootless() || isRootlessCgroupSet(podCgroup) canUseCgroup := !rootless.IsRootless() || isRootlessCgroupSet(podCgroup)
if canUseCgroup { if canUseCgroup {
@ -367,7 +367,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
ctr.config.CgroupParent = CgroupfsDefaultCgroupParent ctr.config.CgroupParent = CgroupfsDefaultCgroupParent
} }
} else if strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") { } else if strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") {
return nil, errors.Wrapf(define.ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs") return nil, fmt.Errorf("systemd slice received as cgroup parent when using cgroupfs: %w", define.ErrInvalidArg)
} }
case config.SystemdCgroupsManager: case config.SystemdCgroupsManager:
if ctr.config.CgroupParent == "" { if ctr.config.CgroupParent == "" {
@ -375,7 +375,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
case pod != nil && pod.config.UsePodCgroup && !ctr.IsInfra(): case pod != nil && pod.config.UsePodCgroup && !ctr.IsInfra():
podCgroup, err := pod.CgroupPath() podCgroup, err := pod.CgroupPath()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error retrieving pod %s cgroup", pod.ID()) return nil, fmt.Errorf("error retrieving pod %s cgroup: %w", pod.ID(), err)
} }
ctr.config.CgroupParent = podCgroup ctr.config.CgroupParent = podCgroup
case rootless.IsRootless() && ctr.config.CgroupsMode != cgroupSplit: case rootless.IsRootless() && ctr.config.CgroupsMode != cgroupSplit:
@ -384,10 +384,10 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
ctr.config.CgroupParent = SystemdDefaultCgroupParent ctr.config.CgroupParent = SystemdDefaultCgroupParent
} }
} else if len(ctr.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") { } else if len(ctr.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(ctr.config.CgroupParent), ".slice") {
return nil, errors.Wrapf(define.ErrInvalidArg, "did not receive systemd slice as cgroup parent when using systemd to manage cgroups") return nil, fmt.Errorf("did not receive systemd slice as cgroup parent when using systemd to manage cgroups: %w", define.ErrInvalidArg)
} }
default: default:
return nil, errors.Wrapf(define.ErrInvalidArg, "unsupported Cgroup manager: %s - cannot validate cgroup parent", r.config.Engine.CgroupManager) return nil, fmt.Errorf("unsupported Cgroup manager: %s - cannot validate cgroup parent: %w", r.config.Engine.CgroupManager, define.ErrInvalidArg)
} }
} }
@ -470,8 +470,8 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
ctrNamedVolumes = append(ctrNamedVolumes, dbVol) ctrNamedVolumes = append(ctrNamedVolumes, dbVol)
// The volume exists, we're good // The volume exists, we're good
continue continue
} else if errors.Cause(err) != define.ErrNoSuchVolume { } else if !errors.Is(err, define.ErrNoSuchVolume) {
return nil, errors.Wrapf(err, "error retrieving named volume %s for new container", vol.Name) return nil, fmt.Errorf("error retrieving named volume %s for new container: %w", vol.Name, err)
} }
} }
@ -504,7 +504,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
} }
newVol, err := r.newVolume(false, volOptions...) newVol, err := r.newVolume(false, volOptions...)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error creating named volume %q", vol.Name) return nil, fmt.Errorf("error creating named volume %q: %w", vol.Name, err)
} }
ctrNamedVolumes = append(ctrNamedVolumes, newVol) ctrNamedVolumes = append(ctrNamedVolumes, newVol)
@ -527,7 +527,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
ctr.config.ShmDir = filepath.Join(ctr.bundlePath(), "shm") ctr.config.ShmDir = filepath.Join(ctr.bundlePath(), "shm")
if err := os.MkdirAll(ctr.config.ShmDir, 0700); err != nil { if err := os.MkdirAll(ctr.config.ShmDir, 0700); err != nil {
if !os.IsExist(err) { if !os.IsExist(err) {
return nil, errors.Wrap(err, "unable to create shm dir") return nil, fmt.Errorf("unable to create shm dir: %w", err)
} }
} }
ctr.config.Mounts = append(ctr.config.Mounts, ctr.config.ShmDir) ctr.config.Mounts = append(ctr.config.Mounts, ctr.config.ShmDir)
@ -596,7 +596,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
// exist once we're done. // exist once we're done.
newConf, err := r.state.GetContainerConfig(c.ID()) newConf, err := r.state.GetContainerConfig(c.ID())
if err != nil { if err != nil {
return errors.Wrapf(err, "error retrieving container %s configuration from DB to remove", c.ID()) return fmt.Errorf("error retrieving container %s configuration from DB to remove: %w", c.ID(), err)
} }
c.config = newConf c.config = newConf
@ -611,12 +611,12 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
if c.config.Pod != "" && !removePod { if c.config.Pod != "" && !removePod {
pod, err = r.state.Pod(c.config.Pod) pod, err = r.state.Pod(c.config.Pod)
if err != nil { if err != nil {
return errors.Wrapf(err, "container %s is in pod %s, but pod cannot be retrieved", c.ID(), pod.ID()) return fmt.Errorf("container %s is in pod %s, but pod cannot be retrieved: %w", c.ID(), pod.ID(), err)
} }
// Lock the pod while we're removing container // Lock the pod while we're removing container
if pod.config.LockID == c.config.LockID { if pod.config.LockID == c.config.LockID {
return errors.Wrapf(define.ErrWillDeadlock, "container %s and pod %s share lock ID %d", c.ID(), pod.ID(), c.config.LockID) return fmt.Errorf("container %s and pod %s share lock ID %d: %w", c.ID(), pod.ID(), c.config.LockID, define.ErrWillDeadlock)
} }
pod.lock.Lock() pod.lock.Lock()
defer pod.lock.Unlock() defer pod.lock.Unlock()
@ -626,7 +626,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
infraID := pod.state.InfraContainerID infraID := pod.state.InfraContainerID
if c.ID() == infraID { if c.ID() == infraID {
return errors.Errorf("container %s is the infra container of pod %s and cannot be removed without removing the pod", c.ID(), pod.ID()) return fmt.Errorf("container %s is the infra container of pod %s and cannot be removed without removing the pod", c.ID(), pod.ID())
} }
} }
@ -693,7 +693,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
} }
if len(deps) != 0 { if len(deps) != 0 {
depsStr := strings.Join(deps, ", ") depsStr := strings.Join(deps, ", ")
return errors.Wrapf(define.ErrCtrExists, "container %s has dependent containers which must be removed before it: %s", c.ID(), depsStr) return fmt.Errorf("container %s has dependent containers which must be removed before it: %s: %w", c.ID(), depsStr, define.ErrCtrExists)
} }
} }
@ -705,8 +705,8 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
} }
// Ignore ErrConmonDead - we couldn't retrieve the container's // Ignore ErrConmonDead - we couldn't retrieve the container's
// exit code properly, but it's still stopped. // exit code properly, but it's still stopped.
if err := c.stop(time); err != nil && errors.Cause(err) != define.ErrConmonDead { if err := c.stop(time); err != nil && !errors.Is(err, define.ErrConmonDead) {
return errors.Wrapf(err, "cannot remove container %s as it could not be stopped", c.ID()) return fmt.Errorf("cannot remove container %s as it could not be stopped: %w", c.ID(), err)
} }
// We unlocked as part of stop() above - there's a chance someone // We unlocked as part of stop() above - there's a chance someone
@ -717,7 +717,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
if ok, _ := r.state.HasContainer(c.ID()); !ok { if ok, _ := r.state.HasContainer(c.ID()); !ok {
// When the container has already been removed, the OCI runtime directory remain. // When the container has already been removed, the OCI runtime directory remain.
if err := c.cleanupRuntime(ctx); err != nil { if err := c.cleanupRuntime(ctx); err != nil {
return errors.Wrapf(err, "error cleaning up container %s from OCI runtime", c.ID()) return fmt.Errorf("error cleaning up container %s from OCI runtime: %w", c.ID(), err)
} }
return nil return nil
} }
@ -729,7 +729,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
// Do this before we set ContainerStateRemoving, to ensure that we can // Do this before we set ContainerStateRemoving, to ensure that we can
// actually remove from the OCI runtime. // actually remove from the OCI runtime.
if err := c.cleanup(ctx); err != nil { if err := c.cleanup(ctx); err != nil {
cleanupErr = errors.Wrapf(err, "error cleaning up container %s", c.ID()) cleanupErr = fmt.Errorf("error cleaning up container %s: %w", c.ID(), err)
} }
// Set ContainerStateRemoving // Set ContainerStateRemoving
@ -739,7 +739,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
if cleanupErr != nil { if cleanupErr != nil {
logrus.Errorf(err.Error()) logrus.Errorf(err.Error())
} }
return errors.Wrapf(err, "unable to set container %s removing state in database", c.ID()) return fmt.Errorf("unable to set container %s removing state in database: %w", c.ID(), err)
} }
// Remove all active exec sessions // Remove all active exec sessions
@ -789,7 +789,7 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
// Deallocate the container's lock // Deallocate the container's lock
if err := c.lock.Free(); err != nil { if err := c.lock.Free(); err != nil {
if cleanupErr == nil { if cleanupErr == nil {
cleanupErr = errors.Wrapf(err, "error freeing lock for container %s", c.ID()) cleanupErr = fmt.Errorf("error freeing lock for container %s: %w", c.ID(), err)
} else { } else {
logrus.Errorf("Free container lock: %v", err) logrus.Errorf("Free container lock: %v", err)
} }
@ -809,8 +809,8 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force, remo
if !volume.Anonymous() { if !volume.Anonymous() {
continue continue
} }
if err := runtime.removeVolume(ctx, volume, false, timeout, false); err != nil && errors.Cause(err) != define.ErrNoSuchVolume { if err := runtime.removeVolume(ctx, volume, false, timeout, false); err != nil && !errors.Is(err, define.ErrNoSuchVolume) {
if errors.Cause(err) == define.ErrVolumeBeingUsed { if errors.Is(err, define.ErrVolumeBeingUsed) {
// Ignore error, since podman will report original error // Ignore error, since podman will report original error
volumesFrom, _ := c.volumesFrom() volumesFrom, _ := c.volumesFrom()
if len(volumesFrom) > 0 { if len(volumesFrom) > 0 {
@ -891,7 +891,7 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
c := new(Container) c := new(Container)
c.config, err = r.state.GetContainerConfig(id) c.config, err = r.state.GetContainerConfig(id)
if err != nil { if err != nil {
return id, errors.Wrapf(err, "failed to retrieve config for ctr ID %q", id) return id, fmt.Errorf("failed to retrieve config for ctr ID %q: %w", id, err)
} }
c.state = new(ContainerState) c.state = new(ContainerState)
@ -903,7 +903,7 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
if c.config.Pod != "" { if c.config.Pod != "" {
pod, err = r.state.Pod(c.config.Pod) pod, err = r.state.Pod(c.config.Pod)
if err != nil { if err != nil {
return id, errors.Wrapf(err, "container %s is in pod %s, but pod cannot be retrieved", c.ID(), pod.ID()) return id, fmt.Errorf("container %s is in pod %s, but pod cannot be retrieved: %w", c.ID(), pod.ID(), err)
} }
// Lock the pod while we're removing container // Lock the pod while we're removing container
@ -918,7 +918,7 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
return "", err return "", err
} }
if c.ID() == infraID { if c.ID() == infraID {
return id, errors.Errorf("container %s is the infra container of pod %s and cannot be removed without removing the pod", c.ID(), pod.ID()) return id, fmt.Errorf("container %s is the infra container of pod %s and cannot be removed without removing the pod", c.ID(), pod.ID())
} }
} }
@ -1115,7 +1115,7 @@ func (r *Runtime) GetContainersByList(containers []string) ([]*Container, error)
for _, inputContainer := range containers { for _, inputContainer := range containers {
ctr, err := r.LookupContainer(inputContainer) ctr, err := r.LookupContainer(inputContainer)
if err != nil { if err != nil {
return ctrs, errors.Wrapf(err, "unable to look up container %s", inputContainer) return ctrs, fmt.Errorf("unable to look up container %s: %w", inputContainer, err)
} }
ctrs = append(ctrs, ctr) ctrs = append(ctrs, ctr)
} }
@ -1128,7 +1128,7 @@ func (r *Runtime) GetLatestContainer() (*Container, error) {
var lastCreatedTime time.Time var lastCreatedTime time.Time
ctrs, err := r.GetAllContainers() ctrs, err := r.GetAllContainers()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "unable to find latest container") return nil, fmt.Errorf("unable to find latest container: %w", err)
} }
if len(ctrs) == 0 { if len(ctrs) == 0 {
return nil, define.ErrNoSuchCtr return nil, define.ErrNoSuchCtr
@ -1209,7 +1209,7 @@ func (r *Runtime) PruneContainers(filterFuncs []ContainerFilter) ([]*reports.Pru
// MountStorageContainer mounts the storage container's root filesystem // MountStorageContainer mounts the storage container's root filesystem
func (r *Runtime) MountStorageContainer(id string) (string, error) { func (r *Runtime) MountStorageContainer(id string) (string, error) {
if _, err := r.GetContainer(id); err == nil { if _, err := r.GetContainer(id); err == nil {
return "", errors.Wrapf(define.ErrCtrExists, "ctr %s is a libpod container", id) return "", fmt.Errorf("ctr %s is a libpod container: %w", id, define.ErrCtrExists)
} }
container, err := r.store.Container(id) container, err := r.store.Container(id)
if err != nil { if err != nil {
@ -1217,7 +1217,7 @@ func (r *Runtime) MountStorageContainer(id string) (string, error) {
} }
mountPoint, err := r.store.Mount(container.ID, "") mountPoint, err := r.store.Mount(container.ID, "")
if err != nil { if err != nil {
return "", errors.Wrapf(err, "error mounting storage for container %s", id) return "", fmt.Errorf("error mounting storage for container %s: %w", id, err)
} }
return mountPoint, nil return mountPoint, nil
} }
@ -1225,7 +1225,7 @@ func (r *Runtime) MountStorageContainer(id string) (string, error) {
// UnmountStorageContainer unmounts the storage container's root filesystem // UnmountStorageContainer unmounts the storage container's root filesystem
func (r *Runtime) UnmountStorageContainer(id string, force bool) (bool, error) { func (r *Runtime) UnmountStorageContainer(id string, force bool) (bool, error) {
if _, err := r.GetContainer(id); err == nil { if _, err := r.GetContainer(id); err == nil {
return false, errors.Wrapf(define.ErrCtrExists, "ctr %s is a libpod container", id) return false, fmt.Errorf("ctr %s is a libpod container: %w", id, define.ErrCtrExists)
} }
container, err := r.store.Container(id) container, err := r.store.Container(id)
if err != nil { if err != nil {
@ -1239,7 +1239,7 @@ func (r *Runtime) UnmountStorageContainer(id string, force bool) (bool, error) {
func (r *Runtime) IsStorageContainerMounted(id string) (bool, string, error) { func (r *Runtime) IsStorageContainerMounted(id string) (bool, string, error) {
var path string var path string
if _, err := r.GetContainer(id); err == nil { if _, err := r.GetContainer(id); err == nil {
return false, "", errors.Wrapf(define.ErrCtrExists, "ctr %s is a libpod container", id) return false, "", fmt.Errorf("ctr %s is a libpod container: %w", id, define.ErrCtrExists)
} }
mountCnt, err := r.storageService.MountedContainerImage(id) mountCnt, err := r.storageService.MountedContainerImage(id)
@ -1265,13 +1265,13 @@ func (r *Runtime) StorageContainers() ([]storage.Container, error) {
storeContainers, err := r.store.Containers() storeContainers, err := r.store.Containers()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error reading list of all storage containers") return nil, fmt.Errorf("error reading list of all storage containers: %w", err)
} }
retCtrs := []storage.Container{} retCtrs := []storage.Container{}
for _, container := range storeContainers { for _, container := range storeContainers {
exists, err := r.state.HasContainer(container.ID) exists, err := r.state.HasContainer(container.ID)
if err != nil && err != define.ErrNoSuchCtr { if err != nil && err != define.ErrNoSuchCtr {
return nil, errors.Wrapf(err, "failed to check if %s container exists in database", container.ID) return nil, fmt.Errorf("failed to check if %s container exists in database: %w", container.ID, err)
} }
if exists { if exists {
continue continue

View File

@ -2,6 +2,8 @@ package libpod
import ( import (
"context" "context"
"errors"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
@ -13,7 +15,6 @@ import (
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events" "github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -40,14 +41,14 @@ func (r *Runtime) RemoveContainersForImageCallback(ctx context.Context) libimage
if ctr.config.IsInfra { if ctr.config.IsInfra {
pod, err := r.state.Pod(ctr.config.Pod) pod, err := r.state.Pod(ctr.config.Pod)
if err != nil { if err != nil {
return errors.Wrapf(err, "container %s is in pod %s, but pod cannot be retrieved", ctr.ID(), ctr.config.Pod) return fmt.Errorf("container %s is in pod %s, but pod cannot be retrieved: %w", ctr.ID(), ctr.config.Pod, err)
} }
if err := r.removePod(ctx, pod, true, true, timeout); err != nil { if err := r.removePod(ctx, pod, true, true, timeout); err != nil {
return errors.Wrapf(err, "removing image %s: container %s using image could not be removed", imageID, ctr.ID()) return fmt.Errorf("removing image %s: container %s using image could not be removed: %w", imageID, ctr.ID(), err)
} }
} else { } else {
if err := r.removeContainer(ctx, ctr, true, false, false, timeout); err != nil { if err := r.removeContainer(ctx, ctr, true, false, false, timeout); err != nil {
return errors.Wrapf(err, "removing image %s: container %s using image could not be removed", imageID, ctr.ID()) return fmt.Errorf("removing image %s: container %s using image could not be removed: %w", imageID, ctr.ID(), err)
} }
} }
} }
@ -106,7 +107,7 @@ func (r *Runtime) Build(ctx context.Context, options buildahDefine.BuildOptions,
func DownloadFromFile(reader *os.File) (string, error) { func DownloadFromFile(reader *os.File) (string, error) {
outFile, err := ioutil.TempFile(util.Tmpdir(), "import") outFile, err := ioutil.TempFile(util.Tmpdir(), "import")
if err != nil { if err != nil {
return "", errors.Wrap(err, "error creating file") return "", fmt.Errorf("error creating file: %w", err)
} }
defer outFile.Close() defer outFile.Close()
@ -114,7 +115,7 @@ func DownloadFromFile(reader *os.File) (string, error) {
_, err = io.Copy(outFile, reader) _, err = io.Copy(outFile, reader)
if err != nil { if err != nil {
return "", errors.Wrapf(err, "error saving %s to %s", reader.Name(), outFile.Name()) return "", fmt.Errorf("error saving %s to %s: %w", reader.Name(), outFile.Name(), err)
} }
return outFile.Name(), nil return outFile.Name(), nil

View File

@ -14,7 +14,6 @@ import (
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/rootless" "github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -22,21 +21,21 @@ func (r *Runtime) stopPauseProcess() error {
if rootless.IsRootless() { if rootless.IsRootless() {
pausePidPath, err := util.GetRootlessPauseProcessPidPathGivenDir(r.config.Engine.TmpDir) pausePidPath, err := util.GetRootlessPauseProcessPidPathGivenDir(r.config.Engine.TmpDir)
if err != nil { if err != nil {
return errors.Wrapf(err, "could not get pause process pid file path") return fmt.Errorf("could not get pause process pid file path: %w", err)
} }
data, err := ioutil.ReadFile(pausePidPath) data, err := ioutil.ReadFile(pausePidPath)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil return nil
} }
return errors.Wrap(err, "cannot read pause process pid file") return fmt.Errorf("cannot read pause process pid file: %w", err)
} }
pausePid, err := strconv.Atoi(string(data)) pausePid, err := strconv.Atoi(string(data))
if err != nil { if err != nil {
return errors.Wrapf(err, "cannot parse pause pid file %s", pausePidPath) return fmt.Errorf("cannot parse pause pid file %s: %w", pausePidPath, err)
} }
if err := os.Remove(pausePidPath); err != nil { if err := os.Remove(pausePidPath); err != nil {
return errors.Wrapf(err, "cannot delete pause pid file %s", pausePidPath) return fmt.Errorf("cannot delete pause pid file %s: %w", pausePidPath, err)
} }
if err := syscall.Kill(pausePid, syscall.SIGKILL); err != nil { if err := syscall.Kill(pausePid, syscall.SIGKILL); err != nil {
return err return err
@ -60,7 +59,7 @@ func (r *Runtime) migrate() error {
for _, ctr := range runningContainers { for _, ctr := range runningContainers {
fmt.Printf("stopped %s\n", ctr.ID()) fmt.Printf("stopped %s\n", ctr.ID())
if err := ctr.Stop(); err != nil { if err := ctr.Stop(); err != nil {
return errors.Wrapf(err, "cannot stop container %s", ctr.ID()) return fmt.Errorf("cannot stop container %s: %w", ctr.ID(), err)
} }
} }
@ -68,7 +67,7 @@ func (r *Runtime) migrate() error {
runtimeChangeRequested := r.migrateRuntime != "" runtimeChangeRequested := r.migrateRuntime != ""
requestedRuntime, runtimeExists := r.ociRuntimes[r.migrateRuntime] requestedRuntime, runtimeExists := r.ociRuntimes[r.migrateRuntime]
if !runtimeExists && runtimeChangeRequested { if !runtimeExists && runtimeChangeRequested {
return errors.Wrapf(define.ErrInvalidArg, "change to runtime %q requested but no such runtime is defined", r.migrateRuntime) return fmt.Errorf("change to runtime %q requested but no such runtime is defined: %w", r.migrateRuntime, define.ErrInvalidArg)
} }
for _, ctr := range allCtrs { for _, ctr := range allCtrs {
@ -93,7 +92,7 @@ func (r *Runtime) migrate() error {
if needsWrite { if needsWrite {
if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil { if err := r.state.RewriteContainerConfig(ctr, ctr.config); err != nil {
return errors.Wrapf(err, "error rewriting config for container %s", ctr.ID()) return fmt.Errorf("error rewriting config for container %s: %w", ctr.ID(), err)
} }
} }
} }

View File

@ -2,11 +2,12 @@ package libpod
import ( import (
"context" "context"
"errors"
"fmt"
"time" "time"
"github.com/containers/common/pkg/util" "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/pkg/errors"
) )
// Contains the public Runtime API for pods // Contains the public Runtime API for pods
@ -112,7 +113,7 @@ func (r *Runtime) GetLatestPod() (*Pod, error) {
var lastCreatedTime time.Time var lastCreatedTime time.Time
pods, err := r.GetAllPods() pods, err := r.GetAllPods()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "unable to get all pods") return nil, fmt.Errorf("unable to get all pods: %w", err)
} }
if len(pods) == 0 { if len(pods) == 0 {
return nil, define.ErrNoSuchPod return nil, define.ErrNoSuchPod
@ -146,7 +147,7 @@ func (r *Runtime) GetRunningPods() ([]*Pod, error) {
pods = append(pods, c.PodID()) pods = append(pods, c.PodID())
pod, err := r.GetPod(c.PodID()) pod, err := r.GetPod(c.PodID())
if err != nil { if err != nil {
if errors.Cause(err) == define.ErrPodRemoved || errors.Cause(err) == define.ErrNoSuchPod { if errors.Is(err, define.ErrPodRemoved) || errors.Is(err, define.ErrNoSuchPod) {
continue continue
} }
return nil, err return nil, err

View File

@ -5,6 +5,7 @@ package libpod
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"os" "os"
"path" "path"
@ -18,7 +19,6 @@ import (
"github.com/containers/podman/v4/pkg/rootless" "github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/podman/v4/pkg/specgen" "github.com/containers/podman/v4/pkg/specgen"
runcconfig "github.com/opencontainers/runc/libcontainer/configs" runcconfig "github.com/opencontainers/runc/libcontainer/configs"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -38,14 +38,14 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option
for _, option := range options { for _, option := range options {
if err := option(pod); err != nil { if err := option(pod); err != nil {
return nil, errors.Wrapf(err, "error running pod create option") return nil, fmt.Errorf("error running pod create option: %w", err)
} }
} }
// Allocate a lock for the pod // Allocate a lock for the pod
lock, err := r.lockManager.AllocateLock() lock, err := r.lockManager.AllocateLock()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error allocating lock for new pod") return nil, fmt.Errorf("error allocating lock for new pod: %w", err)
} }
pod.lock = lock pod.lock = lock
pod.config.LockID = pod.lock.ID() pod.config.LockID = pod.lock.ID()
@ -70,7 +70,7 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option
if pod.config.CgroupParent == "" { if pod.config.CgroupParent == "" {
pod.config.CgroupParent = CgroupfsDefaultCgroupParent pod.config.CgroupParent = CgroupfsDefaultCgroupParent
} else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") { } else if strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
return nil, errors.Wrapf(define.ErrInvalidArg, "systemd slice received as cgroup parent when using cgroupfs") return nil, fmt.Errorf("systemd slice received as cgroup parent when using cgroupfs: %w", define.ErrInvalidArg)
} }
// If we are set to use pod cgroups, set the cgroup parent that // If we are set to use pod cgroups, set the cgroup parent that
// all containers in the pod will share // all containers in the pod will share
@ -108,14 +108,14 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option
pod.config.CgroupParent = SystemdDefaultCgroupParent pod.config.CgroupParent = SystemdDefaultCgroupParent
} }
} else if len(pod.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") { } else if len(pod.config.CgroupParent) < 6 || !strings.HasSuffix(path.Base(pod.config.CgroupParent), ".slice") {
return nil, errors.Wrapf(define.ErrInvalidArg, "did not receive systemd slice as cgroup parent when using systemd to manage cgroups") return nil, fmt.Errorf("did not receive systemd slice as cgroup parent when using systemd to manage cgroups: %w", define.ErrInvalidArg)
} }
// If we are set to use pod cgroups, set the cgroup parent that // If we are set to use pod cgroups, set the cgroup parent that
// all containers in the pod will share // all containers in the pod will share
if pod.config.UsePodCgroup { if pod.config.UsePodCgroup {
cgroupPath, err := systemdSliceFromPath(pod.config.CgroupParent, fmt.Sprintf("libpod_pod_%s", pod.ID()), p.InfraContainerSpec.ResourceLimits) cgroupPath, err := systemdSliceFromPath(pod.config.CgroupParent, fmt.Sprintf("libpod_pod_%s", pod.ID()), p.InfraContainerSpec.ResourceLimits)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "unable to create pod cgroup for pod %s", pod.ID()) return nil, fmt.Errorf("unable to create pod cgroup for pod %s: %w", pod.ID(), err)
} }
pod.state.CgroupPath = cgroupPath pod.state.CgroupPath = cgroupPath
if p.InfraContainerSpec != nil { if p.InfraContainerSpec != nil {
@ -123,7 +123,7 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option
} }
} }
default: default:
return nil, errors.Wrapf(define.ErrInvalidArg, "unsupported Cgroup manager: %s - cannot validate cgroup parent", r.config.Engine.CgroupManager) return nil, fmt.Errorf("unsupported Cgroup manager: %s - cannot validate cgroup parent: %w", r.config.Engine.CgroupManager, define.ErrInvalidArg)
} }
} }
@ -132,7 +132,7 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option
} }
if !pod.HasInfraContainer() && pod.SharesNamespaces() { if !pod.HasInfraContainer() && pod.SharesNamespaces() {
return nil, errors.Errorf("Pods must have an infra container to share namespaces") return nil, errors.New("Pods must have an infra container to share namespaces")
} }
if pod.HasInfraContainer() && !pod.SharesNamespaces() { if pod.HasInfraContainer() && !pod.SharesNamespaces() {
logrus.Infof("Pod has an infra container, but shares no namespaces") logrus.Infof("Pod has an infra container, but shares no namespaces")
@ -157,12 +157,12 @@ func (r *Runtime) NewPod(ctx context.Context, p specgen.PodSpecGenerator, option
if addPodErr = r.state.AddPod(pod); addPodErr == nil { if addPodErr = r.state.AddPod(pod); addPodErr == nil {
return pod, nil return pod, nil
} }
if !generateName || (errors.Cause(addPodErr) != define.ErrPodExists && errors.Cause(addPodErr) != define.ErrCtrExists) { if !generateName || (!errors.Is(addPodErr, define.ErrPodExists) && !errors.Is(addPodErr, define.ErrCtrExists)) {
break break
} }
} }
if addPodErr != nil { if addPodErr != nil {
return nil, errors.Wrapf(addPodErr, "error adding pod to state") return nil, fmt.Errorf("error adding pod to state: %w", addPodErr)
} }
return pod, nil return pod, nil
@ -211,7 +211,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
force = true force = true
} }
if !removeCtrs && numCtrs > 0 { if !removeCtrs && numCtrs > 0 {
return errors.Wrapf(define.ErrCtrExists, "pod %s contains containers and cannot be removed", p.ID()) return fmt.Errorf("pod %s contains containers and cannot be removed: %w", p.ID(), define.ErrCtrExists)
} }
// Go through and lock all containers so we can operate on them all at // Go through and lock all containers so we can operate on them all at
@ -239,7 +239,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
// Ensure state appropriate for removal // Ensure state appropriate for removal
if err := ctr.checkReadyForRemoval(); err != nil { if err := ctr.checkReadyForRemoval(); err != nil {
return errors.Wrapf(err, "pod %s has containers that are not ready to be removed", p.ID()) return fmt.Errorf("pod %s has containers that are not ready to be removed: %w", p.ID(), err)
} }
} }
@ -311,7 +311,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
for volName := range ctrNamedVolumes { for volName := range ctrNamedVolumes {
volume, err := r.state.Volume(volName) volume, err := r.state.Volume(volName)
if err != nil && errors.Cause(err) != define.ErrNoSuchVolume { if err != nil && !errors.Is(err, define.ErrNoSuchVolume) {
logrus.Errorf("Retrieving volume %s: %v", volName, err) logrus.Errorf("Retrieving volume %s: %v", volName, err)
continue continue
} }
@ -319,7 +319,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
continue continue
} }
if err := r.removeVolume(ctx, volume, false, timeout, false); err != nil { if err := r.removeVolume(ctx, volume, false, timeout, false); err != nil {
if errors.Cause(err) == define.ErrNoSuchVolume || errors.Cause(err) == define.ErrVolumeRemoved { if errors.Is(err, define.ErrNoSuchVolume) || errors.Is(err, define.ErrVolumeRemoved) {
continue continue
} }
logrus.Errorf("Removing volume %s: %v", volName, err) logrus.Errorf("Removing volume %s: %v", volName, err)
@ -340,7 +340,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
case config.SystemdCgroupsManager: case config.SystemdCgroupsManager:
if err := deleteSystemdCgroup(p.state.CgroupPath, p.ResourceLim()); err != nil { if err := deleteSystemdCgroup(p.state.CgroupPath, p.ResourceLim()); err != nil {
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(err, "error removing pod %s cgroup", p.ID()) removalErr = fmt.Errorf("error removing pod %s cgroup: %w", p.ID(), err)
} else { } else {
logrus.Errorf("Deleting pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err) logrus.Errorf("Deleting pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err)
} }
@ -354,7 +354,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
conmonCgroup, err := cgroups.Load(conmonCgroupPath) conmonCgroup, err := cgroups.Load(conmonCgroupPath)
if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless { if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(err, "error retrieving pod %s conmon cgroup", p.ID()) removalErr = fmt.Errorf("error retrieving pod %s conmon cgroup: %w", p.ID(), err)
} else { } else {
logrus.Debugf("Error retrieving pod %s conmon cgroup %s: %v", p.ID(), conmonCgroupPath, err) logrus.Debugf("Error retrieving pod %s conmon cgroup %s: %v", p.ID(), conmonCgroupPath, err)
} }
@ -362,7 +362,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
if err == nil { if err == nil {
if err = conmonCgroup.Delete(); err != nil { if err = conmonCgroup.Delete(); err != nil {
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(err, "error removing pod %s conmon cgroup", p.ID()) removalErr = fmt.Errorf("error removing pod %s conmon cgroup: %w", p.ID(), err)
} else { } else {
logrus.Errorf("Deleting pod %s conmon cgroup %s: %v", p.ID(), conmonCgroupPath, err) logrus.Errorf("Deleting pod %s conmon cgroup %s: %v", p.ID(), conmonCgroupPath, err)
} }
@ -371,7 +371,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
cgroup, err := cgroups.Load(p.state.CgroupPath) cgroup, err := cgroups.Load(p.state.CgroupPath)
if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless { if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(err, "error retrieving pod %s cgroup", p.ID()) removalErr = fmt.Errorf("error retrieving pod %s cgroup: %w", p.ID(), err)
} else { } else {
logrus.Errorf("Retrieving pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err) logrus.Errorf("Retrieving pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err)
} }
@ -379,7 +379,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
if err == nil { if err == nil {
if err := cgroup.Delete(); err != nil { if err := cgroup.Delete(); err != nil {
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(err, "error removing pod %s cgroup", p.ID()) removalErr = fmt.Errorf("error removing pod %s cgroup: %w", p.ID(), err)
} else { } else {
logrus.Errorf("Deleting pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err) logrus.Errorf("Deleting pod %s cgroup %s: %v", p.ID(), p.state.CgroupPath, err)
} }
@ -390,7 +390,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
// keep going so we make sure to evict the pod before // keep going so we make sure to evict the pod before
// ending up with an inconsistent state. // ending up with an inconsistent state.
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(define.ErrInternal, "unrecognized cgroup manager %s when removing pod %s cgroups", p.runtime.config.Engine.CgroupManager, p.ID()) removalErr = fmt.Errorf("unrecognized cgroup manager %s when removing pod %s cgroups: %w", p.runtime.config.Engine.CgroupManager, p.ID(), define.ErrInternal)
} else { } else {
logrus.Errorf("Unknown cgroups manager %s specified - cannot remove pod %s cgroup", p.runtime.config.Engine.CgroupManager, p.ID()) logrus.Errorf("Unknown cgroups manager %s specified - cannot remove pod %s cgroup", p.runtime.config.Engine.CgroupManager, p.ID())
} }
@ -416,7 +416,7 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
// Deallocate the pod lock // Deallocate the pod lock
if err := p.lock.Free(); err != nil { if err := p.lock.Free(); err != nil {
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(err, "error freeing pod %s lock", p.ID()) removalErr = fmt.Errorf("error freeing pod %s lock: %w", p.ID(), err)
} else { } else {
logrus.Errorf("Freeing pod %s lock: %v", p.ID(), err) logrus.Errorf("Freeing pod %s lock: %v", p.ID(), err)
} }

View File

@ -1,8 +1,9 @@
package libpod package libpod
import ( import (
"fmt"
"github.com/containers/podman/v4/libpod/events" "github.com/containers/podman/v4/libpod/events"
"github.com/pkg/errors"
) )
// renumberLocks reassigns lock numbers for all containers and pods in the // renumberLocks reassigns lock numbers for all containers and pods in the
@ -26,7 +27,7 @@ func (r *Runtime) renumberLocks() error {
for _, ctr := range allCtrs { for _, ctr := range allCtrs {
lock, err := r.lockManager.AllocateLock() lock, err := r.lockManager.AllocateLock()
if err != nil { if err != nil {
return errors.Wrapf(err, "error allocating lock for container %s", ctr.ID()) return fmt.Errorf("error allocating lock for container %s: %w", ctr.ID(), err)
} }
ctr.config.LockID = lock.ID() ctr.config.LockID = lock.ID()
@ -43,7 +44,7 @@ func (r *Runtime) renumberLocks() error {
for _, pod := range allPods { for _, pod := range allPods {
lock, err := r.lockManager.AllocateLock() lock, err := r.lockManager.AllocateLock()
if err != nil { if err != nil {
return errors.Wrapf(err, "error allocating lock for pod %s", pod.ID()) return fmt.Errorf("error allocating lock for pod %s: %w", pod.ID(), err)
} }
pod.config.LockID = lock.ID() pod.config.LockID = lock.ID()
@ -60,7 +61,7 @@ func (r *Runtime) renumberLocks() error {
for _, vol := range allVols { for _, vol := range allVols {
lock, err := r.lockManager.AllocateLock() lock, err := r.lockManager.AllocateLock()
if err != nil { if err != nil {
return errors.Wrapf(err, "error allocating lock for volume %s", vol.Name()) return fmt.Errorf("error allocating lock for volume %s: %w", vol.Name(), err)
} }
vol.config.LockID = lock.ID() vol.config.LockID = lock.ID()

View File

@ -2,11 +2,11 @@ package libpod
import ( import (
"context" "context"
"errors"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events" "github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/domain/entities/reports" "github.com/containers/podman/v4/pkg/domain/entities/reports"
"github.com/pkg/errors"
) )
// Contains the public Runtime API for volumes // Contains the public Runtime API for volumes
@ -133,7 +133,7 @@ func (r *Runtime) PruneVolumes(ctx context.Context, filterFuncs []VolumeFilter)
report.Id = vol.Name() report.Id = vol.Name()
var timeout *uint var timeout *uint
if err := r.RemoveVolume(ctx, vol, false, timeout); err != nil { if err := r.RemoveVolume(ctx, vol, false, timeout); err != nil {
if errors.Cause(err) != define.ErrVolumeBeingUsed && errors.Cause(err) != define.ErrVolumeRemoved { if !errors.Is(err, define.ErrVolumeBeingUsed) && !errors.Is(err, define.ErrVolumeRemoved) {
report.Err = err report.Err = err
} else { } else {
// We didn't remove the volume for some reason // We didn't remove the volume for some reason

View File

@ -5,6 +5,7 @@ package libpod
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -17,7 +18,6 @@ import (
"github.com/containers/storage/drivers/quota" "github.com/containers/storage/drivers/quota"
"github.com/containers/storage/pkg/stringid" "github.com/containers/storage/pkg/stringid"
pluginapi "github.com/docker/go-plugins-helpers/volume" pluginapi "github.com/docker/go-plugins-helpers/volume"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -36,7 +36,7 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp
volume := newVolume(r) volume := newVolume(r)
for _, option := range options { for _, option := range options {
if err := option(volume); err != nil { if err := option(volume); err != nil {
return nil, errors.Wrapf(err, "running volume create option") return nil, fmt.Errorf("running volume create option: %w", err)
} }
} }
@ -51,17 +51,17 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp
// Check if volume with given name exists. // Check if volume with given name exists.
exists, err := r.state.HasVolume(volume.config.Name) exists, err := r.state.HasVolume(volume.config.Name)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "checking if volume with name %s exists", volume.config.Name) return nil, fmt.Errorf("checking if volume with name %s exists: %w", volume.config.Name, err)
} }
if exists { if exists {
return nil, errors.Wrapf(define.ErrVolumeExists, "volume with name %s already exists", volume.config.Name) return nil, fmt.Errorf("volume with name %s already exists: %w", volume.config.Name, define.ErrVolumeExists)
} }
// Plugin can be nil if driver is local, but that's OK - superfluous // Plugin can be nil if driver is local, but that's OK - superfluous
// assignment doesn't hurt much. // assignment doesn't hurt much.
plugin, err := r.getVolumePlugin(volume.config.Driver) plugin, err := r.getVolumePlugin(volume.config.Driver)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "volume %s uses volume plugin %s but it could not be retrieved", volume.config.Name, volume.config.Driver) return nil, fmt.Errorf("volume %s uses volume plugin %s but it could not be retrieved: %w", volume.config.Name, volume.config.Driver, err)
} }
volume.plugin = plugin volume.plugin = plugin
@ -73,13 +73,13 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp
case "device": case "device":
if strings.ToLower(volume.config.Options["type"]) == "bind" { if strings.ToLower(volume.config.Options["type"]) == "bind" {
if _, err := os.Stat(val); err != nil { if _, err := os.Stat(val); err != nil {
return nil, errors.Wrapf(err, "invalid volume option %s for driver 'local'", key) return nil, fmt.Errorf("invalid volume option %s for driver 'local': %w", key, err)
} }
} }
case "o", "type", "uid", "gid", "size", "inodes", "noquota", "copy", "nocopy": case "o", "type", "uid", "gid", "size", "inodes", "noquota", "copy", "nocopy":
// Do nothing, valid keys // Do nothing, valid keys
default: default:
return nil, errors.Wrapf(define.ErrInvalidArg, "invalid mount option %s for driver 'local'", key) return nil, fmt.Errorf("invalid mount option %s for driver 'local': %w", key, define.ErrInvalidArg)
} }
} }
} }
@ -99,17 +99,17 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp
// Create the mountpoint of this volume // Create the mountpoint of this volume
volPathRoot := filepath.Join(r.config.Engine.VolumePath, volume.config.Name) volPathRoot := filepath.Join(r.config.Engine.VolumePath, volume.config.Name)
if err := os.MkdirAll(volPathRoot, 0700); err != nil { if err := os.MkdirAll(volPathRoot, 0700); err != nil {
return nil, errors.Wrapf(err, "creating volume directory %q", volPathRoot) return nil, fmt.Errorf("creating volume directory %q: %w", volPathRoot, err)
} }
if err := os.Chown(volPathRoot, volume.config.UID, volume.config.GID); err != nil { if err := os.Chown(volPathRoot, volume.config.UID, volume.config.GID); err != nil {
return nil, errors.Wrapf(err, "chowning volume directory %q to %d:%d", volPathRoot, volume.config.UID, volume.config.GID) return nil, fmt.Errorf("chowning volume directory %q to %d:%d: %w", volPathRoot, volume.config.UID, volume.config.GID, err)
} }
fullVolPath := filepath.Join(volPathRoot, "_data") fullVolPath := filepath.Join(volPathRoot, "_data")
if err := os.MkdirAll(fullVolPath, 0755); err != nil { if err := os.MkdirAll(fullVolPath, 0755); err != nil {
return nil, errors.Wrapf(err, "creating volume directory %q", fullVolPath) return nil, fmt.Errorf("creating volume directory %q: %w", fullVolPath, err)
} }
if err := os.Chown(fullVolPath, volume.config.UID, volume.config.GID); err != nil { if err := os.Chown(fullVolPath, volume.config.UID, volume.config.GID); err != nil {
return nil, errors.Wrapf(err, "chowning volume directory %q to %d:%d", fullVolPath, volume.config.UID, volume.config.GID) return nil, fmt.Errorf("chowning volume directory %q to %d:%d: %w", fullVolPath, volume.config.UID, volume.config.GID, err)
} }
if err := LabelVolumePath(fullVolPath); err != nil { if err := LabelVolumePath(fullVolPath); err != nil {
return nil, err return nil, err
@ -134,7 +134,7 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp
} }
if projectQuotaSupported { if projectQuotaSupported {
if err := q.SetQuota(fullVolPath, quota); err != nil { if err := q.SetQuota(fullVolPath, quota); err != nil {
return nil, errors.Wrapf(err, "failed to set size quota size=%d inodes=%d for volume directory %q", volume.config.Size, volume.config.Inodes, fullVolPath) return nil, fmt.Errorf("failed to set size quota size=%d inodes=%d for volume directory %q: %w", volume.config.Size, volume.config.Inodes, fullVolPath, err)
} }
} }
} }
@ -144,7 +144,7 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp
lock, err := r.lockManager.AllocateLock() lock, err := r.lockManager.AllocateLock()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "allocating lock for new volume") return nil, fmt.Errorf("allocating lock for new volume: %w", err)
} }
volume.lock = lock volume.lock = lock
volume.config.LockID = volume.lock.ID() volume.config.LockID = volume.lock.ID()
@ -161,7 +161,7 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp
// Add the volume to state // Add the volume to state
if err := r.state.AddVolume(volume); err != nil { if err := r.state.AddVolume(volume); err != nil {
return nil, errors.Wrapf(err, "adding volume to state") return nil, fmt.Errorf("adding volume to state: %w", err)
} }
defer volume.newVolumeEvent(events.Create) defer volume.newVolumeEvent(events.Create)
return volume, nil return volume, nil
@ -272,7 +272,7 @@ func makeVolumeInPluginIfNotExist(name string, options map[string]string, plugin
createReq.Name = name createReq.Name = name
createReq.Options = options createReq.Options = options
if err := plugin.CreateVolume(createReq); err != nil { if err := plugin.CreateVolume(createReq); err != nil {
return errors.Wrapf(err, "creating volume %q in plugin %s", name, plugin.Name) return fmt.Errorf("creating volume %q in plugin %s: %w", name, plugin.Name, err)
} }
} }
@ -305,7 +305,7 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo
if len(deps) != 0 { if len(deps) != 0 {
depsStr := strings.Join(deps, ", ") depsStr := strings.Join(deps, ", ")
if !force { if !force {
return errors.Wrapf(define.ErrVolumeBeingUsed, "volume %s is being used by the following container(s): %s", v.Name(), depsStr) return fmt.Errorf("volume %s is being used by the following container(s): %s: %w", v.Name(), depsStr, define.ErrVolumeBeingUsed)
} }
// We need to remove all containers using the volume // We need to remove all containers using the volume
@ -314,17 +314,17 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo
if err != nil { if err != nil {
// If the container's removed, no point in // If the container's removed, no point in
// erroring. // erroring.
if errors.Cause(err) == define.ErrNoSuchCtr || errors.Cause(err) == define.ErrCtrRemoved { if errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrRemoved) {
continue continue
} }
return errors.Wrapf(err, "removing container %s that depends on volume %s", dep, v.Name()) return fmt.Errorf("removing container %s that depends on volume %s: %w", dep, v.Name(), err)
} }
logrus.Debugf("Removing container %s (depends on volume %q)", ctr.ID(), v.Name()) logrus.Debugf("Removing container %s (depends on volume %q)", ctr.ID(), v.Name())
if err := r.removeContainer(ctx, ctr, force, false, false, timeout); err != nil { if err := r.removeContainer(ctx, ctr, force, false, false, timeout); err != nil {
return errors.Wrapf(err, "removing container %s that depends on volume %s", ctr.ID(), v.Name()) return fmt.Errorf("removing container %s that depends on volume %s: %w", ctr.ID(), v.Name(), err)
} }
} }
} }
@ -337,7 +337,7 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo
// them. // them.
logrus.Errorf("Unmounting volume %s: %v", v.Name(), err) logrus.Errorf("Unmounting volume %s: %v", v.Name(), err)
} else { } else {
return errors.Wrapf(err, "unmounting volume %s", v.Name()) return fmt.Errorf("unmounting volume %s: %w", v.Name(), err)
} }
} }
@ -353,7 +353,7 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo
// Do we have a volume driver? // Do we have a volume driver?
if v.plugin == nil { if v.plugin == nil {
canRemove = false canRemove = false
removalErr = errors.Wrapf(define.ErrMissingPlugin, "cannot remove volume %s from plugin %s, but it has been removed from Podman", v.Name(), v.Driver()) removalErr = fmt.Errorf("cannot remove volume %s from plugin %s, but it has been removed from Podman: %w", v.Name(), v.Driver(), define.ErrMissingPlugin)
} else { } else {
// Ping the plugin first to verify the volume still // Ping the plugin first to verify the volume still
// exists. // exists.
@ -364,14 +364,14 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo
getReq.Name = v.Name() getReq.Name = v.Name()
if _, err := v.plugin.GetVolume(getReq); err != nil { if _, err := v.plugin.GetVolume(getReq); err != nil {
canRemove = false canRemove = false
removalErr = errors.Wrapf(err, "volume %s could not be retrieved from plugin %s, but it has been removed from Podman", v.Name(), v.Driver()) removalErr = fmt.Errorf("volume %s could not be retrieved from plugin %s, but it has been removed from Podman: %w", v.Name(), v.Driver(), err)
} }
} }
if canRemove { if canRemove {
req := new(pluginapi.RemoveRequest) req := new(pluginapi.RemoveRequest)
req.Name = v.Name() req.Name = v.Name()
if err := v.plugin.RemoveVolume(req); err != nil { if err := v.plugin.RemoveVolume(req); err != nil {
return errors.Wrapf(err, "volume %s could not be removed from plugin %s", v.Name(), v.Driver()) return fmt.Errorf("volume %s could not be removed from plugin %s: %w", v.Name(), v.Driver(), err)
} }
} }
} }
@ -381,13 +381,13 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo
if removalErr != nil { if removalErr != nil {
logrus.Errorf("Removing volume %s from plugin %s: %v", v.Name(), v.Driver(), removalErr) logrus.Errorf("Removing volume %s from plugin %s: %v", v.Name(), v.Driver(), removalErr)
} }
return errors.Wrapf(err, "removing volume %s", v.Name()) return fmt.Errorf("removing volume %s: %w", v.Name(), err)
} }
// Free the volume's lock // Free the volume's lock
if err := v.lock.Free(); err != nil { if err := v.lock.Free(); err != nil {
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(err, "freeing lock for volume %s", v.Name()) removalErr = fmt.Errorf("freeing lock for volume %s: %w", v.Name(), err)
} else { } else {
logrus.Errorf("Freeing lock for volume %q: %v", v.Name(), err) logrus.Errorf("Freeing lock for volume %q: %v", v.Name(), err)
} }
@ -397,7 +397,7 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool, timeo
// from /var/lib/containers/storage/volumes // from /var/lib/containers/storage/volumes
if err := v.teardownStorage(); err != nil { if err := v.teardownStorage(); err != nil {
if removalErr == nil { if removalErr == nil {
removalErr = errors.Wrapf(err, "cleaning up volume storage for %q", v.Name()) removalErr = fmt.Errorf("cleaning up volume storage for %q: %w", v.Name(), err)
} else { } else {
logrus.Errorf("Cleaning up volume storage for volume %q: %v", v.Name(), err) logrus.Errorf("Cleaning up volume storage for volume %q: %v", v.Name(), err)
} }

View File

@ -2,6 +2,7 @@ package compat
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"sort" "sort"
@ -27,7 +28,6 @@ import (
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/docker/go-units" "github.com/docker/go-units"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -46,7 +46,7 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -73,7 +73,7 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
name := utils.GetName(r) name := utils.GetName(r)
reports, err := containerEngine.ContainerRm(r.Context(), []string{name}, options) reports, err := containerEngine.ContainerRm(r.Context(), []string{name}, options)
if err != nil { if err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr { if errors.Is(err, define.ErrNoSuchCtr) {
utils.ContainerNotFound(w, name, err) utils.ContainerNotFound(w, name, err)
return return
} }
@ -83,7 +83,7 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
} }
if len(reports) > 0 && reports[0].Err != nil { if len(reports) > 0 && reports[0].Err != nil {
err = reports[0].Err err = reports[0].Err
if errors.Cause(err) == define.ErrNoSuchCtr { if errors.Is(err, define.ErrNoSuchCtr) {
utils.ContainerNotFound(w, name, err) utils.ContainerNotFound(w, name, err)
return return
} }
@ -110,12 +110,12 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
filterMap, err := util.PrepareFilters(r) filterMap, err := util.PrepareFilters(r)
if err != nil { if err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrapf(err, "failed to decode filter parameters for %s", r.URL.String())) utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to decode filter parameters for %s: %w", r.URL.String(), err))
return return
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusInternalServerError, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -164,7 +164,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
for _, ctnr := range containers { for _, ctnr := range containers {
api, err := LibpodToContainer(ctnr, query.Size) api, err := LibpodToContainer(ctnr, query.Size)
if err != nil { if err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr { if errors.Is(err, define.ErrNoSuchCtr) {
// container was removed between the initial fetch of the list and conversion // container was removed between the initial fetch of the list and conversion
logrus.Debugf("Container %s removed between initial fetch and conversion, ignoring in output", ctnr.ID()) logrus.Debugf("Container %s removed between initial fetch and conversion, ignoring in output", ctnr.ID())
continue continue
@ -187,7 +187,7 @@ func GetContainer(w http.ResponseWriter, r *http.Request) {
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -215,7 +215,7 @@ func KillContainer(w http.ResponseWriter, r *http.Request) {
Signal: "KILL", Signal: "KILL",
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -228,12 +228,12 @@ func KillContainer(w http.ResponseWriter, r *http.Request) {
} }
report, err := containerEngine.ContainerKill(r.Context(), []string{name}, options) report, err := containerEngine.ContainerKill(r.Context(), []string{name}, options)
if err != nil { if err != nil {
if errors.Cause(err) == define.ErrCtrStateInvalid || if errors.Is(err, define.ErrCtrStateInvalid) ||
errors.Cause(err) == define.ErrCtrStopped { errors.Is(err, define.ErrCtrStopped) {
utils.Error(w, http.StatusConflict, err) utils.Error(w, http.StatusConflict, err)
return return
} }
if errors.Cause(err) == define.ErrNoSuchCtr { if errors.Is(err, define.ErrNoSuchCtr) {
utils.ContainerNotFound(w, name, err) utils.ContainerNotFound(w, name, err)
return return
} }
@ -512,7 +512,7 @@ func LibpodToContainerJSON(l *libpod.Container, sz bool) (*types.ContainerJSON,
for ep := range inspect.HostConfig.PortBindings { for ep := range inspect.HostConfig.PortBindings {
splitp := strings.SplitN(ep, "/", 2) splitp := strings.SplitN(ep, "/", 2)
if len(splitp) != 2 { if len(splitp) != 2 {
return nil, errors.Errorf("PORT/PROTOCOL Format required for %q", ep) return nil, fmt.Errorf("PORT/PROTOCOL Format required for %q", ep)
} }
exposedPort, err := nat.NewPort(splitp[1], splitp[0]) exposedPort, err := nat.NewPort(splitp[1], splitp[0])
if err != nil { if err != nil {
@ -616,7 +616,7 @@ func RenameContainer(w http.ResponseWriter, r *http.Request) {
Name string `schema:"name"` Name string `schema:"name"`
}{} }{}
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -627,7 +627,7 @@ func RenameContainer(w http.ResponseWriter, r *http.Request) {
} }
if _, err := runtime.RenameContainer(r.Context(), ctr, query.Name); err != nil { if _, err := runtime.RenameContainer(r.Context(), ctr, query.Name); err != nil {
if errors.Cause(err) == define.ErrPodExists || errors.Cause(err) == define.ErrCtrExists { if errors.Is(err, define.ErrPodExists) || errors.Is(err, define.ErrCtrExists) {
utils.Error(w, http.StatusConflict, err) utils.Error(w, http.StatusConflict, err)
return return
} }

View File

@ -2,6 +2,7 @@ package libpod
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
@ -19,7 +20,6 @@ import (
"github.com/containers/podman/v4/pkg/specgenutil" "github.com/containers/podman/v4/pkg/specgenutil"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -33,11 +33,11 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
) )
psg := specgen.PodSpecGenerator{InfraContainerSpec: &specgen.SpecGenerator{}} psg := specgen.PodSpecGenerator{InfraContainerSpec: &specgen.SpecGenerator{}}
if err := json.NewDecoder(r.Body).Decode(&psg); err != nil { if err := json.NewDecoder(r.Body).Decode(&psg); err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, failedToDecodeSpecgen)) utils.Error(w, http.StatusInternalServerError, fmt.Errorf("%v: %w", failedToDecodeSpecgen, err))
return return
} }
if err != nil { if err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, failedToDecodeSpecgen)) utils.Error(w, http.StatusInternalServerError, fmt.Errorf("%v: %w", failedToDecodeSpecgen, err))
return return
} }
if !psg.NoInfra { if !psg.NoInfra {
@ -51,17 +51,17 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
} }
err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, &infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings) err = specgenutil.FillOutSpecGen(psg.InfraContainerSpec, &infraOptions, []string{}) // necessary for default values in many cases (userns, idmappings)
if err != nil { if err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "error filling out specgen")) utils.Error(w, http.StatusInternalServerError, fmt.Errorf("error filling out specgen: %w", err))
return return
} }
out, err := json.Marshal(psg) // marshal our spec so the matching options can be unmarshaled into infra out, err := json.Marshal(psg) // marshal our spec so the matching options can be unmarshaled into infra
if err != nil { if err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, failedToDecodeSpecgen)) utils.Error(w, http.StatusInternalServerError, fmt.Errorf("%v: %w", failedToDecodeSpecgen, err))
return return
} }
err = json.Unmarshal(out, psg.InfraContainerSpec) // unmarhal matching options err = json.Unmarshal(out, psg.InfraContainerSpec) // unmarhal matching options
if err != nil { if err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, failedToDecodeSpecgen)) utils.Error(w, http.StatusInternalServerError, fmt.Errorf("%v: %w", failedToDecodeSpecgen, err))
return return
} }
// a few extra that do not have the same json tags // a few extra that do not have the same json tags
@ -75,10 +75,10 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
pod, err := generate.MakePod(&podSpecComplete, runtime) pod, err := generate.MakePod(&podSpecComplete, runtime)
if err != nil { if err != nil {
httpCode := http.StatusInternalServerError httpCode := http.StatusInternalServerError
if errors.Cause(err) == define.ErrPodExists { if errors.Is(err, define.ErrPodExists) {
httpCode = http.StatusConflict httpCode = http.StatusConflict
} }
utils.Error(w, httpCode, errors.Wrap(err, "failed to make pod")) utils.Error(w, httpCode, fmt.Errorf("failed to make pod: %w", err))
return return
} }
utils.WriteResponse(w, http.StatusCreated, entities.IDResponse{ID: pod.ID()}) utils.WriteResponse(w, http.StatusCreated, entities.IDResponse{ID: pod.ID()})
@ -89,7 +89,7 @@ func Pods(w http.ResponseWriter, r *http.Request) {
filterMap, err := util.PrepareFilters(r) filterMap, err := util.PrepareFilters(r)
if err != nil { if err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -139,7 +139,7 @@ func PodStop(w http.ResponseWriter, r *http.Request) {
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
name := utils.GetName(r) name := utils.GetName(r)
@ -164,7 +164,7 @@ func PodStop(w http.ResponseWriter, r *http.Request) {
} else { } else {
responses, stopError = pod.Stop(r.Context(), false) responses, stopError = pod.Stop(r.Context(), false)
} }
if stopError != nil && errors.Cause(stopError) != define.ErrPodPartialFail { if stopError != nil && !errors.Is(stopError, define.ErrPodPartialFail) {
utils.Error(w, http.StatusInternalServerError, err) utils.Error(w, http.StatusInternalServerError, err)
return return
} }
@ -178,7 +178,7 @@ func PodStop(w http.ResponseWriter, r *http.Request) {
report := entities.PodStopReport{Id: pod.ID()} report := entities.PodStopReport{Id: pod.ID()}
for id, err := range responses { for id, err := range responses {
report.Errs = append(report.Errs, errors.Wrapf(err, "error stopping container %s", id)) report.Errs = append(report.Errs, fmt.Errorf("error stopping container %s: %w", id, err))
} }
code := http.StatusOK code := http.StatusOK
@ -207,14 +207,14 @@ func PodStart(w http.ResponseWriter, r *http.Request) {
} }
responses, err := pod.Start(r.Context()) responses, err := pod.Start(r.Context())
if err != nil && errors.Cause(err) != define.ErrPodPartialFail { if err != nil && !errors.Is(err, define.ErrPodPartialFail) {
utils.Error(w, http.StatusConflict, err) utils.Error(w, http.StatusConflict, err)
return return
} }
report := entities.PodStartReport{Id: pod.ID()} report := entities.PodStartReport{Id: pod.ID()}
for id, err := range responses { for id, err := range responses {
report.Errs = append(report.Errs, errors.Wrapf(err, "error starting container "+id)) report.Errs = append(report.Errs, fmt.Errorf("%v: %w", "error starting container "+id, err))
} }
code := http.StatusOK code := http.StatusOK
@ -237,7 +237,7 @@ func PodDelete(w http.ResponseWriter, r *http.Request) {
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
name := utils.GetName(r) name := utils.GetName(r)
@ -263,14 +263,14 @@ func PodRestart(w http.ResponseWriter, r *http.Request) {
return return
} }
responses, err := pod.Restart(r.Context()) responses, err := pod.Restart(r.Context())
if err != nil && errors.Cause(err) != define.ErrPodPartialFail { if err != nil && !errors.Is(err, define.ErrPodPartialFail) {
utils.Error(w, http.StatusInternalServerError, err) utils.Error(w, http.StatusInternalServerError, err)
return return
} }
report := entities.PodRestartReport{Id: pod.ID()} report := entities.PodRestartReport{Id: pod.ID()}
for id, err := range responses { for id, err := range responses {
report.Errs = append(report.Errs, errors.Wrapf(err, "error restarting container %s", id)) report.Errs = append(report.Errs, fmt.Errorf("error restarting container %s: %w", id, err))
} }
code := http.StatusOK code := http.StatusOK
@ -314,14 +314,14 @@ func PodPause(w http.ResponseWriter, r *http.Request) {
return return
} }
responses, err := pod.Pause(r.Context()) responses, err := pod.Pause(r.Context())
if err != nil && errors.Cause(err) != define.ErrPodPartialFail { if err != nil && !errors.Is(err, define.ErrPodPartialFail) {
utils.Error(w, http.StatusInternalServerError, err) utils.Error(w, http.StatusInternalServerError, err)
return return
} }
report := entities.PodPauseReport{Id: pod.ID()} report := entities.PodPauseReport{Id: pod.ID()}
for id, v := range responses { for id, v := range responses {
report.Errs = append(report.Errs, errors.Wrapf(v, "error pausing container %s", id)) report.Errs = append(report.Errs, fmt.Errorf("error pausing container %s: %w", id, v))
} }
code := http.StatusOK code := http.StatusOK
@ -340,14 +340,14 @@ func PodUnpause(w http.ResponseWriter, r *http.Request) {
return return
} }
responses, err := pod.Unpause(r.Context()) responses, err := pod.Unpause(r.Context())
if err != nil && errors.Cause(err) != define.ErrPodPartialFail { if err != nil && !errors.Is(err, define.ErrPodPartialFail) {
utils.Error(w, http.StatusInternalServerError, err) utils.Error(w, http.StatusInternalServerError, err)
return return
} }
report := entities.PodUnpauseReport{Id: pod.ID()} report := entities.PodUnpauseReport{Id: pod.ID()}
for id, v := range responses { for id, v := range responses {
report.Errs = append(report.Errs, errors.Wrapf(v, "error unpausing container %s", id)) report.Errs = append(report.Errs, fmt.Errorf("error unpausing container %s: %w", id, v))
} }
code := http.StatusOK code := http.StatusOK
@ -374,7 +374,7 @@ func PodTop(w http.ResponseWriter, r *http.Request) {
PsArgs: psArgs, PsArgs: psArgs,
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -456,7 +456,7 @@ func PodKill(w http.ResponseWriter, r *http.Request) {
// override any golang type defaults // override any golang type defaults
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
if _, found := r.URL.Query()["signal"]; found { if _, found := r.URL.Query()["signal"]; found {
@ -465,7 +465,7 @@ func PodKill(w http.ResponseWriter, r *http.Request) {
sig, err := util.ParseSignal(signal) sig, err := util.ParseSignal(signal)
if err != nil { if err != nil {
utils.InternalServerError(w, errors.Wrapf(err, "unable to parse signal value")) utils.InternalServerError(w, fmt.Errorf("unable to parse signal value: %w", err))
return return
} }
name := utils.GetName(r) name := utils.GetName(r)
@ -488,12 +488,12 @@ func PodKill(w http.ResponseWriter, r *http.Request) {
} }
} }
if !hasRunning { if !hasRunning {
utils.Error(w, http.StatusConflict, errors.Errorf("cannot kill a pod with no running containers: %s", pod.ID())) utils.Error(w, http.StatusConflict, fmt.Errorf("cannot kill a pod with no running containers: %s", pod.ID()))
return return
} }
responses, err := pod.Kill(r.Context(), uint(sig)) responses, err := pod.Kill(r.Context(), uint(sig))
if err != nil && errors.Cause(err) != define.ErrPodPartialFail { if err != nil && !errors.Is(err, define.ErrPodPartialFail) {
utils.Error(w, http.StatusInternalServerError, err) utils.Error(w, http.StatusInternalServerError, err)
return return
} }
@ -534,7 +534,7 @@ func PodStats(w http.ResponseWriter, r *http.Request) {
// default would go here // default would go here
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -549,13 +549,12 @@ func PodStats(w http.ResponseWriter, r *http.Request) {
reports, err := containerEngine.PodStats(r.Context(), query.NamesOrIDs, options) reports, err := containerEngine.PodStats(r.Context(), query.NamesOrIDs, options)
// Error checks as documented in swagger. // Error checks as documented in swagger.
switch errors.Cause(err) { if err != nil {
case define.ErrNoSuchPod: if errors.Is(err, define.ErrNoSuchPod) {
utils.Error(w, http.StatusNotFound, err) utils.Error(w, http.StatusNotFound, err)
return return
case nil: }
// Nothing to do.
default:
utils.InternalServerError(w, err) utils.InternalServerError(w, err)
return return
} }

View File

@ -2,9 +2,12 @@ package libpod
import ( import (
"encoding/json" "encoding/json"
"fmt"
"net/http" "net/http"
"net/url" "net/url"
"errors"
"github.com/containers/podman/v4/libpod" "github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/api/handlers/utils" "github.com/containers/podman/v4/pkg/api/handlers/utils"
@ -16,7 +19,6 @@ import (
"github.com/containers/podman/v4/pkg/domain/infra/abi/parse" "github.com/containers/podman/v4/pkg/domain/infra/abi/parse"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/gorilla/schema" "github.com/gorilla/schema"
"github.com/pkg/errors"
) )
func CreateVolume(w http.ResponseWriter, r *http.Request) { func CreateVolume(w http.ResponseWriter, r *http.Request) {
@ -30,14 +32,14 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
} }
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusInternalServerError, utils.Error(w, http.StatusInternalServerError,
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
input := entities.VolumeCreateOptions{} input := entities.VolumeCreateOptions{}
// decode params from body // decode params from body
if err := json.NewDecoder(r.Body).Decode(&input); err != nil { if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
utils.Error(w, http.StatusInternalServerError, errors.Wrap(err, "Decode()")) utils.Error(w, http.StatusInternalServerError, fmt.Errorf("Decode(): %w", err))
return return
} }
@ -108,7 +110,7 @@ func ListVolumes(w http.ResponseWriter, r *http.Request) {
filterMap, err := util.PrepareFilters(r) filterMap, err := util.PrepareFilters(r)
if err != nil { if err != nil {
utils.Error(w, http.StatusInternalServerError, utils.Error(w, http.StatusInternalServerError,
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
@ -181,7 +183,7 @@ func RemoveVolume(w http.ResponseWriter, r *http.Request) {
if err := decoder.Decode(&query, r.URL.Query()); err != nil { if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusInternalServerError, utils.Error(w, http.StatusInternalServerError,
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
return return
} }
name := utils.GetName(r) name := utils.GetName(r)
@ -191,7 +193,7 @@ func RemoveVolume(w http.ResponseWriter, r *http.Request) {
return return
} }
if err := runtime.RemoveVolume(r.Context(), vol, query.Force, query.Timeout); err != nil { if err := runtime.RemoveVolume(r.Context(), vol, query.Force, query.Timeout); err != nil {
if errors.Cause(err) == define.ErrVolumeBeingUsed { if errors.Is(err, define.ErrVolumeBeingUsed) {
utils.Error(w, http.StatusConflict, err) utils.Error(w, http.StatusConflict, err)
return return
} }

View File

@ -1,17 +1,18 @@
package utils package utils
import ( import (
"errors"
"fmt"
"net/http" "net/http"
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/errorhandling" "github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
var ( var (
ErrLinkNotSupport = errors.New("Link is not supported") ErrLinkNotSupport = errors.New("link is not supported")
) )
// TODO: document the exported functions in this file and make them more // TODO: document the exported functions in this file and make them more
@ -25,7 +26,7 @@ func Error(w http.ResponseWriter, code int, err error) {
// Log detailed message of what happened to machine running podman service // Log detailed message of what happened to machine running podman service
log.Infof("Request Failed(%s): %s", http.StatusText(code), err.Error()) log.Infof("Request Failed(%s): %s", http.StatusText(code), err.Error())
em := errorhandling.ErrorModel{ em := errorhandling.ErrorModel{
Because: (errors.Cause(err)).Error(), Because: errorhandling.Cause(err).Error(),
Message: err.Error(), Message: err.Error(),
ResponseCode: code, ResponseCode: code,
} }
@ -33,51 +34,50 @@ func Error(w http.ResponseWriter, code int, err error) {
} }
func VolumeNotFound(w http.ResponseWriter, name string, err error) { func VolumeNotFound(w http.ResponseWriter, name string, err error) {
if errors.Cause(err) != define.ErrNoSuchVolume { if !errors.Is(err, define.ErrNoSuchVolume) {
InternalServerError(w, err) InternalServerError(w, err)
} }
Error(w, http.StatusNotFound, err) Error(w, http.StatusNotFound, err)
} }
func ContainerNotFound(w http.ResponseWriter, name string, err error) { func ContainerNotFound(w http.ResponseWriter, name string, err error) {
switch errors.Cause(err) { if errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrExists) {
case define.ErrNoSuchCtr, define.ErrCtrExists:
Error(w, http.StatusNotFound, err) Error(w, http.StatusNotFound, err)
default: } else {
InternalServerError(w, err) InternalServerError(w, err)
} }
} }
func ImageNotFound(w http.ResponseWriter, name string, err error) { func ImageNotFound(w http.ResponseWriter, name string, err error) {
if errors.Cause(err) != storage.ErrImageUnknown { if !errors.Is(err, storage.ErrImageUnknown) {
InternalServerError(w, err) InternalServerError(w, err)
} }
Error(w, http.StatusNotFound, err) Error(w, http.StatusNotFound, err)
} }
func NetworkNotFound(w http.ResponseWriter, name string, err error) { func NetworkNotFound(w http.ResponseWriter, name string, err error) {
if errors.Cause(err) != define.ErrNoSuchNetwork { if !errors.Is(err, define.ErrNoSuchNetwork) {
InternalServerError(w, err) InternalServerError(w, err)
} }
Error(w, http.StatusNotFound, err) Error(w, http.StatusNotFound, err)
} }
func PodNotFound(w http.ResponseWriter, name string, err error) { func PodNotFound(w http.ResponseWriter, name string, err error) {
if errors.Cause(err) != define.ErrNoSuchPod { if !errors.Is(err, define.ErrNoSuchPod) {
InternalServerError(w, err) InternalServerError(w, err)
} }
Error(w, http.StatusNotFound, err) Error(w, http.StatusNotFound, err)
} }
func SessionNotFound(w http.ResponseWriter, name string, err error) { func SessionNotFound(w http.ResponseWriter, name string, err error) {
if errors.Cause(err) != define.ErrNoSuchExecSession { if !errors.Is(err, define.ErrNoSuchExecSession) {
InternalServerError(w, err) InternalServerError(w, err)
} }
Error(w, http.StatusNotFound, err) Error(w, http.StatusNotFound, err)
} }
func SecretNotFound(w http.ResponseWriter, nameOrID string, err error) { func SecretNotFound(w http.ResponseWriter, nameOrID string, err error) {
if errors.Cause(err).Error() != "no such secret" { if errorhandling.Cause(err).Error() != "no such secret" {
InternalServerError(w, err) InternalServerError(w, err)
} }
Error(w, http.StatusNotFound, err) Error(w, http.StatusNotFound, err)
@ -92,7 +92,7 @@ func InternalServerError(w http.ResponseWriter, err error) {
} }
func BadRequest(w http.ResponseWriter, key string, value string, err error) { func BadRequest(w http.ResponseWriter, key string, value string, err error) {
e := errors.Wrapf(err, "failed to parse query parameter '%s': %q", key, value) e := fmt.Errorf("failed to parse query parameter '%s': %q: %w", key, value, err)
Error(w, http.StatusBadRequest, e) Error(w, http.StatusBadRequest, e)
} }

View File

@ -231,7 +231,7 @@ func Modify(ctx context.Context, name string, images []string, options *ModifyOp
err = errorhandling.JoinErrors(report.Errors) err = errorhandling.JoinErrors(report.Errors)
if err != nil { if err != nil {
errModel := errorhandling.ErrorModel{ errModel := errorhandling.ErrorModel{
Because: (errors.Cause(err)).Error(), Because: errorhandling.Cause(err).Error(),
Message: err.Error(), Message: err.Error(),
ResponseCode: response.StatusCode, ResponseCode: response.StatusCode,
} }

View File

@ -2,6 +2,7 @@ package abi
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -32,7 +33,6 @@ import (
"github.com/containers/podman/v4/pkg/specgenutil" "github.com/containers/podman/v4/pkg/specgenutil"
"github.com/containers/podman/v4/pkg/util" "github.com/containers/podman/v4/pkg/util"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -80,7 +80,7 @@ func getContainersByContext(all, latest bool, names []string, runtime *libpod.Ru
func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string, options entities.ContainerExistsOptions) (*entities.BoolReport, error) { func (ic *ContainerEngine) ContainerExists(ctx context.Context, nameOrID string, options entities.ContainerExistsOptions) (*entities.BoolReport, error) {
_, err := ic.Libpod.LookupContainer(nameOrID) _, err := ic.Libpod.LookupContainer(nameOrID)
if err != nil { if err != nil {
if errors.Cause(err) != define.ErrNoSuchCtr { if !errors.Is(err, define.ErrNoSuchCtr) {
return nil, err return nil, err
} }
if options.External { if options.External {
@ -120,7 +120,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
report := make([]*entities.PauseUnpauseReport, 0, len(ctrs)) report := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
for _, c := range ctrs { for _, c := range ctrs {
err := c.Pause() err := c.Pause()
if err != nil && options.All && errors.Cause(err) == define.ErrCtrStateInvalid { if err != nil && options.All && errors.Is(err, define.ErrCtrStateInvalid) {
logrus.Debugf("Container %s is not running", c.ID()) logrus.Debugf("Container %s is not running", c.ID())
continue continue
} }
@ -137,7 +137,7 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
report := make([]*entities.PauseUnpauseReport, 0, len(ctrs)) report := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
for _, c := range ctrs { for _, c := range ctrs {
err := c.Unpause() err := c.Unpause()
if err != nil && options.All && errors.Cause(err) == define.ErrCtrStateInvalid { if err != nil && options.All && errors.Is(err, define.ErrCtrStateInvalid) {
logrus.Debugf("Container %s is not paused", c.ID()) logrus.Debugf("Container %s is not paused", c.ID())
continue continue
} }
@ -148,7 +148,7 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []string, options entities.StopOptions) ([]*entities.StopReport, error) { func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []string, options entities.StopOptions) ([]*entities.StopReport, error) {
names := namesOrIds names := namesOrIds
ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, names, ic.Libpod) ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, names, ic.Libpod)
if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) { if err != nil && !(options.Ignore && errors.Is(err, define.ErrNoSuchCtr)) {
return nil, err return nil, err
} }
ctrMap := map[string]string{} ctrMap := map[string]string{}
@ -166,13 +166,13 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
} }
if err != nil { if err != nil {
switch { switch {
case errors.Cause(err) == define.ErrCtrStopped: case errors.Is(err, define.ErrCtrStopped):
logrus.Debugf("Container %s is already stopped", c.ID()) logrus.Debugf("Container %s is already stopped", c.ID())
case options.All && errors.Cause(err) == define.ErrCtrStateInvalid: case options.All && errors.Is(err, define.ErrCtrStateInvalid):
logrus.Debugf("Container %s is not running, could not stop", c.ID()) logrus.Debugf("Container %s is not running, could not stop", c.ID())
// container never created in OCI runtime // container never created in OCI runtime
// docker parity: do nothing just return container id // docker parity: do nothing just return container id
case errors.Cause(err) == define.ErrCtrStateInvalid: case errors.Is(err, define.ErrCtrStateInvalid):
logrus.Debugf("Container %s is either not created on runtime or is in a invalid state", c.ID()) logrus.Debugf("Container %s is either not created on runtime or is in a invalid state", c.ID())
default: default:
return err return err
@ -238,7 +238,7 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
reports := make([]*entities.KillReport, 0, len(ctrs)) reports := make([]*entities.KillReport, 0, len(ctrs))
for _, con := range ctrs { for _, con := range ctrs {
err := con.Kill(uint(sig)) err := con.Kill(uint(sig))
if options.All && errors.Cause(err) == define.ErrCtrStateInvalid { if options.All && errors.Is(err, define.ErrCtrStateInvalid) {
logrus.Debugf("Container %s is not running", con.ID()) logrus.Debugf("Container %s is not running", con.ID())
continue continue
} }
@ -289,8 +289,7 @@ func (ic *ContainerEngine) removeContainer(ctx context.Context, ctr *libpod.Cont
return nil return nil
} }
logrus.Debugf("Failed to remove container %s: %s", ctr.ID(), err.Error()) logrus.Debugf("Failed to remove container %s: %s", ctr.ID(), err.Error())
switch errors.Cause(err) { if errors.Is(err, define.ErrNoSuchCtr) {
case define.ErrNoSuchCtr:
// Ignore if the container does not exist (anymore) when either // Ignore if the container does not exist (anymore) when either
// it has been requested by the user of if the container is a // it has been requested by the user of if the container is a
// service one. Service containers are removed along with its // service one. Service containers are removed along with its
@ -301,7 +300,7 @@ func (ic *ContainerEngine) removeContainer(ctx context.Context, ctr *libpod.Cont
logrus.Debugf("Ignoring error (--allow-missing): %v", err) logrus.Debugf("Ignoring error (--allow-missing): %v", err)
return nil return nil
} }
case define.ErrCtrRemoved: } else if errors.Is(err, define.ErrCtrRemoved) {
return nil return nil
} }
return err return err
@ -317,15 +316,15 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
for _, ctr := range names { for _, ctr := range names {
report := reports.RmReport{Id: ctr} report := reports.RmReport{Id: ctr}
report.Err = ic.Libpod.RemoveStorageContainer(ctr, options.Force) report.Err = ic.Libpod.RemoveStorageContainer(ctr, options.Force)
switch errors.Cause(report.Err) { //nolint:gocritic
case nil: if report.Err == nil {
// remove container names that we successfully deleted // remove container names that we successfully deleted
rmReports = append(rmReports, &report) rmReports = append(rmReports, &report)
case define.ErrNoSuchCtr, define.ErrCtrExists: } else if errors.Is(report.Err, define.ErrNoSuchCtr) || errors.Is(report.Err, define.ErrCtrExists) {
// There is still a potential this is a libpod container // There is still a potential this is a libpod container
tmpNames = append(tmpNames, ctr) tmpNames = append(tmpNames, ctr)
default: } else {
if _, err := ic.Libpod.LookupContainer(ctr); errors.Cause(err) == define.ErrNoSuchCtr { if _, err := ic.Libpod.LookupContainer(ctr); errors.Is(err, define.ErrNoSuchCtr) {
// remove container failed, but not a libpod container // remove container failed, but not a libpod container
rmReports = append(rmReports, &report) rmReports = append(rmReports, &report)
continue continue
@ -337,7 +336,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
names = tmpNames names = tmpNames
ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod) ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod)
if err != nil && !(options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr) { if err != nil && !(options.Ignore && errors.Is(err, define.ErrNoSuchCtr)) {
// Failed to get containers. If force is specified, get the containers ID // Failed to get containers. If force is specified, get the containers ID
// and evict them // and evict them
if !options.Force { if !options.Force {
@ -349,7 +348,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
report := reports.RmReport{Id: ctr} report := reports.RmReport{Id: ctr}
_, err := ic.Libpod.EvictContainer(ctx, ctr, options.Volumes) _, err := ic.Libpod.EvictContainer(ctx, ctr, options.Volumes)
if err != nil { if err != nil {
if options.Ignore && errors.Cause(err) == define.ErrNoSuchCtr { if options.Ignore && errors.Is(err, define.ErrNoSuchCtr) {
logrus.Debugf("Ignoring error (--allow-missing): %v", err) logrus.Debugf("Ignoring error (--allow-missing): %v", err)
rmReports = append(rmReports, &report) rmReports = append(rmReports, &report)
continue continue
@ -426,7 +425,7 @@ func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []st
ctr, err := ic.Libpod.GetLatestContainer() ctr, err := ic.Libpod.GetLatestContainer()
if err != nil { if err != nil {
if errors.Is(err, define.ErrNoSuchCtr) { if errors.Is(err, define.ErrNoSuchCtr) {
return nil, []error{errors.Wrapf(err, "no containers to inspect")}, nil return nil, []error{fmt.Errorf("no containers to inspect: %w", err)}, nil
} }
return nil, nil, err return nil, nil, err
} }
@ -452,7 +451,7 @@ func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []st
// ErrNoSuchCtr is non-fatal, other errors will be // ErrNoSuchCtr is non-fatal, other errors will be
// treated as fatal. // treated as fatal.
if errors.Is(err, define.ErrNoSuchCtr) { if errors.Is(err, define.ErrNoSuchCtr) {
errs = append(errs, errors.Errorf("no such container %s", name)) errs = append(errs, fmt.Errorf("no such container %s", name))
continue continue
} }
return nil, nil, err return nil, nil, err
@ -463,7 +462,7 @@ func (ic *ContainerEngine) ContainerInspect(ctx context.Context, namesOrIds []st
// ErrNoSuchCtr is non-fatal, other errors will be // ErrNoSuchCtr is non-fatal, other errors will be
// treated as fatal. // treated as fatal.
if errors.Is(err, define.ErrNoSuchCtr) { if errors.Is(err, define.ErrNoSuchCtr) {
errs = append(errs, errors.Errorf("no such container %s", name)) errs = append(errs, fmt.Errorf("no such container %s", name))
continue continue
} }
return nil, nil, err return nil, nil, err
@ -487,7 +486,7 @@ func (ic *ContainerEngine) ContainerTop(ctx context.Context, options entities.To
container, err = ic.Libpod.LookupContainer(options.NameOrID) container, err = ic.Libpod.LookupContainer(options.NameOrID)
} }
if err != nil { if err != nil {
return nil, errors.Wrap(err, "unable to look up requested container") return nil, fmt.Errorf("unable to look up requested container: %w", err)
} }
// Run Top. // Run Top.
@ -512,12 +511,12 @@ func (ic *ContainerEngine) ContainerCommit(ctx context.Context, nameOrID string,
case "oci": case "oci":
mimeType = buildah.OCIv1ImageManifest mimeType = buildah.OCIv1ImageManifest
if len(options.Message) > 0 { if len(options.Message) > 0 {
return nil, errors.Errorf("messages are only compatible with the docker image format (-f docker)") return nil, fmt.Errorf("messages are only compatible with the docker image format (-f docker)")
} }
case "docker": case "docker":
mimeType = manifest.DockerV2Schema2MediaType mimeType = manifest.DockerV2Schema2MediaType
default: default:
return nil, errors.Errorf("unrecognized image format %q", options.Format) return nil, fmt.Errorf("unrecognized image format %q", options.Format)
} }
sc := ic.Libpod.SystemContext() sc := ic.Libpod.SystemContext()
@ -660,7 +659,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
// CRImportCheckpoint is expected to import exactly one container from checkpoint image // CRImportCheckpoint is expected to import exactly one container from checkpoint image
checkpointImageImportErrors = append( checkpointImageImportErrors = append(
checkpointImageImportErrors, checkpointImageImportErrors,
errors.Errorf("unable to import checkpoint from image: %q: %v", nameOrID, err), fmt.Errorf("unable to import checkpoint from image: %q: %v", nameOrID, err),
) )
} else { } else {
containers = append(containers, importedContainers[0]) containers = append(containers, importedContainers[0])
@ -720,16 +719,16 @@ func (ic *ContainerEngine) ContainerAttach(ctx context.Context, nameOrID string,
ctr := ctrs[0] ctr := ctrs[0]
conState, err := ctr.State() conState, err := ctr.State()
if err != nil { if err != nil {
return errors.Wrapf(err, "unable to determine state of %s", ctr.ID()) return fmt.Errorf("unable to determine state of %s: %w", ctr.ID(), err)
} }
if conState != define.ContainerStateRunning { if conState != define.ContainerStateRunning {
return errors.Errorf("you can only attach to running containers") return fmt.Errorf("you can only attach to running containers")
} }
// If the container is in a pod, also set to recursively start dependencies // If the container is in a pod, also set to recursively start dependencies
err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, false) err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, false)
if err != nil && errors.Cause(err) != define.ErrDetach { if err != nil && !errors.Is(err, define.ErrDetach) {
return errors.Wrapf(err, "error attaching to container %s", ctr.ID()) return fmt.Errorf("error attaching to container %s: %w", ctr.ID(), err)
} }
os.Stdout.WriteString("\n") os.Stdout.WriteString("\n")
return nil return nil
@ -751,12 +750,12 @@ func makeExecConfig(options entities.ExecOptions, rt *libpod.Runtime) (*libpod.E
storageConfig := rt.StorageConfig() storageConfig := rt.StorageConfig()
runtimeConfig, err := rt.GetConfig() runtimeConfig, err := rt.GetConfig()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error retrieving Libpod configuration to build exec exit command") return nil, fmt.Errorf("error retrieving Libpod configuration to build exec exit command: %w", err)
} }
// TODO: Add some ability to toggle syslog // TODO: Add some ability to toggle syslog
exitCommandArgs, err := specgenutil.CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), false, true) exitCommandArgs, err := specgenutil.CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), false, true)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "error constructing exit command for exec session") return nil, fmt.Errorf("error constructing exit command for exec session: %w", err)
} }
execConfig.ExitCommand = exitCommandArgs execConfig.ExitCommand = exitCommandArgs
@ -774,7 +773,7 @@ func checkExecPreserveFDs(options entities.ExecOptions) error {
for _, e := range entries { for _, e := range entries {
i, err := strconv.Atoi(e.Name()) i, err := strconv.Atoi(e.Name())
if err != nil { if err != nil {
return errors.Wrapf(err, "cannot parse %s in /proc/self/fd", e.Name()) return fmt.Errorf("cannot parse %s in /proc/self/fd: %w", e.Name(), err)
} }
m[i] = true m[i] = true
} }
@ -891,7 +890,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
if options.Attach { if options.Attach {
err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, !ctrRunning) err = terminal.StartAttachCtr(ctx, ctr, options.Stdout, options.Stderr, options.Stdin, options.DetachKeys, options.SigProxy, !ctrRunning)
if errors.Cause(err) == define.ErrDetach { if errors.Is(err, define.ErrDetach) {
// User manually detached // User manually detached
// Exit cleanly immediately // Exit cleanly immediately
reports = append(reports, &entities.ContainerStartReport{ reports = append(reports, &entities.ContainerStartReport{
@ -903,7 +902,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
return reports, nil return reports, nil
} }
if errors.Cause(err) == define.ErrWillDeadlock { if errors.Is(err, define.ErrWillDeadlock) {
logrus.Debugf("Deadlock error: %v", err) logrus.Debugf("Deadlock error: %v", err)
reports = append(reports, &entities.ContainerStartReport{ reports = append(reports, &entities.ContainerStartReport{
Id: ctr.ID(), Id: ctr.ID(),
@ -911,7 +910,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
Err: err, Err: err,
ExitCode: define.ExitCode(err), ExitCode: define.ExitCode(err),
}) })
return reports, errors.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID()) return reports, fmt.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID())
} }
if ctrRunning { if ctrRunning {
@ -936,7 +935,7 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
logrus.Errorf("Removing container %s: %v", ctr.ID(), err) logrus.Errorf("Removing container %s: %v", ctr.ID(), err)
} }
} }
return reports, errors.Wrapf(err, "unable to start container %s", ctr.ID()) return reports, fmt.Errorf("unable to start container %s: %w", ctr.ID(), err)
} }
exitCode = ic.GetContainerExitCode(ctx, ctr) exitCode = ic.GetContainerExitCode(ctx, ctr)
@ -960,12 +959,12 @@ func (ic *ContainerEngine) ContainerStart(ctx context.Context, namesOrIds []stri
} }
if err := ctr.Start(ctx, true); err != nil { if err := ctr.Start(ctx, true); err != nil {
report.Err = err report.Err = err
if errors.Cause(err) == define.ErrWillDeadlock { if errors.Is(err, define.ErrWillDeadlock) {
report.Err = errors.Wrapf(err, "please run 'podman system renumber' to resolve deadlocks") report.Err = fmt.Errorf("please run 'podman system renumber' to resolve deadlocks: %w", err)
reports = append(reports, report) reports = append(reports, report)
continue continue
} }
report.Err = errors.Wrapf(err, "unable to start container %q", ctr.ID()) report.Err = fmt.Errorf("unable to start container %q: %w", ctr.ID(), err)
reports = append(reports, report) reports = append(reports, report)
if ctr.AutoRemove() { if ctr.AutoRemove() {
if err := ic.removeContainer(ctx, ctr, entities.RmOptions{}); err != nil { if err := ic.removeContainer(ctx, ctr, entities.RmOptions{}); err != nil {
@ -1001,7 +1000,7 @@ func (ic *ContainerEngine) Diff(ctx context.Context, namesOrIDs []string, opts e
if opts.Latest { if opts.Latest {
ctnr, err := ic.Libpod.GetLatestContainer() ctnr, err := ic.Libpod.GetLatestContainer()
if err != nil { if err != nil {
return nil, errors.Wrap(err, "unable to get latest container") return nil, fmt.Errorf("unable to get latest container: %w", err)
} }
base = ctnr.ID() base = ctnr.ID()
} }
@ -1064,7 +1063,7 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
// We've manually detached from the container // We've manually detached from the container
// Do not perform cleanup, or wait for container exit code // Do not perform cleanup, or wait for container exit code
// Just exit immediately // Just exit immediately
if errors.Cause(err) == define.ErrDetach { if errors.Is(err, define.ErrDetach) {
report.ExitCode = 0 report.ExitCode = 0
return &report, nil return &report, nil
} }
@ -1074,10 +1073,10 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
logrus.Debugf("unable to remove container %s after failing to start and attach to it", ctr.ID()) logrus.Debugf("unable to remove container %s after failing to start and attach to it", ctr.ID())
} }
} }
if errors.Cause(err) == define.ErrWillDeadlock { if errors.Is(err, define.ErrWillDeadlock) {
logrus.Debugf("Deadlock error on %q: %v", ctr.ID(), err) logrus.Debugf("Deadlock error on %q: %v", ctr.ID(), err)
report.ExitCode = define.ExitCode(err) report.ExitCode = define.ExitCode(err)
return &report, errors.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID()) return &report, fmt.Errorf("attempting to start container %s would cause a deadlock; please run 'podman system renumber' to resolve", ctr.ID())
} }
report.ExitCode = define.ExitCode(err) report.ExitCode = define.ExitCode(err)
return &report, err return &report, err
@ -1086,8 +1085,8 @@ func (ic *ContainerEngine) ContainerRun(ctx context.Context, opts entities.Conta
if opts.Rm && !ctr.ShouldRestart(ctx) { if opts.Rm && !ctr.ShouldRestart(ctx) {
var timeout *uint var timeout *uint
if err := ic.Libpod.RemoveContainer(ctx, ctr, false, true, timeout); err != nil { if err := ic.Libpod.RemoveContainer(ctx, ctr, false, true, timeout); err != nil {
if errors.Cause(err) == define.ErrNoSuchCtr || if errors.Is(err, define.ErrNoSuchCtr) ||
errors.Cause(err) == define.ErrCtrRemoved { errors.Is(err, define.ErrCtrRemoved) {
logrus.Infof("Container %s was already removed, skipping --rm", ctr.ID()) logrus.Infof("Container %s was already removed, skipping --rm", ctr.ID())
} else { } else {
logrus.Errorf("Removing container %s: %v", ctr.ID(), err) logrus.Errorf("Removing container %s: %v", ctr.ID(), err)
@ -1180,12 +1179,12 @@ func (ic *ContainerEngine) ContainerCleanup(ctx context.Context, namesOrIds []st
var timeout *uint var timeout *uint
err = ic.Libpod.RemoveContainer(ctx, ctr, false, true, timeout) err = ic.Libpod.RemoveContainer(ctx, ctr, false, true, timeout)
if err != nil { if err != nil {
report.RmErr = errors.Wrapf(err, "failed to clean up and remove container %v", ctr.ID()) report.RmErr = fmt.Errorf("failed to clean up and remove container %v: %w", ctr.ID(), err)
} }
} else { } else {
err := ctr.Cleanup(ctx) err := ctr.Cleanup(ctx)
if err != nil { if err != nil {
report.CleanErr = errors.Wrapf(err, "failed to clean up container %v", ctr.ID()) report.CleanErr = fmt.Errorf("failed to clean up container %v: %w", ctr.ID(), err)
} }
} }
@ -1212,7 +1211,7 @@ func (ic *ContainerEngine) ContainerInit(ctx context.Context, namesOrIds []strin
err := ctr.Init(ctx, ctr.PodID() != "") err := ctr.Init(ctx, ctr.PodID() != "")
// If we're initializing all containers, ignore invalid state errors // If we're initializing all containers, ignore invalid state errors
if options.All && errors.Cause(err) == define.ErrCtrStateInvalid { if options.All && errors.Is(err, define.ErrCtrStateInvalid) {
err = nil err = nil
} }
report.Err = err report.Err = err
@ -1323,7 +1322,7 @@ func (ic *ContainerEngine) ContainerUnmount(ctx context.Context, nameOrIDs []str
if mounted { if mounted {
report := entities.ContainerUnmountReport{Id: sctr.ID} report := entities.ContainerUnmountReport{Id: sctr.ID}
if _, report.Err = ic.Libpod.UnmountStorageContainer(sctr.ID, options.Force); report.Err != nil { if _, report.Err = ic.Libpod.UnmountStorageContainer(sctr.ID, options.Force); report.Err != nil {
if errors.Cause(report.Err) != define.ErrCtrExists { if !errors.Is(report.Err, define.ErrCtrExists) {
reports = append(reports, &report) reports = append(reports, &report)
} }
} else { } else {
@ -1357,11 +1356,11 @@ func (ic *ContainerEngine) ContainerUnmount(ctx context.Context, nameOrIDs []str
report := entities.ContainerUnmountReport{Id: ctr.ID()} report := entities.ContainerUnmountReport{Id: ctr.ID()}
if err := ctr.Unmount(options.Force); err != nil { if err := ctr.Unmount(options.Force); err != nil {
if options.All && errors.Cause(err) == storage.ErrLayerNotMounted { if options.All && errors.Is(err, storage.ErrLayerNotMounted) {
logrus.Debugf("Error umounting container %s, storage.ErrLayerNotMounted", ctr.ID()) logrus.Debugf("Error umounting container %s, storage.ErrLayerNotMounted", ctr.ID())
continue continue
} }
report.Err = errors.Wrapf(err, "error unmounting container %s", ctr.ID()) report.Err = fmt.Errorf("error unmounting container %s: %w", ctr.ID(), err)
} }
reports = append(reports, &report) reports = append(reports, &report)
} }
@ -1410,7 +1409,7 @@ func (ic *ContainerEngine) Shutdown(_ context.Context) {
func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) (statsChan chan entities.ContainerStatsReport, err error) { func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []string, options entities.ContainerStatsOptions) (statsChan chan entities.ContainerStatsReport, err error) {
if options.Interval < 1 { if options.Interval < 1 {
return nil, errors.New("Invalid interval, must be a positive number greater zero") return nil, errors.New("invalid interval, must be a positive number greater zero")
} }
if rootless.IsRootless() { if rootless.IsRootless() {
unified, err := cgroups.IsCgroup2UnifiedMode() unified, err := cgroups.IsCgroup2UnifiedMode()
@ -1465,19 +1464,18 @@ func (ic *ContainerEngine) ContainerStats(ctx context.Context, namesOrIds []stri
computeStats := func() ([]define.ContainerStats, error) { computeStats := func() ([]define.ContainerStats, error) {
containers, err = containerFunc() containers, err = containerFunc()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "unable to get list of containers") return nil, fmt.Errorf("unable to get list of containers: %w", err)
} }
reportStats := []define.ContainerStats{} reportStats := []define.ContainerStats{}
for _, ctr := range containers { for _, ctr := range containers {
stats, err := ctr.GetContainerStats(containerStats[ctr.ID()]) stats, err := ctr.GetContainerStats(containerStats[ctr.ID()])
if err != nil { if err != nil {
cause := errors.Cause(err) if queryAll && (errors.Is(err, define.ErrCtrRemoved) || errors.Is(err, define.ErrNoSuchCtr) || errors.Is(err, define.ErrCtrStateInvalid)) {
if queryAll && (cause == define.ErrCtrRemoved || cause == define.ErrNoSuchCtr || cause == define.ErrCtrStateInvalid) {
continue continue
} }
if cause == cgroups.ErrCgroupV1Rootless { if errors.Is(err, cgroups.ErrCgroupV1Rootless) {
err = cause err = cgroups.ErrCgroupV1Rootless
} }
return nil, err return nil, err
} }

View File

@ -1,11 +1,11 @@
package errorhandling package errorhandling
import ( import (
"errors"
"os" "os"
"strings" "strings"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -121,3 +121,22 @@ func (e PodConflictErrorModel) Error() string {
func (e PodConflictErrorModel) Code() int { func (e PodConflictErrorModel) Code() int {
return 409 return 409
} }
// Cause returns the most underlying error for the provided one. There is a
// maximum error depth of 100 to avoid endless loops. An additional error log
// message will be created if this maximum has reached.
func Cause(err error) (cause error) {
cause = err
const maxDepth = 100
for i := 0; i <= maxDepth; i++ {
res := errors.Unwrap(cause)
if res == nil {
return cause
}
cause = res
}
logrus.Errorf("Max error depth of %d reached, cannot unwrap until root cause: %v", maxDepth, err)
return cause
}

View File

@ -0,0 +1,53 @@
package errorhandling
import (
"errors"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestCause(t *testing.T) {
t.Parallel()
for _, tc := range []struct {
name string
err func() error
expectedErr error
}{
{
name: "nil error",
err: func() error { return nil },
expectedErr: nil,
},
{
name: "equal errors",
err: func() error { return errors.New("foo") },
expectedErr: errors.New("foo"),
},
{
name: "wrapped error",
err: func() error { return fmt.Errorf("baz: %w", fmt.Errorf("bar: %w", errors.New("foo"))) },
expectedErr: errors.New("foo"),
},
{
name: "max depth reached",
err: func() error {
err := errors.New("error")
for i := 0; i <= 101; i++ {
err = fmt.Errorf("%d: %w", i, err)
}
return err
},
expectedErr: fmt.Errorf("0: %w", errors.New("error")),
},
} {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
err := Cause(tc.err())
assert.Equal(t, tc.expectedErr, err)
})
}
}

View File

@ -16,7 +16,6 @@ import (
"github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/define"
"github.com/containers/storage/pkg/archive" "github.com/containers/storage/pkg/archive"
"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
"github.com/pkg/errors"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -114,7 +113,7 @@ func UntarToFileSystem(dest string, tarball *os.File, options *archive.TarOption
func CreateTarFromSrc(source string, dest string) error { func CreateTarFromSrc(source string, dest string) error {
file, err := os.Create(dest) file, err := os.Create(dest)
if err != nil { if err != nil {
return errors.Wrapf(err, "Could not create tarball file '%s'", dest) return fmt.Errorf("could not create tarball file '%s': %w", dest, err)
} }
defer file.Close() defer file.Close()
return TarToFilesystem(source, file) return TarToFilesystem(source, file)
@ -154,7 +153,7 @@ func RemoveScientificNotationFromFloat(x float64) (float64, error) {
} }
result, err := strconv.ParseFloat(bigNum, 64) result, err := strconv.ParseFloat(bigNum, 64)
if err != nil { if err != nil {
return x, errors.Wrapf(err, "unable to remove scientific number from calculations") return x, fmt.Errorf("unable to remove scientific number from calculations: %w", err)
} }
return result, nil return result, nil
} }
@ -181,11 +180,11 @@ func moveProcessPIDFileToScope(pidPath, slice, scope string) error {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil return nil
} }
return errors.Wrapf(err, "cannot read pid file %s", pidPath) return fmt.Errorf("cannot read pid file %s: %w", pidPath, err)
} }
pid, err := strconv.ParseUint(string(data), 10, 0) pid, err := strconv.ParseUint(string(data), 10, 0)
if err != nil { if err != nil {
return errors.Wrapf(err, "cannot parse pid file %s", pidPath) return fmt.Errorf("cannot parse pid file %s: %w", pidPath, err)
} }
return moveProcessToScope(int(pid), slice, scope) return moveProcessToScope(int(pid), slice, scope)