Skip to content

Commit

Permalink
Merge pull request containers#8515 from baude/netconnectstate
Browse files Browse the repository at this point in the history
network connect disconnect on non-running containers
  • Loading branch information
openshift-merge-robot authored Dec 1, 2020
2 parents e3f0b7d + 7d43cc0 commit 429d949
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 170 deletions.
25 changes: 14 additions & 11 deletions libpod/networking_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -1047,21 +1047,25 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
return err
}

if err := c.runtime.state.NetworkDisconnect(c, netName); err != nil {
return err
}

c.newNetworkEvent(events.NetworkDisconnect, netName)
if c.state.State != define.ContainerStateRunning {
return errors.Wrapf(define.ErrCtrStateInvalid, "cannot disconnect container %s from networks as it is not running", nameOrID)
return nil
}

if c.state.NetNS == nil {
return errors.Wrapf(define.ErrNoNetwork, "unable to disconnect %s from %s", nameOrID, netName)
}

podConfig := c.runtime.getPodNetwork(c.ID(), c.Name(), c.state.NetNS.Path(), []string{netName}, c.config.PortMappings, nil, nil, c.state.NetInterfaceDescriptions)
if err := c.runtime.netPlugin.TearDownPod(podConfig); err != nil {
return err
}
if err := c.runtime.state.NetworkDisconnect(c, netName); err != nil {
return err
}

// update network status
// update network status if container is not running
networkStatus := c.state.NetworkStatus
// clip out the index of the network
tmpNetworkStatus := make([]*cnitypes.Result, len(networkStatus)-1)
Expand All @@ -1071,7 +1075,6 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
}
}
c.state.NetworkStatus = tmpNetworkStatus
c.newNetworkEvent(events.NetworkDisconnect, netName)
return c.save()
}

Expand All @@ -1096,15 +1099,16 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
return err
}

if err := c.runtime.state.NetworkConnect(c, netName, aliases); err != nil {
return err
}
c.newNetworkEvent(events.NetworkConnect, netName)
if c.state.State != define.ContainerStateRunning {
return errors.Wrapf(define.ErrCtrStateInvalid, "cannot connect container %s to networks as it is not running", nameOrID)
return nil
}
if c.state.NetNS == nil {
return errors.Wrapf(define.ErrNoNetwork, "unable to connect %s to %s", nameOrID, netName)
}
if err := c.runtime.state.NetworkConnect(c, netName, aliases); err != nil {
return err
}

ctrNetworks, _, err := c.networks()
if err != nil {
Expand Down Expand Up @@ -1159,7 +1163,6 @@ func (c *Container) NetworkConnect(nameOrID, netName string, aliases []string) e
networkStatus[index] = networkResults[0]
c.state.NetworkStatus = networkStatus
}
c.newNetworkEvent(events.NetworkConnect, netName)
return c.save()
}

Expand Down
6 changes: 6 additions & 0 deletions test/e2e/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -788,3 +788,9 @@ func generateNetworkConfig(p *PodmanTestIntegration) (string, string) {

return name, path
}

func (p *PodmanTestIntegration) removeCNINetwork(name string) {
session := p.Podman([]string{"network", "rm", "-f", name})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeNumerically("<=", 1))
}
217 changes: 217 additions & 0 deletions test/e2e/network_connect_disconnect_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
package integration

