aboutsummaryrefslogtreecommitdiff
path: root/pkg/specgenutil
diff options
context:
space:
mode:
authorSascha Grunert <sgrunert@redhat.com>2022-07-06 09:48:36 +0200
committerSascha Grunert <sgrunert@redhat.com>2022-07-08 08:54:47 +0200
commita46f798831df06c472b288db7b34de8536a7ea5a (patch)
treec370fb0fc23b461691906e308b179a50e583228b /pkg/specgenutil
parent862cc42ddc11ff56b41be128182b748b0843dff3 (diff)
downloadpodman-a46f798831df06c472b288db7b34de8536a7ea5a.tar.gz
podman-a46f798831df06c472b288db7b34de8536a7ea5a.tar.bz2
podman-a46f798831df06c472b288db7b34de8536a7ea5a.zip
pkg: 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>
Diffstat (limited to 'pkg/specgenutil')
-rw-r--r--pkg/specgenutil/createparse.go5
-rw-r--r--pkg/specgenutil/ports.go5
-rw-r--r--pkg/specgenutil/specgen.go66
-rw-r--r--pkg/specgenutil/util.go47
-rw-r--r--pkg/specgenutil/volumes.go130
5 files changed, 128 insertions, 125 deletions
diff --git a/pkg/specgenutil/createparse.go b/pkg/specgenutil/createparse.go
index 132f93771..373fb6faa 100644
--- a/pkg/specgenutil/createparse.go
+++ b/pkg/specgenutil/createparse.go
@@ -1,9 +1,10 @@
package specgenutil
import (
+ "errors"
+
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v4/pkg/domain/entities"
- "github.com/pkg/errors"
)
// validate determines if the flags and values given by the user are valid. things checked
@@ -11,7 +12,7 @@ import (
func validate(c *entities.ContainerCreateOptions) error {
var ()
if c.Rm && (c.Restart != "" && c.Restart != "no" && c.Restart != "on-failure") {
- return errors.Errorf(`the --rm option conflicts with --restart, when the restartPolicy is not "" and "no"`)
+ return errors.New(`the --rm option conflicts with --restart, when the restartPolicy is not "" and "no"`)
}
if _, err := config.ParsePullPolicy(c.Pull); err != nil {
diff --git a/pkg/specgenutil/ports.go b/pkg/specgenutil/ports.go
index 6cc4de1ed..23ee9b4d3 100644
--- a/pkg/specgenutil/ports.go
+++ b/pkg/specgenutil/ports.go
@@ -1,8 +1,9 @@
package specgenutil
import (
+ "fmt"
+
"github.com/docker/go-connections/nat"
- "github.com/pkg/errors"
)
func verifyExpose(expose []string) error {
@@ -15,7 +16,7 @@ func verifyExpose(expose []string) error {
// if expose a port, the start and end port are the same
_, _, err := nat.ParsePortRange(port)
if err != nil {
- return errors.Wrapf(err, "invalid range format for --expose: %s", expose)
+ return fmt.Errorf("invalid range format for --expose: %s: %w", expose, err)
}
}
return nil
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 34350579d..9a7d50947 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -2,6 +2,7 @@ package specgenutil
import (
"encoding/json"
+ "errors"
"fmt"
"os"
"strconv"
@@ -22,7 +23,6 @@ import (
"github.com/docker/docker/opts"
"github.com/docker/go-units"
"github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
)
func getCPULimits(c *entities.ContainerCreateOptions) *specs.LinuxCPU {
@@ -78,7 +78,7 @@ func getIOLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (
if b := c.BlkIOWeight; len(b) > 0 {
u, err := strconv.ParseUint(b, 10, 16)
if err != nil {
- return nil, errors.Wrapf(err, "invalid value for blkio-weight")
+ return nil, fmt.Errorf("invalid value for blkio-weight: %w", err)
}
nu := uint16(u)
io.Weight = &nu
@@ -143,7 +143,7 @@ func getMemoryLimits(c *entities.ContainerCreateOptions) (*specs.LinuxMemory, er
if m := c.Memory; len(m) > 0 {
ml, err := units.RAMInBytes(m)
if err != nil {
- return nil, errors.Wrapf(err, "invalid value for memory")
+ return nil, fmt.Errorf("invalid value for memory: %w", err)
}
LimitToSwap(memory, c.MemorySwap, ml)
hasLimits = true
@@ -151,7 +151,7 @@ func getMemoryLimits(c *entities.ContainerCreateOptions) (*specs.LinuxMemory, er
if m := c.MemoryReservation; len(m) > 0 {
mr, err := units.RAMInBytes(m)
if err != nil {
- return nil, errors.Wrapf(err, "invalid value for memory")
+ return nil, fmt.Errorf("invalid value for memory: %w", err)
}
memory.Reservation = &mr
hasLimits = true
@@ -164,7 +164,7 @@ func getMemoryLimits(c *entities.ContainerCreateOptions) (*specs.LinuxMemory, er
ms, err = units.RAMInBytes(m)
memory.Swap = &ms
if err != nil {
- return nil, errors.Wrapf(err, "invalid value for memory")
+ return nil, fmt.Errorf("invalid value for memory: %w", err)
}
hasLimits = true
}
@@ -248,7 +248,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
if len(c.HealthCmd) > 0 {
if c.NoHealthCheck {
- return errors.New("Cannot specify both --no-healthcheck and --health-cmd")
+ return errors.New("cannot specify both --no-healthcheck and --health-cmd")
}
s.HealthConfig, err = makeHealthCheckFromCli(c.HealthCmd, c.HealthInterval, c.HealthRetries, c.HealthTimeout, c.HealthStartPeriod)
if err != nil {
@@ -318,7 +318,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
if len(c.PodIDFile) > 0 {
if len(s.Pod) > 0 {
- return errors.New("Cannot specify both --pod and --pod-id-file")
+ return errors.New("cannot specify both --pod and --pod-id-file")
}
podID, err := ReadPodIDFile(c.PodIDFile)
if err != nil {
@@ -357,7 +357,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
// any case.
osEnv, err := envLib.ParseSlice(os.Environ())
if err != nil {
- return errors.Wrap(err, "error parsing host environment variables")
+ return fmt.Errorf("error parsing host environment variables: %w", err)
}
if !s.EnvHost {
@@ -390,7 +390,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
// LABEL VARIABLES
labels, err := parse.GetAllLabels(c.LabelFile, c.Label)
if err != nil {
- return errors.Wrapf(err, "unable to process labels")
+ return fmt.Errorf("unable to process labels: %w", err)
}
if systemdUnit, exists := osEnv[systemdDefine.EnvVariable]; exists {
@@ -414,7 +414,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
for _, annotation := range c.Annotation {
splitAnnotation := strings.SplitN(annotation, "=", 2)
if len(splitAnnotation) < 2 {
- return errors.Errorf("Annotations must be formatted KEY=VALUE")
+ return errors.New("annotations must be formatted KEY=VALUE")
}
annotations[splitAnnotation[0]] = splitAnnotation[1]
}
@@ -427,7 +427,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
for _, opt := range c.StorageOpts {
split := strings.SplitN(opt, "=", 2)
if len(split) != 2 {
- return errors.Errorf("storage-opt must be formatted KEY=VALUE")
+ return errors.New("storage-opt must be formatted KEY=VALUE")
}
opts[split[0]] = split[1]
}
@@ -459,7 +459,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
if c.ShmSize != "" {
var m opts.MemBytes
if err := m.Set(c.ShmSize); err != nil {
- return errors.Wrapf(err, "unable to translate --shm-size")
+ return fmt.Errorf("unable to translate --shm-size: %w", err)
}
val := m.Value()
s.ShmSize = &val
@@ -531,7 +531,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
for _, unified := range c.CgroupConf {
splitUnified := strings.SplitN(unified, "=", 2)
if len(splitUnified) < 2 {
- return errors.Errorf("--cgroup-conf must be formatted KEY=VALUE")
+ return errors.New("--cgroup-conf must be formatted KEY=VALUE")
}
unifieds[splitUnified[0]] = splitUnified[1]
}
@@ -608,7 +608,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
for _, ctl := range c.Sysctl {
splitCtl := strings.SplitN(ctl, "=", 2)
if len(splitCtl) < 2 {
- return errors.Errorf("invalid sysctl value %q", ctl)
+ return fmt.Errorf("invalid sysctl value %q", ctl)
}
sysmap[splitCtl[0]] = splitCtl[1]
}
@@ -731,7 +731,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
}
ul, err := units.ParseUlimit(u)
if err != nil {
- return errors.Wrapf(err, "ulimit option %q requires name=SOFT:HARD, failed to be parsed", u)
+ return fmt.Errorf("ulimit option %q requires name=SOFT:HARD, failed to be parsed: %w", u, err)
}
rl := specs.POSIXRlimit{
Type: ul.Name,
@@ -745,7 +745,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
for _, o := range c.LogOptions {
split := strings.SplitN(o, "=", 2)
if len(split) < 2 {
- return errors.Errorf("invalid log option %q", o)
+ return fmt.Errorf("invalid log option %q", o)
}
switch strings.ToLower(split[0]) {
case "driver":
@@ -782,19 +782,19 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions
// No retries specified
case 2:
if strings.ToLower(splitRestart[0]) != "on-failure" {
- return errors.Errorf("restart policy retries can only be specified with on-failure restart policy")
+ return errors.New("restart policy retries can only be specified with on-failure restart policy")
}
retries, err := strconv.Atoi(splitRestart[1])
if err != nil {
- return errors.Wrapf(err, "error parsing restart policy retry count")
+ return fmt.Errorf("error parsing restart policy retry count: %w", err)
}
if retries < 0 {
- return errors.Errorf("must specify restart policy retry count as a number greater than 0")
+ return errors.New("must specify restart policy retry count as a number greater than 0")
}
var retriesUint = uint(retries)
s.RestartRetries = &retriesUint
default:
- return errors.Errorf("invalid restart policy: may specify retries at most once")
+ return errors.New("invalid restart policy: may specify retries at most once")
}
s.RestartPolicy = splitRestart[0]
}
@@ -869,7 +869,7 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
}
// Every healthcheck requires a command
if len(cmdArr) == 0 {
- return nil, errors.New("Must define a healthcheck command for all healthchecks")
+ return nil, errors.New("must define a healthcheck command for all healthchecks")
}
var concat string
@@ -902,7 +902,7 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
}
intervalDuration, err := time.ParseDuration(interval)
if err != nil {
- return nil, errors.Wrapf(err, "invalid healthcheck-interval")
+ return nil, fmt.Errorf("invalid healthcheck-interval: %w", err)
}
hc.Interval = intervalDuration
@@ -913,7 +913,7 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
hc.Retries = int(retries)
timeoutDuration, err := time.ParseDuration(timeout)
if err != nil {
- return nil, errors.Wrapf(err, "invalid healthcheck-timeout")
+ return nil, fmt.Errorf("invalid healthcheck-timeout: %w", err)
}
if timeoutDuration < time.Duration(1) {
return nil, errors.New("healthcheck-timeout must be at least 1 second")
@@ -922,7 +922,7 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
startPeriodDuration, err := time.ParseDuration(startPeriod)
if err != nil {
- return nil, errors.Wrapf(err, "invalid healthcheck-start-period")
+ return nil, fmt.Errorf("invalid healthcheck-start-period: %w", err)
}
if startPeriodDuration < time.Duration(0) {
return nil, errors.New("healthcheck-start-period must be 0 seconds or greater")
@@ -1035,17 +1035,17 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
for _, val := range split {
kv := strings.SplitN(val, "=", 2)
if len(kv) < 2 {
- return nil, nil, errors.Wrapf(secretParseError, "option %s must be in form option=value", val)
+ return nil, nil, fmt.Errorf("option %s must be in form option=value: %w", val, secretParseError)
}
switch kv[0] {
case "source":
source = kv[1]
case "type":
if secretType != "" {
- return nil, nil, errors.Wrap(secretParseError, "cannot set more than one secret type")
+ return nil, nil, fmt.Errorf("cannot set more than one secret type: %w", secretParseError)
}
if kv[1] != "mount" && kv[1] != "env" {
- return nil, nil, errors.Wrapf(secretParseError, "type %s is invalid", kv[1])
+ return nil, nil, fmt.Errorf("type %s is invalid: %w", kv[1], secretParseError)
}
secretType = kv[1]
case "target":
@@ -1054,26 +1054,26 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
mountOnly = true
mode64, err := strconv.ParseUint(kv[1], 8, 32)
if err != nil {
- return nil, nil, errors.Wrapf(secretParseError, "mode %s invalid", kv[1])
+ return nil, nil, fmt.Errorf("mode %s invalid: %w", kv[1], secretParseError)
}
mode = uint32(mode64)
case "uid", "UID":
mountOnly = true
uid64, err := strconv.ParseUint(kv[1], 10, 32)
if err != nil {
- return nil, nil, errors.Wrapf(secretParseError, "UID %s invalid", kv[1])
+ return nil, nil, fmt.Errorf("UID %s invalid: %w", kv[1], secretParseError)
}
uid = uint32(uid64)
case "gid", "GID":
mountOnly = true
gid64, err := strconv.ParseUint(kv[1], 10, 32)
if err != nil {
- return nil, nil, errors.Wrapf(secretParseError, "GID %s invalid", kv[1])
+ return nil, nil, fmt.Errorf("GID %s invalid: %w", kv[1], secretParseError)
}
gid = uint32(gid64)
default:
- return nil, nil, errors.Wrapf(secretParseError, "option %s invalid", val)
+ return nil, nil, fmt.Errorf("option %s invalid: %w", val, secretParseError)
}
}
@@ -1081,7 +1081,7 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
secretType = "mount"
}
if source == "" {
- return nil, nil, errors.Wrapf(secretParseError, "no source found %s", val)
+ return nil, nil, fmt.Errorf("no source found %s: %w", val, secretParseError)
}
if secretType == "mount" {
mountSecret := specgen.Secret{
@@ -1095,7 +1095,7 @@ func parseSecrets(secrets []string) ([]specgen.Secret, map[string]string, error)
}
if secretType == "env" {
if mountOnly {
- return nil, nil, errors.Wrap(secretParseError, "UID, GID, Mode options cannot be set with secret type env")
+ return nil, nil, fmt.Errorf("UID, GID, Mode options cannot be set with secret type env: %w", secretParseError)
}
if target == "" {
target = source
diff --git a/pkg/specgenutil/util.go b/pkg/specgenutil/util.go
index fa2e90457..66d148672 100644
--- a/pkg/specgenutil/util.go
+++ b/pkg/specgenutil/util.go
@@ -1,6 +1,8 @@
package specgenutil
import (
+ "errors"
+ "fmt"
"io/ioutil"
"net"
"os"
@@ -10,7 +12,6 @@ import (
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
storageTypes "github.com/containers/storage/types"
- "github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -19,7 +20,7 @@ import (
func ReadPodIDFile(path string) (string, error) {
content, err := ioutil.ReadFile(path)
if err != nil {
- return "", errors.Wrap(err, "error reading pod ID file")
+ return "", fmt.Errorf("error reading pod ID file: %w", err)
}
return strings.Split(string(content), "\n")[0], nil
}
@@ -50,7 +51,7 @@ func CreateExpose(expose []string) (map[uint16]string, error) {
proto := "tcp"
splitProto := strings.Split(e, "/")
if len(splitProto) > 2 {
- return nil, errors.Errorf("invalid expose format - protocol can only be specified once")
+ return nil, errors.New("invalid expose format - protocol can only be specified once")
} else if len(splitProto) == 2 {
proto = splitProto[1]
}
@@ -96,7 +97,7 @@ func CreatePortBindings(ports []string) ([]types.PortMapping, error) {
case 2:
proto = &(splitProto[1])
default:
- return nil, errors.Errorf("invalid port format - protocol can only be specified once")
+ return nil, errors.New("invalid port format - protocol can only be specified once")
}
remainder := splitProto[0]
@@ -111,23 +112,23 @@ func CreatePortBindings(ports []string) ([]types.PortMapping, error) {
// We potentially have an IPv6 address
haveV6 = true
if !strings.HasPrefix(splitV6[0], "[") {
- return nil, errors.Errorf("invalid port format - IPv6 addresses must be enclosed by []")
+ return nil, errors.New("invalid port format - IPv6 addresses must be enclosed by []")
}
if !strings.HasPrefix(splitV6[1], ":") {
- return nil, errors.Errorf("invalid port format - IPv6 address must be followed by a colon (':')")
+ return nil, errors.New("invalid port format - IPv6 address must be followed by a colon (':')")
}
ipNoPrefix := strings.TrimPrefix(splitV6[0], "[")
hostIP = &ipNoPrefix
remainder = strings.TrimPrefix(splitV6[1], ":")
default:
- return nil, errors.Errorf("invalid port format - at most one IPv6 address can be specified in a --publish")
+ return nil, errors.New("invalid port format - at most one IPv6 address can be specified in a --publish")
}
splitPort := strings.Split(remainder, ":")
switch len(splitPort) {
case 1:
if haveV6 {
- return nil, errors.Errorf("invalid port format - must provide host and destination port if specifying an IP")
+ return nil, errors.New("invalid port format - must provide host and destination port if specifying an IP")
}
ctrPort = splitPort[0]
case 2:
@@ -135,13 +136,13 @@ func CreatePortBindings(ports []string) ([]types.PortMapping, error) {
ctrPort = splitPort[1]
case 3:
if haveV6 {
- return nil, errors.Errorf("invalid port format - when v6 address specified, must be [ipv6]:hostPort:ctrPort")
+ return nil, errors.New("invalid port format - when v6 address specified, must be [ipv6]:hostPort:ctrPort")
}
hostIP = &(splitPort[0])
hostPort = &(splitPort[1])
ctrPort = splitPort[2]
default:
- return nil, errors.Errorf("invalid port format - format is [[hostIP:]hostPort:]containerPort")
+ return nil, errors.New("invalid port format - format is [[hostIP:]hostPort:]containerPort")
}
newPort, err := parseSplitPort(hostIP, hostPort, ctrPort, proto)
@@ -160,30 +161,30 @@ func CreatePortBindings(ports []string) ([]types.PortMapping, error) {
func parseSplitPort(hostIP, hostPort *string, ctrPort string, protocol *string) (types.PortMapping, error) {
newPort := types.PortMapping{}
if ctrPort == "" {
- return newPort, errors.Errorf("must provide a non-empty container port to publish")
+ return newPort, errors.New("must provide a non-empty container port to publish")
}
ctrStart, ctrLen, err := parseAndValidateRange(ctrPort)
if err != nil {
- return newPort, errors.Wrapf(err, "error parsing container port")
+ return newPort, fmt.Errorf("error parsing container port: %w", err)
}
newPort.ContainerPort = ctrStart
newPort.Range = ctrLen
if protocol != nil {
if *protocol == "" {
- return newPort, errors.Errorf("must provide a non-empty protocol to publish")
+ return newPort, errors.New("must provide a non-empty protocol to publish")
}
newPort.Protocol = *protocol
}
if hostIP != nil {
if *hostIP == "" {
- return newPort, errors.Errorf("must provide a non-empty container host IP to publish")
+ return newPort, errors.New("must provide a non-empty container host IP to publish")
} else if *hostIP != "0.0.0.0" {
// If hostIP is 0.0.0.0, leave it unset - CNI treats
// 0.0.0.0 and empty differently, Docker does not.
testIP := net.ParseIP(*hostIP)
if testIP == nil {
- return newPort, errors.Errorf("cannot parse %q as an IP address", *hostIP)
+ return newPort, fmt.Errorf("cannot parse %q as an IP address", *hostIP)
}
newPort.HostIP = testIP.String()
}
@@ -196,10 +197,10 @@ func parseSplitPort(hostIP, hostPort *string, ctrPort string, protocol *string)
} else {
hostStart, hostLen, err := parseAndValidateRange(*hostPort)
if err != nil {
- return newPort, errors.Wrapf(err, "error parsing host port")
+ return newPort, fmt.Errorf("error parsing host port: %w", err)
}
if hostLen != ctrLen {
- return newPort, errors.Errorf("host and container port ranges have different lengths: %d vs %d", hostLen, ctrLen)
+ return newPort, fmt.Errorf("host and container port ranges have different lengths: %d vs %d", hostLen, ctrLen)
}
newPort.HostPort = hostStart
}
@@ -216,11 +217,11 @@ func parseSplitPort(hostIP, hostPort *string, ctrPort string, protocol *string)
func parseAndValidateRange(portRange string) (uint16, uint16, error) {
splitRange := strings.Split(portRange, "-")
if len(splitRange) > 2 {
- return 0, 0, errors.Errorf("invalid port format - port ranges are formatted as startPort-stopPort")
+ return 0, 0, errors.New("invalid port format - port ranges are formatted as startPort-stopPort")
}
if splitRange[0] == "" {
- return 0, 0, errors.Errorf("port numbers cannot be negative")
+ return 0, 0, errors.New("port numbers cannot be negative")
}
startPort, err := parseAndValidatePort(splitRange[0])
@@ -231,14 +232,14 @@ func parseAndValidateRange(portRange string) (uint16, uint16, error) {
var rangeLen uint16 = 1
if len(splitRange) == 2 {
if splitRange[1] == "" {
- return 0, 0, errors.Errorf("must provide ending number for port range")
+ return 0, 0, errors.New("must provide ending number for port range")
}
endPort, err := parseAndValidatePort(splitRange[1])
if err != nil {
return 0, 0, err
}
if endPort <= startPort {
- return 0, 0, errors.Errorf("the end port of a range must be higher than the start port - %d is not higher than %d", endPort, startPort)
+ return 0, 0, fmt.Errorf("the end port of a range must be higher than the start port - %d is not higher than %d", endPort, startPort)
}
// Our range is the total number of ports
// involved, so we need to add 1 (8080:8081 is
@@ -253,10 +254,10 @@ func parseAndValidateRange(portRange string) (uint16, uint16, error) {
func parseAndValidatePort(port string) (uint16, error) {
num, err := strconv.Atoi(port)
if err != nil {
- return 0, errors.Wrapf(err, "invalid port number")
+ return 0, fmt.Errorf("invalid port number: %w", err)
}
if num < 1 || num > 65535 {
- return 0, errors.Errorf("port numbers must be between 1 and 65535 (inclusive), got %d", num)
+ return 0, fmt.Errorf("port numbers must be between 1 and 65535 (inclusive), got %d", num)
}
return uint16(num), nil
}
diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go
index 016166a20..e9fffdca9 100644
--- a/pkg/specgenutil/volumes.go
+++ b/pkg/specgenutil/volumes.go
@@ -2,6 +2,7 @@ package specgenutil
import (
"encoding/csv"
+ "errors"
"fmt"
"path"
"strings"
@@ -11,14 +12,13 @@ import (
"github.com/containers/podman/v4/pkg/specgen"
"github.com/containers/podman/v4/pkg/util"
spec "github.com/opencontainers/runtime-spec/specs-go"
- "github.com/pkg/errors"
)
var (
- errDuplicateDest = errors.Errorf("duplicate mount destination")
- optionArgError = errors.Errorf("must provide an argument for option")
- noDestError = errors.Errorf("must set volume destination")
- errInvalidSyntax = errors.Errorf("incorrect mount format: should be --mount type=<bind|tmpfs|volume>,[src=<host-dir|volume-name>,]target=<ctr-dir>[,options]")
+ errDuplicateDest = errors.New("duplicate mount destination")
+ errOptionArg = errors.New("must provide an argument for option")
+ errNoDest = errors.New("must set volume destination")
+ errInvalidSyntax = errors.New("incorrect mount format: should be --mount type=<bind|tmpfs|volume>,[src=<host-dir|volume-name>,]target=<ctr-dir>[,options]")
)
// Parse all volume-related options in the create config into a set of mounts
@@ -50,20 +50,20 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo
// Start with --volume.
for dest, mount := range volumeMounts {
if _, ok := unifiedMounts[dest]; ok {
- return nil, nil, nil, nil, errors.Wrapf(errDuplicateDest, dest)
+ return nil, nil, nil, nil, fmt.Errorf("%v: %w", dest, errDuplicateDest)
}
unifiedMounts[dest] = mount
}
for dest, volume := range volumeVolumes {
if _, ok := unifiedVolumes[dest]; ok {
- return nil, nil, nil, nil, errors.Wrapf(errDuplicateDest, dest)
+ return nil, nil, nil, nil, fmt.Errorf("%v: %w", dest, errDuplicateDest)
}
unifiedVolumes[dest] = volume
}
// Now --tmpfs
for dest, tmpfs := range tmpfsMounts {
if _, ok := unifiedMounts[dest]; ok {
- return nil, nil, nil, nil, errors.Wrapf(errDuplicateDest, dest)
+ return nil, nil, nil, nil, fmt.Errorf("%v: %w", dest, errDuplicateDest)
}
unifiedMounts[dest] = tmpfs
}
@@ -93,7 +93,7 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo
allMounts := make(map[string]bool)
testAndSet := func(dest string) error {
if _, ok := allMounts[dest]; ok {
- return errors.Wrapf(errDuplicateDest, "conflict at mount destination %v", dest)
+ return fmt.Errorf("conflict at mount destination %v: %w", dest, errDuplicateDest)
}
allMounts[dest] = true
return nil
@@ -125,7 +125,7 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo
if mount.Type == define.TypeBind {
absSrc, err := specgen.ConvertWinMountPath(mount.Source)
if err != nil {
- return nil, nil, nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source)
+ return nil, nil, nil, nil, fmt.Errorf("error getting absolute path of %s: %w", mount.Source, err)
}
mount.Source = absSrc
}
@@ -199,7 +199,7 @@ func Mounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.Name
return nil, nil, nil, err
}
if _, ok := finalMounts[mount.Destination]; ok {
- return nil, nil, nil, errors.Wrapf(errDuplicateDest, mount.Destination)
+ return nil, nil, nil, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
}
finalMounts[mount.Destination] = mount
case define.TypeTmpfs:
@@ -208,7 +208,7 @@ func Mounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.Name
return nil, nil, nil, err
}
if _, ok := finalMounts[mount.Destination]; ok {
- return nil, nil, nil, errors.Wrapf(errDuplicateDest, mount.Destination)
+ return nil, nil, nil, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
}
finalMounts[mount.Destination] = mount
case define.TypeDevpts:
@@ -217,7 +217,7 @@ func Mounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.Name
return nil, nil, nil, err
}
if _, ok := finalMounts[mount.Destination]; ok {
- return nil, nil, nil, errors.Wrapf(errDuplicateDest, mount.Destination)
+ return nil, nil, nil, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
}
finalMounts[mount.Destination] = mount
case "image":
@@ -226,7 +226,7 @@ func Mounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.Name
return nil, nil, nil, err
}
if _, ok := finalImageVolumes[volume.Destination]; ok {
- return nil, nil, nil, errors.Wrapf(errDuplicateDest, volume.Destination)
+ return nil, nil, nil, fmt.Errorf("%v: %w", volume.Destination, errDuplicateDest)
}
finalImageVolumes[volume.Destination] = volume
case "volume":
@@ -235,11 +235,11 @@ func Mounts(mountFlag []string) (map[string]spec.Mount, map[string]*specgen.Name
return nil, nil, nil, err
}
if _, ok := finalNamedVolumes[volume.Dest]; ok {
- return nil, nil, nil, errors.Wrapf(errDuplicateDest, volume.Dest)
+ return nil, nil, nil, fmt.Errorf("%v: %w", volume.Dest, errDuplicateDest)
}
finalNamedVolumes[volume.Dest] = volume
default:
- return nil, nil, nil, errors.Errorf("invalid filesystem type %q", mountType)
+ return nil, nil, nil, fmt.Errorf("invalid filesystem type %q", mountType)
}
}
@@ -261,7 +261,7 @@ func getBindMount(args []string) (spec.Mount, error) {
newMount.Options = append(newMount.Options, "bind")
case "readonly", "ro", "rw":
if setRORW {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'readonly', 'ro', or 'rw' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'readonly', 'ro', or 'rw' options more than once: %w", errOptionArg)
}
setRORW = true
// Can be formatted as one of:
@@ -288,26 +288,26 @@ func getBindMount(args []string) (spec.Mount, error) {
newMount.Options = append(newMount.Options, "ro")
}
default:
- return newMount, errors.Wrapf(optionArgError, "'readonly', 'ro', or 'rw' must be set to true or false, instead received %q", kv[1])
+ return newMount, fmt.Errorf("'readonly', 'ro', or 'rw' must be set to true or false, instead received %q: %w", kv[1], errOptionArg)
}
default:
- return newMount, errors.Wrapf(optionArgError, "badly formatted option %q", val)
+ return newMount, fmt.Errorf("badly formatted option %q: %w", val, errOptionArg)
}
case "nosuid", "suid":
if setSuid {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'nosuid' and 'suid' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'nosuid' and 'suid' options more than once: %w", errOptionArg)
}
setSuid = true
newMount.Options = append(newMount.Options, kv[0])
case "nodev", "dev":
if setDev {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'nodev' and 'dev' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'nodev' and 'dev' options more than once: %w", errOptionArg)
}
setDev = true
newMount.Options = append(newMount.Options, kv[0])
case "noexec", "exec":
if setExec {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'noexec' and 'exec' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'noexec' and 'exec' options more than once: %w", errOptionArg)
}
setExec = true
newMount.Options = append(newMount.Options, kv[0])
@@ -315,21 +315,21 @@ func getBindMount(args []string) (spec.Mount, error) {
newMount.Options = append(newMount.Options, kv[0])
case "bind-propagation":
if len(kv) == 1 {
- return newMount, errors.Wrapf(optionArgError, kv[0])
+ return newMount, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
newMount.Options = append(newMount.Options, kv[1])
case "src", "source":
if len(kv) == 1 {
- return newMount, errors.Wrapf(optionArgError, kv[0])
+ return newMount, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
if len(kv[1]) == 0 {
- return newMount, errors.Wrapf(optionArgError, "host directory cannot be empty")
+ return newMount, fmt.Errorf("host directory cannot be empty: %w", errOptionArg)
}
newMount.Source = kv[1]
setSource = true
case "target", "dst", "destination":
if len(kv) == 1 {
- return newMount, errors.Wrapf(optionArgError, kv[0])
+ return newMount, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return newMount, err
@@ -338,11 +338,11 @@ func getBindMount(args []string) (spec.Mount, error) {
setDest = true
case "relabel":
if setRelabel {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'relabel' option more than once")
+ return newMount, fmt.Errorf("cannot pass 'relabel' option more than once: %w", errOptionArg)
}
setRelabel = true
if len(kv) != 2 {
- return newMount, errors.Wrapf(util.ErrBadMntOption, "%s mount option must be 'private' or 'shared'", kv[0])
+ return newMount, fmt.Errorf("%s mount option must be 'private' or 'shared': %w", kv[0], util.ErrBadMntOption)
}
switch kv[1] {
case "private":
@@ -350,11 +350,11 @@ func getBindMount(args []string) (spec.Mount, error) {
case "shared":
newMount.Options = append(newMount.Options, "z")
default:
- return newMount, errors.Wrapf(util.ErrBadMntOption, "%s mount option must be 'private' or 'shared'", kv[0])
+ return newMount, fmt.Errorf("%s mount option must be 'private' or 'shared': %w", kv[0], util.ErrBadMntOption)
}
case "U", "chown":
if setOwnership {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'U' or 'chown' option more than once")
+ return newMount, fmt.Errorf("cannot pass 'U' or 'chown' option more than once: %w", errOptionArg)
}
ok, err := validChownFlag(val)
if err != nil {
@@ -375,12 +375,12 @@ func getBindMount(args []string) (spec.Mount, error) {
// Since Docker ignores this option so shall we.
continue
default:
- return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
+ return newMount, fmt.Errorf("%s: %w", kv[0], util.ErrBadMntOption)
}
}
if !setDest {
- return newMount, noDestError
+ return newMount, errNoDest
}
if !setSource {
@@ -409,49 +409,49 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
switch kv[0] {
case "tmpcopyup", "notmpcopyup":
if setTmpcopyup {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'tmpcopyup' and 'notmpcopyup' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'tmpcopyup' and 'notmpcopyup' options more than once: %w", errOptionArg)
}
setTmpcopyup = true
newMount.Options = append(newMount.Options, kv[0])
case "ro", "rw":
if setRORW {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'ro' and 'rw' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'ro' and 'rw' options more than once: %w", errOptionArg)
}
setRORW = true
newMount.Options = append(newMount.Options, kv[0])
case "nosuid", "suid":
if setSuid {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'nosuid' and 'suid' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'nosuid' and 'suid' options more than once: %w", errOptionArg)
}
setSuid = true
newMount.Options = append(newMount.Options, kv[0])
case "nodev", "dev":
if setDev {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'nodev' and 'dev' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'nodev' and 'dev' options more than once: %w", errOptionArg)
}
setDev = true
newMount.Options = append(newMount.Options, kv[0])
case "noexec", "exec":
if setExec {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'noexec' and 'exec' options more than once")
+ return newMount, fmt.Errorf("cannot pass 'noexec' and 'exec' options more than once: %w", errOptionArg)
}
setExec = true
newMount.Options = append(newMount.Options, kv[0])
case "tmpfs-mode":
if len(kv) == 1 {
- return newMount, errors.Wrapf(optionArgError, kv[0])
+ return newMount, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
newMount.Options = append(newMount.Options, fmt.Sprintf("mode=%s", kv[1]))
case "tmpfs-size":
if len(kv) == 1 {
- return newMount, errors.Wrapf(optionArgError, kv[0])
+ return newMount, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
newMount.Options = append(newMount.Options, fmt.Sprintf("size=%s", kv[1]))
case "src", "source":
- return newMount, errors.Errorf("source is not supported with tmpfs mounts")
+ return newMount, fmt.Errorf("source is not supported with tmpfs mounts")
case "target", "dst", "destination":
if len(kv) == 1 {
- return newMount, errors.Wrapf(optionArgError, kv[0])
+ return newMount, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return newMount, err
@@ -460,7 +460,7 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
setDest = true
case "U", "chown":
if setOwnership {
- return newMount, errors.Wrapf(optionArgError, "cannot pass 'U' or 'chown' option more than once")
+ return newMount, fmt.Errorf("cannot pass 'U' or 'chown' option more than once: %w", errOptionArg)
}
ok, err := validChownFlag(val)
if err != nil {
@@ -475,12 +475,12 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
// Since Docker ignores this option so shall we.
continue
default:
- return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
+ return newMount, fmt.Errorf("%s: %w", kv[0], util.ErrBadMntOption)
}
}
if !setDest {
- return newMount, noDestError
+ return newMount, errNoDest
}
return newMount, nil
@@ -502,7 +502,7 @@ func getDevptsMount(args []string) (spec.Mount, error) {
newMount.Options = append(newMount.Options, val)
case "target", "dst", "destination":
if len(kv) == 1 {
- return newMount, errors.Wrapf(optionArgError, kv[0])
+ return newMount, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return newMount, err
@@ -510,12 +510,12 @@ func getDevptsMount(args []string) (spec.Mount, error) {
newMount.Destination = unixPathClean(kv[1])
setDest = true
default:
- return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
+ return newMount, fmt.Errorf("%s: %w", kv[0], util.ErrBadMntOption)
}
}
if !setDest {
- return newMount, noDestError
+ return newMount, errNoDest
}
return newMount, nil
@@ -536,38 +536,38 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) {
newVolume.Options = append(newVolume.Options, val)
case "ro", "rw":
if setRORW {
- return nil, errors.Wrapf(optionArgError, "cannot pass 'ro' and 'rw' options more than once")
+ return nil, fmt.Errorf("cannot pass 'ro' and 'rw' options more than once: %w", errOptionArg)
}
setRORW = true
newVolume.Options = append(newVolume.Options, kv[0])
case "nosuid", "suid":
if setSuid {
- return nil, errors.Wrapf(optionArgError, "cannot pass 'nosuid' and 'suid' options more than once")
+ return nil, fmt.Errorf("cannot pass 'nosuid' and 'suid' options more than once: %w", errOptionArg)
}
setSuid = true
newVolume.Options = append(newVolume.Options, kv[0])
case "nodev", "dev":
if setDev {
- return nil, errors.Wrapf(optionArgError, "cannot pass 'nodev' and 'dev' options more than once")
+ return nil, fmt.Errorf("cannot pass 'nodev' and 'dev' options more than once: %w", errOptionArg)
}
setDev = true
newVolume.Options = append(newVolume.Options, kv[0])
case "noexec", "exec":
if setExec {
- return nil, errors.Wrapf(optionArgError, "cannot pass 'noexec' and 'exec' options more than once")
+ return nil, fmt.Errorf("cannot pass 'noexec' and 'exec' options more than once: %w", errOptionArg)
}
setExec = true
newVolume.Options = append(newVolume.Options, kv[0])
case "volume-label":
- return nil, errors.Errorf("the --volume-label option is not presently implemented")
+ return nil, fmt.Errorf("the --volume-label option is not presently implemented")
case "src", "source":
if len(kv) == 1 {
- return nil, errors.Wrapf(optionArgError, kv[0])
+ return nil, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
newVolume.Name = kv[1]
case "target", "dst", "destination":
if len(kv) == 1 {
- return nil, errors.Wrapf(optionArgError, kv[0])
+ return nil, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return nil, err
@@ -576,7 +576,7 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) {
setDest = true
case "U", "chown":
if setOwnership {
- return newVolume, errors.Wrapf(optionArgError, "cannot pass 'U' or 'chown' option more than once")
+ return newVolume, fmt.Errorf("cannot pass 'U' or 'chown' option more than once: %w", errOptionArg)
}
ok, err := validChownFlag(val)
if err != nil {
@@ -591,12 +591,12 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) {
// Since Docker ignores this option so shall we.
continue
default:
- return nil, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
+ return nil, fmt.Errorf("%s: %w", kv[0], util.ErrBadMntOption)
}
}
if !setDest {
- return nil, noDestError
+ return nil, errNoDest
}
return newVolume, nil
@@ -614,12 +614,12 @@ func getImageVolume(args []string) (*specgen.ImageVolume, error) {
switch kv[0] {
case "src", "source":
if len(kv) == 1 {
- return nil, errors.Wrapf(optionArgError, kv[0])
+ return nil, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
newVolume.Source = kv[1]
case "target", "dst", "destination":
if len(kv) == 1 {
- return nil, errors.Wrapf(optionArgError, kv[0])
+ return nil, fmt.Errorf("%v: %w", kv[0], errOptionArg)
}
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
return nil, err
@@ -632,19 +632,19 @@ func getImageVolume(args []string) (*specgen.ImageVolume, error) {
case "false":
// Nothing to do. RO is default.
default:
- return nil, errors.Wrapf(util.ErrBadMntOption, "invalid rw value %q", kv[1])
+ return nil, fmt.Errorf("invalid rw value %q: %w", kv[1], util.ErrBadMntOption)
}
case "consistency":
// Often used on MACs and mistakenly on Linux platforms.
// Since Docker ignores this option so shall we.
continue
default:
- return nil, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
+ return nil, fmt.Errorf("%s: %w", kv[0], util.ErrBadMntOption)
}
}
if len(newVolume.Source)*len(newVolume.Destination) == 0 {
- return nil, errors.Errorf("must set source and destination for image volume")
+ return nil, errors.New("must set source and destination for image volume")
}
return newVolume, nil
@@ -666,7 +666,7 @@ func getTmpfsMounts(tmpfsFlag []string) (map[string]spec.Mount, error) {
}
if _, ok := m[destPath]; ok {
- return nil, errors.Wrapf(errDuplicateDest, destPath)
+ return nil, fmt.Errorf("%v: %w", destPath, errDuplicateDest)
}
mount := spec.Mount{
@@ -692,10 +692,10 @@ func validChownFlag(flag string) (bool, error) {
case "false":
return false, nil
default:
- return false, errors.Wrapf(optionArgError, "'U' or 'chown' must be set to true or false, instead received %q", kv[1])
+ return false, fmt.Errorf("'U' or 'chown' must be set to true or false, instead received %q: %w", kv[1], errOptionArg)
}
default:
- return false, errors.Wrapf(optionArgError, "badly formatted option %q", flag)
+ return false, fmt.Errorf("badly formatted option %q: %w", flag, errOptionArg)
}
return true, nil