mirror of
https://github.com/containers/podman.git
synced 2025-06-26 12:56:45 +08:00
Merge pull request #16756 from Luap99/netns-db
libpod: move NetNS into state db instead of extra bucket
This commit is contained in:
@ -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)
|
||||
|
@ -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 {
|
||||
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 {
|
||||
|
@ -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.
|
||||
// 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"`
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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, " "))
|
||||
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user