mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-08-26 18:27:53 +00:00
add the ability to add multiple containers into a single k8s pod instead of just one. also fixed some bugs in the resulting yaml where an empty service description was being added on error causing the k8s validation to fail. Signed-off-by: baude <bbaude@redhat.com>
143 lines
3.9 KiB
Go
143 lines
3.9 KiB
Go
package abi
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/containers/podman/v2/libpod"
|
|
"github.com/containers/podman/v2/libpod/define"
|
|
"github.com/containers/podman/v2/pkg/domain/entities"
|
|
"github.com/containers/podman/v2/pkg/systemd/generate"
|
|
"github.com/ghodss/yaml"
|
|
"github.com/pkg/errors"
|
|
k8sAPI "k8s.io/api/core/v1"
|
|
)
|
|
|
|
func (ic *ContainerEngine) GenerateSystemd(ctx context.Context, nameOrID string, options entities.GenerateSystemdOptions) (*entities.GenerateSystemdReport, error) {
|
|
// First assume it's a container.
|
|
ctr, ctrErr := ic.Libpod.LookupContainer(nameOrID)
|
|
if ctrErr == nil {
|
|
// Generate the unit for the container.
|
|
name, content, err := generate.ContainerUnit(ctr, options)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &entities.GenerateSystemdReport{Units: map[string]string{name: content}}, nil
|
|
}
|
|
|
|
// If it's not a container, we either have a pod or garbage.
|
|
pod, err := ic.Libpod.LookupPod(nameOrID)
|
|
if err != nil {
|
|
err = errors.Wrap(ctrErr, err.Error())
|
|
return nil, errors.Wrapf(err, "%s does not refer to a container or pod", nameOrID)
|
|
}
|
|
|
|
// Generate the units for the pod and all its containers.
|
|
units, err := generate.PodUnits(pod, options)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &entities.GenerateSystemdReport{Units: units}, nil
|
|
}
|
|
|
|
func (ic *ContainerEngine) GenerateKube(ctx context.Context, nameOrIDs []string, options entities.GenerateKubeOptions) (*entities.GenerateKubeReport, error) {
|
|
var (
|
|
pods []*libpod.Pod
|
|
podYAML *k8sAPI.Pod
|
|
err error
|
|
ctrs []*libpod.Container
|
|
servicePorts []k8sAPI.ServicePort
|
|
serviceYAML k8sAPI.Service
|
|
)
|
|
for _, nameOrID := range nameOrIDs {
|
|
// Get the container in question
|
|
ctr, err := ic.Libpod.LookupContainer(nameOrID)
|
|
if err != nil {
|
|
pod, err := ic.Libpod.LookupPod(nameOrID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
pods = append(pods, pod)
|
|
if len(pods) > 1 {
|
|
return nil, errors.New("can only generate single pod at a time")
|
|
}
|
|
} else {
|
|
if len(ctr.Dependencies()) > 0 {
|
|
return nil, errors.Wrapf(define.ErrNotImplemented, "containers with dependencies")
|
|
}
|
|
// we cannot deal with ctrs already in a pod
|
|
if len(ctr.PodID()) > 0 {
|
|
return nil, errors.Errorf("container %s is associated with pod %s: use generate on the pod itself", ctr.ID(), ctr.PodID())
|
|
}
|
|
ctrs = append(ctrs, ctr)
|
|
}
|
|
}
|
|
|
|
// check our inputs
|
|
if len(pods) > 0 && len(ctrs) > 0 {
|
|
return nil, errors.New("cannot generate pods and containers at the same time")
|
|
}
|
|
|
|
if len(pods) == 1 {
|
|
podYAML, servicePorts, err = pods[0].GenerateForKube()
|
|
} else {
|
|
podYAML, err = libpod.GenerateForKube(ctrs)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if options.Service {
|
|
serviceYAML = libpod.GenerateKubeServiceFromV1Pod(podYAML, servicePorts)
|
|
}
|
|
|
|
content, err := generateKubeOutput(podYAML, &serviceYAML, options.Service)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &entities.GenerateKubeReport{Reader: bytes.NewReader(content)}, nil
|
|
}
|
|
|
|
func generateKubeOutput(podYAML *k8sAPI.Pod, serviceYAML *k8sAPI.Service, hasService bool) ([]byte, error) {
|
|
var (
|
|
output []byte
|
|
marshalledPod []byte
|
|
marshalledService []byte
|
|
err error
|
|
)
|
|
|
|
marshalledPod, err = yaml.Marshal(podYAML)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if hasService {
|
|
marshalledService, err = yaml.Marshal(serviceYAML)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
header := `# Generation of Kubernetes YAML is still under development!
|
|
#
|
|
# Save the output of this file and use kubectl create -f to import
|
|
# it into Kubernetes.
|
|
#
|
|
# Created with podman-%s
|
|
`
|
|
podmanVersion, err := define.GetVersion()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
output = append(output, []byte(fmt.Sprintf(header, podmanVersion.Version))...)
|
|
output = append(output, marshalledPod...)
|
|
if hasService {
|
|
output = append(output, []byte("---\n")...)
|
|
output = append(output, marshalledService...)
|
|
}
|
|
|
|
return output, nil
|
|
}
|