summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_config.go2
-rw-r--r--libpod/container_internal_linux.go1
-rw-r--r--libpod/container_path_resolution.go2
-rw-r--r--libpod/network/cni/run.go2
-rw-r--r--libpod/network/cni/run_test.go14
-rw-r--r--libpod/network/types/network.go50
-rw-r--r--libpod/network/types/network_test.go82
-rw-r--r--libpod/networking_linux.go249
-rw-r--r--libpod/oci_conmon_linux.go2
-rw-r--r--libpod/options.go2
-rw-r--r--libpod/runtime.go4
11 files changed, 273 insertions, 137 deletions
diff --git a/libpod/container_config.go b/libpod/container_config.go
index 87d37a9e6..412be835f 100644
--- a/libpod/container_config.go
+++ b/libpod/container_config.go
@@ -233,7 +233,7 @@ type ContainerNetworkConfig struct {
// StaticMAC is a static MAC to request for the container.
// This cannot be set unless CreateNetNS is set.
// If not set, the container will be dynamically assigned a MAC by CNI.
- StaticMAC net.HardwareAddr `json:"staticMAC"`
+ StaticMAC types.HardwareAddr `json:"staticMAC"`
// PortMappings are the ports forwarded to the container's network
// namespace
// These are not used unless CreateNetNS is true
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index d3151f7e0..2fd519990 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -1546,6 +1546,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
logrus.Debugf("Restored container %s", c.ID())
c.state.State = define.ContainerStateRunning
+ c.state.Checkpointed = false
if !options.Keep {
// Delete all checkpoint related files. At this point, in theory, all files
diff --git a/libpod/container_path_resolution.go b/libpod/container_path_resolution.go
index bb2ef1a73..7db23b783 100644
--- a/libpod/container_path_resolution.go
+++ b/libpod/container_path_resolution.go
@@ -161,7 +161,7 @@ func isPathOnBindMount(c *Container, containerPath string) bool {
if cleanedContainerPath == filepath.Clean(m.Destination) {
return true
}
- for dest := m.Destination; dest != "/"; dest = filepath.Dir(dest) {
+ for dest := m.Destination; dest != "/" && dest != "."; dest = filepath.Dir(dest) {
if cleanedContainerPath == dest {
return true
}
diff --git a/libpod/network/cni/run.go b/libpod/network/cni/run.go
index 99b2adce5..7795dfeeb 100644
--- a/libpod/network/cni/run.go
+++ b/libpod/network/cni/run.go
@@ -160,7 +160,7 @@ func CNIResultToStatus(res cnitypes.Result) (types.StatusBlock, error) {
return result, err
}
interfaces[cniInt.Name] = types.NetInterface{
- MacAddress: mac,
+ MacAddress: types.HardwareAddr(mac),
Networks: []types.NetAddress{{
Subnet: types.IPNet{IPNet: ip.Address},
Gateway: ip.Gateway,
diff --git a/libpod/network/cni/run_test.go b/libpod/network/cni/run_test.go
index 965203c2a..3169cd0eb 100644
--- a/libpod/network/cni/run_test.go
+++ b/libpod/network/cni/run_test.go
@@ -398,7 +398,7 @@ var _ = Describe("run CNI", func() {
i, err := net.InterfaceByName(intName1)
Expect(err).To(BeNil())
Expect(i.Name).To(Equal(intName1))
- Expect(i.HardwareAddr).To(Equal(macInt1))
+ Expect(i.HardwareAddr).To(Equal((net.HardwareAddr)(macInt1)))
addrs, err := i.Addrs()
Expect(err).To(BeNil())
subnet := &net.IPNet{
@@ -448,7 +448,7 @@ var _ = Describe("run CNI", func() {
i, err := net.InterfaceByName(intName1)
Expect(err).To(BeNil())
Expect(i.Name).To(Equal(intName1))
- Expect(i.HardwareAddr).To(Equal(macInt1))
+ Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt1)))
addrs, err := i.Addrs()
Expect(err).To(BeNil())
subnet := &net.IPNet{
@@ -460,7 +460,7 @@ var _ = Describe("run CNI", func() {
i, err = net.InterfaceByName(intName2)
Expect(err).To(BeNil())
Expect(i.Name).To(Equal(intName2))
- Expect(i.HardwareAddr).To(Equal(macInt2))
+ Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt2)))
addrs, err = i.Addrs()
Expect(err).To(BeNil())
subnet = &net.IPNet{
@@ -600,7 +600,7 @@ var _ = Describe("run CNI", func() {
i, err := net.InterfaceByName(intName1)
Expect(err).To(BeNil())
Expect(i.Name).To(Equal(intName1))
- Expect(i.HardwareAddr).To(Equal(macInt1))
+ Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt1)))
addrs, err := i.Addrs()
Expect(err).To(BeNil())
subnet := &net.IPNet{
@@ -612,7 +612,7 @@ var _ = Describe("run CNI", func() {
i, err = net.InterfaceByName(intName2)
Expect(err).To(BeNil())
Expect(i.Name).To(Equal(intName2))
- Expect(i.HardwareAddr).To(Equal(macInt2))
+ Expect(i.HardwareAddr).To(Equal(net.HardwareAddr(macInt2)))
addrs, err = i.Addrs()
Expect(err).To(BeNil())
subnet = &net.IPNet{
@@ -690,7 +690,7 @@ var _ = Describe("run CNI", func() {
netName: {
InterfaceName: interfaceName,
StaticIPs: []net.IP{ip1, ip2},
- StaticMAC: mac,
+ StaticMAC: types.HardwareAddr(mac),
},
},
},
@@ -708,7 +708,7 @@ var _ = Describe("run CNI", func() {
Expect(res[netName].Interfaces[interfaceName].Networks[1].Subnet.IP.String()).To(Equal(ip2.String()))
Expect(res[netName].Interfaces[interfaceName].Networks[1].Subnet.Mask).To(Equal(subnet2.Mask))
Expect(res[netName].Interfaces[interfaceName].Networks[1].Gateway).To(Equal(net.ParseIP("fd41:0a75:2ca0:48a9::1")))
- Expect(res[netName].Interfaces[interfaceName].MacAddress).To(Equal(mac))
+ Expect(res[netName].Interfaces[interfaceName].MacAddress).To(Equal(types.HardwareAddr(mac)))
// default network has no dns
Expect(res[netName].DNSServerIPs).To(BeEmpty())
Expect(res[netName].DNSSearchDomains).To(BeEmpty())
diff --git a/libpod/network/types/network.go b/libpod/network/types/network.go
index 657c1ca6a..ba5e018fd 100644
--- a/libpod/network/types/network.go
+++ b/libpod/network/types/network.go
@@ -1,6 +1,7 @@
package types
import (
+ "encoding/json"
"net"
"time"
)
@@ -94,6 +95,51 @@ func (n *IPNet) UnmarshalText(text []byte) error {
return nil
}
+// HardwareAddr is the same as net.HardwareAddr except
+// that it adds the json marshal/unmarshal methods.
+// This allows us to read the mac from a json string
+// and a byte array.
+// swagger:model MacAddress
+type HardwareAddr net.HardwareAddr
+
+func (h *HardwareAddr) String() string {
+ return (*net.HardwareAddr)(h).String()
+}
+
+func (h *HardwareAddr) MarshalText() ([]byte, error) {
+ return []byte((*net.HardwareAddr)(h).String()), nil
+}
+
+func (h *HardwareAddr) UnmarshalJSON(text []byte) error {
+ if len(text) == 0 {
+ *h = nil
+ return nil
+ }
+
+ // if the json string start with a quote we got a string
+ // unmarshal the string and parse the mac from this string
+ if string(text[0]) == `"` {
+ var macString string
+ err := json.Unmarshal(text, &macString)
+ if err == nil {
+ mac, err := net.ParseMAC(macString)
+ if err == nil {
+ *h = HardwareAddr(mac)
+ return nil
+ }
+ }
+ }
+ // not a string or got an error fallback to the normal parsing
+ mac := make(net.HardwareAddr, 0, 6)
+ // use the standard json unmarshal for backwards compat
+ err := json.Unmarshal(text, &mac)
+ if err != nil {
+ return err
+ }
+ *h = HardwareAddr(mac)
+ return nil
+}
+
type Subnet struct {
// Subnet for this Network in CIDR form.
// swagger:strfmt string
@@ -134,7 +180,7 @@ type NetInterface struct {
// Networks list of assigned subnets with their gateway.
Networks []NetAddress `json:"networks,omitempty"`
// MacAddress for this Interface.
- MacAddress net.HardwareAddr `json:"mac_address"`
+ MacAddress HardwareAddr `json:"mac_address"`
}
// NetAddress contains the subnet and gateway.
@@ -157,7 +203,7 @@ type PerNetworkOptions struct {
// Optional.
Aliases []string `json:"aliases,omitempty"`
// StaticMac for this container. Optional.
- StaticMAC net.HardwareAddr `json:"static_mac,omitempty"`
+ StaticMAC HardwareAddr `json:"static_mac,omitempty"`
// InterfaceName for this container. Required.
InterfaceName string `json:"interface_name"`
}
diff --git a/libpod/network/types/network_test.go b/libpod/network/types/network_test.go
new file mode 100644
index 000000000..91ee93692
--- /dev/null
+++ b/libpod/network/types/network_test.go
@@ -0,0 +1,82 @@
+package types_test
+
+import (
+ "encoding/json"
+ "reflect"
+ "testing"
+
+ "github.com/containers/podman/v3/libpod/network/types"
+)
+
+func TestUnmarshalMacAddress(t *testing.T) {
+ tests := []struct {
+ name string
+ json string
+ want types.HardwareAddr
+ wantErr bool
+ }{
+ {
+ name: "mac as string with colon",
+ json: `"52:54:00:1c:2e:46"`,
+ want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46},
+ },
+ {
+ name: "mac as string with dash",
+ json: `"52-54-00-1c-2e-46"`,
+ want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46},
+ },
+ {
+ name: "mac as byte array",
+ json: `[82, 84, 0, 28, 46, 70]`,
+ want: types.HardwareAddr{0x52, 0x54, 0x00, 0x1c, 0x2e, 0x46},
+ },
+ {
+ name: "null value",
+ json: `null`,
+ want: nil,
+ },
+ {
+ name: "mac as base64",
+ json: `"qrvM3e7/"`,
+ want: types.HardwareAddr{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff},
+ },
+ {
+ name: "invalid string",
+ json: `"52:54:00:1c:2e`,
+ wantErr: true,
+ },
+ {
+ name: "invalid array",
+ json: `[82, 84, 0, 28, 46`,
+ wantErr: true,
+ },
+
+ {
+ name: "invalid value",
+ json: `ab`,
+ wantErr: true,
+ },
+ {
+ name: "invalid object",
+ json: `{}`,
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ test := tt
+ t.Run(test.name, func(t *testing.T) {
+ mac := types.HardwareAddr{}
+ err := json.Unmarshal([]byte(test.json), &mac)
+ if (err != nil) != test.wantErr {
+ t.Errorf("types.HardwareAddress Unmarshal() error = %v, wantErr %v", err, test.wantErr)
+ return
+ }
+ if test.wantErr {
+ return
+ }
+ if !reflect.DeepEqual(mac, test.want) {
+ t.Errorf("types.HardwareAddress Unmarshal() got = %v, want %v", mac, test.want)
+ }
+ })
+ }
+}
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index d0f56ce95..ef261a438 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -42,8 +42,11 @@ const (
// default slirp4ns subnet
defaultSlirp4netnsSubnet = "10.0.2.0/24"
- // rootlessCNINSName is the file name for the rootless network namespace bind mount
- rootlessCNINSName = "rootless-cni-ns"
+ // rootlessNetNsName is the file name for the rootless network namespace bind mount
+ rootlessNetNsName = "rootless-netns"
+
+ // rootlessNetNsSilrp4netnsPidFile is the name of the rootless netns slirp4netns pid file
+ rootlessNetNsSilrp4netnsPidFile = "rootless-netns-slirp4netns.pid"
// persistentCNIDir is the directory where the CNI files are stored
persistentCNIDir = "/var/lib/cni"
@@ -134,21 +137,21 @@ func (c *Container) getNetworkOptions() (types.NetworkOptions, error) {
return opts, nil
}
-type RootlessCNI struct {
+type RootlessNetNS struct {
ns ns.NetNS
dir string
Lock lockfile.Locker
}
-// getPath will join the given path to the rootless cni dir
-func (r *RootlessCNI) getPath(path string) string {
+// getPath will join the given path to the rootless netns dir
+func (r *RootlessNetNS) getPath(path string) string {
return filepath.Join(r.dir, path)
}
-// Do - run the given function in the rootless cni ns.
+// Do - run the given function in the rootless netns.
// It does not lock the rootlessCNI lock, the caller
// should only lock when needed, e.g. for cni operations.
-func (r *RootlessCNI) Do(toRun func() error) error {
+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.
@@ -159,11 +162,11 @@ func (r *RootlessCNI) Do(toRun func() error) error {
// Because the plugins also need access to XDG_RUNTIME_DIR/netns some special setup is needed.
// The following bind mounts are needed
- // 1. XDG_RUNTIME_DIR/netns -> XDG_RUNTIME_DIR/rootless-cni/XDG_RUNTIME_DIR/netns
- // 2. /run/systemd -> XDG_RUNTIME_DIR/rootless-cni/run/systemd (only if it exists)
- // 3. XDG_RUNTIME_DIR/rootless-cni/resolv.conf -> /etc/resolv.conf or XDG_RUNTIME_DIR/rootless-cni/run/symlink/target
- // 4. XDG_RUNTIME_DIR/rootless-cni/var/lib/cni -> /var/lib/cni (if /var/lib/cni does not exists use the parent dir)
- // 5. XDG_RUNTIME_DIR/rootless-cni/run -> /run
+ // 1. XDG_RUNTIME_DIR -> XDG_RUNTIME_DIR/rootless-netns/XDG_RUNTIME_DIR
+ // 2. /run/systemd -> XDG_RUNTIME_DIR/rootless-netns/run/systemd (only if it exists)
+ // 3. XDG_RUNTIME_DIR/rootless-netns/resolv.conf -> /etc/resolv.conf or XDG_RUNTIME_DIR/rootless-netns/run/symlink/target
+ // 4. XDG_RUNTIME_DIR/rootless-netns/var/lib/cni -> /var/lib/cni (if /var/lib/cni does not exists use the parent dir)
+ // 5. XDG_RUNTIME_DIR/rootless-netns/run -> /run
// Create a new mount namespace,
// this must happen inside the netns thread.
@@ -172,16 +175,16 @@ func (r *RootlessCNI) Do(toRun func() error) error {
return errors.Wrapf(err, "cannot create a new mount namespace")
}
- netNsDir, err := netns.GetNSRunDir()
+ xdgRuntimeDir, err := util.GetRuntimeDir()
if err != nil {
- return errors.Wrap(err, "could not get network namespace directory")
+ return errors.Wrap(err, "could not get runtime directory")
}
- newNetNsDir := r.getPath(netNsDir)
+ 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(netNsDir, newNetNsDir, "none", unix.MS_BIND|unix.MS_SHARED|unix.MS_REC, "")
+ 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 netns directory for rootless cni")
+ return errors.Wrap(err, "failed to mount runtime directory for rootless netns")
}
// 2. Also keep /run/systemd if it exists.
@@ -192,7 +195,7 @@ func (r *RootlessCNI) 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 cni")
+ return errors.Wrap(err, "failed to mount /run/systemd directory for rootless netns")
}
}
@@ -240,25 +243,25 @@ func (r *RootlessCNI) 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 cni", rsr)
+ return errors.Wrapf(err, "failed to mount tmpfs on %q for rootless netns", rsr)
}
}
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-cni resolv.conf directory")
+ return errors.Wrap(err, "failed to create rootless-netns resolv.conf directory")
}
// 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-cni resolv.conf file")
+ return errors.Wrap(err, "failed to create rootless-netns resolv.conf file")
}
}
// 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 cni")
+ return errors.Wrap(err, "failed to mount resolv.conf for rootless netns")
}
// 4. CNI plugins need access to /var/lib/cni and /run
@@ -283,14 +286,14 @@ func (r *RootlessCNI) 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 cni", varTarget)
+ return errors.Wrapf(err, "failed to mount %s for rootless netns", varTarget)
}
// 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 cni")
+ return errors.Wrap(err, "failed to mount /run for rootless netns")
}
// run the given function in the correct namespace
@@ -300,10 +303,11 @@ func (r *RootlessCNI) Do(toRun func() error) error {
return err
}
-// Cleanup the rootless cni namespace if needed.
+// Cleanup the rootless network namespace if needed.
// It checks if we have running containers with the bridge network mode.
-// Cleanup() will try to lock RootlessCNI, therefore you have to call it with an unlocked
-func (r *RootlessCNI) Cleanup(runtime *Runtime) error {
+// Cleanup() will try to lock RootlessNetNS, therefore you have to call
+// it with an unlocked lock.
+func (r *RootlessNetNS) Cleanup(runtime *Runtime) error {
_, err := os.Stat(r.dir)
if os.IsNotExist(err) {
// the directory does not exists no need for cleanup
@@ -312,8 +316,25 @@ func (r *RootlessCNI) Cleanup(runtime *Runtime) error {
r.Lock.Lock()
defer r.Lock.Unlock()
running := func(c *Container) bool {
+ // no bridge => no need to check
+ if !c.config.NetMode.IsBridge() {
+ return false
+ }
+
// we cannot use c.state() because it will try to lock the container
- // using c.state.State directly should be good enough for this use case
+ // locking is a problem because cleanup is called after net teardown
+ // at this stage the container is already locked.
+ // also do not try to lock only containers which are not currently in net
+ // teardown because this will result in an ABBA deadlock between the rootless
+ // cni lock and the container lock
+ // because we need to get the state we have to sync otherwise this will not
+ // work because the state is empty by default
+ // I do not like this but I do not see a better way at moment
+ err := c.syncContainer()
+ if err != nil {
+ return false
+ }
+
state := c.state.State
return state == define.ContainerStateRunning
}
@@ -321,101 +342,89 @@ func (r *RootlessCNI) Cleanup(runtime *Runtime) error {
if err != nil {
return err
}
- cleanup := true
- for _, ctr := range ctrs {
- if ctr.config.NetMode.IsBridge() {
- cleanup = false
- }
+ // no cleanup if we found containers
+ if len(ctrs) > 0 {
+ return nil
}
- if cleanup {
- // make sure the the cni results (cache) dir is empty
- // libpod instances with another root dir are not covered by the check above
- // this allows several libpod instances to use the same rootless cni ns
- contents, err := ioutil.ReadDir(r.getPath("var/lib/cni/results"))
- if (err == nil && len(contents) == 0) || os.IsNotExist(err) {
- logrus.Debug("Cleaning up rootless cni namespace")
- err = netns.UnmountNS(r.ns)
- if err != nil {
- return err
- }
- // make the following errors not fatal
- err = r.ns.Close()
- if err != nil {
- logrus.Error(err)
- }
- b, err := ioutil.ReadFile(r.getPath("rootless-cni-slirp4netns.pid"))
- if err == nil {
- var i int
- i, err = strconv.Atoi(string(b))
- if err == nil {
- // kill the slirp process so we do not leak it
- err = syscall.Kill(i, syscall.SIGTERM)
- }
- }
- if err != nil {
- logrus.Errorf("Failed to kill slirp4netns process: %s", err)
- }
- err = os.RemoveAll(r.dir)
- if err != nil {
- logrus.Error(err)
- }
- } else if err != nil && !os.IsNotExist(err) {
- logrus.Errorf("Could not read rootless cni directory, skipping cleanup: %s", err)
+ logrus.Debug("Cleaning up rootless network namespace")
+ err = netns.UnmountNS(r.ns)
+ if err != nil {
+ return err
+ }
+ // make the following errors not fatal
+ err = r.ns.Close()
+ if err != nil {
+ logrus.Error(err)
+ }
+ b, err := ioutil.ReadFile(r.getPath(rootlessNetNsSilrp4netnsPidFile))
+ if err == nil {
+ var i int
+ i, err = strconv.Atoi(string(b))
+ if err == nil {
+ // kill the slirp process so we do not leak it
+ err = syscall.Kill(i, syscall.SIGTERM)
}
}
+ if err != nil {
+ logrus.Errorf("Failed to kill slirp4netns process: %s", err)
+ }
+ err = os.RemoveAll(r.dir)
+ if err != nil {
+ logrus.Error(err)
+ }
return nil
}
-// GetRootlessCNINetNs returns the rootless cni object. If create is set to true
-// the rootless cni namespace will be created if it does not exists already.
+// GetRootlessNetNs returns the rootless netns object. If create is set to true
+// the rootless network namespace will be created if it does not exists already.
// If called as root it returns always nil.
// On success the returned RootlessCNI lock is locked and must be unlocked by the caller.
-func (r *Runtime) GetRootlessCNINetNs(new bool) (*RootlessCNI, error) {
+func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
if !rootless.IsRootless() {
return nil, nil
}
- var rootlessCNINS *RootlessCNI
+ var rootlessNetNS *RootlessNetNS
runDir, err := util.GetRuntimeDir()
if err != nil {
return nil, err
}
- lfile := filepath.Join(runDir, "rootless-cni.lock")
+ lfile := filepath.Join(runDir, "rootless-netns.lock")
lock, err := lockfile.GetLockfile(lfile)
if err != nil {
- return nil, errors.Wrap(err, "failed to get rootless-cni lockfile")
+ return nil, errors.Wrap(err, "failed to get rootless-netns lockfile")
}
lock.Lock()
defer func() {
- // In case of an error (early exit) rootlessCNINS will be nil.
+ // In case of an error (early exit) rootlessNetNS will be nil.
// Make sure to unlock otherwise we could deadlock.
- if rootlessCNINS == nil {
+ if rootlessNetNS == nil {
lock.Unlock()
}
}()
- cniDir := filepath.Join(runDir, "rootless-cni")
- err = os.MkdirAll(cniDir, 0700)
+ rootlessNetNsDir := filepath.Join(runDir, rootlessNetNsName)
+ err = os.MkdirAll(rootlessNetNsDir, 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-cni directory")
+ return nil, errors.Wrap(err, "could not create rootless-netns directory")
}
nsDir, err := netns.GetNSRunDir()
if err != nil {
return nil, err
}
- path := filepath.Join(nsDir, rootlessCNINSName)
+ path := filepath.Join(nsDir, rootlessNetNsName)
ns, err := ns.GetNS(path)
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 cni network namespace")
+ return nil, errors.Wrap(err, "error getting rootless network namespace")
}
// create a new namespace
- logrus.Debug("creating rootless cni network namespace")
- ns, err = netns.NewNSWithName(rootlessCNINSName)
+ logrus.Debug("creating rootless network namespace")
+ ns, err = netns.NewNSWithName(rootlessNetNsName)
if err != nil {
- return nil, errors.Wrap(err, "error creating rootless cni network namespace")
+ return nil, errors.Wrap(err, "error creating rootless network namespace")
}
// setup slirp4netns here
path := r.config.Engine.NetworkCmdPath
@@ -465,7 +474,7 @@ func (r *Runtime) GetRootlessCNINetNs(new bool) (*RootlessCNI, error) {
// Leak one end of the pipe in slirp4netns
cmd.ExtraFiles = append(cmd.ExtraFiles, syncW)
- logPath := filepath.Join(r.config.Engine.TmpDir, "slirp4netns-rootless-cni.log")
+ 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)
@@ -484,9 +493,9 @@ func (r *Runtime) GetRootlessCNINetNs(new bool) (*RootlessCNI, error) {
// 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(cniDir, "rootless-cni-slirp4netns.pid"), []byte(pid), 0700)
+ err = ioutil.WriteFile(filepath.Join(rootlessNetNsDir, rootlessNetNsSilrp4netnsPidFile), []byte(pid), 0700)
if err != nil {
- errors.Wrap(err, "unable to write rootless-cni slirp4netns pid file")
+ errors.Wrap(err, "unable to write rootless-netns slirp4netns pid file")
}
defer func() {
@@ -527,43 +536,43 @@ func (r *Runtime) GetRootlessCNINetNs(new bool) (*RootlessCNI, error) {
dnsOptions := resolvconf.GetOptions(conf.Content)
nameServers := resolvconf.GetNameservers(conf.Content)
- _, err = resolvconf.Build(filepath.Join(cniDir, "resolv.conf"), append([]string{resolveIP.String()}, nameServers...), searchDomains, dnsOptions)
+ _, 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 cni resolv.conf")
+ return nil, errors.Wrap(err, "failed to create rootless netns resolv.conf")
}
// 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(cniDir, strings.TrimPrefix(persistentCNIDir, "/")), 0700)
+ err = os.MkdirAll(filepath.Join(rootlessNetNsDir, persistentCNIDir), 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-cni var directory")
+ return nil, errors.Wrap(err, "could not create rootless-netns var directory")
}
- runDir := filepath.Join(cniDir, "run")
+ runDir := filepath.Join(rootlessNetNsDir, "run")
err = os.MkdirAll(runDir, 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-cni run directory")
+ return nil, errors.Wrap(err, "could not create rootless-netns run directory")
}
// 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-cni run directory")
+ return nil, errors.Wrap(err, "could not create relabel rootless-netns run directory")
}
// create systemd run directory
err = os.MkdirAll(filepath.Join(runDir, "systemd"), 0700)
if err != nil {
- return nil, errors.Wrap(err, "could not create rootless-cni systemd directory")
+ return nil, errors.Wrap(err, "could not create rootless-netns systemd directory")
}
// create the directory for the netns files at the same location
- // relative to the rootless-cni location
- err = os.MkdirAll(filepath.Join(cniDir, nsDir), 0700)
+ // 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-cni netns directory")
+ return nil, errors.Wrap(err, "could not create rootless-netns netns directory")
}
}
- // The CNI plugins need access to iptables in $PATH. As it turns out debian doesn't put
- // /usr/sbin in $PATH for rootless users. This will break rootless cni completely.
+ // The CNI plugins and netavark need access to iptables in $PATH. As it turns out debian doesn't put
+ // /usr/sbin in $PATH for rootless users. This will break rootless networking completely.
// We might break existing users and we cannot expect everyone to change their $PATH so
// lets add /usr/sbin to $PATH ourselves.
path = os.Getenv("PATH")
@@ -572,14 +581,14 @@ func (r *Runtime) GetRootlessCNINetNs(new bool) (*RootlessCNI, error) {
os.Setenv("PATH", path)
}
- // Important set rootlessCNINS as last step.
+ // Important set rootlessNetNS as last step.
// Do not return any errors after this.
- rootlessCNINS = &RootlessCNI{
+ rootlessNetNS = &RootlessNetNS{
ns: ns,
- dir: cniDir,
+ dir: rootlessNetNsDir,
Lock: lock,
}
- return rootlessCNINS, nil
+ return rootlessNetNS, nil
}
// setPrimaryMachineIP is used for podman-machine and it sets
@@ -601,14 +610,14 @@ func setPrimaryMachineIP() error {
}
// setUpNetwork will set up the the networks, on error it will also tear down the cni
-// networks. If rootless it will join/create the rootless cni namespace.
+// networks. If rootless it will join/create the rootless network namespace.
func (r *Runtime) setUpNetwork(ns string, opts types.NetworkOptions) (map[string]types.StatusBlock, error) {
if r.config.MachineEnabled() {
if err := setPrimaryMachineIP(); err != nil {
return nil, err
}
}
- rootlessCNINS, err := r.GetRootlessCNINetNs(true)
+ rootlessNetNS, err := r.GetRootlessNetNs(true)
if err != nil {
return nil, err
}
@@ -617,11 +626,11 @@ func (r *Runtime) setUpNetwork(ns string, opts types.NetworkOptions) (map[string
results, err = r.network.Setup(ns, types.SetupOptions{NetworkOptions: opts})
return err
}
- // rootlessCNINS is nil if we are root
- if rootlessCNINS != nil {
- // execute the cni setup in the rootless net ns
- err = rootlessCNINS.Do(setUpPod)
- rootlessCNINS.Lock.Unlock()
+ // rootlessNetNS is nil if we are root
+ if rootlessNetNS != nil {
+ // execute the setup in the rootless net ns
+ err = rootlessNetNS.Do(setUpPod)
+ rootlessNetNS.Lock.Unlock()
} else {
err = setUpPod()
}
@@ -695,10 +704,10 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) error {
return err
}
if len(networks) > 0 && len(ctr.config.PortMappings) > 0 {
- // set up port forwarder for CNI-in-slirp4netns
+ // set up port forwarder for rootless netns
netnsPath := ctr.state.NetNS.Path()
// TODO: support slirp4netns port forwarder as well
- // make sure to fix this container.handleRestartPolicy() as well
+ // make sure to fix this in container.handleRestartPolicy() as well
return r.setupRootlessPortMappingViaRLK(ctr, netnsPath)
}
return nil
@@ -717,7 +726,7 @@ func (r *Runtime) setupNetNS(ctr *Container) error {
if err != nil {
return err
}
- nsPath = filepath.Join(nsPath, fmt.Sprintf("cni-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]))
+ nsPath = filepath.Join(nsPath, fmt.Sprintf("netns-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:]))
if err := os.MkdirAll(filepath.Dir(nsPath), 0711); err != nil {
return err
@@ -775,10 +784,10 @@ func (r *Runtime) closeNetNS(ctr *Container) error {
return nil
}
-// Tear down a container's CNI network configuration and joins the
+// Tear down a container's network configuration and joins the
// rootless net ns as rootless user
func (r *Runtime) teardownNetwork(ns string, opts types.NetworkOptions) error {
- rootlessCNINS, err := r.GetRootlessCNINetNs(false)
+ rootlessNetNS, err := r.GetRootlessNetNs(false)
if err != nil {
return err
}
@@ -787,13 +796,13 @@ func (r *Runtime) teardownNetwork(ns string, opts types.NetworkOptions) error {
return errors.Wrapf(err, "error tearing down network namespace configuration for container %s", opts.ContainerID)
}
- // rootlessCNINS is nil if we are root
- if rootlessCNINS != nil {
+ // rootlessNetNS is nil if we are root
+ if rootlessNetNS != nil {
// execute the cni setup in the rootless net ns
- err = rootlessCNINS.Do(tearDownPod)
- rootlessCNINS.Lock.Unlock()
+ err = rootlessNetNS.Do(tearDownPod)
+ rootlessNetNS.Lock.Unlock()
if err == nil {
- err = rootlessCNINS.Cleanup(r)
+ err = rootlessNetNS.Cleanup(r)
}
} else {
err = tearDownPod()
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 1719b2dfa..db906fabb 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -1016,7 +1016,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
}
if ctr.config.CgroupsMode == cgroupSplit {
- if err := utils.MoveUnderCgroupSubtree("supervisor"); err != nil {
+ if err := utils.MoveUnderCgroupSubtree("runtime"); err != nil {
return err
}
}
diff --git a/libpod/options.go b/libpod/options.go
index 59795432f..250b16556 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1104,7 +1104,7 @@ func WithNetworkOptions(options map[string][]string) CtrCreateOption {
// It cannot be set unless WithNetNS has already been passed.
// Further, it cannot be set if additional CNI networks to join have been
// specified.
-func WithStaticMAC(mac net.HardwareAddr) CtrCreateOption {
+func WithStaticMAC(mac nettypes.HardwareAddr) CtrCreateOption {
return func(ctr *Container) error {
if ctr.valid {
return define.ErrCtrFinalized
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 950ac65eb..b01f8dd13 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -545,9 +545,7 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
if became {
// Check if the pause process was created. If it was created, then
// move it to its own systemd scope.
- if _, err = os.Stat(pausePid); err == nil {
- utils.MovePauseProcessToScope(pausePid)
- }
+ utils.MovePauseProcessToScope(pausePid)
os.Exit(ret)
}
}