From 1585b175dbf47e7ee0d5a26600aaec898ec5c26b Mon Sep 17 00:00:00 2001 From: cdoern Date: Thu, 28 Apr 2022 22:37:11 -0400 Subject: pass networks to container clone since the network config is a string map, json.unmarshal does not recognize the config and spec as the same entity, need to map this option manually resolves #13713 Signed-off-by: cdoern --- libpod/container.go | 14 +++++++++++++- pkg/domain/infra/abi/containers.go | 6 ++++++ pkg/specgen/generate/container.go | 2 ++ pkg/specgen/generate/container_create.go | 16 +++++++++------- test/e2e/container_clone_test.go | 26 ++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 8 deletions(-) diff --git a/libpod/container.go b/libpod/container.go index 3e7ab7b0a..457b290b7 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -288,6 +288,15 @@ func (c *Container) Config() *ContainerConfig { return nil } + if c != nil { + networks, err := c.networks() + if err != nil { + return nil + } + + returnConfig.Networks = networks + } + return returnConfig } @@ -1260,7 +1269,10 @@ func (c *Container) NetworkMode() string { // Unlocked accessor for networks func (c *Container) networks() (map[string]types.PerNetworkOptions, error) { - return c.runtime.state.GetNetworks(c) + if c != nil && c.runtime != nil && c.runtime.state != nil { // can fail if c.networks is called from the tests + return c.runtime.state.GetNetworks(c) + } + return nil, nil } // getInterfaceByName returns a formatted interface name for a given diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go index b56c36015..92e29c822 100644 --- a/pkg/domain/infra/abi/containers.go +++ b/pkg/domain/infra/abi/containers.go @@ -1544,6 +1544,12 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti return nil, err } + if len(spec.Networks) > 0 && pod.SharesNet() { + logrus.Warning("resetting network config, cannot specify a network other than the pod's when sharing the net namespace") + spec.Networks = nil + spec.NetworkOptions = nil + } + allNamespaces := []struct { isShared bool value *specgen.Namespace diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go index 831c1d7b9..63caaa77c 100644 --- a/pkg/specgen/generate/container.go +++ b/pkg/specgen/generate/container.go @@ -501,6 +501,8 @@ func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, contaierID s _, mounts := c.SortUserVolumes(c.Spec()) specg.Mounts = mounts specg.HostDeviceList = conf.DeviceHostSrc + specg.Networks = conf.Networks + mapSecurityConfig(conf, specg) if c.IsInfra() { // if we are creating this spec for a pod's infra ctr, map the compatible options diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go index 8b9ed8ffe..19a2b702c 100644 --- a/pkg/specgen/generate/container_create.go +++ b/pkg/specgen/generate/container_create.go @@ -175,13 +175,15 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener return nil, nil, nil, errors.New("the given container could not be retrieved") } conf := c.Config() - out, err := json.Marshal(conf.Spec.Linux) - if err != nil { - return nil, nil, nil, err - } - err = json.Unmarshal(out, runtimeSpec.Linux) - if err != nil { - return nil, nil, nil, err + if conf != nil && conf.Spec != nil && conf.Spec.Linux != nil { + out, err := json.Marshal(conf.Spec.Linux) + if err != nil { + return nil, nil, nil, err + } + err = json.Unmarshal(out, runtimeSpec.Linux) + if err != nil { + return nil, nil, nil, err + } } if s.ResourceLimits != nil { switch { diff --git a/test/e2e/container_clone_test.go b/test/e2e/container_clone_test.go index c47a89332..075ed8264 100644 --- a/test/e2e/container_clone_test.go +++ b/test/e2e/container_clone_test.go @@ -267,4 +267,30 @@ var _ = Describe("Podman container clone", func() { Expect(clone).ToNot(Exit(0)) }) + + It("podman container clone network passing", func() { + networkCreate := podmanTest.Podman([]string{"network", "create", "testing123"}) + networkCreate.WaitWithDefaultTimeout() + defer podmanTest.removeNetwork("testing123") + Expect(networkCreate).To(Exit(0)) + run := podmanTest.Podman([]string{"run", "--network", "bridge", "-dt", ALPINE}) + run.WaitWithDefaultTimeout() + Expect(run).To(Exit(0)) + + connect := podmanTest.Podman([]string{"network", "connect", "testing123", run.OutputToString()}) + connect.WaitWithDefaultTimeout() + Expect(connect).To(Exit(0)) + + clone := podmanTest.Podman([]string{"container", "clone", run.OutputToString()}) + clone.WaitWithDefaultTimeout() + Expect(clone).To(Exit(0)) + + inspect := podmanTest.Podman([]string{"inspect", clone.OutputToString()}) + inspect.WaitWithDefaultTimeout() + Expect(inspect).To(Exit(0)) + Expect(inspect.InspectContainerToJSON()[0].NetworkSettings.Networks).To(HaveLen(2)) + _, ok := inspect.InspectContainerToJSON()[0].NetworkSettings.Networks["testing123"] + Expect(ok).To(BeTrue()) + + }) }) -- cgit v1.2.3-54-g00ecf