mirror of
https://github.com/containers/podman.git
synced 2025-10-13 17:26:13 +08:00
Add Play
podman play kube adds the ability for the user to recreate pods and containers from a Kubernetes YAML file in libpod. Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
24
API.md
24
API.md
@ -31,6 +31,10 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
|
||||
|
||||
[func ExportImage(name: string, destination: string, compress: bool, tags: []string) string](#ExportImage)
|
||||
|
||||
[func GenerateKube() NotImplemented](#GenerateKube)
|
||||
|
||||
[func GenerateKubeService() NotImplemented](#GenerateKubeService)
|
||||
|
||||
[func GetAttachSockets(name: string) Sockets](#GetAttachSockets)
|
||||
|
||||
[func GetContainer(name: string) ListContainerData](#GetContainer)
|
||||
@ -99,6 +103,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
|
||||
|
||||
[func RenameContainer() NotImplemented](#RenameContainer)
|
||||
|
||||
[func ReplayKube() NotImplemented](#ReplayKube)
|
||||
|
||||
[func ResizeContainerTty() NotImplemented](#ResizeContainerTty)
|
||||
|
||||
[func RestartContainer(name: string, timeout: int) string](#RestartContainer)
|
||||
@ -358,6 +364,18 @@ a booleon option to force compression. It also takes in a string array of tags
|
||||
tags of the same image to a tarball (each tag should be of the form <image>:<tag>). Upon completion, the ID
|
||||
of the image is returned. If the image cannot be found in local storage, an [ImageNotFound](#ImageNotFound)
|
||||
error will be returned. See also [ImportImage](ImportImage).
|
||||
### <a name="GenerateKube"></a>func GenerateKube
|
||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||
|
||||
method GenerateKube() [NotImplemented](#NotImplemented)</div>
|
||||
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).
|
||||
### <a name="GenerateKubeService"></a>func GenerateKubeService
|
||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||
|
||||
method GenerateKubeService() [NotImplemented](#NotImplemented)</div>
|
||||
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).
|
||||
### <a name="GetAttachSockets"></a>func GetAttachSockets
|
||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||
|
||||
@ -808,6 +826,12 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.RemovePod '{"name": "62f4
|
||||
|
||||
method RenameContainer() [NotImplemented](#NotImplemented)</div>
|
||||
This method has not be implemented yet.
|
||||
### <a name="ReplayKube"></a>func ReplayKube
|
||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||
|
||||
method ReplayKube() [NotImplemented](#NotImplemented)</div>
|
||||
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).
|
||||
### <a name="ResizeContainerTty"></a>func ResizeContainerTty
|
||||
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
|
||||
|
||||
|
@ -146,37 +146,10 @@ func createContainer(c *cli.Context, runtime *libpod.Runtime) (*libpod.Container
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
runtimeSpec, err := cc.CreateConfigToOCISpec(createConfig)
|
||||
ctr, err := createContainerFromCreateConfig(runtime, createConfig, ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
options, err := createConfig.GetContainerCreateOptions(runtime)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
became, ret, err := joinOrCreateRootlessUserNamespace(createConfig, runtime)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if became {
|
||||
os.Exit(ret)
|
||||
}
|
||||
|
||||
ctr, err := runtime.NewContainer(ctx, runtimeSpec, options...)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
createConfigJSON, err := json.Marshal(createConfig)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if err := ctr.AddArtifact("create-config", createConfigJSON); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if cidFile != nil {
|
||||
_, err = cidFile.WriteString(ctr.ID())
|
||||
if err != nil {
|
||||
@ -913,3 +886,37 @@ func joinOrCreateRootlessUserNamespace(createConfig *cc.CreateConfig, runtime *l
|
||||
}
|
||||
return rootless.BecomeRootInUserNS()
|
||||
}
|
||||
|
||||
func createContainerFromCreateConfig(r *libpod.Runtime, createConfig *cc.CreateConfig, ctx context.Context) (*libpod.Container, error) {
|
||||
runtimeSpec, err := cc.CreateConfigToOCISpec(createConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
options, err := createConfig.GetContainerCreateOptions(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
became, ret, err := joinOrCreateRootlessUserNamespace(createConfig, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if became {
|
||||
os.Exit(ret)
|
||||
}
|
||||
|
||||
ctr, err := r.NewContainer(ctx, runtimeSpec, options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
createConfigJSON, err := json.Marshal(createConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ctr.AddArtifact("create-config", createConfigJSON); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ctr, nil
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
// generateKubeYAMLCmdgenerates or replays kube
|
||||
func generateKubeYAMLCmd(c *cli.Context) error {
|
||||
var (
|
||||
podYAML *v1.Pod
|
||||
|
@ -90,6 +90,7 @@ func main() {
|
||||
portCommand,
|
||||
pullCommand,
|
||||
pushCommand,
|
||||
playCommand,
|
||||
restartCommand,
|
||||
rmCommand,
|
||||
rmiCommand,
|
||||
|
23
cmd/podman/play.go
Normal file
23
cmd/podman/play.go
Normal file
@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
playSubCommands = []cli.Command{
|
||||
playKubeCommand,
|
||||
}
|
||||
|
||||
playDescription = "Play a pod and its containers from a structured file."
|
||||
playCommand = cli.Command{
|
||||
Name: "play",
|
||||
Usage: "play a container or pod",
|
||||
Description: playDescription,
|
||||
ArgsUsage: "",
|
||||
Subcommands: playSubCommands,
|
||||
UseShortOptionHandling: true,
|
||||
OnUsageError: usageErrorHandler,
|
||||
Hidden: true,
|
||||
}
|
||||
)
|
245
cmd/podman/play_kube.go
Normal file
245
cmd/podman/play_kube.go
Normal file
@ -0,0 +1,245 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/types"
|
||||
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
||||
"github.com/containers/libpod/cmd/podman/shared"
|
||||
"github.com/containers/libpod/libpod"
|
||||
image2 "github.com/containers/libpod/libpod/image"
|
||||
ns "github.com/containers/libpod/pkg/namespaces"
|
||||
"github.com/containers/libpod/pkg/rootless"
|
||||
"github.com/containers/libpod/pkg/spec"
|
||||
"github.com/containers/storage"
|
||||
"github.com/cri-o/ocicni/pkg/ocicni"
|
||||
"github.com/ghodss/yaml"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
"k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
var (
|
||||
playKubeFlags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "authfile",
|
||||
Usage: "Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json. Use REGISTRY_AUTH_FILE environment variable to override. ",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "cert-dir",
|
||||
Usage: "`pathname` of a directory containing TLS certificates and keys",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "creds",
|
||||
Usage: "`credentials` (USERNAME:PASSWORD) to use for authenticating to a registry",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "quiet, q",
|
||||
Usage: "Suppress output information when pulling images",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "signature-policy",
|
||||
Usage: "`pathname` of signature policy file (not usually used)",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "tls-verify",
|
||||
Usage: "require HTTPS and verify certificates when contacting registries (default: true)",
|
||||
},
|
||||
}
|
||||
playKubeDescription = "Play a Pod and its containers based on a Kubrernetes YAML"
|
||||
playKubeCommand = cli.Command{
|
||||
Name: "kube",
|
||||
Usage: "Play a pod based on Kubernetes YAML",
|
||||
Description: playKubeDescription,
|
||||
Action: playKubeYAMLCmd,
|
||||
Flags: sortFlags(playKubeFlags),
|
||||
ArgsUsage: "kubernetes YAML file",
|
||||
UseShortOptionHandling: true,
|
||||
OnUsageError: usageErrorHandler,
|
||||
}
|
||||
)
|
||||
|
||||
func playKubeYAMLCmd(c *cli.Context) error {
|
||||
var (
|
||||
podOptions []libpod.PodCreateOption
|
||||
podYAML v1.Pod
|
||||
registryCreds *types.DockerAuthConfig
|
||||
containers []*libpod.Container
|
||||
writer io.Writer
|
||||
)
|
||||
|
||||
ctx := getContext()
|
||||
if rootless.IsRootless() {
|
||||
return errors.Wrapf(libpod.ErrNotImplemented, "rootless users")
|
||||
}
|
||||
args := c.Args()
|
||||
if len(args) > 1 {
|
||||
return errors.New("you can only play one kubernetes file at a time")
|
||||
}
|
||||
if len(args) < 1 {
|
||||
return errors.New("you must supply at least one file")
|
||||
}
|
||||
|
||||
runtime, err := libpodruntime.GetRuntime(c)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "could not get runtime")
|
||||
}
|
||||
defer runtime.Shutdown(false)
|
||||
|
||||
content, err := ioutil.ReadFile(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(content, &podYAML); err != nil {
|
||||
return errors.Wrapf(err, "unable to read %s as YAML", args[0])
|
||||
}
|
||||
|
||||
podOptions = append(podOptions, libpod.WithInfraContainer())
|
||||
podOptions = append(podOptions, libpod.WithPodName(podYAML.ObjectMeta.Name))
|
||||
// TODO for now we just used the default kernel namespaces; we need to add/subtract this from yaml
|
||||
|
||||
nsOptions, err := shared.GetNamespaceOptions(strings.Split(DefaultKernelNamespaces, ","))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
podOptions = append(podOptions, nsOptions...)
|
||||
podPorts := getPodPorts(podYAML.Spec.Containers)
|
||||
podOptions = append(podOptions, libpod.WithInfraContainerPorts(podPorts))
|
||||
|
||||
// Create the Pod
|
||||
pod, err := runtime.NewPod(ctx, podOptions...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Print the Pod's ID
|
||||
fmt.Println(pod.ID())
|
||||
|
||||
podInfraID, err := pod.InfraContainerID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespaces := map[string]string{
|
||||
// Disabled during code review per mheon
|
||||
//"pid": fmt.Sprintf("container:%s", podInfraID),
|
||||
"net": fmt.Sprintf("container:%s", podInfraID),
|
||||
"user": fmt.Sprintf("container:%s", podInfraID),
|
||||
"ipc": fmt.Sprintf("container:%s", podInfraID),
|
||||
"uts": fmt.Sprintf("container:%s", podInfraID),
|
||||
}
|
||||
if !c.Bool("quiet") {
|
||||
writer = os.Stderr
|
||||
}
|
||||
|
||||
dockerRegistryOptions := image2.DockerRegistryOptions{
|
||||
DockerRegistryCreds: registryCreds,
|
||||
DockerCertPath: c.String("cert-dir"),
|
||||
}
|
||||
if c.IsSet("tls-verify") {
|
||||
dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.BoolT("tls-verify"))
|
||||
}
|
||||
|
||||
for _, container := range podYAML.Spec.Containers {
|
||||
newImage, err := runtime.ImageRuntime().New(ctx, container.Image, c.String("signature-policy"), c.String("authfile"), writer, &dockerRegistryOptions, image2.SigningOptions{}, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createConfig := kubeContainerToCreateConfig(container, runtime, newImage, namespaces)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ctr, err := createContainerFromCreateConfig(runtime, createConfig, ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
containers = append(containers, ctr)
|
||||
}
|
||||
|
||||
// start the containers
|
||||
for _, ctr := range containers {
|
||||
if err := ctr.Start(ctx); err != nil {
|
||||
// Making this a hard failure here to avoid a mess
|
||||
// the other containers are in created status
|
||||
return err
|
||||
}
|
||||
fmt.Println(ctr.ID())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getPodPorts converts a slice of kube container descriptions to an
|
||||
// array of ocicni portmapping descriptions usable in libpod
|
||||
func getPodPorts(containers []v1.Container) []ocicni.PortMapping {
|
||||
var infraPorts []ocicni.PortMapping
|
||||
for _, container := range containers {
|
||||
for _, p := range container.Ports {
|
||||
portBinding := ocicni.PortMapping{
|
||||
HostPort: p.HostPort,
|
||||
ContainerPort: p.ContainerPort,
|
||||
Protocol: strings.ToLower(string(p.Protocol)),
|
||||
}
|
||||
if p.HostIP != "" {
|
||||
logrus.Debug("HostIP on port bindings is not supported")
|
||||
}
|
||||
infraPorts = append(infraPorts, portBinding)
|
||||
}
|
||||
}
|
||||
return infraPorts
|
||||
}
|
||||
|
||||
// kubeContainerToCreateConfig takes a v1.Container and returns a createconfig describing a container
|
||||
func kubeContainerToCreateConfig(containerYAML v1.Container, runtime *libpod.Runtime, newImage *image2.Image, namespaces map[string]string) *createconfig.CreateConfig {
|
||||
var (
|
||||
containerConfig createconfig.CreateConfig
|
||||
envs map[string]string
|
||||
)
|
||||
|
||||
containerConfig.Runtime = runtime
|
||||
containerConfig.Image = containerYAML.Image
|
||||
containerConfig.ImageID = newImage.ID()
|
||||
containerConfig.Name = containerYAML.Name
|
||||
containerConfig.Tty = containerYAML.TTY
|
||||
containerConfig.WorkDir = containerYAML.WorkingDir
|
||||
if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
|
||||
containerConfig.ReadOnlyRootfs = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
|
||||
}
|
||||
if containerYAML.SecurityContext.Privileged != nil {
|
||||
containerConfig.Privileged = *containerYAML.SecurityContext.Privileged
|
||||
}
|
||||
|
||||
if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
|
||||
containerConfig.NoNewPrivs = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
|
||||
}
|
||||
|
||||
containerConfig.Command = containerYAML.Command
|
||||
containerConfig.StopSignal = 15
|
||||
|
||||
// If the user does not pass in ID mappings, just set to basics
|
||||
if containerConfig.IDMappings == nil {
|
||||
containerConfig.IDMappings = &storage.IDMappingOptions{}
|
||||
}
|
||||
|
||||
containerConfig.NetMode = ns.NetworkMode(namespaces["net"])
|
||||
containerConfig.IpcMode = ns.IpcMode(namespaces["ipc"])
|
||||
containerConfig.UtsMode = ns.UTSMode(namespaces["uts"])
|
||||
// disabled in code review per mheon
|
||||
//containerConfig.PidMode = ns.PidMode(namespaces["pid"])
|
||||
containerConfig.UsernsMode = ns.UsernsMode(namespaces["user"])
|
||||
|
||||
if len(containerYAML.Env) > 0 {
|
||||
envs = make(map[string]string)
|
||||
}
|
||||
// Environment Variables
|
||||
for _, e := range containerYAML.Env {
|
||||
envs[e.Name] = e.Value
|
||||
}
|
||||
containerConfig.Env = envs
|
||||
return &containerConfig
|
||||
}
|
@ -1016,6 +1016,18 @@ method UnmountContainer(name: string, force: bool) -> ()
|
||||
# This function is not implemented yet.
|
||||
method ListContainerPorts(name: string) -> (notimplemented: NotImplemented)
|
||||
|
||||
# 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)
|
||||
|
||||
# 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).
|
||||
method ReplayKube() -> (notimplemented: NotImplemented)
|
||||
|
||||
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
|
||||
error ImageNotFound (name: string)
|
||||
|
||||
|
@ -895,6 +895,26 @@ _podman_generate() {
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_podman_play() {
|
||||
local boolean_options="
|
||||
--help
|
||||
-h
|
||||
"
|
||||
subcommands="
|
||||
kube
|
||||
"
|
||||
__podman_subcommands "$subcommands $aliases" && return
|
||||
|
||||
case "$cur" in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
}
|
||||
_podman_container() {
|
||||
local boolean_options="
|
||||
--help
|
||||
@ -2247,6 +2267,22 @@ _podman_generate_kube() {
|
||||
--service
|
||||
"
|
||||
|
||||
_podman_play_kube() {
|
||||
local options_with_args="
|
||||
--authfile
|
||||
--cert-dir
|
||||
--creds
|
||||
--signature-policy
|
||||
"
|
||||
|
||||
local boolean_options="
|
||||
-h
|
||||
--help
|
||||
--quiet
|
||||
-q
|
||||
--tls-verify
|
||||
"
|
||||
|
||||
_podman_container_runlabel() {
|
||||
local options_with_args="
|
||||
--authfile
|
||||
@ -2750,6 +2786,7 @@ _podman_podman() {
|
||||
ps
|
||||
pull
|
||||
push
|
||||
play
|
||||
restart
|
||||
rm
|
||||
rmi
|
||||
|
@ -145,7 +145,7 @@ status:
|
||||
```
|
||||
|
||||
## SEE ALSO
|
||||
podman(1), podman-container, podman-pod
|
||||
podman(1), podman-container, podman-pod, podman-play
|
||||
|
||||
# HISTORY
|
||||
Decemeber 2018, Originally compiled by Brent Baude (bbaude at redhat dot com)
|
||||
|
78
docs/podman-play-kube.1.md
Normal file
78
docs/podman-play-kube.1.md
Normal file
@ -0,0 +1,78 @@
|
||||
% podman-play-kube Podman Man Pages
|
||||
% Brent Baude
|
||||
% December 2018
|
||||
# NAME
|
||||
podman-play-kube - Create pods and containers based on Kubernetes YAML
|
||||
|
||||
# SYNOPSIS
|
||||
**podman play kube **
|
||||
[**-h**|**--help**]
|
||||
[**--authfile**]
|
||||
[**--cert-dir**]
|
||||
[**--creds**]
|
||||
[***-q** | **--quiet**]
|
||||
[**--signature-policy**]
|
||||
[**--tls-verify**]
|
||||
kubernetes_input.yml
|
||||
|
||||
# DESCRIPTION
|
||||
**podman play kube** will read in a structured file of Kubernetes YAML. It will then recreate
|
||||
the pod and containers described in the YAML. The containers within the pod are then started and
|
||||
the ID of the new Pod is output.
|
||||
|
||||
Ideally the input file would be one created by Podman. This would guarantee a smooth import and expected results.
|
||||
|
||||
# OPTIONS:
|
||||
|
||||
**--authfile**
|
||||
|
||||
Path of the authentication file. Default is ${XDG_RUNTIME\_DIR}/containers/auth.json, which is set using `podman login`.
|
||||
If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using `docker login`.
|
||||
|
||||
Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE
|
||||
environment variable. `export REGISTRY_AUTH_FILE=path`
|
||||
|
||||
**--cert-dir** *path*
|
||||
|
||||
Use certificates at *path* (\*.crt, \*.cert, \*.key) to connect to the registry.
|
||||
Default certificates directory is _/etc/containers/certs.d_.
|
||||
|
||||
**--creds**
|
||||
|
||||
The [username[:password]] to use to authenticate with the registry if required.
|
||||
If one or both values are not supplied, a command line prompt will appear and the
|
||||
value can be entered. The password is entered without echo.
|
||||
|
||||
**--quiet, -q**
|
||||
|
||||
Suppress output information when pulling images
|
||||
|
||||
**--signature-policy="PATHNAME"**
|
||||
|
||||
Pathname of a signature policy file to use. It is not recommended that this
|
||||
option be used, as the default behavior of using the system-wide default policy
|
||||
(frequently */etc/containers/policy.json*) is most often preferred.
|
||||
|
||||
**--tls-verify**
|
||||
|
||||
Require HTTPS and verify certificates when contacting registries (default: true). If explicitly set to true,
|
||||
then TLS verification will be used. If set to false, then TLS verification will not be used. If not specified,
|
||||
TLS verification will be used unless the target registry is listed as an insecure registry in registries.conf.
|
||||
|
||||
**--help**, **-h**
|
||||
|
||||
Print usage statement
|
||||
|
||||
## Examples ##
|
||||
|
||||
Recreate the pod and containers as described in a file called `demo.yml`
|
||||
```
|
||||
$ podman play kube demo.yml
|
||||
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
|
||||
```
|
||||
|
||||
## SEE ALSO
|
||||
podman(1), podman-container(1), podman-pod(1), podman-generate(1), podman-play(1)
|
||||
|
||||
# HISTORY
|
||||
Decemeber 2018, Originally compiled by Brent Baude (bbaude at redhat dot com)
|
20
docs/podman-play.1.md
Normal file
20
docs/podman-play.1.md
Normal file
@ -0,0 +1,20 @@
|
||||
% podman-play(1)
|
||||
|
||||
## NAME
|
||||
podman\-container - play pods and containers based on a structured input file
|
||||
|
||||
## SYNOPSIS
|
||||
**podman play** *subcommand*
|
||||
|
||||
## DESCRIPTION
|
||||
The play command will recreate pods and containers based on the input from a structured (like YAML)
|
||||
file input. Containers will be automatically started.
|
||||
|
||||
## COMMANDS
|
||||
|
||||
| Command | Man Page | Description |
|
||||
| ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| kube | [podman-play-kube(1)](podman-play-kube.1.md) | Recreate pods and containers based on Kubernetes YAML.
|
||||
|
||||
## SEE ALSO
|
||||
podman, podman-pod(1), podman-container(1), podman-generate(1), podman-play(1), podman-play-kube(1)
|
@ -30,7 +30,10 @@ func (c *Container) GenerateForKube() (*v1.Pod, error) {
|
||||
// one v1.Pod description
|
||||
func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
|
||||
// Generate the v1.Pod yaml description
|
||||
var servicePorts []v1.ServicePort
|
||||
var (
|
||||
servicePorts []v1.ServicePort
|
||||
ports []v1.ContainerPort
|
||||
)
|
||||
|
||||
allContainers, err := p.allContainers()
|
||||
if err != nil {
|
||||
@ -51,13 +54,13 @@ func (p *Pod) GenerateForKube() (*v1.Pod, []v1.ServicePort, error) {
|
||||
return nil, servicePorts, err
|
||||
}
|
||||
|
||||
ports, err := ocicniPortMappingToContainerPort(infraContainer.config.PortMappings)
|
||||
ports, err = ocicniPortMappingToContainerPort(infraContainer.config.PortMappings)
|
||||
if err != nil {
|
||||
return nil, servicePorts, err
|
||||
}
|
||||
servicePorts = containerPortsToServicePorts(ports)
|
||||
}
|
||||
pod, err := p.podWithContainers(allContainers)
|
||||
pod, err := p.podWithContainers(allContainers, ports)
|
||||
return pod, servicePorts, err
|
||||
}
|
||||
|
||||
@ -124,18 +127,27 @@ func containersToServicePorts(containers []v1.Container) []v1.ServicePort {
|
||||
return sps
|
||||
}
|
||||
|
||||
func (p *Pod) podWithContainers(containers []*Container) (*v1.Pod, error) {
|
||||
var podContainers []v1.Container
|
||||
func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPort) (*v1.Pod, error) {
|
||||
var (
|
||||
podContainers []v1.Container
|
||||
)
|
||||
first := true
|
||||
for _, ctr := range containers {
|
||||
if !ctr.IsInfra() {
|
||||
result, err := containerToV1Container(ctr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !ctr.IsInfra() {
|
||||
// We add the original port declarations from the libpod infra container
|
||||
// to the first kubernetes container description because otherwise we loose
|
||||
// the original container/port bindings.
|
||||
if first && len(ports) > 0 {
|
||||
result.Ports = ports
|
||||
first = false
|
||||
}
|
||||
podContainers = append(podContainers, result)
|
||||
}
|
||||
}
|
||||
|
||||
return addContainersToPodObject(podContainers, p.Name()), nil
|
||||
}
|
||||
|
||||
@ -150,7 +162,7 @@ func addContainersToPodObject(containers []v1.Container, podName string) *v1.Pod
|
||||
labels["app"] = removeUnderscores(podName)
|
||||
om := v12.ObjectMeta{
|
||||
// The name of the pod is container_name-libpod
|
||||
Name: fmt.Sprintf("%s-libpod", removeUnderscores(podName)),
|
||||
Name: fmt.Sprintf("%s", removeUnderscores(podName)),
|
||||
Labels: labels,
|
||||
// CreationTimestamp seems to be required, so adding it; in doing so, the timestamp
|
||||
// will reflect time this is run (not container create time) because the conversion
|
||||
|
Reference in New Issue
Block a user