import (
"os"

. "github.com/containers/podman/v2/test/utils"
"github.com/containers/storage/pkg/stringid"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("Podman network connect and disconnect", func() {
var (
tempdir string
err error
podmanTest *PodmanTestIntegration
)

BeforeEach(func() {
tempdir, err = CreateTempDirInTempDir()
if err != nil {
os.Exit(1)
}
podmanTest = PodmanTestCreate(tempdir)
podmanTest.Setup()
})

AfterEach(func() {
podmanTest.Cleanup()
f := CurrentGinkgoTestDescription()
processTestResult(f)

})

It("bad network name in disconnect should result in error", func() {
SkipIfRootless("network connect and disconnect are only rootfull")
dis := podmanTest.Podman([]string{"network", "disconnect", "foobar", "test"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).ToNot(BeZero())

})

It("bad container name in network disconnect should result in error", func() {
SkipIfRootless("network connect and disconnect are only rootfull")
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)

dis := podmanTest.Podman([]string{"network", "disconnect", netName, "foobar"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).ToNot(BeZero())

})

It("podman network disconnect", func() {
SkipIfRootless("network connect and disconnect are only rootfull")
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)

ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, 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", netName, "test"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).To(BeZero())

exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).ToNot(BeZero())
})

It("bad network name in connect should result in error", func() {
SkipIfRootless("network connect and disconnect are only rootfull")
dis := podmanTest.Podman([]string{"network", "connect", "foobar", "test"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).ToNot(BeZero())

})

It("bad container name in network connect should result in error", func() {
SkipIfRootless("network connect and disconnect are only rootfull")
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)

dis := podmanTest.Podman([]string{"network", "connect", netName, "foobar"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).ToNot(BeZero())

})

It("podman connect on a container that already is connected to the network should error", func() {
SkipIfRootless("network connect and disconnect are only rootfull")
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)

ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName, ALPINE, "top"})
ctr.WaitWithDefaultTimeout()
Expect(ctr.ExitCode()).To(BeZero())

con := podmanTest.Podman([]string{"network", "connect", netName, "test"})
con.WaitWithDefaultTimeout()
Expect(con.ExitCode()).ToNot(BeZero())
})

It("podman network connect", func() {
SkipIfRemote("This requires a pending PR to be merged before it will work")
SkipIfRootless("network connect and disconnect are only rootfull")
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)

ctr := podmanTest.Podman([]string{"run", "-dt", "--name", "test", "--network", netName, 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 := "aliasTest" + stringid.GenerateNonCryptoID()
session = podmanTest.Podman([]string{"network", "create", newNetName})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(newNetName)

connect := podmanTest.Podman([]string{"network", "connect", newNetName, "test"})
connect.WaitWithDefaultTimeout()
Expect(connect.ExitCode()).To(BeZero())

exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"})
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).To(BeZero())
})

It("podman network connect when not running", func() {
SkipIfRootless("network connect and disconnect are only rootfull")
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName)

ctr := podmanTest.Podman([]string{"create", "--name", "test", ALPINE, "top"})
ctr.WaitWithDefaultTimeout()
Expect(ctr.ExitCode()).To(BeZero())

dis := podmanTest.Podman([]string{"network", "connect", netName, "test"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).To(BeZero())

start := podmanTest.Podman([]string{"start", "test"})
start.WaitWithDefaultTimeout()
Expect(start.ExitCode()).To(BeZero())

exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).To(BeZero())

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 rootfull")
netName1 := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName1})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName1)

netName2 := "aliasTest" + stringid.GenerateNonCryptoID()
session2 := podmanTest.Podman([]string{"network", "create", netName2})
session2.WaitWithDefaultTimeout()
Expect(session2.ExitCode()).To(BeZero())
defer podmanTest.removeCNINetwork(netName2)

ctr := podmanTest.Podman([]string{"create", "--name", "test", "--network", netName1 + "," + netName2, ALPINE, "top"})
ctr.WaitWithDefaultTimeout()
Expect(ctr.ExitCode()).To(BeZero())

dis := podmanTest.Podman([]string{"network", "disconnect", netName1, "test"})
dis.WaitWithDefaultTimeout()
Expect(dis.ExitCode()).To(BeZero())

start := podmanTest.Podman([]string{"start", "test"})
start.WaitWithDefaultTimeout()
Expect(start.ExitCode()).To(BeZero())

exec := podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth0"})
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).To(BeZero())

exec = podmanTest.Podman([]string{"exec", "-it", "test", "ip", "addr", "show", "eth1"})
exec.WaitWithDefaultTimeout()
Expect(exec.ExitCode()).ToNot(BeZero())
})
})
6 changes: 0 additions & 6 deletions test/e2e/network_create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ func genericPluginsToPortMap(plugins interface{}, pluginType string) (network.Po
return portMap, err
}

func (p *PodmanTestIntegration) removeCNINetwork(name string) {
session := p.Podman([]string{"network", "rm", "-f", name})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeNumerically("<=", 1))
}

func removeNetworkDevice(name string) {
session := SystemExec("ip", []string{"link", "delete", name})
session.WaitWithDefaultTimeout()
Expand Down
Loading

0 comments on commit 429d949

Please sign in to comment.