mirror of https://github.com/containers/podman.git
Merge pull request #2061 from adrianreber/static-ip
Use existing interface to request IP address during restore
This commit is contained in:
commit
7b9d4f1c92
|
|
@ -128,6 +128,11 @@ type Container struct {
|
||||||
|
|
||||||
rootlessSlirpSyncR *os.File
|
rootlessSlirpSyncR *os.File
|
||||||
rootlessSlirpSyncW *os.File
|
rootlessSlirpSyncW *os.File
|
||||||
|
|
||||||
|
// A restored container should have the same IP address as before
|
||||||
|
// being checkpointed. If requestedIP is set it will be used instead
|
||||||
|
// of config.StaticIP.
|
||||||
|
requestedIP net.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
// containerState contains the current state of the container
|
// containerState contains the current state of the container
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// +build seccomp ostree selinux varlink exclude_graphdriver_devicemapper
|
// +build seccomp ostree selinux varlink exclude_graphdriver_devicemapper
|
||||||
|
|
||||||
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
|
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT
|
||||||
|
|
||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -549,10 +549,8 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if IP != nil {
|
if IP != nil {
|
||||||
env := fmt.Sprintf("IP=%s", IP)
|
|
||||||
// Tell CNI which IP address we want.
|
// Tell CNI which IP address we want.
|
||||||
os.Setenv("CNI_ARGS", env)
|
c.requestedIP = IP
|
||||||
logrus.Debugf("Restoring container with %s", env)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -568,12 +566,6 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use existing way to request static IPs, once it is merged in ocicni
|
|
||||||
// https://github.com/cri-o/ocicni/pull/23/
|
|
||||||
|
|
||||||
// CNI_ARGS was used to request a certain IP address. Unconditionally remove it.
|
|
||||||
os.Unsetenv("CNI_ARGS")
|
|
||||||
|
|
||||||
// Read config
|
// Read config
|
||||||
jsonPath := filepath.Join(c.bundlePath(), "config.json")
|
jsonPath := filepath.Join(c.bundlePath(), "config.json")
|
||||||
logrus.Debugf("generate.NewFromFile at %v", jsonPath)
|
logrus.Debugf("generate.NewFromFile at %v", jsonPath)
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,16 @@ func (r *Runtime) getPodNetwork(id, name, nsPath string, networks []string, port
|
||||||
|
|
||||||
// Create and configure a new network namespace for a container
|
// Create and configure a new network namespace for a container
|
||||||
func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Result, error) {
|
func (r *Runtime) configureNetNS(ctr *Container, ctrNS ns.NetNS) ([]*cnitypes.Result, error) {
|
||||||
podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctrNS.Path(), ctr.config.Networks, ctr.config.PortMappings, ctr.config.StaticIP)
|
var requestedIP net.IP
|
||||||
|
if ctr.requestedIP != nil {
|
||||||
|
requestedIP = ctr.requestedIP
|
||||||
|
// cancel request for a specific IP in case the container is reused later
|
||||||
|
ctr.requestedIP = nil
|
||||||
|
} else {
|
||||||
|
requestedIP = ctr.config.StaticIP
|
||||||
|
}
|
||||||
|
|
||||||
|
podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctrNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP)
|
||||||
|
|
||||||
results, err := r.netPlugin.SetUpPod(podNetwork)
|
results, err := r.netPlugin.SetUpPod(podNetwork)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -258,7 +267,16 @@ func (r *Runtime) teardownNetNS(ctr *Container) error {
|
||||||
|
|
||||||
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.Path(), ctr.ID())
|
||||||
|
|
||||||
podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.Networks, ctr.config.PortMappings, ctr.config.StaticIP)
|
var requestedIP net.IP
|
||||||
|
if ctr.requestedIP != nil {
|
||||||
|
requestedIP = ctr.requestedIP
|
||||||
|
// cancel request for a specific IP in case the container is reused later
|
||||||
|
ctr.requestedIP = nil
|
||||||
|
} else {
|
||||||
|
requestedIP = ctr.config.StaticIP
|
||||||
|
}
|
||||||
|
|
||||||
|
podNetwork := r.getPodNetwork(ctr.ID(), ctr.Name(), ctr.state.NetNS.Path(), ctr.config.Networks, ctr.config.PortMappings, requestedIP)
|
||||||
|
|
||||||
// The network may have already been torn down, so don't fail here, just log
|
// The network may have already been torn down, so don't fail here, just log
|
||||||
if err := r.netPlugin.TearDownPod(podNetwork); err != nil {
|
if err := r.netPlugin.TearDownPod(podNetwork); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -199,14 +199,17 @@ var _ = Describe("Podman checkpoint", func() {
|
||||||
})
|
})
|
||||||
|
|
||||||
It("podman checkpoint container with established tcp connections", func() {
|
It("podman checkpoint container with established tcp connections", func() {
|
||||||
Skip("Seems to not work (yet) in CI")
|
|
||||||
podmanTest.RestoreArtifact(redis)
|
podmanTest.RestoreArtifact(redis)
|
||||||
session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--network", "host", "-d", redis})
|
session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "-d", redis})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
Expect(session.ExitCode()).To(Equal(0))
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
IP := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"})
|
||||||
|
IP.WaitWithDefaultTimeout()
|
||||||
|
Expect(IP.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
// Open a network connection to the redis server
|
// Open a network connection to the redis server
|
||||||
conn, err := net.Dial("tcp", "127.0.0.1:6379")
|
conn, err := net.Dial("tcp", IP.OutputToString()+":6379")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
@ -287,4 +290,40 @@ var _ = Describe("Podman checkpoint", func() {
|
||||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman checkpoint and restore container with same IP", func() {
|
||||||
|
session := podmanTest.Podman([]string{"run", "-it", "--security-opt", "seccomp=unconfined", "--name", "test_name", "-d", ALPINE, "top"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
IPBefore := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"})
|
||||||
|
IPBefore.WaitWithDefaultTimeout()
|
||||||
|
Expect(IPBefore.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||||
|
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
|
||||||
|
|
||||||
|
result = podmanTest.Podman([]string{"container", "restore", "test_name"})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
|
||||||
|
IPAfter := podmanTest.Podman([]string{"inspect", "-l", "--format={{.NetworkSettings.IPAddress}}"})
|
||||||
|
IPAfter.WaitWithDefaultTimeout()
|
||||||
|
Expect(IPAfter.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
// Check that IP address did not change between checkpointing and restoring
|
||||||
|
Expect(IPBefore.OutputToString()).To(Equal(IPAfter.OutputToString()))
|
||||||
|
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||||
|
Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
|
||||||
|
|
||||||
|
result = podmanTest.Podman([]string{"rm", "-fa"})
|
||||||
|
result.WaitWithDefaultTimeout()
|
||||||
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
|
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue