podman-remote generate kube

Allow the ability to generate kube YAML from the podman remote-client.

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude 2019-04-07 13:38:58 -05:00
parent 4596c39655
commit 80b2c097fe
9 changed files with 115 additions and 70 deletions

View file

@ -13,7 +13,6 @@ func getMainCommands() []*cobra.Command {
rootCommands := []*cobra.Command{
_commitCommand,
_execCommand,
_generateCommand,
_playCommand,
_loginCommand,
_logoutCommand,
@ -71,12 +70,6 @@ func getContainerSubCommands() []*cobra.Command {
}
}
func getGenerateSubCommands() []*cobra.Command {
return []*cobra.Command{
_containerKubeCommand,
}
}
// Commands that the local client implements
func getPlaySubCommands() []*cobra.Command {
return []*cobra.Command{

View file

@ -14,10 +14,15 @@ var (
Long: generateDescription,
RunE: commandRunE(),
}
// Commands that are universally implemented
generateCommands = []*cobra.Command{
_containerKubeCommand,
}
)
func init() {
generateCommand.Command = _generateCommand
generateCommand.AddCommand(getGenerateSubCommands()...)
generateCommand.AddCommand(generateCommands...)
generateCommand.SetUsageTemplate(UsageTemplate())
}

View file

@ -3,13 +3,11 @@ package main
import (
"fmt"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/adapter"
podmanVersion "github.com/containers/libpod/version"
"github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
)
var (
@ -42,14 +40,12 @@ func init() {
func generateKubeYAMLCmd(c *cliconfig.GenerateKubeValues) error {
var (
podYAML *v1.Pod
container *libpod.Container
err error
output []byte
pod *libpod.Pod
//podYAML *v1.Pod
err error
output []byte
//pod *libpod.Pod
marshalledPod []byte
marshalledService []byte
servicePorts []v1.ServicePort
)
args := c.InputArgs
@ -57,43 +53,27 @@ func generateKubeYAMLCmd(c *cliconfig.GenerateKubeValues) error {
return errors.Errorf("you must provide exactly one container|pod ID or name")
}
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
// Get the container in question
container, err = runtime.LookupContainer(args[0])
if err != nil {
pod, err = runtime.LookupPod(args[0])
if err != nil {
return err
}
podYAML, servicePorts, err = pod.GenerateForKube()
} else {
if len(container.Dependencies()) > 0 {
return errors.Wrapf(libpod.ErrNotImplemented, "containers with dependencies")
}
podYAML, err = container.GenerateForKube()
}
podYAML, serviceYAML, err := runtime.GenerateKube(c)
if err != nil {
return err
}
if c.Service {
serviceYAML := libpod.GenerateKubeServiceFromV1Pod(podYAML, servicePorts)
marshalledService, err = yaml.Marshal(serviceYAML)
if err != nil {
return err
}
}
// Marshall the results
marshalledPod, err = yaml.Marshal(podYAML)
if err != nil {
return err
}
if c.Service {
marshalledService, err = yaml.Marshal(serviceYAML)
if err != nil {
return err
}
}
header := `# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import

View file

@ -36,6 +36,7 @@ var mainCommands = []*cobra.Command{
_createCommand,
_eventsCommand,
_exportCommand,
_generateCommand,
_historyCommand,
&_imagesCommand,
_importCommand,

View file

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
v1 "k8s.io/api/core/v1"
"os"
"path/filepath"
"regexp"
@ -938,3 +939,37 @@ func envSliceToMap(env []string) map[string]string {
}
return m
}
// GenerateKube generates kubernetes yaml based on a pod or container
func GenerateKube(name string, service bool, r *libpod.Runtime) (*v1.Pod, *v1.Service, error) {
var (
pod *libpod.Pod
podYAML *v1.Pod
err error
container *libpod.Container
servicePorts []v1.ServicePort
serviceYAML v1.Service
)
// Get the container in question
container, err = r.LookupContainer(name)
if err != nil {
pod, err = r.LookupPod(name)
if err != nil {
return nil, nil, err
}
podYAML, servicePorts, err = pod.GenerateForKube()
} else {
if len(container.Dependencies()) > 0 {
return nil, nil, errors.Wrapf(libpod.ErrNotImplemented, "containers with dependencies")
}
podYAML, err = container.GenerateForKube()
}
if err != nil {
return nil, nil, err
}
if service {
serviceYAML = libpod.GenerateKubeServiceFromV1Pod(podYAML, servicePorts)
}
return podYAML, &serviceYAML, nil
}

View file

@ -98,6 +98,11 @@ type ImageSearchFilter (
star_count: int
)
type KubePodService (
pod: string,
service: string
)
type Container (
id: string,
image: string,
@ -1122,11 +1127,7 @@ method ImagesPrune(all: bool) -> (pruned: []string)
# GenerateKube generates a Kubernetes v1 Pod description of a Podman container or pod
# and its containers. The description is in YAML. See also [ReplayKube](ReplayKube).
# method GenerateKube() -> (notimplemented: NotImplemented)
# GenerateKubeService generates a Kubernetes v1 Service description of a Podman container or pod
# and its containers. The description is in YAML. See also [GenerateKube](GenerateKube).
# method GenerateKubeService() -> (notimplemented: NotImplemented)
method GenerateKube(name: string, service: bool) -> (pod: KubePodService)
# ReplayKube recreates a pod and its containers based on a Kubernetes v1 Pod description (in YAML)
# like that created by GenerateKube. See also [GenerateKube](GenerateKube).

View file

@ -7,6 +7,7 @@ import (
"context"
"io"
"io/ioutil"
"k8s.io/api/core/v1"
"os"
"text/template"
@ -404,27 +405,7 @@ func (r *LocalRuntime) Diff(c *cliconfig.DiffValues, to string) ([]archive.Chang
return r.Runtime.GetDiff("", to)
}
// func (r *LocalRuntime) joinContainerOrCreateRootlessUserNS(ctr *libpod.Container) (bool, int, error) {
// if os.Geteuid() == 0 {
// return false, 0, nil
// }
// s, err := ctr.State()
// if err != nil {
// return false, -1, err
// }
// opts := rootless.Opts{
// Argument: ctr.ID(),
// }
// if s == libpod.ContainerStateRunning || s == libpod.ContainerStatePaused {
// data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile)
// if err != nil {
// return false, -1, errors.Wrapf(err, "Container %s cannot read conmon PID file %q", ctr.ID(), ctr.Config().ConmonPidFile)
// }
// conmonPid, err := strconv.Atoi(string(data))
// if err != nil {
// return false, -1, errors.Wrapf(err, "Container %s cannot parse PID %q", ctr.ID(), data)
// }
// return rootless.JoinDirectUserAndMountNSWithOpts(uint(conmonPid), &opts)
// }
// return rootless.BecomeRootInUserNSWithOpts(&opts)
// }
// GenerateKube creates kubernetes email from containers and pods
func (r *LocalRuntime) GenerateKube(c *cliconfig.GenerateKubeValues) (*v1.Pod, *v1.Service, error) {
return shared.GenerateKube(c.InputArgs[0], c.Service, r.Runtime)
}

View file

@ -5,9 +5,11 @@ package adapter
import (
"bufio"
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
v1 "k8s.io/api/core/v1"
"os"
"strings"
"text/template"
@ -858,3 +860,20 @@ func stringToChangeType(change string) archive.ChangeType {
return archive.ChangeModify
}
}
// GenerateKube creates kubernetes email from containers and pods
func (r *LocalRuntime) GenerateKube(c *cliconfig.GenerateKubeValues) (*v1.Pod, *v1.Service, error) {
var (
pod v1.Pod
service v1.Service
)
reply, err := iopodman.GenerateKube().Call(r.Conn, c.InputArgs[0], c.Service)
if err != nil {
return nil, nil, errors.Wrap(err, "unable to create kubernetes YAML")
}
if err := json.Unmarshal([]byte(reply.Pod), &pod); err != nil {
return nil, nil, err
}
err = json.Unmarshal([]byte(reply.Service), &service)
return &pod, &service, err
}

View file

@ -0,0 +1,30 @@
// +build varlink
package varlinkapi
import (
"encoding/json"
"github.com/containers/libpod/cmd/podman/shared"
iopodman "github.com/containers/libpod/cmd/podman/varlink"
)
// GenerateKube ...
func (i *LibpodAPI) GenerateKube(call iopodman.VarlinkCall, name string, service bool) error {
pod, serv, err := shared.GenerateKube(name, service, i.Runtime)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
podB, err := json.Marshal(pod)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
servB, err := json.Marshal(serv)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
return call.ReplyGenerateKube(iopodman.KubePodService{
Pod: string(podB),
Service: string(servB),
})
}