summaryrefslogtreecommitdiff
path: root/libpod/networking_linux.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/networking_linux.go')
-rw-r--r--libpod/networking_linux.go176
1 files changed, 97 insertions, 79 deletions
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 0c124cf0b..c05796768 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -6,6 +6,7 @@ package libpod
import (
"crypto/rand"
"crypto/sha256"
+ "errors"
"fmt"
"io/ioutil"
"net"
@@ -21,22 +22,21 @@ import (
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/common/libnetwork/etchosts"
+ "github.com/containers/common/libnetwork/resolvconf"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/machine"
"github.com/containers/common/pkg/netns"
+ "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/errorhandling"
"github.com/containers/podman/v4/pkg/namespaces"
- "github.com/containers/podman/v4/pkg/resolvconf"
"github.com/containers/podman/v4/pkg/rootless"
- "github.com/containers/podman/v4/pkg/util"
"github.com/containers/podman/v4/utils"
"github.com/containers/storage/pkg/lockfile"
- spec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
- "github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
"golang.org/x/sys/unix"
@@ -109,7 +109,7 @@ func (r *RootlessNetNS) getPath(path string) string {
func (r *RootlessNetNS) Do(toRun func() error) error {
err := r.ns.Do(func(_ ns.NetNS) error {
// Before we can run the given function,
- // we have to setup all mounts correctly.
+ // we have to set up all mounts correctly.
// The order of the mounts is IMPORTANT.
// The idea of the extra mount ns is to make /run and /var/lib/cni writeable
@@ -127,19 +127,19 @@ func (r *RootlessNetNS) Do(toRun func() error) error {
// this must happen inside the netns thread.
err := unix.Unshare(unix.CLONE_NEWNS)
if err != nil {
- return errors.Wrapf(err, "cannot create a new mount namespace")
+ return fmt.Errorf("cannot create a new mount namespace: %w", err)
}
xdgRuntimeDir, err := util.GetRuntimeDir()
if err != nil {
- return errors.Wrap(err, "could not get runtime directory")
+ return fmt.Errorf("could not get runtime directory: %w", err)
}
newXDGRuntimeDir := r.getPath(xdgRuntimeDir)
// 1. Mount the netns into the new run to keep them accessible.
// Otherwise cni setup will fail because it cannot access the netns files.
err = unix.Mount(xdgRuntimeDir, newXDGRuntimeDir, "none", unix.MS_BIND|unix.MS_SHARED|unix.MS_REC, "")
if err != nil {
- return errors.Wrap(err, "failed to mount runtime directory for rootless netns")
+ return fmt.Errorf("failed to mount runtime directory for rootless netns: %w", err)
}
// 2. Also keep /run/systemd if it exists.
@@ -150,7 +150,7 @@ func (r *RootlessNetNS) Do(toRun func() error) error {
newRunSystemd := r.getPath(runSystemd)
err = unix.Mount(runSystemd, newRunSystemd, "none", unix.MS_BIND|unix.MS_REC, "")
if err != nil {
- return errors.Wrap(err, "failed to mount /run/systemd directory for rootless netns")
+ return fmt.Errorf("failed to mount /run/systemd directory for rootless netns: %w", err)
}
}
@@ -185,7 +185,7 @@ func (r *RootlessNetNS) Do(toRun func() error) error {
fi, err := os.Lstat(path)
if err != nil {
- return errors.Wrap(err, "failed to stat resolv.conf path")
+ return fmt.Errorf("failed to stat resolv.conf path: %w", err)
}
// no link, just continue
@@ -195,7 +195,7 @@ func (r *RootlessNetNS) Do(toRun func() error) error {
link, err := os.Readlink(path)
if err != nil {
- return errors.Wrap(err, "failed to read resolv.conf symlink")
+ return fmt.Errorf("failed to read resolv.conf symlink: %w", err)
}
linkCount++
if filepath.IsAbs(link) {
@@ -231,25 +231,25 @@ func (r *RootlessNetNS) Do(toRun func() error) error {
rsr := r.getPath("/run/systemd/resolve")
err = unix.Mount("", rsr, "tmpfs", unix.MS_NOEXEC|unix.MS_NOSUID|unix.MS_NODEV, "")
if err != nil {
- return errors.Wrapf(err, "failed to mount tmpfs on %q for rootless netns", rsr)
+ return fmt.Errorf("failed to mount tmpfs on %q for rootless netns: %w", rsr, err)
}
}
if strings.HasPrefix(resolvePath, "/run/") {
resolvePath = r.getPath(resolvePath)
err = os.MkdirAll(filepath.Dir(resolvePath), 0700)
if err != nil {
- return errors.Wrap(err, "failed to create rootless-netns resolv.conf directory")
+ return fmt.Errorf("failed to create rootless-netns resolv.conf directory: %w", err)
}
// we want to bind mount on this file so we have to create the file first
_, err = os.OpenFile(resolvePath, os.O_CREATE|os.O_RDONLY, 0700)
if err != nil {
- return errors.Wrap(err, "failed to create rootless-netns resolv.conf file")
+ return fmt.Errorf("failed to create rootless-netns resolv.conf file: %w", err)
}
}
// mount resolv.conf to make use of the host dns
err = unix.Mount(r.getPath("resolv.conf"), resolvePath, "none", unix.MS_BIND, "")
if err != nil {
- return errors.Wrap(err, "failed to mount resolv.conf for rootless netns")
+ return fmt.Errorf("failed to mount resolv.conf for rootless netns: %w", err)
}
// 4. CNI plugins need access to /var/lib/cni and /run
@@ -274,14 +274,14 @@ func (r *RootlessNetNS) Do(toRun func() error) error {
// make sure to mount var first
err = unix.Mount(varDir, varTarget, "none", unix.MS_BIND, "")
if err != nil {
- return errors.Wrapf(err, "failed to mount %s for rootless netns", varTarget)
+ return fmt.Errorf("failed to mount %s for rootless netns: %w", varTarget, err)
}
// 5. Mount the new prepared run dir to /run, it has to be recursive to keep the other bind mounts.
runDir := r.getPath("run")
err = unix.Mount(runDir, "/run", "none", unix.MS_BIND|unix.MS_REC, "")
if err != nil {
- return errors.Wrap(err, "failed to mount /run for rootless netns")
+ return fmt.Errorf("failed to mount /run for rootless netns: %w", err)
}
// run the given function in the correct namespace
@@ -291,7 +291,7 @@ func (r *RootlessNetNS) Do(toRun func() error) error {
return err
}
-// Cleanup the rootless network namespace if needed.
+// Clean up the rootless network namespace if needed.
// It checks if we have running containers with the bridge network mode.
// Cleanup() expects that r.Lock is locked
func (r *RootlessNetNS) Cleanup(runtime *Runtime) error {
@@ -377,7 +377,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
lfile := filepath.Join(runDir, "rootless-netns.lock")
lock, err := lockfile.GetLockfile(lfile)
if err != nil {
- return nil, errors.Wrap(err, "failed to get rootless-netns lockfile")
+ return nil, fmt.Errorf("failed to get rootless-netns lockfile: %w", err)
}
lock.Lock()
defer func() {
@@ -391,7 +391,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
rootlessNetNsDir := filepath.Join(runDir, rootlessNetNsName)
err = os.MkdirAll(rootlessNetNsDir, 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-netns directory")
+ return nil, fmt.Errorf("could not create rootless-netns directory: %w", err)
}
nsDir, err := netns.GetNSRunDir()
@@ -411,15 +411,15 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
if err != nil {
if !new {
// return a error if we could not get the namespace and should no create one
- return nil, errors.Wrap(err, "error getting rootless network namespace")
+ return nil, fmt.Errorf("error getting rootless network namespace: %w", err)
}
// create a new namespace
logrus.Debugf("creating rootless network namespace with name %q", netnsName)
ns, err = netns.NewNSWithName(netnsName)
if err != nil {
- return nil, errors.Wrap(err, "error creating rootless network namespace")
+ return nil, fmt.Errorf("error creating rootless network namespace: %w", err)
}
- // setup slirp4netns here
+ // set up slirp4netns here
path := r.config.Engine.NetworkCmdPath
if path == "" {
var err error
@@ -431,7 +431,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
syncR, syncW, err := os.Pipe()
if err != nil {
- return nil, errors.Wrapf(err, "failed to open pipe")
+ return nil, fmt.Errorf("failed to open pipe: %w", err)
}
defer errorhandling.CloseQuiet(syncR)
defer errorhandling.CloseQuiet(syncW)
@@ -442,7 +442,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
}
slirpFeatures, err := checkSlirpFlags(path)
if err != nil {
- return nil, errors.Wrapf(err, "error checking slirp4netns binary %s: %q", path, err)
+ return nil, fmt.Errorf("error checking slirp4netns binary %s: %q: %w", path, err, err)
}
cmdArgs, err := createBasicSlirp4netnsCmdArgs(netOptions, slirpFeatures)
if err != nil {
@@ -470,25 +470,25 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
logPath := filepath.Join(r.config.Engine.TmpDir, "slirp4netns-rootless-netns.log")
logFile, err := os.Create(logPath)
if err != nil {
- return nil, errors.Wrapf(err, "failed to open slirp4netns log file %s", logPath)
+ return nil, fmt.Errorf("failed to open slirp4netns log file %s: %w", logPath, err)
}
defer logFile.Close()
// Unlink immediately the file so we won't need to worry about cleaning it up later.
// It is still accessible through the open fd logFile.
if err := os.Remove(logPath); err != nil {
- return nil, errors.Wrapf(err, "delete file %s", logPath)
+ return nil, fmt.Errorf("delete file %s: %w", logPath, err)
}
cmd.Stdout = logFile
cmd.Stderr = logFile
if err := cmd.Start(); err != nil {
- return nil, errors.Wrapf(err, "failed to start slirp4netns process")
+ return nil, fmt.Errorf("failed to start slirp4netns process: %w", err)
}
// create pid file for the slirp4netns process
// this is need to kill the process in the cleanup
pid := strconv.Itoa(cmd.Process.Pid)
err = ioutil.WriteFile(filepath.Join(rootlessNetNsDir, rootlessNetNsSilrp4netnsPidFile), []byte(pid), 0700)
if err != nil {
- return nil, errors.Wrap(err, "unable to write rootless-netns slirp4netns pid file")
+ return nil, fmt.Errorf("unable to write rootless-netns slirp4netns pid file: %w", err)
}
defer func() {
@@ -513,63 +513,59 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
// build a new resolv.conf file which uses the slirp4netns dns server address
resolveIP, err := GetSlirp4netnsDNS(nil)
if err != nil {
- return nil, errors.Wrap(err, "failed to determine default slirp4netns DNS address")
+ return nil, fmt.Errorf("failed to determine default slirp4netns DNS address: %w", err)
}
if netOptions.cidr != "" {
_, cidr, err := net.ParseCIDR(netOptions.cidr)
if err != nil {
- return nil, errors.Wrap(err, "failed to parse slirp4netns cidr")
+ return nil, fmt.Errorf("failed to parse slirp4netns cidr: %w", err)
}
resolveIP, err = GetSlirp4netnsDNS(cidr)
if err != nil {
- return nil, errors.Wrapf(err, "failed to determine slirp4netns DNS address from cidr: %s", cidr.String())
+ return nil, fmt.Errorf("failed to determine slirp4netns DNS address from cidr: %s: %w", cidr.String(), err)
}
}
- conf, err := resolvconf.Get()
- if err != nil {
- return nil, err
- }
- conf, err = resolvconf.FilterResolvDNS(conf.Content, netOptions.enableIPv6, true)
- if err != nil {
- return nil, err
- }
- searchDomains := resolvconf.GetSearchDomains(conf.Content)
- dnsOptions := resolvconf.GetOptions(conf.Content)
- nameServers := resolvconf.GetNameservers(conf.Content)
- _, err = resolvconf.Build(filepath.Join(rootlessNetNsDir, "resolv.conf"), append([]string{resolveIP.String()}, nameServers...), searchDomains, dnsOptions)
- if err != nil {
- return nil, errors.Wrap(err, "failed to create rootless netns resolv.conf")
+ if err := resolvconf.New(&resolvconf.Params{
+ Path: filepath.Join(rootlessNetNsDir, "resolv.conf"),
+ // fake the netns since we want to filter localhost
+ Namespaces: []specs.LinuxNamespace{
+ {Type: specs.NetworkNamespace},
+ },
+ IPv6Enabled: netOptions.enableIPv6,
+ KeepHostServers: true,
+ Nameservers: []string{resolveIP.String()},
+ }); err != nil {
+ return nil, fmt.Errorf("failed to create rootless netns resolv.conf: %w", err)
}
-
// create cni directories to store files
// they will be bind mounted to the correct location in a extra mount ns
err = os.MkdirAll(filepath.Join(rootlessNetNsDir, persistentCNIDir), 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-netns var directory")
+ return nil, fmt.Errorf("could not create rootless-netns var directory: %w", err)
}
runDir := filepath.Join(rootlessNetNsDir, "run")
err = os.MkdirAll(runDir, 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-netns run directory")
+ return nil, fmt.Errorf("could not create rootless-netns run directory: %w", err)
}
// relabel the new run directory to the iptables /run label
// this is important, otherwise the iptables command will fail
err = label.Relabel(runDir, "system_u:object_r:iptables_var_run_t:s0", false)
if err != nil {
- return nil, errors.Wrap(err, "could not create relabel rootless-netns run directory")
+ return nil, fmt.Errorf("could not create relabel rootless-netns run directory: %w", err)
}
// create systemd run directory
err = os.MkdirAll(filepath.Join(runDir, "systemd"), 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-netns systemd directory")
+ return nil, fmt.Errorf("could not create rootless-netns systemd directory: %w", err)
}
// create the directory for the netns files at the same location
// relative to the rootless-netns location
err = os.MkdirAll(filepath.Join(rootlessNetNsDir, nsDir), 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-netns netns directory")
+ return nil, fmt.Errorf("could not create rootless-netns netns directory: %w", err)
}
}
@@ -660,9 +656,9 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
return nil, err
}
- // setup rootless port forwarder when rootless with ports and the network status is empty,
+ // set up rootless port forwarder when rootless with ports and the network status is empty,
// if this is called from network reload the network status will not be empty and we should
- // not setup port because they are still active
+ // not set up port because they are still active
if rootless.IsRootless() && len(ctr.config.PortMappings) > 0 && ctr.getNetworkStatus() == nil {
// set up port forwarder for rootless netns
netnsPath := ctrNS.Path()
@@ -679,7 +675,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
func (r *Runtime) createNetNS(ctr *Container) (n ns.NetNS, q map[string]types.StatusBlock, retErr error) {
ctrNS, err := netns.NewNS()
if err != nil {
- return nil, nil, errors.Wrapf(err, "error creating network namespace for container %s", ctr.ID())
+ return nil, nil, fmt.Errorf("error creating network namespace for container %s: %w", ctr.ID(), err)
}
defer func() {
if retErr != nil {
@@ -706,7 +702,7 @@ func (r *Runtime) setupNetNS(ctr *Container) error {
b := make([]byte, 16)
if _, err := rand.Reader.Read(b); err != nil {
- return errors.Wrapf(err, "failed to generate random netns name")
+ return fmt.Errorf("failed to generate random netns name: %w", err)
}
nsPath, err := netns.GetNSRunDir()
if err != nil {
@@ -727,7 +723,7 @@ func (r *Runtime) setupNetNS(ctr *Container) error {
}
if err := unix.Mount(nsProcess, nsPath, "none", unix.MS_BIND, ""); err != nil {
- return errors.Wrapf(err, "cannot mount %s", nsPath)
+ return fmt.Errorf("cannot mount %s: %w", nsPath, err)
}
netNS, err := ns.GetNS(nsPath)
@@ -746,7 +742,7 @@ func (r *Runtime) setupNetNS(ctr *Container) error {
func joinNetNS(path string) (ns.NetNS, error) {
netNS, err := ns.GetNS(path)
if err != nil {
- return nil, errors.Wrapf(err, "error retrieving network namespace at %s", path)
+ return nil, fmt.Errorf("error retrieving network namespace at %s: %w", path, err)
}
return netNS, nil
@@ -762,7 +758,7 @@ func (r *Runtime) closeNetNS(ctr *Container) error {
}
if err := ctr.state.NetNS.Close(); err != nil {
- return errors.Wrapf(err, "error closing network namespace for container %s", ctr.ID())
+ return fmt.Errorf("error closing network namespace for container %s: %w", ctr.ID(), err)
}
ctr.state.NetNS = nil
@@ -778,8 +774,10 @@ func (r *Runtime) teardownNetwork(ns string, opts types.NetworkOptions) error {
return err
}
tearDownPod := func() error {
- err := r.network.Teardown(ns, types.TeardownOptions{NetworkOptions: opts})
- return errors.Wrapf(err, "error tearing down network namespace configuration for container %s", opts.ContainerID)
+ if err := r.network.Teardown(ns, types.TeardownOptions{NetworkOptions: opts}); err != nil {
+ return fmt.Errorf("error tearing down network namespace configuration for container %s: %w", opts.ContainerID, err)
+ }
+ return nil
}
// rootlessNetNS is nil if we are root
@@ -787,7 +785,7 @@ func (r *Runtime) teardownNetwork(ns string, opts types.NetworkOptions) error {
// execute the cni setup in the rootless net ns
err = rootlessNetNS.Do(tearDownPod)
if cerr := rootlessNetNS.Cleanup(r); cerr != nil {
- logrus.WithError(err).Error("failed to cleanup rootless netns")
+ logrus.WithError(err).Error("failed to clean up rootless netns")
}
rootlessNetNS.Lock.Unlock()
} else {
@@ -830,12 +828,12 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
// First unmount the namespace
if err := netns.UnmountNS(ctr.state.NetNS); err != nil {
- return errors.Wrapf(err, "error unmounting network namespace for container %s", ctr.ID())
+ return fmt.Errorf("error unmounting network namespace for container %s: %w", ctr.ID(), err)
}
// Now close the open file descriptor
if err := ctr.state.NetNS.Close(); err != nil {
- return errors.Wrapf(err, "error closing network namespace for container %s", ctr.ID())
+ return fmt.Errorf("error closing network namespace for container %s: %w", ctr.ID(), err)
}
ctr.state.NetNS = nil
@@ -868,7 +866,7 @@ func getContainerNetNS(ctr *Container) (string, *Container, error) {
// It returns nil when it is set to bridge and an error otherwise.
func isBridgeNetMode(n namespaces.NetworkMode) error {
if !n.IsBridge() {
- return errors.Wrapf(define.ErrNetworkModeInvalid, "%q is not supported", n)
+ return fmt.Errorf("%q is not supported: %w", n, define.ErrNetworkModeInvalid)
}
return nil
}
@@ -884,7 +882,7 @@ func isBridgeNetMode(n namespaces.NetworkMode) error {
// extend this to stop + restart slirp4netns
func (r *Runtime) reloadContainerNetwork(ctr *Container) (map[string]types.StatusBlock, error) {
if ctr.state.NetNS == nil {
- return nil, errors.Wrapf(define.ErrCtrStateInvalid, "container %s network is not configured, refusing to reload", ctr.ID())
+ return nil, fmt.Errorf("container %s network is not configured, refusing to reload: %w", ctr.ID(), define.ErrCtrStateInvalid)
}
if err := isBridgeNetMode(ctr.config.NetMode); err != nil {
return nil, err
@@ -930,6 +928,8 @@ func (r *Runtime) reloadContainerNetwork(ctr *Container) (map[string]types.Statu
return r.configureNetNS(ctr, ctr.state.NetNS)
}
+// TODO (5.0): return the statistics per network interface
+// This would allow better compat with docker.
func getContainerNetIO(ctr *Container) (*netlink.LinkStatistics, error) {
var netStats *netlink.LinkStatistics
@@ -943,21 +943,39 @@ func getContainerNetIO(ctr *Container) (*netlink.LinkStatistics, error) {
return nil, nil
}
- // FIXME get the interface from the container netstatus
- dev := "eth0"
netMode := ctr.config.NetMode
+ netStatus := ctr.getNetworkStatus()
if otherCtr != nil {
netMode = otherCtr.config.NetMode
+ netStatus = otherCtr.getNetworkStatus()
}
if netMode.IsSlirp4netns() {
- dev = "tap0"
+ // create a fake status with correct interface name for the logic below
+ netStatus = map[string]types.StatusBlock{
+ "slirp4netns": {
+ Interfaces: map[string]types.NetInterface{"tap0": {}},
+ },
+ }
}
err := ns.WithNetNSPath(netNSPath, func(_ ns.NetNS) error {
- link, err := netlink.LinkByName(dev)
- if err != nil {
- return err
+ for _, status := range netStatus {
+ for dev := range status.Interfaces {
+ link, err := netlink.LinkByName(dev)
+ if err != nil {
+ return err
+ }
+ if netStats == nil {
+ netStats = link.Attrs().Statistics
+ continue
+ }
+ // Currently only Tx/RxBytes are used.
+ // In the future we should return all stats per interface so that
+ // api users have a better options.
+ stats := link.Attrs().Statistics
+ netStats.TxBytes += stats.TxBytes
+ netStats.RxBytes += stats.RxBytes
+ }
}
- netStats = link.Attrs().Statistics
return nil
})
return netStats, err
@@ -1031,7 +1049,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
// If we have networks - handle that here
if len(networks) > 0 {
if len(networks) != len(netStatus) {
- return nil, errors.Wrapf(define.ErrInternal, "network inspection mismatch: asked to join %d network(s) %v, but have information on %d network(s)", len(networks), networks, len(netStatus))
+ return nil, fmt.Errorf("network inspection mismatch: asked to join %d network(s) %v, but have information on %d network(s): %w", len(networks), networks, len(netStatus), define.ErrInternal)
}
settings.Networks = make(map[string]*define.InspectAdditionalNetwork)
@@ -1056,7 +1074,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
// If not joining networks, we should have at most 1 result
if len(netStatus) > 1 {
- return nil, errors.Wrapf(define.ErrInternal, "should have at most 1 network status result if not joining networks, instead got %d", len(netStatus))
+ return nil, fmt.Errorf("should have at most 1 network status result if not joining networks, instead got %d: %w", len(netStatus), define.ErrInternal)
}
if len(netStatus) == 1 {
@@ -1069,7 +1087,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
func (c *Container) joinedNetworkNSPath() string {
for _, namespace := range c.config.Spec.Linux.Namespaces {
- if namespace.Type == spec.NetworkNamespace {
+ if namespace.Type == specs.NetworkNamespace {
return namespace.Path
}
}
@@ -1209,7 +1227,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
_, nameExists := networks[netName]
if !nameExists && len(networks) > 0 {
- return errors.Errorf("container %s is not connected to network %s", nameOrID, netName)
+ return fmt.Errorf("container %s is not connected to network %s", nameOrID, netName)
}
if err := c.syncContainer(); err != nil {
@@ -1228,7 +1246,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
}
if c.state.NetNS == nil {
- return errors.Wrapf(define.ErrNoNetwork, "unable to disconnect %s from %s", nameOrID, netName)
+ return fmt.Errorf("unable to disconnect %s from %s: %w", nameOrID, netName, define.ErrNoNetwork)
}
opts := types.NetworkOptions{
@@ -1346,7 +1364,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
return nil
}
if c.state.NetNS == nil {
- return errors.Wrapf(define.ErrNoNetwork, "unable to connect %s to %s", nameOrID, netName)
+ return fmt.Errorf("unable to connect %s to %s: %w", nameOrID, netName, define.ErrNoNetwork)
}
opts := types.NetworkOptions{