diff --git a/libpod/kube.go b/libpod/kube.go index b5ff66fd44..6ea6d08659 100644 --- a/libpod/kube.go +++ b/libpod/kube.go @@ -33,14 +33,14 @@ import ( // GenerateForKube takes a slice of libpod containers and generates // one v1.Pod description that includes just a single container. -func GenerateForKube(ctx context.Context, ctrs []*Container) (*v1.Pod, error) { +func GenerateForKube(ctx context.Context, ctrs []*Container, getService bool) (*v1.Pod, error) { // Generate the v1.Pod yaml description - return simplePodWithV1Containers(ctx, ctrs) + return simplePodWithV1Containers(ctx, ctrs, getService) } // GenerateForKube takes a slice of libpod containers and generates // one v1.Pod description -func (p *Pod) GenerateForKube(ctx context.Context) (*v1.Pod, []v1.ServicePort, error) { +func (p *Pod) GenerateForKube(ctx context.Context, getService bool) (*v1.Pod, []v1.ServicePort, error) { // Generate the v1.Pod yaml description var ( ports []v1.ContainerPort @@ -78,7 +78,7 @@ func (p *Pod) GenerateForKube(ctx context.Context) (*v1.Pod, []v1.ServicePort, e Hostnames: []string{hostSli[0]}, }) } - ports, err = portMappingToContainerPort(infraContainer.config.PortMappings) + ports, err = portMappingToContainerPort(infraContainer.config.PortMappings, getService) if err != nil { return nil, servicePorts, err } @@ -90,7 +90,7 @@ func (p *Pod) GenerateForKube(ctx context.Context) (*v1.Pod, []v1.ServicePort, e hostNetwork = infraContainer.NetworkMode() == string(namespaces.NetworkMode(specgen.Host)) hostUsers = infraContainer.IDMappings().HostUIDMapping && infraContainer.IDMappings().HostGIDMapping } - pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork, hostUsers) + pod, err := p.podWithContainers(ctx, allContainers, ports, hostNetwork, hostUsers, getService) if err != nil { return nil, servicePorts, err } @@ -350,7 +350,7 @@ func containersToServicePorts(containers []v1.Container) ([]v1.ServicePort, erro return sps, nil } -func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork, hostUsers bool) (*v1.Pod, error) { +func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, ports []v1.ContainerPort, hostNetwork, hostUsers, getService bool) (*v1.Pod, error) { deDupPodVolumes := make(map[string]*v1.Volume) first := true podContainers := make([]v1.Container, 0, len(containers)) @@ -385,7 +385,7 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po } } - ctr, volumes, _, annotations, err := containerToV1Container(ctx, ctr) + ctr, volumes, _, annotations, err := containerToV1Container(ctx, ctr, getService) if err != nil { return nil, err } @@ -421,7 +421,7 @@ func (p *Pod) podWithContainers(ctx context.Context, containers []*Container, po deDupPodVolumes[vol.Name] = &vol } } else { - _, _, infraDNS, _, err := containerToV1Container(ctx, ctr) + _, _, infraDNS, _, err := containerToV1Container(ctx, ctr, getService) if err != nil { return nil, err } @@ -497,7 +497,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 // for a single container. we "insert" that container description in a pod. -func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, error) { +func simplePodWithV1Containers(ctx context.Context, ctrs []*Container, getService bool) (*v1.Pod, error) { kubeCtrs := make([]v1.Container, 0, len(ctrs)) kubeInitCtrs := []v1.Container{} kubeVolumes := make([]v1.Volume, 0) @@ -555,7 +555,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, if !(ctr.IDMappings().HostUIDMapping && ctr.IDMappings().HostGIDMapping) { hostUsers = false } - kubeCtr, kubeVols, ctrDNS, annotations, err := containerToV1Container(ctx, ctr) + kubeCtr, kubeVols, ctrDNS, annotations, err := containerToV1Container(ctx, ctr, getService) if err != nil { return nil, err } @@ -622,7 +622,7 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod, // containerToV1Container converts information we know about a libpod container // to a V1.Container specification. -func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []v1.Volume, *v1.PodDNSConfig, map[string]string, error) { +func containerToV1Container(ctx context.Context, c *Container, getService bool) (v1.Container, []v1.Volume, *v1.PodDNSConfig, map[string]string, error) { kubeContainer := v1.Container{} kubeVolumes := []v1.Volume{} annotations := make(map[string]string) @@ -652,7 +652,7 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, [] if err != nil { return kubeContainer, kubeVolumes, nil, annotations, err } - ports, err := portMappingToContainerPort(portmappings) + ports, err := portMappingToContainerPort(portmappings, getService) if err != nil { return kubeContainer, kubeVolumes, nil, annotations, err } @@ -799,7 +799,7 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, [] // portMappingToContainerPort takes an portmapping and converts // it to a v1.ContainerPort format for kube output -func portMappingToContainerPort(portMappings []types.PortMapping) ([]v1.ContainerPort, error) { +func portMappingToContainerPort(portMappings []types.PortMapping, getService bool) ([]v1.ContainerPort, error) { containerPorts := make([]v1.ContainerPort, 0, len(portMappings)) for _, p := range portMappings { protocols := strings.Split(p.Protocol, ",") @@ -819,11 +819,13 @@ func portMappingToContainerPort(portMappings []types.PortMapping) ([]v1.Containe for i := uint16(0); i < p.Range; i++ { cp := v1.ContainerPort{ // Name will not be supported - HostPort: int32(p.HostPort + i), HostIP: p.HostIP, ContainerPort: int32(p.ContainerPort + i), Protocol: protocol, } + if !getService { + cp.HostPort = int32(p.HostPort + i) + } containerPorts = append(containerPorts, cp) } } diff --git a/pkg/domain/infra/abi/generate.go b/pkg/domain/infra/abi/generate.go index f588f591aa..1da3b21e9a 100644 --- a/pkg/domain/infra/abi/generate.go +++ b/pkg/domain/infra/abi/generate.go @@ -200,7 +200,7 @@ func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string, // Generate the kube pods from containers. if len(ctrs) >= 1 { - po, err := libpod.GenerateForKube(ctx, ctrs) + po, err := libpod.GenerateForKube(ctx, ctrs, options.Service) if err != nil { return nil, err } @@ -249,7 +249,7 @@ func getKubePods(ctx context.Context, pods []*libpod.Pod, getService bool) ([][] svcs := [][]byte{} for _, p := range pods { - po, sp, err := p.GenerateForKube(ctx) + po, sp, err := p.GenerateForKube(ctx, getService) if err != nil { return nil, nil, err } diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go index 00b68ee551..5377bd5441 100644 --- a/test/e2e/generate_kube_test.go +++ b/test/e2e/generate_kube_test.go @@ -150,6 +150,43 @@ var _ = Describe("Podman kube generate", func() { Expect(err).ToNot(HaveOccurred()) }) + It("podman generate kube on container with and without service", func() { + session := podmanTest.Podman([]string{"create", "--name", "test-ctr", "-p", "3890:3890", ALPINE, "ls"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + kube := podmanTest.Podman([]string{"kube", "generate", "-s", "test-ctr"}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + + // Separate out the Service and Pod yaml + arr := strings.Split(string(kube.Out.Contents()), "---") + Expect(arr).To(HaveLen(2)) + + svc := new(v1.Service) + err := yaml.Unmarshal([]byte(arr[0]), svc) + Expect(err).ToNot(HaveOccurred()) + Expect(svc.Spec.Ports).To(HaveLen(1)) + Expect(svc.Spec.Ports[0].TargetPort.IntValue()).To(Equal(3890)) + + pod := new(v1.Pod) + err = yaml.Unmarshal([]byte(arr[1]), pod) + Expect(err).ToNot(HaveOccurred()) + // Since hostPort will not be set in the yaml, when we unmarshal it it will have a value of 0 + Expect(pod.Spec.Containers[0].Ports[0].HostPort).To(Equal(int32(0))) + + // Now do kube generate without the --service flag + kube = podmanTest.Podman([]string{"kube", "generate", "test-ctr"}) + kube.WaitWithDefaultTimeout() + Expect(kube).Should(Exit(0)) + + // The hostPort in the pod yaml should be set to 3890 + pod = new(v1.Pod) + err = yaml.Unmarshal(kube.Out.Contents(), pod) + Expect(err).ToNot(HaveOccurred()) + Expect(pod.Spec.Containers[0].Ports[0].HostPort).To(Equal(int32(3890))) + }) + It("podman generate kube on pod", func() { _, rc, _ := podmanTest.CreatePod(map[string][]string{"--name": {"toppod"}}) Expect(rc).To(Equal(0))