mirror of
https://github.com/containers/podman.git
synced 2025-07-15 03:02:52 +08:00
podman generate kube should not include images command
If the command came from the underlying image, then we should not include it in the generate yaml file. Fixes: https://github.com/containers/podman/issues/11672 Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
@ -1,9 +1,11 @@
|
|||||||
package libpod
|
package libpod
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -27,14 +29,14 @@ import (
|
|||||||
|
|
||||||
// GenerateForKube takes a slice of libpod containers and generates
|
// GenerateForKube takes a slice of libpod containers and generates
|
||||||
// one v1.Pod description that includes just a single container.
|
// one v1.Pod description that includes just a single container.
|
||||||
func GenerateForKube(ctrs []*Container) (*v1.Pod, error) {
|
func GenerateForKube(ctx context.Context, ctrs []*Container) (*v1.Pod, error) {
|
||||||
// Generate the v1.Pod yaml description
|
// Generate the v1.Pod yaml description
|
||||||
return simplePodWithV1Containers(ctrs)
|
return simplePodWithV1Containers(ctx, ctrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateForKube takes a slice of libpod containers and generates
|
// GenerateForKube takes a slice of libpod containers and generates
|
||||||
// one v1.Pod description
|
// one v1.Pod description
|
||||||
func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
|
func (p *Pod) GenerateForKube(ctx context.Context) (*v1.Pod, []v1.ServicePort, error) {
|
||||||
// Generate the v1.Pod yaml description
|
// Generate the v1.Pod yaml description
|
||||||
var (
|
var (
|
||||||
ports []v1.ContainerPort //nolint
|
ports []v1.ContainerPort //nolint
|
||||||
@ -78,7 +80,7 @@ func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
|
|||||||
servicePorts = containerPortsToServicePorts(ports)
|
servicePorts = containerPortsToServicePorts(ports)
|
||||||
hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host))
|
hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host))
|
||||||
}
|
}
|
||||||
pod, err := p.podWithContainers(allContainers, ports, hostNetwork)
|
pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, servicePorts, err
|
return nil, servicePorts, err
|
||||||
}
|
}
|
||||||
@ -218,7 +220,7 @@ func containersToServicePorts(containers []v1.Container) []v1.ServicePort {
|
|||||||
return sps
|
return sps
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPort, hostNetwork bool) (*v1.Pod, error) {
|
func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork bool) (*v1.Pod, error) {
|
||||||
deDupPodVolumes := make(map[string]*v1.Volume)
|
deDupPodVolumes := make(map[string]*v1.Volume)
|
||||||
first := true
|
first := true
|
||||||
podContainers := make([]v1.Container, 0, len(containers))
|
podContainers := make([]v1.Container, 0, len(containers))
|
||||||
@ -239,7 +241,7 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
|
|||||||
|
|
||||||
isInit := ctr.IsInitCtr()
|
isInit := ctr.IsInitCtr()
|
||||||
|
|
||||||
ctr, volumes, _, err := containerToV1Container(ctr)
|
ctr, volumes, _, err := containerToV1Container(ctx, ctr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -267,7 +269,7 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
|
|||||||
deDupPodVolumes[vol.Name] = &vol
|
deDupPodVolumes[vol.Name] = &vol
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_, _, infraDNS, err := containerToV1Container(ctr)
|
_, _, infraDNS, err := containerToV1Container(ctx, ctr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -337,7 +339,7 @@ func newPodObject(podName string, annotations map[string]string, initCtrs, conta
|
|||||||
|
|
||||||
// simplePodWithV1Containers is a function used by inspect when kube yaml needs to be generated
|
// simplePodWithV1Containers is a function used by inspect when kube yaml needs to be generated
|
||||||
// for a single container. we "insert" that container description in a pod.
|
// for a single container. we "insert" that container description in a pod.
|
||||||
func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
|
func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, error) {
|
||||||
kubeCtrs := make([]v1.Container, 0, len(ctrs))
|
kubeCtrs := make([]v1.Container, 0, len(ctrs))
|
||||||
kubeInitCtrs := []v1.Container{}
|
kubeInitCtrs := []v1.Container{}
|
||||||
kubeVolumes := make([]v1.Volume, 0)
|
kubeVolumes := make([]v1.Volume, 0)
|
||||||
@ -355,7 +357,7 @@ func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
|
|||||||
if !ctr.HostNetwork() {
|
if !ctr.HostNetwork() {
|
||||||
hostNetwork = false
|
hostNetwork = false
|
||||||
}
|
}
|
||||||
kubeCtr, kubeVols, ctrDNS, err := containerToV1Container(ctr)
|
kubeCtr, kubeVols, ctrDNS, err := containerToV1Container(ctx, ctr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -411,7 +413,7 @@ func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
|
|||||||
|
|
||||||
// containerToV1Container converts information we know about a libpod container
|
// containerToV1Container converts information we know about a libpod container
|
||||||
// to a V1.Container specification.
|
// to a V1.Container specification.
|
||||||
func containerToV1Container(c *Container) (v1.Container, []v1.Volume, *v1.PodDNSConfig, error) {
|
func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []v1.Volume, *v1.PodDNSConfig, error) {
|
||||||
kubeContainer := v1.Container{}
|
kubeContainer := v1.Container{}
|
||||||
kubeVolumes := []v1.Volume{}
|
kubeVolumes := []v1.Volume{}
|
||||||
kubeSec, err := generateKubeSecurityContext(c)
|
kubeSec, err := generateKubeSecurityContext(c)
|
||||||
@ -463,6 +465,17 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, *v1.PodDNS
|
|||||||
_, image := c.Image()
|
_, image := c.Image()
|
||||||
kubeContainer.Image = image
|
kubeContainer.Image = image
|
||||||
kubeContainer.Stdin = c.Stdin()
|
kubeContainer.Stdin = c.Stdin()
|
||||||
|
img, _, err := c.runtime.libimageRuntime.LookupImage(image, nil)
|
||||||
|
if err != nil {
|
||||||
|
return kubeContainer, kubeVolumes, nil, err
|
||||||
|
}
|
||||||
|
imgData, err := img.Inspect(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return kubeContainer, kubeVolumes, nil, err
|
||||||
|
}
|
||||||
|
if reflect.DeepEqual(imgData.Config.Cmd, kubeContainer.Command) {
|
||||||
|
kubeContainer.Command = nil
|
||||||
|
}
|
||||||
|
|
||||||
kubeContainer.WorkingDir = c.WorkingDir()
|
kubeContainer.WorkingDir = c.WorkingDir()
|
||||||
kubeContainer.Ports = ports
|
kubeContainer.Ports = ports
|
||||||
|
@ -107,7 +107,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
|
|||||||
|
|
||||||
// Generate kube pods and services from pods.
|
// Generate kube pods and services from pods.
|
||||||
if len(pods) >= 1 {
|
if len(pods) >= 1 {
|
||||||
pos, svcs, err := getKubePods(pods, options.Service)
|
pos, svcs, err := getKubePods(ctx, pods, options.Service)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
|
|||||||
|
|
||||||
// Generate the kube pods from containers.
|
// Generate the kube pods from containers.
|
||||||
if len(ctrs) >= 1 {
|
if len(ctrs) >= 1 {
|
||||||
po, err := libpod.GenerateForKube(ctrs)
|
po, err := libpod.GenerateForKube(ctx, ctrs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -153,12 +153,12 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getKubePods returns kube pod and service YAML files from podman pods.
|
// getKubePods returns kube pod and service YAML files from podman pods.
|
||||||
func getKubePods(pods []*libpod.Pod, getService bool) ([][]byte, [][]byte, error) {
|
func getKubePods(ctx context.Context, pods []*libpod.Pod, getService bool) ([][]byte, [][]byte, error) {
|
||||||
pos := [][]byte{}
|
pos := [][]byte{}
|
||||||
svcs := [][]byte{}
|
svcs := [][]byte{}
|
||||||
|
|
||||||
for _, p := range pods {
|
for _, p := range pods {
|
||||||
po, sp, err := p.GenerateForKube()
|
po, sp, err := p.GenerateForKube(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -792,6 +792,45 @@ var _ = Describe("Podman generate kube", func() {
|
|||||||
Expect(containers[0].Args).To(Equal([]string{"10s"}))
|
Expect(containers[0].Args).To(Equal([]string{"10s"}))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman generate kube - no command", func() {
|
||||||
|
session := podmanTest.Podman([]string{"create", "--name", "test", ALPINE})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
|
kube := podmanTest.Podman([]string{"generate", "kube", "test"})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube).Should(Exit(0))
|
||||||
|
|
||||||
|
// Now make sure that the container's command is not set to the
|
||||||
|
// entrypoint and it's arguments to "10s".
|
||||||
|
pod := new(v1.Pod)
|
||||||
|
err := yaml.Unmarshal(kube.Out.Contents(), pod)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
containers := pod.Spec.Containers
|
||||||
|
Expect(len(containers)).To(Equal(1))
|
||||||
|
Expect(len(containers[0].Command)).To(Equal(0))
|
||||||
|
|
||||||
|
cmd := []string{"echo", "hi"}
|
||||||
|
session = podmanTest.Podman(append([]string{"create", "--name", "test1", ALPINE}, cmd...))
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session).Should(Exit(0))
|
||||||
|
|
||||||
|
kube = podmanTest.Podman([]string{"generate", "kube", "test1"})
|
||||||
|
kube.WaitWithDefaultTimeout()
|
||||||
|
Expect(kube).Should(Exit(0))
|
||||||
|
|
||||||
|
// Now make sure that the container's command is not set to the
|
||||||
|
// entrypoint and it's arguments to "10s".
|
||||||
|
pod = new(v1.Pod)
|
||||||
|
err = yaml.Unmarshal(kube.Out.Contents(), pod)
|
||||||
|
Expect(err).To(BeNil())
|
||||||
|
|
||||||
|
containers = pod.Spec.Containers
|
||||||
|
Expect(len(containers)).To(Equal(1))
|
||||||
|
Expect(containers[0].Command).To(Equal(cmd))
|
||||||
|
})
|
||||||
|
|
||||||
It("podman generate kube - use entrypoint from image", func() {
|
It("podman generate kube - use entrypoint from image", func() {
|
||||||
// Build an image with an entrypoint.
|
// Build an image with an entrypoint.
|
||||||
containerfile := `FROM quay.io/libpod/alpine:latest
|
containerfile := `FROM quay.io/libpod/alpine:latest
|
||||||
|
Reference in New Issue
Block a user