Skip to content

Commit

Permalink
Merge pull request containers#9455 from Luap99/fix-network-ids
Browse files Browse the repository at this point in the history
Fix podman network IDs handling
  • Loading branch information
openshift-merge-robot authored Feb 22, 2021
2 parents c69decc + 9d818be commit d999328
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 15 deletions.
4 changes: 2 additions & 2 deletions libpod/network/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}

// ReadRawCNIConfByName reads the raw CNI configuration for a CNI
// ReadRawCNIConfByNameOrID reads the raw CNI configuration for a CNI
// 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)
if err != nil {
return nil, err
Expand Down
19 changes: 17 additions & 2 deletions libpod/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net"
"os"

"github.com/containernetworking/cni/libcni"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/plugins/plugins/ipam/host-local/backend/allocator"
"github.com/containers/common/pkg/config"
Expand Down Expand Up @@ -222,7 +223,7 @@ func RemoveNetwork(config *config.Config, name string) error {

// InspectNetwork reads a CNI config and returns its configuration
func InspectNetwork(config *config.Config, name string) (map[string]interface{}, error) {
b, err := ReadRawCNIConfByName(config, name)
b, err := ReadRawCNIConfByNameOrID(config, name)
if err != nil {
return nil, err
}
Expand All @@ -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
// specifically for restful responses so 404s can be used
func Exists(config *config.Config, name string) (bool, error) {
_, err := ReadRawCNIConfByName(config, name)
_, err := ReadRawCNIConfByNameOrID(config, name)
if err != nil {
if errors.Cause(err) == define.ErrNoSuchNetwork {
return false, nil
Expand Down Expand Up @@ -277,3 +278,17 @@ func PruneNetworks(rtc *config.Config, usedNetworks map[string]bool) ([]*entitie
}
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
}
14 changes: 6 additions & 8 deletions libpod/networking_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1139,13 +1139,12 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
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 {
return err
}
if !exists {
return errors.Wrap(define.ErrNoSuchNetwork, netName)
}

index, nameExists := networks[netName]
if !nameExists && len(networks) > 0 {
Expand Down Expand Up @@ -1196,13 +1195,12 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
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 {
return err
}
if !exists {
return errors.Wrap(define.ErrNoSuchNetwork, netName)
}

c.lock.Lock()
defer c.lock.Unlock()
Expand Down
16 changes: 16 additions & 0 deletions libpod/runtime_ctr.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/define"
"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/pkg/cgroups"
"github.com/containers/podman/v3/pkg/domain/entities/reports"
Expand Down Expand Up @@ -285,6 +286,21 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
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
shutdown.Inhibit()
defer shutdown.Uninhibit()
Expand Down
12 changes: 9 additions & 3 deletions test/e2e/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

. "github.com/containers/podman/v3/test/utils"
"github.com/containers/storage/pkg/stringid"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
Expand Down Expand Up @@ -576,15 +577,20 @@ var _ = Describe("Podman create", func() {
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"
pod := podmanTest.RunTopContainerInPod("", "new:"+name)
pod.WaitWithDefaultTimeout()
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()
//Expect(session.ExitCode()).ToNot(BeZero())
Expect(session.ExitCode()).To(BeZero())
})

Expand Down
85 changes: 85 additions & 0 deletions test/e2e/network_connect_disconnect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,55 @@ var _ = Describe("Podman network connect and disconnect", func() {
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() {
SkipIfRootless("network connect and disconnect are only rootful")
netName1 := "aliasTest" + stringid.GenerateNonCryptoID()
Expand Down Expand Up @@ -234,4 +283,40 @@ var _ = Describe("Podman network connect and disconnect", func() {
exec.WaitWithDefaultTimeout()
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())
})
})

0 comments on commit d999328

Please sign in to comment.