mirror of
https://github.com/containers/podman.git
synced 2025-06-23 18:59:30 +08:00
Merge pull request #9455 from Luap99/fix-network-ids
Fix podman network IDs handling
This commit is contained in:
@ -81,9 +81,9 @@ func GetCNIConfigPathByNameOrID(config *config.Config, name string) (string, err
|
|||||||
return "", errors.Wrap(define.ErrNoSuchNetwork, fmt.Sprintf("unable to find network configuration for %s", name))
|
return "", errors.Wrap(define.ErrNoSuchNetwork, fmt.Sprintf("unable to find network configuration for %s", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadRawCNIConfByName reads the raw CNI configuration for a CNI
|
// ReadRawCNIConfByNameOrID reads the raw CNI configuration for a CNI
|
||||||
// network by name
|
// network by name
|
||||||
func ReadRawCNIConfByName(config *config.Config, name string) ([]byte, error) {
|
func ReadRawCNIConfByNameOrID(config *config.Config, name string) ([]byte, error) {
|
||||||
confFile, err := GetCNIConfigPathByNameOrID(config, name)
|
confFile, err := GetCNIConfigPathByNameOrID(config, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/libcni"
|
||||||
"github.com/containernetworking/cni/pkg/types"
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
|
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
|
||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
@ -222,7 +223,7 @@ func RemoveNetwork(config *config.Config, name string) error {
|
|||||||
|
|
||||||
// InspectNetwork reads a CNI config and returns its configuration
|
// InspectNetwork reads a CNI config and returns its configuration
|
||||||
func InspectNetwork(config *config.Config, name string) (map[string]interface{}, error) {
|
func InspectNetwork(config *config.Config, name string) (map[string]interface{}, error) {
|
||||||
b, err := ReadRawCNIConfByName(config, name)
|
b, err := ReadRawCNIConfByNameOrID(config, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -234,7 +235,7 @@ func InspectNetwork(config *config.Config, name string) (map[string]interface{},
|
|||||||
// Exists says whether a given network exists or not; it meant
|
// Exists says whether a given network exists or not; it meant
|
||||||
// specifically for restful responses so 404s can be used
|
// specifically for restful responses so 404s can be used
|
||||||
func Exists(config *config.Config, name string) (bool, error) {
|
func Exists(config *config.Config, name string) (bool, error) {
|
||||||
_, err := ReadRawCNIConfByName(config, name)
|
_, err := ReadRawCNIConfByNameOrID(config, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Cause(err) == define.ErrNoSuchNetwork {
|
if errors.Cause(err) == define.ErrNoSuchNetwork {
|
||||||
return false, nil
|
return false, nil
|
||||||
@ -277,3 +278,17 @@ func PruneNetworks(rtc *config.Config, usedNetworks map[string]bool) ([]*entitie
|
|||||||
}
|
}
|
||||||
return reports, nil
|
return reports, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NormalizeName translates a network ID into a name.
|
||||||
|
// If the input is a name the name is returned.
|
||||||
|
func NormalizeName(config *config.Config, nameOrID string) (string, error) {
|
||||||
|
path, err := GetCNIConfigPathByNameOrID(config, nameOrID)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
conf, err := libcni.ConfListFromFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return conf.Name, nil
|
||||||
|
}
|
||||||
|
@ -1139,13 +1139,12 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
exists, err := network.Exists(c.runtime.config, netName)
|
// check if network exists and if the input is a ID we get the name
|
||||||
|
// ocicni only uses names so it is important that we only use the name
|
||||||
|
netName, err = network.NormalizeName(c.runtime.config, netName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !exists {
|
|
||||||
return errors.Wrap(define.ErrNoSuchNetwork, netName)
|
|
||||||
}
|
|
||||||
|
|
||||||
index, nameExists := networks[netName]
|
index, nameExists := networks[netName]
|
||||||
if !nameExists && len(networks) > 0 {
|
if !nameExists && len(networks) > 0 {
|
||||||
@ -1196,13 +1195,12 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
exists, err := network.Exists(c.runtime.config, netName)
|
// check if network exists and if the input is a ID we get the name
|
||||||
|
// ocicni only uses names so it is important that we only use the name
|
||||||
|
netName, err = network.NormalizeName(c.runtime.config, netName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !exists {
|
|
||||||
return errors.Wrap(define.ErrNoSuchNetwork, netName)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.lock.Lock()
|
c.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer c.lock.Unlock()
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/containers/common/pkg/config"
|
"github.com/containers/common/pkg/config"
|
||||||
"github.com/containers/podman/v3/libpod/define"
|
"github.com/containers/podman/v3/libpod/define"
|
||||||
"github.com/containers/podman/v3/libpod/events"
|
"github.com/containers/podman/v3/libpod/events"
|
||||||
|
"github.com/containers/podman/v3/libpod/network"
|
||||||
"github.com/containers/podman/v3/libpod/shutdown"
|
"github.com/containers/podman/v3/libpod/shutdown"
|
||||||
"github.com/containers/podman/v3/pkg/cgroups"
|
"github.com/containers/podman/v3/pkg/cgroups"
|
||||||
"github.com/containers/podman/v3/pkg/domain/entities/reports"
|
"github.com/containers/podman/v3/pkg/domain/entities/reports"
|
||||||
@ -285,6 +286,21 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// normalize the networks to names
|
||||||
|
// ocicni only knows about cni names so we have to make
|
||||||
|
// sure we do not use ids internally
|
||||||
|
if len(ctr.config.Networks) > 0 {
|
||||||
|
netNames := make([]string, 0, len(ctr.config.Networks))
|
||||||
|
for _, nameOrID := range ctr.config.Networks {
|
||||||
|
netName, err := network.NormalizeName(r.config, nameOrID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
netNames = append(netNames, netName)
|
||||||
|
}
|
||||||
|
ctr.config.Networks = netNames
|
||||||
|
}
|
||||||
|
|
||||||
// Inhibit shutdown until creation succeeds
|
// Inhibit shutdown until creation succeeds
|
||||||
shutdown.Inhibit()
|
shutdown.Inhibit()
|
||||||
defer shutdown.Uninhibit()
|
defer shutdown.Uninhibit()
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
. "github.com/containers/podman/v3/test/utils"
|
. "github.com/containers/podman/v3/test/utils"
|
||||||
|
"github.com/containers/storage/pkg/stringid"
|
||||||
. "github.com/onsi/ginkgo"
|
. "github.com/onsi/ginkgo"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
)
|
)
|
||||||
@ -576,15 +577,20 @@ var _ = Describe("Podman create", func() {
|
|||||||
Expect(session.ExitCode()).ToNot(BeZero())
|
Expect(session.ExitCode()).ToNot(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
It("create container in pod with network should fail", func() {
|
It("create container in pod with network should not fail", func() {
|
||||||
name := "createwithnetwork"
|
name := "createwithnetwork"
|
||||||
pod := podmanTest.RunTopContainerInPod("", "new:"+name)
|
pod := podmanTest.RunTopContainerInPod("", "new:"+name)
|
||||||
pod.WaitWithDefaultTimeout()
|
pod.WaitWithDefaultTimeout()
|
||||||
Expect(pod.ExitCode()).To(BeZero())
|
Expect(pod.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
session := podmanTest.Podman([]string{"create", "--pod", name, "--network", "foobar", ALPINE, "top"})
|
netName := "pod" + stringid.GenerateNonCryptoID()
|
||||||
|
session := podmanTest.Podman([]string{"network", "create", netName})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
defer podmanTest.removeCNINetwork(netName)
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"create", "--pod", name, "--network", netName, ALPINE, "top"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
//Expect(session.ExitCode()).ToNot(BeZero())
|
|
||||||
Expect(session.ExitCode()).To(BeZero())
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -195,6 +195,55 @@ var _ = Describe("Podman network connect and disconnect", func() {
|
|||||||
Expect(exec.ExitCode()).To(BeZero())
|
Expect(exec.ExitCode()).To(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman network connect and run with network ID", func() {
|
||||||
|
SkipIfRemote("remote flakes to much I will fix this in another PR")
|
||||||
|
SkipIfRootless("network connect and disconnect are only rootful")
|
||||||
|
netName := "ID" + stringid.GenerateNonCryptoID()
|
||||||
|
session := podmanTest.Podman([]string{"network", "create", netName})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
defer podmanTest.removeCNINetwork(netName)
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
netID := session.OutputToString()
|
||||||
|
|
||||||
|
ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, ALPINE, "top"})
|
||||||
|
ctr.WaitWithDefaultTimeout()
|
||||||
|
Expect(ctr.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
|
||||||
|
exec.WaitWithDefaultTimeout()
|
||||||
|
Expect(exec.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
// Create a second network
|
||||||
|
newNetName := "ID2" + stringid.GenerateNonCryptoID()
|
||||||
|
session = podmanTest.Podman([]string{"network", "create", newNetName})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
defer podmanTest.removeCNINetwork(newNetName)
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + newNetName})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
newNetID := session.OutputToString()
|
||||||
|
|
||||||
|
connect := podmanTest.Podman([]string{"network", "connect", newNetID, "test"})
|
||||||
|
connect.WaitWithDefaultTimeout()
|
||||||
|
Expect(connect.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{.NetworkSettings.Networks}}"})
|
||||||
|
inspect.WaitWithDefaultTimeout()
|
||||||
|
Expect(inspect.ExitCode()).To(BeZero())
|
||||||
|
Expect(inspect.OutputToString()).To(ContainSubstring(netName))
|
||||||
|
Expect(inspect.OutputToString()).To(ContainSubstring(newNetName))
|
||||||
|
|
||||||
|
exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"})
|
||||||
|
exec.WaitWithDefaultTimeout()
|
||||||
|
Expect(exec.ExitCode()).To(BeZero())
|
||||||
|
})
|
||||||
|
|
||||||
It("podman network disconnect when not running", func() {
|
It("podman network disconnect when not running", func() {
|
||||||
SkipIfRootless("network connect and disconnect are only rootful")
|
SkipIfRootless("network connect and disconnect are only rootful")
|
||||||
netName1 := "aliasTest" + stringid.GenerateNonCryptoID()
|
netName1 := "aliasTest" + stringid.GenerateNonCryptoID()
|
||||||
@ -234,4 +283,40 @@ var _ = Describe("Podman network connect and disconnect", func() {
|
|||||||
exec.WaitWithDefaultTimeout()
|
exec.WaitWithDefaultTimeout()
|
||||||
Expect(exec.ExitCode()).ToNot(BeZero())
|
Expect(exec.ExitCode()).ToNot(BeZero())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman network disconnect and run with network ID", func() {
|
||||||
|
SkipIfRemote("remote flakes to much I will fix this in another PR")
|
||||||
|
SkipIfRootless("network connect and disconnect are only rootful")
|
||||||
|
netName := "aliasTest" + stringid.GenerateNonCryptoID()
|
||||||
|
session := podmanTest.Podman([]string{"network", "create", netName})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
defer podmanTest.removeCNINetwork(netName)
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"network", "ls", "--format", "{{.ID}}", "--filter", "name=" + netName})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(BeZero())
|
||||||
|
netID := session.OutputToString()
|
||||||
|
|
||||||
|
ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netID, ALPINE, "top"})
|
||||||
|
ctr.WaitWithDefaultTimeout()
|
||||||
|
Expect(ctr.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
|
||||||
|
exec.WaitWithDefaultTimeout()
|
||||||
|
Expect(exec.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
dis := podmanTest.Podman([]string{"network", "disconnect", netID, "test"})
|
||||||
|
dis.WaitWithDefaultTimeout()
|
||||||
|
Expect(dis.ExitCode()).To(BeZero())
|
||||||
|
|
||||||
|
inspect := podmanTest.Podman([]string{"container", "inspect", "test", "--format", "{{len .NetworkSettings.Networks}}"})
|
||||||
|
inspect.WaitWithDefaultTimeout()
|
||||||
|
Expect(inspect.ExitCode()).To(BeZero())
|
||||||
|
Expect(inspect.OutputToString()).To(Equal("0"))
|
||||||
|
|
||||||
|
exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
|
||||||
|
exec.WaitWithDefaultTimeout()
|
||||||
|
Expect(exec.ExitCode()).ToNot(BeZero())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user