Merge pull request #16756 from Luap99/netns-db

libpod: move NetNS into state db instead of extra bucket
This commit is contained in:
OpenShift Merge Robot
2022-12-17 04:17:20 -05:00
committed by GitHub
15 changed files with 73 additions and 245 deletions

View File

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net"
"os"
"strconv"
"strings"
"sync"
@ -817,7 +816,6 @@ func (s *BoltState) UpdateContainer(ctr *Container) error {
}
newState := new(ContainerState)
netNSPath := ""
ctrID := []byte(ctr.ID())
@ -848,9 +846,10 @@ func (s *BoltState) UpdateContainer(ctr *Container) error {
return fmt.Errorf("unmarshalling container %s state: %w", ctr.ID(), err)
}
// backwards compat, previously we used a extra bucket for the netns so try to get it from there
netNSBytes := ctrToUpdate.Get(netNSKey)
if netNSBytes != nil {
netNSPath = string(netNSBytes)
if netNSBytes != nil && newState.NetNS == "" {
newState.NetNS = string(netNSBytes)
}
return nil
@ -859,15 +858,6 @@ func (s *BoltState) UpdateContainer(ctr *Container) error {
return err
}
// Handle network namespace.
if os.Geteuid() == 0 {
// Do it only when root, either on the host or as root in the
// user namespace.
if err := replaceNetNS(netNSPath, ctr, newState); err != nil {
return err
}
}
// New state compiled successfully, swap it into the current state
ctr.state = newState
@ -892,7 +882,7 @@ func (s *BoltState) SaveContainer(ctr *Container) error {
if err != nil {
return fmt.Errorf("marshalling container %s state to JSON: %w", ctr.ID(), err)
}
netNSPath := getNetNSPath(ctr)
netNSPath := ctr.state.NetNS
ctrID := []byte(ctr.ID())
@ -919,11 +909,7 @@ func (s *BoltState) SaveContainer(ctr *Container) error {
return fmt.Errorf("updating container %s state in DB: %w", ctr.ID(), err)
}
if netNSPath != "" {
if err := ctrToSave.Put(netNSKey, []byte(netNSPath)); err != nil {
return fmt.Errorf("updating network namespace path for container %s in DB: %w", ctr.ID(), err)
}
} else {
if netNSPath == "" {
// Delete the existing network namespace
if err := ctrToSave.Delete(netNSKey); err != nil {
return fmt.Errorf("removing network namespace path for container %s in DB: %w", ctr.ID(), err)

View File

@ -1,25 +0,0 @@
//go:build freebsd
// +build freebsd
package libpod
// replaceNetNS handle network namespace transitions after updating a
// container's state.
func replaceNetNS(netNSPath string, ctr *Container, newState *ContainerState) error {
if netNSPath != "" {
// On FreeBSD, we just record the network jail's name in our state.
newState.NetNS = &jailNetNS{Name: netNSPath}
} else {
newState.NetNS = nil
}
return nil
}
// getNetNSPath retrieves the netns path to be stored in the database
func getNetNSPath(ctr *Container) string {
if ctr.state.NetNS != nil {
return ctr.state.NetNS.Name
} else {
return ""
}
}

View File

@ -590,7 +590,6 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error {
if err != nil {
return fmt.Errorf("marshalling container %s state to JSON: %w", ctr.ID(), err)
}
netNSPath := getNetNSPath(ctr)
dependsCtrs := ctr.Dependencies()
ctrID := []byte(ctr.ID())
@ -741,11 +740,6 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error {
return fmt.Errorf("adding container %s pod to DB: %w", ctr.ID(), err)
}
}
if netNSPath != "" {
if err := newCtrBkt.Put(netNSKey, []byte(netNSPath)); err != nil {
return fmt.Errorf("adding container %s netns path to DB: %w", ctr.ID(), err)
}
}
if len(networks) > 0 {
ctrNetworksBkt, err := newCtrBkt.CreateBucket(networksBkt)
if err != nil {

View File

@ -1,57 +0,0 @@
//go:build linux
// +build linux
package libpod
import (
"fmt"
"github.com/containers/podman/v4/libpod/define"
"github.com/sirupsen/logrus"
)
// replaceNetNS handle network namespace transitions after updating a
// container's state.
func replaceNetNS(netNSPath string, ctr *Container, newState *ContainerState) error {
if netNSPath != "" {
// Check if the container's old state has a good netns
if ctr.state.NetNS != nil && netNSPath == ctr.state.NetNS.Path() {
newState.NetNS = ctr.state.NetNS
} else {
// Close the existing namespace.
// Whoever removed it from the database already tore it down.
if err := ctr.runtime.closeNetNS(ctr); err != nil {
return err
}
// Open the new network namespace
ns, err := joinNetNS(netNSPath)
if err == nil {
newState.NetNS = ns
} else {
if ctr.ensureState(define.ContainerStateRunning, define.ContainerStatePaused) {
return fmt.Errorf("joining network namespace of container %s: %w", ctr.ID(), err)
}
logrus.Errorf("Joining network namespace for container %s: %v", ctr.ID(), err)
ctr.state.NetNS = nil
}
}
} else {
// The container no longer has a network namespace
// Close the old one, whoever removed it from the DB should have
// cleaned it up already.
if err := ctr.runtime.closeNetNS(ctr); err != nil {
return err
}
}
return nil
}
// getNetNSPath retrieves the netns path to be stored in the database
func getNetNSPath(ctr *Container) string {
if ctr.state.NetNS != nil {
return ctr.state.NetNS.Path()
}
return ""
}

View File

@ -169,6 +169,8 @@ type ContainerState struct {
// Podman.
// These are DEPRECATED and will be removed in a future release.
LegacyExecSessions map[string]*legacyExecSession `json:"execSessions,omitempty"`
// NetNS is the path or name of the NetNS
NetNS string `json:"netns,omitempty"`
// NetworkStatusOld contains the configuration results for all networks
// the pod is attached to. Only populated if we created a network
// namespace for the container, and the network namespace is currently
@ -228,9 +230,6 @@ type ContainerState struct {
// `podman-play-kube`.
Service Service
// containerPlatformState holds platform-specific container state.
containerPlatformState
// Following checkpoint/restore related information is displayed
// if the container has been checkpointed or restored.
CheckpointedTime time.Time `json:"checkpointedTime,omitempty"`

View File

@ -3,29 +3,12 @@
package libpod
type containerPlatformState struct {
// NetNS is the name of the container's network VNET
// jail. Will only be set if config.CreateNetNS is true, or
// the container was told to join another container's network
// namespace.
NetNS *jailNetNS `json:"-"`
}
type jailNetNS struct {
Name string `json:"-"`
}
func (ns *jailNetNS) Path() string {
// The jail name approximately corresponds to the Linux netns path
return ns.Name
}
func networkDisabled(c *Container) (bool, error) {
if c.config.CreateNetNS {
return false, nil
}
if !c.config.PostConfigureNetNS {
return c.state.NetNS != nil, nil
return c.state.NetNS != "", nil
}
return false, nil
}

View File

@ -625,6 +625,9 @@ func resetState(state *ContainerState) {
state.StartupHCPassed = false
state.StartupHCSuccessCount = 0
state.StartupHCFailureCount = 0
state.NetNS = ""
state.NetworkStatus = nil
state.NetworkStatusOld = nil
}
// Refresh refreshes the container's state after a restart.

View File

@ -36,7 +36,7 @@ func (c *Container) unmountSHM(path string) error {
func (c *Container) prepare() error {
var (
wg sync.WaitGroup
ctrNS *jailNetNS
ctrNS string
networkStatus map[string]types.StatusBlock
createNetNSErr, mountStorageErr error
mountPoint string
@ -48,7 +48,7 @@ func (c *Container) prepare() error {
go func() {
defer wg.Done()
// Set up network namespace if not already set up
noNetNS := c.state.NetNS == nil
noNetNS := c.state.NetNS == ""
if c.config.CreateNetNS && noNetNS && !c.config.PostConfigureNetNS {
ctrNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
if createNetNSErr != nil {
@ -168,8 +168,8 @@ func (c *Container) addNetworkContainer(g *generate.Generator, ctr string) error
return fmt.Errorf("retrieving dependency %s of container %s from state: %w", ctr, c.ID(), err)
}
c.runtime.state.UpdateContainer(nsCtr)
if nsCtr.state.NetNS != nil {
g.AddAnnotation("org.freebsd.parentJail", nsCtr.state.NetNS.Name)
if nsCtr.state.NetNS != "" {
g.AddAnnotation("org.freebsd.parentJail", nsCtr.state.NetNS)
}
return nil
}
@ -193,7 +193,7 @@ func openDirectory(path string) (fd int, err error) {
func (c *Container) addNetworkNamespace(g *generate.Generator) error {
if c.config.CreateNetNS {
if c.state.NetNS == nil {
if c.state.NetNS == "" {
// This should not happen since network setup
// errors should be propagated correctly from
// (*Runtime).createNetNS. Check for it anyway
@ -201,7 +201,7 @@ func (c *Container) addNetworkNamespace(g *generate.Generator) error {
// the past (see #16333).
return fmt.Errorf("Inconsistent state: c.config.CreateNetNS is set but c.state.NetNS is nil")
}
g.AddAnnotation("org.freebsd.parentJail", c.state.NetNS.Name)
g.AddAnnotation("org.freebsd.parentJail", c.state.NetNS)
}
return nil
}
@ -286,7 +286,7 @@ func (c *Container) isSlirp4netnsIPv6() (bool, error) {
// check for net=none
func (c *Container) hasNetNone() bool {
return c.state.NetNS == nil
return c.state.NetNS == ""
}
func setVolumeAtime(mountPoint string, st os.FileInfo) error {
@ -310,8 +310,8 @@ func (c *Container) getConmonPidFd() int {
}
func (c *Container) jailName() string {
if c.state.NetNS != nil {
return c.state.NetNS.Name + "." + c.ID()
if c.state.NetNS != "" {
return c.state.NetNS + "." + c.ID()
} else {
return c.ID()
}

View File

@ -14,7 +14,6 @@ import (
"syscall"
"time"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/cgroups"
"github.com/containers/common/pkg/config"
@ -56,7 +55,7 @@ func (c *Container) unmountSHM(mount string) error {
func (c *Container) prepare() error {
var (
wg sync.WaitGroup
netNS ns.NetNS
netNS string
networkStatus map[string]types.StatusBlock
createNetNSErr, mountStorageErr error
mountPoint string
@ -68,7 +67,7 @@ func (c *Container) prepare() error {
go func() {
defer wg.Done()
// Set up network namespace if not already set up
noNetNS := c.state.NetNS == nil
noNetNS := c.state.NetNS == ""
if c.config.CreateNetNS && noNetNS && !c.config.PostConfigureNetNS {
netNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
if createNetNSErr != nil {
@ -159,7 +158,7 @@ func (c *Container) cleanupNetwork() error {
if netDisabled {
return nil
}
if c.state.NetNS == nil {
if c.state.NetNS == "" {
logrus.Debugf("Network is already cleaned up, skipping...")
return nil
}
@ -169,7 +168,7 @@ func (c *Container) cleanupNetwork() error {
logrus.Errorf("Unable to clean up network for container %s: %q", c.ID(), err)
}
c.state.NetNS = nil
c.state.NetNS = ""
c.state.NetworkStatus = nil
c.state.NetworkStatusOld = nil
@ -411,7 +410,7 @@ func (c *Container) setupRootlessNetwork() error {
// set up rootlesskit port forwarder again since it dies when conmon exits
// we use rootlesskit port forwarder only as rootless and when bridge network is used
if rootless.IsRootless() && c.config.NetMode.IsBridge() && len(c.config.PortMappings) > 0 {
err := c.runtime.setupRootlessPortMappingViaRLK(c, c.state.NetNS.Path(), c.state.NetworkStatus)
err := c.runtime.setupRootlessPortMappingViaRLK(c, c.state.NetNS, c.state.NetworkStatus)
if err != nil {
return err
}
@ -430,7 +429,7 @@ func (c *Container) addNetworkNamespace(g *generate.Generator) error {
return err
}
} else {
if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), c.state.NetNS.Path()); err != nil {
if err := g.AddOrReplaceLinuxNamespace(string(spec.NetworkNamespace), c.state.NetNS); err != nil {
return err
}
}

View File

@ -4,17 +4,9 @@
package libpod
import (
"github.com/containernetworking/plugins/pkg/ns"
spec "github.com/opencontainers/runtime-spec/specs-go"
)
type containerPlatformState struct {
// NetNSPath is the path of the container's network namespace
// Will only be set if config.CreateNetNS is true, or the container was
// told to join another container's network namespace
NetNS ns.NetNS `json:"-"`
}
func networkDisabled(c *Container) (bool, error) {
if c.config.CreateNetNS {
return false, nil

View File

@ -121,12 +121,12 @@ func (r *Runtime) teardownNetworkBackend(ns string, opts types.NetworkOptions) e
// Tear down a container's network backend configuration, but do not tear down the
// namespace itself.
func (r *Runtime) teardownNetwork(ctr *Container) error {
if ctr.state.NetNS == nil {
if ctr.state.NetNS == "" {
// The container has no network namespace, we're set
return nil
}
logrus.Debugf("Tearing down network namespace at %s for container %s", ctr.state.NetNS.Path(), ctr.ID())
logrus.Debugf("Tearing down network namespace at %s for container %s", ctr.state.NetNS, ctr.ID())
networks, err := ctr.networks()
if err != nil {
@ -136,7 +136,7 @@ func (r *Runtime) teardownNetwork(ctr *Container) error {
if !ctr.config.NetMode.IsSlirp4netns() &&
!ctr.config.NetMode.IsPasta() && len(networks) > 0 {
netOpts := ctr.getNetworkOptions(networks)
return r.teardownNetworkBackend(ctr.state.NetNS.Path(), netOpts)
return r.teardownNetworkBackend(ctr.state.NetNS, netOpts)
}
return nil
}
@ -158,7 +158,7 @@ func isBridgeNetMode(n namespaces.NetworkMode) error {
// Only works on containers with bridge networking at present, though in the future we could
// extend this to stop + restart slirp4netns
func (r *Runtime) reloadContainerNetwork(ctr *Container) (map[string]types.StatusBlock, error) {
if ctr.state.NetNS == nil {
if ctr.state.NetNS == "" {
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 {
@ -234,7 +234,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
return nil, err
}
if c.state.NetNS == nil {
if c.state.NetNS == "" {
if networkNSPath := c.joinedNetworkNSPath(); networkNSPath != "" {
if result, err := c.inspectJoinedNetworkNS(networkNSPath); err == nil {
// fallback to dummy configuration
@ -262,7 +262,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
}
// Set network namespace path
settings.SandboxKey = c.state.NetNS.Path()
settings.SandboxKey = c.state.NetNS
netStatus := c.getNetworkStatus()
// If this is empty, we're probably slirp4netns
@ -394,7 +394,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
return nil
}
if c.state.NetNS == nil {
if c.state.NetNS == "" {
return fmt.Errorf("unable to disconnect %s from %s: %w", nameOrID, netName, define.ErrNoNetwork)
}
@ -407,7 +407,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
netName: networks[netName],
}
if err := c.runtime.teardownNetworkBackend(c.state.NetNS.Path(), opts); err != nil {
if err := c.runtime.teardownNetworkBackend(c.state.NetNS, opts); err != nil {
return err
}
@ -517,7 +517,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
if !c.ensureState(define.ContainerStateRunning, define.ContainerStateCreated) {
return nil
}
if c.state.NetNS == nil {
if c.state.NetNS == "" {
return fmt.Errorf("unable to connect %s to %s: %w", nameOrID, netName, define.ErrNoNetwork)
}
@ -530,7 +530,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
netName: netOpts,
}
results, err := c.runtime.setUpNetwork(c.state.NetNS.Path(), opts)
results, err := c.runtime.setUpNetwork(c.state.NetNS, opts)
if err != nil {
return err
}

View File

@ -116,7 +116,7 @@ func (r *Runtime) setupNetNS(ctr *Container) error {
}
// Create and configure a new network namespace for a container
func (r *Runtime) configureNetNS(ctr *Container, ctrNS *jailNetNS) (status map[string]types.StatusBlock, rerr error) {
func (r *Runtime) configureNetNS(ctr *Container, ctrNS string) (status map[string]types.StatusBlock, rerr error) {
if err := r.exposeMachinePorts(ctr.config.PortMappings); err != nil {
return nil, err
}
@ -139,7 +139,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS *jailNetNS) (status map[s
}
netOpts := ctr.getNetworkOptions(networks)
netStatus, err := r.setUpNetwork(ctrNS.Name, netOpts)
netStatus, err := r.setUpNetwork(ctrNS, netOpts)
if err != nil {
return nil, err
}
@ -148,16 +148,16 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS *jailNetNS) (status map[s
}
// Create and configure a new network namespace for a container
func (r *Runtime) createNetNS(ctr *Container) (n *jailNetNS, q map[string]types.StatusBlock, retErr error) {
func (r *Runtime) createNetNS(ctr *Container) (n string, q map[string]types.StatusBlock, retErr error) {
b := make([]byte, 16)
_, err := rand.Reader.Read(b)
if err != nil {
return nil, nil, fmt.Errorf("failed to generate random vnet name: %v", err)
return "", nil, fmt.Errorf("failed to generate random vnet name: %v", err)
}
ctrNS := &jailNetNS{Name: fmt.Sprintf("vnet-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])}
netns := fmt.Sprintf("vnet-%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
jconf := jail.NewConfig()
jconf.Set("name", ctrNS.Name)
jconf.Set("name", netns)
jconf.Set("vnet", jail.NEW)
jconf.Set("children.max", 1)
jconf.Set("persist", true)
@ -168,22 +168,22 @@ func (r *Runtime) createNetNS(ctr *Container) (n *jailNetNS, q map[string]types.
jconf.Set("securelevel", -1)
j, err := jail.Create(jconf)
if err != nil {
return nil, nil, fmt.Errorf("Failed to create vnet jail %s for container %s: %w", ctrNS.Name, ctr.ID(), err)
return "", nil, fmt.Errorf("Failed to create vnet jail %s for container %s: %w", netns, ctr.ID(), err)
}
logrus.Debugf("Created vnet jail %s for container %s", ctrNS.Name, ctr.ID())
logrus.Debugf("Created vnet jail %s for container %s", netns, ctr.ID())
var networkStatus map[string]types.StatusBlock
networkStatus, err = r.configureNetNS(ctr, ctrNS)
networkStatus, err = r.configureNetNS(ctr, netns)
if err != nil {
jconf := jail.NewConfig()
jconf.Set("persist", false)
if err := j.Set(jconf); err != nil {
// Log this error and return the error from configureNetNS
logrus.Errorf("failed to destroy vnet jail %s: %w", ctrNS.Name, err)
logrus.Errorf("failed to destroy vnet jail %s: %w", netns, err)
}
}
return ctrNS, networkStatus, err
return netns, networkStatus, err
}
// Tear down a network namespace, undoing all state associated with it.
@ -196,28 +196,28 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
return err
}
if ctr.state.NetNS != nil {
if ctr.state.NetNS != "" {
// Rather than destroying the jail immediately, reset the
// persist flag so that it will live until the container is
// done.
netjail, err := jail.FindByName(ctr.state.NetNS.Name)
netjail, err := jail.FindByName(ctr.state.NetNS)
if err != nil {
return fmt.Errorf("finding network jail %s: %w", ctr.state.NetNS.Name, err)
return fmt.Errorf("finding network jail %s: %w", ctr.state.NetNS, err)
}
jconf := jail.NewConfig()
jconf.Set("persist", false)
if err := netjail.Set(jconf); err != nil {
return fmt.Errorf("releasing network jail %s: %w", ctr.state.NetNS.Name, err)
return fmt.Errorf("releasing network jail %s: %w", ctr.state.NetNS, err)
}
ctr.state.NetNS = nil
ctr.state.NetNS = ""
}
return nil
}
func getContainerNetIO(ctr *Container) (*LinkStatistics64, error) {
if ctr.state.NetNS == nil {
if ctr.state.NetNS == "" {
// If NetNS is nil, it was set as none, and no netNS
// was set up this is a valid state and thus return no
// error, nor any statistics
@ -225,7 +225,7 @@ func getContainerNetIO(ctr *Container) (*LinkStatistics64, error) {
}
// FIXME get the interface from the container netstatus
cmd := exec.Command("jexec", ctr.state.NetNS.Name, "netstat", "-bI", "eth0", "--libxo", "json")
cmd := exec.Command("jexec", ctr.state.NetNS, "netstat", "-bI", "eth0", "--libxo", "json")
out, err := cmd.Output()
if err != nil {
return nil, err
@ -255,11 +255,7 @@ func getContainerNetIO(ctr *Container) (*LinkStatistics64, error) {
}
func (c *Container) joinedNetworkNSPath() string {
if c.state.NetNS != nil {
return c.state.NetNS.Name
} else {
return ""
}
return c.state.NetNS
}
func (c *Container) inspectJoinedNetworkNS(networkns string) (q types.StatusBlock, retErr error) {

View File

@ -281,7 +281,7 @@ func (r *RootlessNetNS) Cleanup(runtime *Runtime) error {
// only check for an active netns, we cannot use the container state
// because not running does not mean that the netns does not need cleanup
// only if the netns is empty we know that we do not need cleanup
return c.state.NetNS != nil
return c.state.NetNS != ""
}
ctrs, err := runtime.GetContainers(activeNetns)
if err != nil {
@ -548,7 +548,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
}
// Create and configure a new network namespace for a container
func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[string]types.StatusBlock, rerr error) {
func (r *Runtime) configureNetNS(ctr *Container, ctrNS string) (status map[string]types.StatusBlock, rerr error) {
if err := r.exposeMachinePorts(ctr.config.PortMappings); err != nil {
return nil, err
}
@ -577,7 +577,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
}
netOpts := ctr.getNetworkOptions(networks)
netStatus, err := r.setUpNetwork(ctrNS.Path(), netOpts)
netStatus, err := r.setUpNetwork(ctrNS, netOpts)
if err != nil {
return nil, err
}
@ -587,21 +587,20 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
// 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()
// TODO: support slirp4netns port forwarder as well
// make sure to fix this in container.handleRestartPolicy() as well
// Important we have to call this after r.setUpNetwork() so that
// we can use the proper netStatus
err = r.setupRootlessPortMappingViaRLK(ctr, netnsPath, netStatus)
err = r.setupRootlessPortMappingViaRLK(ctr, ctrNS, netStatus)
}
return netStatus, err
}
// Create and configure a new network namespace for a container
func (r *Runtime) createNetNS(ctr *Container) (n ns.NetNS, q map[string]types.StatusBlock, retErr error) {
func (r *Runtime) createNetNS(ctr *Container) (n string, q map[string]types.StatusBlock, retErr error) {
ctrNS, err := netns.NewNS()
if err != nil {
return nil, nil, fmt.Errorf("creating network namespace for container %s: %w", ctr.ID(), err)
return "", nil, fmt.Errorf("creating network namespace for container %s: %w", ctr.ID(), err)
}
defer func() {
if retErr != nil {
@ -617,8 +616,8 @@ func (r *Runtime) createNetNS(ctr *Container) (n ns.NetNS, q map[string]types.St
logrus.Debugf("Made network namespace at %s for container %s", ctrNS.Path(), ctr.ID())
var networkStatus map[string]types.StatusBlock
networkStatus, err = r.configureNetNS(ctr, ctrNS)
return ctrNS, networkStatus, err
networkStatus, err = r.configureNetNS(ctr, ctrNS.Path())
return ctrNS.Path(), networkStatus, err
}
// Configure the network namespace using the container process
@ -652,46 +651,14 @@ func (r *Runtime) setupNetNS(ctr *Container) error {
return fmt.Errorf("cannot mount %s: %w", nsPath, err)
}
netNS, err := ns.GetNS(nsPath)
if err != nil {
return err
}
networkStatus, err := r.configureNetNS(ctr, netNS)
networkStatus, err := r.configureNetNS(ctr, nsPath)
// Assign NetNS attributes to container
ctr.state.NetNS = netNS
ctr.state.NetNS = nsPath
ctr.state.NetworkStatus = networkStatus
return err
}
// Join an existing network namespace
func joinNetNS(path string) (ns.NetNS, error) {
netNS, err := ns.GetNS(path)
if err != nil {
return nil, fmt.Errorf("retrieving network namespace at %s: %w", path, err)
}
return netNS, nil
}
// Close a network namespace.
// Differs from teardownNetNS() in that it will not attempt to undo the setup of
// the namespace, but will instead only close the open file descriptor
func (r *Runtime) closeNetNS(ctr *Container) error {
if ctr.state.NetNS == nil {
// The container has no network namespace, we're set
return nil
}
if err := ctr.state.NetNS.Close(); err != nil {
return fmt.Errorf("closing network namespace for container %s: %w", ctr.ID(), err)
}
ctr.state.NetNS = nil
return nil
}
// Tear down a network namespace, undoing all state associated with it.
func (r *Runtime) teardownNetNS(ctr *Container) error {
if err := r.unexposeMachinePorts(ctr.config.PortMappings); err != nil {
@ -705,29 +672,21 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
prevErr := r.teardownNetwork(ctr)
// First unmount the namespace
if err := netns.UnmountNS(ctr.state.NetNS.Path()); err != nil {
if err := netns.UnmountNS(ctr.state.NetNS); err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
return fmt.Errorf("unmounting network namespace for container %s: %w", ctr.ID(), err)
}
// Now close the open file descriptor
if err := ctr.state.NetNS.Close(); err != nil {
if prevErr != nil {
logrus.Error(prevErr)
}
return fmt.Errorf("closing network namespace for container %s: %w", ctr.ID(), err)
}
ctr.state.NetNS = nil
ctr.state.NetNS = ""
return prevErr
}
func getContainerNetNS(ctr *Container) (string, *Container, error) {
if ctr.state.NetNS != nil {
return ctr.state.NetNS.Path(), nil, nil
if ctr.state.NetNS != "" {
return ctr.state.NetNS, nil, nil
}
if ctr.config.NetNsCtr != "" {
c, err := ctr.runtime.GetContainer(ctr.config.NetNsCtr)

View File

@ -12,11 +12,10 @@ import (
"os/exec"
"strings"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/sirupsen/logrus"
)
func (r *Runtime) setupPasta(ctr *Container, netns ns.NetNS) error {
func (r *Runtime) setupPasta(ctr *Container, netns string) error {
var NoTCPInitPorts = true
var NoUDPInitPorts = true
var NoTCPNamespacePorts = true
@ -93,7 +92,7 @@ func (r *Runtime) setupPasta(ctr *Container, netns ns.NetNS) error {
cmdArgs = append(cmdArgs, "--no-map-gw")
}
cmdArgs = append(cmdArgs, "--netns", netns.Path())
cmdArgs = append(cmdArgs, "--netns", netns)
logrus.Debugf("pasta arguments: %s", strings.Join(cmdArgs, " "))

View File

@ -212,7 +212,7 @@ func createBasicSlirp4netnsCmdArgs(options *slirp4netnsNetworkOptions, features
}
// setupSlirp4netns can be called in rootful as well as in rootless
func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
func (r *Runtime) setupSlirp4netns(ctr *Container, netns string) error {
path := r.config.Engine.NetworkCmdPath
if path == "" {
var err error
@ -267,7 +267,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
if err != nil {
return fmt.Errorf("failed to create rootless network sync pipe: %w", err)
}
netnsPath = netns.Path()
netnsPath = netns
cmdArgs = append(cmdArgs, "--netns-type=path", netnsPath, "tap0")
} else {
defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncR)