mirror of https://github.com/containers/podman.git
libpod: move NetNS into state db instead of extra bucket
This should simplify the db logic. We no longer need a extra db bucket for the netns, it is still supported in read only mode for backwards compat. The old version required us to always open the netns before we could attach it to the container state struct which caused problem in some cases were the netns was no longer valid. Now we use the netns as string throughout the code, this allow us to only open it when needed reducing possible errors. [NO NEW TESTS NEEDED] Existing tests should cover it and it is only a flake so hard to reproduce the error. Fixes #16140 Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
parent
fd7049b187
commit
0bc3d35791
|
@ -5,7 +5,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -817,7 +816,6 @@ func (s *BoltState) UpdateContainer(ctr *Container) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
newState := new(ContainerState)
|
newState := new(ContainerState)
|
||||||
netNSPath := ""
|
|
||||||
|
|
||||||
ctrID := []byte(ctr.ID())
|
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)
|
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)
|
netNSBytes := ctrToUpdate.Get(netNSKey)
|
||||||
if netNSBytes != nil {
|
if netNSBytes != nil && newState.NetNS == "" {
|
||||||
netNSPath = string(netNSBytes)
|
newState.NetNS = string(netNSBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -859,15 +858,6 @@ func (s *BoltState) UpdateContainer(ctr *Container) error {
|
||||||
return err
|
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
|
// New state compiled successfully, swap it into the current state
|
||||||
ctr.state = newState
|
ctr.state = newState
|
||||||
|
|
||||||
|
@ -892,7 +882,7 @@ func (s *BoltState) SaveContainer(ctr *Container) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("marshalling container %s state to JSON: %w", ctr.ID(), err)
|
return fmt.Errorf("marshalling container %s state to JSON: %w", ctr.ID(), err)
|
||||||
}
|
}
|
||||||
netNSPath := getNetNSPath(ctr)
|
netNSPath := ctr.state.NetNS
|
||||||
|
|
||||||
ctrID := []byte(ctr.ID())
|
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)
|
return fmt.Errorf("updating container %s state in DB: %w", ctr.ID(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if netNSPath != "" {
|
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 {
|
|
||||||
// Delete the existing network namespace
|
// Delete the existing network namespace
|
||||||
if err := ctrToSave.Delete(netNSKey); err != nil {
|
if err := ctrToSave.Delete(netNSKey); err != nil {
|
||||||
return fmt.Errorf("removing network namespace path for container %s in DB: %w", ctr.ID(), err)
|
return fmt.Errorf("removing network namespace path for container %s in DB: %w", ctr.ID(), err)
|
||||||
|
|
|
@ -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 ""
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -590,7 +590,6 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("marshalling container %s state to JSON: %w", ctr.ID(), err)
|
return fmt.Errorf("marshalling container %s state to JSON: %w", ctr.ID(), err)
|
||||||
}
|
}
|
||||||
netNSPath := getNetNSPath(ctr)
|
|
||||||
dependsCtrs := ctr.Dependencies()
|
dependsCtrs := ctr.Dependencies()
|
||||||
|
|
||||||
ctrID := []byte(ctr.ID())
|
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)
|
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 {
|
if len(networks) > 0 {
|
||||||
ctrNetworksBkt, err := newCtrBkt.CreateBucket(networksBkt)
|
ctrNetworksBkt, err := newCtrBkt.CreateBucket(networksBkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -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 ""
|
|
||||||
}
|
|
|
@ -169,6 +169,8 @@ type ContainerState struct {
|
||||||
// Podman.
|
// Podman.
|
||||||
// These are DEPRECATED and will be removed in a future release.
|
// These are DEPRECATED and will be removed in a future release.
|
||||||
LegacyExecSessions map[string]*legacyExecSession `json:"execSessions,omitempty"`
|
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
|
// NetworkStatusOld contains the configuration results for all networks
|
||||||
// the pod is attached to. Only populated if we created a network
|
// the pod is attached to. Only populated if we created a network
|
||||||
// namespace for the container, and the network namespace is currently
|
// namespace for the container, and the network namespace is currently
|
||||||
|
@ -228,9 +230,6 @@ type ContainerState struct {
|
||||||
// `podman-play-kube`.
|
// `podman-play-kube`.
|
||||||
Service Service
|
Service Service
|
||||||
|
|
||||||
// containerPlatformState holds platform-specific container state.
|
|
||||||
containerPlatformState
|
|
||||||
|
|
||||||
// Following checkpoint/restore related information is displayed
|
// Following checkpoint/restore related information is displayed
|
||||||
// if the container has been checkpointed or restored.
|
// if the container has been checkpointed or restored.
|
||||||
CheckpointedTime time.Time `json:"checkpointedTime,omitempty"`
|
CheckpointedTime time.Time `json:"checkpointedTime,omitempty"`
|
||||||
|
|
|
@ -3,29 +3,12 @@
|
||||||
|
|
||||||
package libpod
|
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) {
|
func networkDisabled(c *Container) (bool, error) {
|
||||||
if c.config.CreateNetNS {
|
if c.config.CreateNetNS {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
if !c.config.PostConfigureNetNS {
|
if !c.config.PostConfigureNetNS {
|
||||||
return c.state.NetNS != nil, nil
|
return c.state.NetNS != "", nil
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -625,6 +625,9 @@ func resetState(state *ContainerState) {
|
||||||
state.StartupHCPassed = false
|
state.StartupHCPassed = false
|
||||||
state.StartupHCSuccessCount = 0
|
state.StartupHCSuccessCount = 0
|
||||||
state.StartupHCFailureCount = 0
|
state.StartupHCFailureCount = 0
|
||||||
|
state.NetNS = ""
|
||||||
|
state.NetworkStatus = nil
|
||||||
|
state.NetworkStatusOld = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh refreshes the container's state after a restart.
|
// Refresh refreshes the container's state after a restart.
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (c *Container) unmountSHM(path string) error {
|
||||||
func (c *Container) prepare() error {
|
func (c *Container) prepare() error {
|
||||||
var (
|
var (
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
ctrNS *jailNetNS
|
ctrNS string
|
||||||
networkStatus map[string]types.StatusBlock
|
networkStatus map[string]types.StatusBlock
|
||||||
createNetNSErr, mountStorageErr error
|
createNetNSErr, mountStorageErr error
|
||||||
mountPoint string
|
mountPoint string
|
||||||
|
@ -48,7 +48,7 @@ func (c *Container) prepare() error {
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
// Set up network namespace if not already set up
|
// 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 {
|
if c.config.CreateNetNS && noNetNS && !c.config.PostConfigureNetNS {
|
||||||
ctrNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
|
ctrNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
|
||||||
if createNetNSErr != nil {
|
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)
|
return fmt.Errorf("retrieving dependency %s of container %s from state: %w", ctr, c.ID(), err)
|
||||||
}
|
}
|
||||||
c.runtime.state.UpdateContainer(nsCtr)
|
c.runtime.state.UpdateContainer(nsCtr)
|
||||||
if nsCtr.state.NetNS != nil {
|
if nsCtr.state.NetNS != "" {
|
||||||
g.AddAnnotation("org.freebsd.parentJail", nsCtr.state.NetNS.Name)
|
g.AddAnnotation("org.freebsd.parentJail", nsCtr.state.NetNS)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ func openDirectory(path string) (fd int, err error) {
|
||||||
|
|
||||||
func (c *Container) addNetworkNamespace(g *generate.Generator) error {
|
func (c *Container) addNetworkNamespace(g *generate.Generator) error {
|
||||||
if c.config.CreateNetNS {
|
if c.config.CreateNetNS {
|
||||||
if c.state.NetNS == nil {
|
if c.state.NetNS == "" {
|
||||||
// This should not happen since network setup
|
// This should not happen since network setup
|
||||||
// errors should be propagated correctly from
|
// errors should be propagated correctly from
|
||||||
// (*Runtime).createNetNS. Check for it anyway
|
// (*Runtime).createNetNS. Check for it anyway
|
||||||
|
@ -201,7 +201,7 @@ func (c *Container) addNetworkNamespace(g *generate.Generator) error {
|
||||||
// the past (see #16333).
|
// the past (see #16333).
|
||||||
return fmt.Errorf("Inconsistent state: c.config.CreateNetNS is set but c.state.NetNS is nil")
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -286,7 +286,7 @@ func (c *Container) isSlirp4netnsIPv6() (bool, error) {
|
||||||
|
|
||||||
// check for net=none
|
// check for net=none
|
||||||
func (c *Container) hasNetNone() bool {
|
func (c *Container) hasNetNone() bool {
|
||||||
return c.state.NetNS == nil
|
return c.state.NetNS == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func setVolumeAtime(mountPoint string, st os.FileInfo) error {
|
func setVolumeAtime(mountPoint string, st os.FileInfo) error {
|
||||||
|
@ -310,8 +310,8 @@ func (c *Container) getConmonPidFd() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) jailName() string {
|
func (c *Container) jailName() string {
|
||||||
if c.state.NetNS != nil {
|
if c.state.NetNS != "" {
|
||||||
return c.state.NetNS.Name + "." + c.ID()
|
return c.state.NetNS + "." + c.ID()
|
||||||
} else {
|
} else {
|
||||||
return c.ID()
|
return c.ID()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containernetworking/plugins/pkg/ns"
|
|
||||||
"github.com/containers/common/libnetwork/types"
|
"github.com/containers/common/libnetwork/types"
|
||||||
"github.com/containers/common/pkg/cgroups"
|
"github.com/containers/common/pkg/cgroups"
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
|
@ -56,7 +55,7 @@ func (c *Container) unmountSHM(mount string) error {
|
||||||
func (c *Container) prepare() error {
|
func (c *Container) prepare() error {
|
||||||
var (
|
var (
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
netNS ns.NetNS
|
netNS string
|
||||||
networkStatus map[string]types.StatusBlock
|
networkStatus map[string]types.StatusBlock
|
||||||
createNetNSErr, mountStorageErr error
|
createNetNSErr, mountStorageErr error
|
||||||
mountPoint string
|
mountPoint string
|
||||||
|
@ -68,7 +67,7 @@ func (c *Container) prepare() error {
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
// Set up network namespace if not already set up
|
// 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 {
|
if c.config.CreateNetNS && noNetNS && !c.config.PostConfigureNetNS {
|
||||||
netNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
|
netNS, networkStatus, createNetNSErr = c.runtime.createNetNS(c)
|
||||||
if createNetNSErr != nil {
|
if createNetNSErr != nil {
|
||||||
|
@ -159,7 +158,7 @@ func (c *Container) cleanupNetwork() error {
|
||||||
if netDisabled {
|
if netDisabled {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if c.state.NetNS == nil {
|
if c.state.NetNS == "" {
|
||||||
logrus.Debugf("Network is already cleaned up, skipping...")
|
logrus.Debugf("Network is already cleaned up, skipping...")
|
||||||
return nil
|
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)
|
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.NetworkStatus = nil
|
||||||
c.state.NetworkStatusOld = 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
|
// 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
|
// 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 {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -430,7 +429,7 @@ func (c *Container) addNetworkNamespace(g *generate.Generator) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} 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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,9 @@
|
||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/containernetworking/plugins/pkg/ns"
|
|
||||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
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) {
|
func networkDisabled(c *Container) (bool, error) {
|
||||||
if c.config.CreateNetNS {
|
if c.config.CreateNetNS {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
|
@ -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
|
// Tear down a container's network backend configuration, but do not tear down the
|
||||||
// namespace itself.
|
// namespace itself.
|
||||||
func (r *Runtime) teardownNetwork(ctr *Container) error {
|
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
|
// The container has no network namespace, we're set
|
||||||
return nil
|
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()
|
networks, err := ctr.networks()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -136,7 +136,7 @@ func (r *Runtime) teardownNetwork(ctr *Container) error {
|
||||||
if !ctr.config.NetMode.IsSlirp4netns() &&
|
if !ctr.config.NetMode.IsSlirp4netns() &&
|
||||||
!ctr.config.NetMode.IsPasta() && len(networks) > 0 {
|
!ctr.config.NetMode.IsPasta() && len(networks) > 0 {
|
||||||
netOpts := ctr.getNetworkOptions(networks)
|
netOpts := ctr.getNetworkOptions(networks)
|
||||||
return r.teardownNetworkBackend(ctr.state.NetNS.Path(), netOpts)
|
return r.teardownNetworkBackend(ctr.state.NetNS, netOpts)
|
||||||
}
|
}
|
||||||
return nil
|
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
|
// Only works on containers with bridge networking at present, though in the future we could
|
||||||
// extend this to stop + restart slirp4netns
|
// extend this to stop + restart slirp4netns
|
||||||
func (r *Runtime) reloadContainerNetwork(ctr *Container) (map[string]types.StatusBlock, error) {
|
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)
|
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 {
|
if err := isBridgeNetMode(ctr.config.NetMode); err != nil {
|
||||||
|
@ -234,7 +234,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.state.NetNS == nil {
|
if c.state.NetNS == "" {
|
||||||
if networkNSPath := c.joinedNetworkNSPath(); networkNSPath != "" {
|
if networkNSPath := c.joinedNetworkNSPath(); networkNSPath != "" {
|
||||||
if result, err := c.inspectJoinedNetworkNS(networkNSPath); err == nil {
|
if result, err := c.inspectJoinedNetworkNS(networkNSPath); err == nil {
|
||||||
// fallback to dummy configuration
|
// fallback to dummy configuration
|
||||||
|
@ -262,7 +262,7 @@ func (c *Container) getContainerNetworkInfo() (*define.InspectNetworkSettings, e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set network namespace path
|
// Set network namespace path
|
||||||
settings.SandboxKey = c.state.NetNS.Path()
|
settings.SandboxKey = c.state.NetNS
|
||||||
|
|
||||||
netStatus := c.getNetworkStatus()
|
netStatus := c.getNetworkStatus()
|
||||||
// If this is empty, we're probably slirp4netns
|
// If this is empty, we're probably slirp4netns
|
||||||
|
@ -394,7 +394,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
|
||||||
return nil
|
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)
|
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],
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ func (c *Container) NetworkConnect(nameOrID, netName string, netOpts types.PerNe
|
||||||
if !c.ensureState(define.ContainerStateRunning, define.ContainerStateCreated) {
|
if !c.ensureState(define.ContainerStateRunning, define.ContainerStateCreated) {
|
||||||
return nil
|
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)
|
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,
|
netName: netOpts,
|
||||||
}
|
}
|
||||||
|
|
||||||
results, err := c.runtime.setUpNetwork(c.state.NetNS.Path(), opts)
|
results, err := c.runtime.setUpNetwork(c.state.NetNS, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ func (r *Runtime) setupNetNS(ctr *Container) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and configure a new network namespace for a container
|
// 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 {
|
if err := r.exposeMachinePorts(ctr.config.PortMappings); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS *jailNetNS) (status map[s
|
||||||
}
|
}
|
||||||
|
|
||||||
netOpts := ctr.getNetworkOptions(networks)
|
netOpts := ctr.getNetworkOptions(networks)
|
||||||
netStatus, err := r.setUpNetwork(ctrNS.Name, netOpts)
|
netStatus, err := r.setUpNetwork(ctrNS, netOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// 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)
|
b := make([]byte, 16)
|
||||||
_, err := rand.Reader.Read(b)
|
_, err := rand.Reader.Read(b)
|
||||||
if err != nil {
|
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 := jail.NewConfig()
|
||||||
jconf.Set("name", ctrNS.Name)
|
jconf.Set("name", netns)
|
||||||
jconf.Set("vnet", jail.NEW)
|
jconf.Set("vnet", jail.NEW)
|
||||||
jconf.Set("children.max", 1)
|
jconf.Set("children.max", 1)
|
||||||
jconf.Set("persist", true)
|
jconf.Set("persist", true)
|
||||||
|
@ -168,22 +168,22 @@ func (r *Runtime) createNetNS(ctr *Container) (n *jailNetNS, q map[string]types.
|
||||||
jconf.Set("securelevel", -1)
|
jconf.Set("securelevel", -1)
|
||||||
j, err := jail.Create(jconf)
|
j, err := jail.Create(jconf)
|
||||||
if err != nil {
|
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
|
var networkStatus map[string]types.StatusBlock
|
||||||
networkStatus, err = r.configureNetNS(ctr, ctrNS)
|
networkStatus, err = r.configureNetNS(ctr, netns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
jconf := jail.NewConfig()
|
jconf := jail.NewConfig()
|
||||||
jconf.Set("persist", false)
|
jconf.Set("persist", false)
|
||||||
if err := j.Set(jconf); err != nil {
|
if err := j.Set(jconf); err != nil {
|
||||||
// Log this error and return the error from configureNetNS
|
// 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.
|
// Tear down a network namespace, undoing all state associated with it.
|
||||||
|
@ -196,28 +196,28 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctr.state.NetNS != nil {
|
if ctr.state.NetNS != "" {
|
||||||
// Rather than destroying the jail immediately, reset the
|
// Rather than destroying the jail immediately, reset the
|
||||||
// persist flag so that it will live until the container is
|
// persist flag so that it will live until the container is
|
||||||
// done.
|
// done.
|
||||||
netjail, err := jail.FindByName(ctr.state.NetNS.Name)
|
netjail, err := jail.FindByName(ctr.state.NetNS)
|
||||||
if err != nil {
|
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 := jail.NewConfig()
|
||||||
jconf.Set("persist", false)
|
jconf.Set("persist", false)
|
||||||
if err := netjail.Set(jconf); err != nil {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainerNetIO(ctr *Container) (*LinkStatistics64, error) {
|
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
|
// If NetNS is nil, it was set as none, and no netNS
|
||||||
// was set up this is a valid state and thus return no
|
// was set up this is a valid state and thus return no
|
||||||
// error, nor any statistics
|
// error, nor any statistics
|
||||||
|
@ -225,7 +225,7 @@ func getContainerNetIO(ctr *Container) (*LinkStatistics64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME get the interface from the container netstatus
|
// 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()
|
out, err := cmd.Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -255,11 +255,7 @@ func getContainerNetIO(ctr *Container) (*LinkStatistics64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) joinedNetworkNSPath() string {
|
func (c *Container) joinedNetworkNSPath() string {
|
||||||
if c.state.NetNS != nil {
|
return c.state.NetNS
|
||||||
return c.state.NetNS.Name
|
|
||||||
} else {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) inspectJoinedNetworkNS(networkns string) (q types.StatusBlock, retErr error) {
|
func (c *Container) inspectJoinedNetworkNS(networkns string) (q types.StatusBlock, retErr error) {
|
||||||
|
|
|
@ -281,7 +281,7 @@ func (r *RootlessNetNS) Cleanup(runtime *Runtime) error {
|
||||||
// only check for an active netns, we cannot use the container state
|
// 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
|
// 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
|
// 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)
|
ctrs, err := runtime.GetContainers(activeNetns)
|
||||||
if err != nil {
|
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
|
// 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 {
|
if err := r.exposeMachinePorts(ctr.config.PortMappings); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -577,7 +577,7 @@ func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) (status map[str
|
||||||
}
|
}
|
||||||
|
|
||||||
netOpts := ctr.getNetworkOptions(networks)
|
netOpts := ctr.getNetworkOptions(networks)
|
||||||
netStatus, err := r.setUpNetwork(ctrNS.Path(), netOpts)
|
netStatus, err := r.setUpNetwork(ctrNS, netOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// not set up port because they are still active
|
||||||
if rootless.IsRootless() && len(ctr.config.PortMappings) > 0 && ctr.getNetworkStatus() == nil {
|
if rootless.IsRootless() && len(ctr.config.PortMappings) > 0 && ctr.getNetworkStatus() == nil {
|
||||||
// set up port forwarder for rootless netns
|
// set up port forwarder for rootless netns
|
||||||
netnsPath := ctrNS.Path()
|
|
||||||
// TODO: support slirp4netns port forwarder as well
|
// TODO: support slirp4netns port forwarder as well
|
||||||
// make sure to fix this in container.handleRestartPolicy() as well
|
// make sure to fix this in container.handleRestartPolicy() as well
|
||||||
// Important we have to call this after r.setUpNetwork() so that
|
// Important we have to call this after r.setUpNetwork() so that
|
||||||
// we can use the proper netStatus
|
// we can use the proper netStatus
|
||||||
err = r.setupRootlessPortMappingViaRLK(ctr, netnsPath, netStatus)
|
err = r.setupRootlessPortMappingViaRLK(ctr, ctrNS, netStatus)
|
||||||
}
|
}
|
||||||
return netStatus, err
|
return netStatus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and configure a new network namespace for a container
|
// 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()
|
ctrNS, err := netns.NewNS()
|
||||||
if err != nil {
|
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() {
|
defer func() {
|
||||||
if retErr != nil {
|
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())
|
logrus.Debugf("Made network namespace at %s for container %s", ctrNS.Path(), ctr.ID())
|
||||||
|
|
||||||
var networkStatus map[string]types.StatusBlock
|
var networkStatus map[string]types.StatusBlock
|
||||||
networkStatus, err = r.configureNetNS(ctr, ctrNS)
|
networkStatus, err = r.configureNetNS(ctr, ctrNS.Path())
|
||||||
return ctrNS, networkStatus, err
|
return ctrNS.Path(), networkStatus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure the network namespace using the container process
|
// 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)
|
return fmt.Errorf("cannot mount %s: %w", nsPath, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
netNS, err := ns.GetNS(nsPath)
|
networkStatus, err := r.configureNetNS(ctr, nsPath)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
networkStatus, err := r.configureNetNS(ctr, netNS)
|
|
||||||
|
|
||||||
// Assign NetNS attributes to container
|
// Assign NetNS attributes to container
|
||||||
ctr.state.NetNS = netNS
|
ctr.state.NetNS = nsPath
|
||||||
ctr.state.NetworkStatus = networkStatus
|
ctr.state.NetworkStatus = networkStatus
|
||||||
return err
|
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.
|
// Tear down a network namespace, undoing all state associated with it.
|
||||||
func (r *Runtime) teardownNetNS(ctr *Container) error {
|
func (r *Runtime) teardownNetNS(ctr *Container) error {
|
||||||
if err := r.unexposeMachinePorts(ctr.config.PortMappings); err != nil {
|
if err := r.unexposeMachinePorts(ctr.config.PortMappings); err != nil {
|
||||||
|
@ -705,29 +672,21 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
|
||||||
prevErr := r.teardownNetwork(ctr)
|
prevErr := r.teardownNetwork(ctr)
|
||||||
|
|
||||||
// First unmount the namespace
|
// 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 {
|
if prevErr != nil {
|
||||||
logrus.Error(prevErr)
|
logrus.Error(prevErr)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("unmounting network namespace for container %s: %w", ctr.ID(), err)
|
return fmt.Errorf("unmounting network namespace for container %s: %w", ctr.ID(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now close the open file descriptor
|
ctr.state.NetNS = ""
|
||||||
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
|
|
||||||
|
|
||||||
return prevErr
|
return prevErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContainerNetNS(ctr *Container) (string, *Container, error) {
|
func getContainerNetNS(ctr *Container) (string, *Container, error) {
|
||||||
if ctr.state.NetNS != nil {
|
if ctr.state.NetNS != "" {
|
||||||
return ctr.state.NetNS.Path(), nil, nil
|
return ctr.state.NetNS, nil, nil
|
||||||
}
|
}
|
||||||
if ctr.config.NetNsCtr != "" {
|
if ctr.config.NetNsCtr != "" {
|
||||||
c, err := ctr.runtime.GetContainer(ctr.config.NetNsCtr)
|
c, err := ctr.runtime.GetContainer(ctr.config.NetNsCtr)
|
||||||
|
|
|
@ -12,11 +12,10 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containernetworking/plugins/pkg/ns"
|
|
||||||
"github.com/sirupsen/logrus"
|
"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 NoTCPInitPorts = true
|
||||||
var NoUDPInitPorts = true
|
var NoUDPInitPorts = true
|
||||||
var NoTCPNamespacePorts = 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, "--no-map-gw")
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdArgs = append(cmdArgs, "--netns", netns.Path())
|
cmdArgs = append(cmdArgs, "--netns", netns)
|
||||||
|
|
||||||
logrus.Debugf("pasta arguments: %s", strings.Join(cmdArgs, " "))
|
logrus.Debugf("pasta arguments: %s", strings.Join(cmdArgs, " "))
|
||||||
|
|
||||||
|
|
|
@ -212,7 +212,7 @@ func createBasicSlirp4netnsCmdArgs(options *slirp4netnsNetworkOptions, features
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupSlirp4netns can be called in rootful as well as in rootless
|
// 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
|
path := r.config.Engine.NetworkCmdPath
|
||||||
if path == "" {
|
if path == "" {
|
||||||
var err error
|
var err error
|
||||||
|
@ -267,7 +267,7 @@ func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to create rootless network sync pipe: %w", err)
|
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")
|
cmdArgs = append(cmdArgs, "--netns-type=path", netnsPath, "tap0")
|
||||||
} else {
|
} else {
|
||||||
defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncR)
|
defer errorhandling.CloseQuiet(ctr.rootlessSlirpSyncR)
|
||||||
|
|
Loading…
Reference in New Issue