mirror of
https://github.com/containers/podman
synced 2024-10-19 08:44:11 +00:00
Added option to share kernel namespaces in libpod and podman
A pause container is added to the pod if the user opts in. The default pause image and command can be overridden. Pause containers are ignored in ps unless the -a option is present. Pod inspect and pod ps show shared namespaces and pause container. A pause container can't be removed with podman rm, and a pod can be removed if it only has a pause container. Signed-off-by: haircommander <pehunt@redhat.com> Closes: #1187 Approved by: mheon
This commit is contained in:
parent
63dd200e7e
commit
d5e690914d
|
@ -368,16 +368,6 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
|
|||
|
||||
tty := c.Bool("tty")
|
||||
|
||||
pidMode := container.PidMode(c.String("pid"))
|
||||
if !cc.IsNS(string(pidMode)) && !pidMode.Valid() {
|
||||
return nil, errors.Errorf("--pid %q is not valid", c.String("pid"))
|
||||
}
|
||||
|
||||
usernsMode := container.UsernsMode(c.String("userns"))
|
||||
if !cc.IsNS(string(usernsMode)) && !usernsMode.Valid() {
|
||||
return nil, errors.Errorf("--userns %q is not valid", c.String("userns"))
|
||||
}
|
||||
|
||||
if c.Bool("detach") && c.Bool("rm") {
|
||||
return nil, errors.Errorf("--rm and --detach can not be specified together")
|
||||
}
|
||||
|
@ -388,14 +378,62 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
|
|||
return nil, errors.Errorf("--cpu-quota and --cpus cannot be set together")
|
||||
}
|
||||
|
||||
utsMode := container.UTSMode(c.String("uts"))
|
||||
if !cc.IsNS(string(utsMode)) && !utsMode.Valid() {
|
||||
// Kernel Namespaces
|
||||
var pod *libpod.Pod
|
||||
if c.IsSet("pod") {
|
||||
pod, err = runtime.LookupPod(c.String("pod"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
pidModeStr := c.String("pid")
|
||||
if !c.IsSet("pid") && pod != nil && pod.SharesPID() {
|
||||
pidModeStr = "pod"
|
||||
}
|
||||
pidMode := container.PidMode(pidModeStr)
|
||||
if !cc.Valid(string(pidMode), pidMode) {
|
||||
return nil, errors.Errorf("--pid %q is not valid", c.String("pid"))
|
||||
}
|
||||
|
||||
usernsModeStr := c.String("userns")
|
||||
if !c.IsSet("userns") && pod != nil && pod.SharesUser() {
|
||||
usernsModeStr = "pod"
|
||||
}
|
||||
usernsMode := container.UsernsMode(usernsModeStr)
|
||||
if !cc.Valid(string(usernsMode), usernsMode) {
|
||||
return nil, errors.Errorf("--userns %q is not valid", c.String("userns"))
|
||||
}
|
||||
|
||||
utsModeStr := c.String("uts")
|
||||
if !c.IsSet("uts") && pod != nil && pod.SharesUTS() {
|
||||
utsModeStr = "pod"
|
||||
}
|
||||
utsMode := container.UTSMode(utsModeStr)
|
||||
if !cc.Valid(string(utsMode), utsMode) {
|
||||
return nil, errors.Errorf("--uts %q is not valid", c.String("uts"))
|
||||
}
|
||||
ipcMode := container.IpcMode(c.String("ipc"))
|
||||
if !cc.IsNS(string(ipcMode)) && !ipcMode.Valid() {
|
||||
|
||||
ipcModeStr := c.String("ipc")
|
||||
if !c.IsSet("ipc") && pod != nil && pod.SharesIPC() {
|
||||
ipcModeStr = "pod"
|
||||
}
|
||||
ipcMode := container.IpcMode(ipcModeStr)
|
||||
if !cc.Valid(string(ipcMode), ipcMode) {
|
||||
return nil, errors.Errorf("--ipc %q is not valid", ipcMode)
|
||||
}
|
||||
netModeStr := c.String("net")
|
||||
if !c.IsSet("net") && pod != nil && pod.SharesNet() {
|
||||
netModeStr = "pod"
|
||||
}
|
||||
// Make sure if network is set to container namespace, port binding is not also being asked for
|
||||
netMode := container.NetworkMode(netModeStr)
|
||||
if netMode.IsContainer() || cc.IsPod(netModeStr) {
|
||||
if len(c.StringSlice("publish")) > 0 || c.Bool("publish-all") {
|
||||
return nil, errors.Errorf("cannot set port bindings on an existing container network namespace")
|
||||
}
|
||||
}
|
||||
|
||||
shmDir := ""
|
||||
if ipcMode.IsHost() {
|
||||
shmDir = "/dev/shm"
|
||||
|
@ -534,14 +572,6 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim
|
|||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to translate --shm-size")
|
||||
}
|
||||
// Network
|
||||
netMode := container.NetworkMode(c.String("network"))
|
||||
// Make sure if network is set to container namespace, port binding is not also being asked for
|
||||
if netMode.IsContainer() {
|
||||
if len(c.StringSlice("publish")) > 0 || c.Bool("publish-all") {
|
||||
return nil, errors.Errorf("cannot set port bindings on an existing container network namespace")
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the additional hosts are in correct format
|
||||
for _, host := range c.StringSlice("add-host") {
|
||||
|
|
|
@ -124,5 +124,14 @@ func GetRuntimeWithStorageOpts(c *cli.Context, storageOpts *storage.StoreOptions
|
|||
|
||||
// TODO flag to set CNI plugins dir?
|
||||
|
||||
// Pod create options
|
||||
if c.IsSet("pause-image") {
|
||||
options = append(options, libpod.WithDefaultPauseImage(c.String("pause-image")))
|
||||
}
|
||||
|
||||
if c.IsSet("pause-command") {
|
||||
options = append(options, libpod.WithDefaultPauseCommand(c.String("pause-command")))
|
||||
}
|
||||
|
||||
return libpod.NewRuntime(options...)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
||||
"github.com/containers/libpod/libpod"
|
||||
|
@ -11,6 +12,11 @@ import (
|
|||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
// CRI-O default kernel namespaces
|
||||
DefaultKernelNamespaces = "ipc,net,uts"
|
||||
)
|
||||
|
||||
var podCreateDescription = "Creates a new empty pod. The pod ID is then" +
|
||||
" printed to stdout. You can then start it at any time with the" +
|
||||
" podman pod start <pod_id> command. The pod will be created with the" +
|
||||
|
@ -33,10 +39,27 @@ var podCreateFlags = []cli.Flag{
|
|||
Name: "name, n",
|
||||
Usage: "Assign a name to the pod",
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "pause",
|
||||
Usage: "Create a pause container associated with the pod to share namespaces with",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "pause-image",
|
||||
Usage: "The image of the pause container to associate with the pod",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "pause-command",
|
||||
Usage: "The command to run on the pause container when the pod is started",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "pod-id-file",
|
||||
Usage: "Write the pod ID to the file",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "share",
|
||||
Usage: "A comma deliminated list of kernel namespaces the pod will share",
|
||||
Value: DefaultKernelNamespaces,
|
||||
},
|
||||
}
|
||||
|
||||
var podCreateCommand = cli.Command{
|
||||
|
@ -71,6 +94,9 @@ func podCreateCmd(c *cli.Context) error {
|
|||
return errors.Wrapf(err, "unable to write pod id file %s", c.String("pod-id-file"))
|
||||
}
|
||||
}
|
||||
if !c.BoolT("pause") && c.IsSet("share") && c.String("share") != "none" && c.String("share") != "" {
|
||||
return errors.Errorf("You cannot share kernel namespaces on the pod level without a pause container")
|
||||
}
|
||||
|
||||
if c.IsSet("cgroup-parent") {
|
||||
options = append(options, libpod.WithPodCgroupParent(c.String("cgroup-parent")))
|
||||
|
@ -88,10 +114,39 @@ func podCreateCmd(c *cli.Context) error {
|
|||
options = append(options, libpod.WithPodName(c.String("name")))
|
||||
}
|
||||
|
||||
if c.BoolT("pause") {
|
||||
options = append(options, libpod.WithPauseContainer())
|
||||
for _, toShare := range strings.Split(c.String("share"), ",") {
|
||||
switch toShare {
|
||||
case "net":
|
||||
options = append(options, libpod.WithPodNet())
|
||||
case "mnt":
|
||||
//options = append(options, libpod.WithPodMNT())
|
||||
logrus.Debug("Mount Namespace sharing functionality not supported")
|
||||
case "pid":
|
||||
options = append(options, libpod.WithPodPID())
|
||||
case "user":
|
||||
// Note: more set up needs to be done before this doesn't error out a create.
|
||||
logrus.Debug("User Namespace sharing functionality not supported")
|
||||
case "ipc":
|
||||
options = append(options, libpod.WithPodIPC())
|
||||
case "uts":
|
||||
options = append(options, libpod.WithPodUTS())
|
||||
case "":
|
||||
case "none":
|
||||
continue
|
||||
default:
|
||||
return errors.Errorf("Invalid kernel namespace to share: %s. Options are: %s, or none", toShare, strings.Join(libpod.KernelNamespaces, ","))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// always have containers use pod cgroups
|
||||
// User Opt out is not yet supported
|
||||
options = append(options, libpod.WithPodCgroups())
|
||||
|
||||
pod, err := runtime.NewPod(options...)
|
||||
ctx := getContext()
|
||||
pod, err := runtime.NewPod(ctx, options...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -56,8 +56,9 @@ type podPsTemplateParams struct {
|
|||
NumberOfContainers int
|
||||
Status string
|
||||
Cgroup string
|
||||
UsePodCgroup bool
|
||||
ContainerInfo string
|
||||
PauseContainerID string
|
||||
SharedNamespaces string
|
||||
}
|
||||
|
||||
// podPsJSONParams is used as a base structure for the psParams
|
||||
|
@ -73,7 +74,8 @@ type podPsJSONParams struct {
|
|||
Status string `json:"status"`
|
||||
CtrsInfo []podPsCtrInfo `json:"containerinfo,omitempty"`
|
||||
Cgroup string `json:"cgroup,omitempty"`
|
||||
UsePodCgroup bool `json:"podcgroup,omitempty"`
|
||||
PauseContainerID string `json:"pausecontainerid,omitempty"`
|
||||
SharedNamespaces []string `json:"sharednamespaces,omitempty"`
|
||||
}
|
||||
|
||||
// Type declaration and functions for sorting the pod PS output
|
||||
|
@ -110,10 +112,6 @@ func (a podPsSortedStatus) Less(i, j int) bool {
|
|||
|
||||
var (
|
||||
podPsFlags = []cli.Flag{
|
||||
cli.BoolFlag{
|
||||
Name: "cgroup",
|
||||
Usage: "Print the Cgroup information of the pod",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "ctr-names",
|
||||
Usage: "Display the container names",
|
||||
|
@ -138,6 +136,10 @@ var (
|
|||
Name: "latest, l",
|
||||
Usage: "Show the latest pod created",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "namespace, ns",
|
||||
Usage: "Display namespace information of the pod",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "no-trunc",
|
||||
Usage: "Do not truncate pod and container IDs",
|
||||
|
@ -348,14 +350,15 @@ func genPodPsFormat(c *cli.Context) string {
|
|||
format = formats.IDString
|
||||
} else {
|
||||
format = "table {{.ID}}\t{{.Name}}\t{{.Status}}\t{{.Created}}"
|
||||
if c.Bool("cgroup") {
|
||||
format += "\t{{.Cgroup}}\t{{.UsePodCgroup}}"
|
||||
if c.Bool("namespace") {
|
||||
format += "\t{{.Cgroup}}\t{{.SharedNamespaces}}"
|
||||
}
|
||||
if c.Bool("ctr-names") || c.Bool("ctr-ids") || c.Bool("ctr-status") {
|
||||
format += "\t{{.ContainerInfo}}"
|
||||
} else {
|
||||
format += "\t{{.NumberOfContainers}}"
|
||||
}
|
||||
format += "\t{{.PauseContainerID}}"
|
||||
}
|
||||
return format
|
||||
}
|
||||
|
@ -415,6 +418,7 @@ func getPodTemplateOutput(psParams []podPsJSONParams, opts podPsOptions) ([]podP
|
|||
|
||||
for _, psParam := range psParams {
|
||||
podID := psParam.ID
|
||||
pauseID := psParam.PauseContainerID
|
||||
var ctrStr string
|
||||
|
||||
truncated := ""
|
||||
|
@ -424,6 +428,7 @@ func getPodTemplateOutput(psParams []podPsJSONParams, opts podPsOptions) ([]podP
|
|||
psParam.CtrsInfo = psParam.CtrsInfo[:NUM_CTR_INFO]
|
||||
truncated = "..."
|
||||
}
|
||||
pauseID = shortID(pauseID)
|
||||
}
|
||||
for _, ctrInfo := range psParam.CtrsInfo {
|
||||
ctrStr += "[ "
|
||||
|
@ -449,9 +454,10 @@ func getPodTemplateOutput(psParams []podPsJSONParams, opts podPsOptions) ([]podP
|
|||
Name: psParam.Name,
|
||||
Status: psParam.Status,
|
||||
NumberOfContainers: psParam.NumberOfContainers,
|
||||
UsePodCgroup: psParam.UsePodCgroup,
|
||||
Cgroup: psParam.Cgroup,
|
||||
ContainerInfo: ctrStr,
|
||||
PauseContainerID: pauseID,
|
||||
SharedNamespaces: strings.Join(psParam.SharedNamespaces, ","),
|
||||
}
|
||||
|
||||
psOutput = append(psOutput, params)
|
||||
|
@ -460,6 +466,32 @@ func getPodTemplateOutput(psParams []podPsJSONParams, opts podPsOptions) ([]podP
|
|||
return psOutput, nil
|
||||
}
|
||||
|
||||
func getSharedNamespaces(pod *libpod.Pod) []string {
|
||||
var shared []string
|
||||
if pod.SharesPID() {
|
||||
shared = append(shared, "pid")
|
||||
}
|
||||
if pod.SharesNet() {
|
||||
shared = append(shared, "net")
|
||||
}
|
||||
if pod.SharesMNT() {
|
||||
shared = append(shared, "mnt")
|
||||
}
|
||||
if pod.SharesIPC() {
|
||||
shared = append(shared, "ipc")
|
||||
}
|
||||
if pod.SharesUser() {
|
||||
shared = append(shared, "user")
|
||||
}
|
||||
if pod.SharesCgroup() {
|
||||
shared = append(shared, "cgroup")
|
||||
}
|
||||
if pod.SharesUTS() {
|
||||
shared = append(shared, "uts")
|
||||
}
|
||||
return shared
|
||||
}
|
||||
|
||||
// getAndSortPodJSONOutput returns the container info in its raw, sorted form
|
||||
func getAndSortPodJSONParams(pods []*libpod.Pod, opts podPsOptions, runtime *libpod.Runtime) ([]podPsJSONParams, error) {
|
||||
var (
|
||||
|
@ -478,6 +510,10 @@ func getAndSortPodJSONParams(pods []*libpod.Pod, opts podPsOptions, runtime *lib
|
|||
return nil, err
|
||||
}
|
||||
|
||||
pauseContainerID, err := pod.PauseContainerID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, ctr := range ctrs {
|
||||
batchInfo, err := shared.BatchContainerOp(ctr, bc_opts)
|
||||
if err != nil {
|
||||
|
@ -508,9 +544,10 @@ func getAndSortPodJSONParams(pods []*libpod.Pod, opts podPsOptions, runtime *lib
|
|||
Name: pod.Name(),
|
||||
Status: status,
|
||||
Cgroup: pod.CgroupParent(),
|
||||
UsePodCgroup: pod.UsePodCgroup(),
|
||||
NumberOfContainers: ctrNum,
|
||||
CtrsInfo: ctrsInfo,
|
||||
SharedNamespaces: getSharedNamespaces(pod),
|
||||
PauseContainerID: pauseContainerID,
|
||||
}
|
||||
|
||||
psOutput = append(psOutput, params)
|
||||
|
|
|
@ -44,6 +44,7 @@ type psTemplateParams struct {
|
|||
User string
|
||||
UTS string
|
||||
Pod string
|
||||
IsPause bool
|
||||
}
|
||||
|
||||
// psJSONParams is used as a base structure for the psParams
|
||||
|
@ -71,6 +72,7 @@ type psJSONParams struct {
|
|||
ContainerRunning bool `json:"ctrRunning"`
|
||||
Namespaces *shared.Namespace `json:"namespace,omitempty"`
|
||||
Pod string `json:"pod,omitempty"`
|
||||
IsPause bool `json:"pause"`
|
||||
}
|
||||
|
||||
// Type declaration and functions for sorting the PS output
|
||||
|
@ -216,7 +218,7 @@ func psCmd(c *cli.Context) error {
|
|||
return errors.Errorf("too many arguments, ps takes no arguments")
|
||||
}
|
||||
|
||||
format := genPsFormat(c.String("format"), c.Bool("quiet"), c.Bool("size"), c.Bool("namespace"), c.Bool("pod"))
|
||||
format := genPsFormat(c.String("format"), c.Bool("quiet"), c.Bool("size"), c.Bool("namespace"), c.Bool("pod"), c.Bool("all"))
|
||||
|
||||
opts := shared.PsOptions{
|
||||
All: c.Bool("all"),
|
||||
|
@ -239,7 +241,8 @@ func psCmd(c *cli.Context) error {
|
|||
// only get running containers
|
||||
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
|
||||
state, _ := c.State()
|
||||
return state == libpod.ContainerStateRunning
|
||||
// Don't return pause containers
|
||||
return state == libpod.ContainerStateRunning && !c.IsPause()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -417,7 +420,7 @@ func generateContainerFilterFuncs(filter, filterValue string, runtime *libpod.Ru
|
|||
}
|
||||
|
||||
// generate the template based on conditions given
|
||||
func genPsFormat(format string, quiet, size, namespace, pod bool) string {
|
||||
func genPsFormat(format string, quiet, size, namespace, pod, pause bool) string {
|
||||
if format != "" {
|
||||
// "\t" from the command line is not being recognized as a tab
|
||||
// replacing the string "\t" to a tab character if the user passes in "\t"
|
||||
|
@ -431,13 +434,16 @@ func genPsFormat(format string, quiet, size, namespace, pod bool) string {
|
|||
podappend = "{{.Pod}}\t"
|
||||
}
|
||||
if namespace {
|
||||
return fmt.Sprintf("table {{.ID}}\t{{.Names}}\t%s{{.PID}}\t{{.Cgroup}}\t{{.IPC}}\t{{.MNT}}\t{{.NET}}\t{{.PIDNS}}\t{{.User}}\t{{.UTS}}\t", podappend)
|
||||
return fmt.Sprintf("table {{.ID}}\t{{.Names}}\t%s{{.PID}}\t{{.Cgroup}}\t{{.IPC}}\t{{.MNT}}\t{{.NET}}\t{{.PIDNS}}\t{{.User}}\t{{.UTS}}", podappend)
|
||||
}
|
||||
format = "table {{.ID}}\t{{.Image}}\t{{.Command}}\t{{.Created}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}\t"
|
||||
format += podappend
|
||||
if size {
|
||||
format += "{{.Size}}\t"
|
||||
}
|
||||
if pause {
|
||||
format += "{{.IsPause}}\t"
|
||||
}
|
||||
return format
|
||||
}
|
||||
|
||||
|
@ -572,6 +578,7 @@ func getTemplateOutput(psParams []psJSONParams, opts shared.PsOptions) ([]psTemp
|
|||
Mounts: getMounts(psParam.Mounts, opts.NoTrunc),
|
||||
PID: psParam.PID,
|
||||
Pod: pod,
|
||||
IsPause: psParam.IsPause,
|
||||
}
|
||||
|
||||
if opts.Namespace {
|
||||
|
@ -628,6 +635,7 @@ func getAndSortJSONParams(containers []*libpod.Container, opts shared.PsOptions)
|
|||
ContainerRunning: batchInfo.ConState == libpod.ContainerStateRunning,
|
||||
Namespaces: ns,
|
||||
Pod: ctr.PodID(),
|
||||
IsPause: ctr.IsPause(),
|
||||
}
|
||||
|
||||
psOutput = append(psOutput, params)
|
||||
|
|
|
@ -2077,6 +2077,9 @@ _podman_logout() {
|
|||
_podman_pod_create() {
|
||||
local options_with_args="
|
||||
--cgroup-parent
|
||||
--share
|
||||
--pause-command
|
||||
--pause-image
|
||||
--podidfile
|
||||
--label-file
|
||||
--label
|
||||
|
@ -2085,6 +2088,7 @@ _podman_pod_create() {
|
|||
"
|
||||
|
||||
local boolean_options="
|
||||
--pause
|
||||
"
|
||||
_complete_ "$options_with_args" "$boolean_options"
|
||||
}
|
||||
|
|
|
@ -39,6 +39,22 @@ Read in a line delimited file of labels
|
|||
|
||||
Assign a name to the pod
|
||||
|
||||
**--pause**
|
||||
|
||||
Create a pause container and associate it with the pod. A pause container is a lightweight container used to coordinate the shared kernel namespace of a pod. Default: true
|
||||
|
||||
**--pause-command**=""
|
||||
|
||||
The command that will be run to start the pause container. Default: "/pause"
|
||||
|
||||
**--pause-image**=""
|
||||
|
||||
The image that will be created for the pause container. Default: "k8s.gcr.io/pause:3.1"
|
||||
|
||||
**--share**=""
|
||||
|
||||
A comma deliminated list of kernel namespaces to share. If none or "" is specified, no namespaces will be shared. The namespaces to choose from are ipc, net, pid, user, uts.
|
||||
|
||||
The operator can identify a pod in three ways:
|
||||
UUID long identifier (“f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”)
|
||||
UUID short identifier (“f78375b1c487”)
|
||||
|
@ -53,6 +69,10 @@ for it. The name is useful any place you need to identify a pod.
|
|||
|
||||
# podman pod create --name test
|
||||
|
||||
# podman pod create --pause=false
|
||||
|
||||
# podman pod create --pause-command /top
|
||||
|
||||
## SEE ALSO
|
||||
podman-pod(1)
|
||||
|
||||
|
|
|
@ -65,3 +65,9 @@ cni_plugin_dir = [
|
|||
# The default namespace is "", which corresponds to no namespace. When no
|
||||
# namespace is set, all containers and pods are visible.
|
||||
#namespace = ""
|
||||
|
||||
# Default pause image name for pod pause containers
|
||||
pause_image = "k8s.gcr.io/pause:3.1"
|
||||
|
||||
# Default command to run the pause container
|
||||
pause_command = "/pause"
|
||||
|
|
|
@ -252,6 +252,19 @@ type ContainerConfig struct {
|
|||
UTSNsCtr string `json:"utsNsCtr,omitempty"`
|
||||
CgroupNsCtr string `json:"cgroupNsCtr,omitempty"`
|
||||
|
||||
// Whether container shares an NS with the pod
|
||||
// NetNsPod conflicts with the CreateNetNS bool
|
||||
// {namespace}NsPod conflicts with {namespace}NsCtr
|
||||
// The pause container will be considered dependencies of the given container
|
||||
// It must be started before the given container is started
|
||||
IPCNsPod bool `json:"ipcNsPod,omitempty"`
|
||||
MountNsPod bool `json:"mountNsPod,omitempty"`
|
||||
NetNsPod bool `json:"netNsPod,omitempty"`
|
||||
PIDNsPod bool `json:"pidNsPod,omitempty"`
|
||||
UserNsPod bool `json:"userNsPod,omitempty"`
|
||||
UTSNsPod bool `json:"utsNsPod,omitempty"`
|
||||
CgroupNsPod bool `json:"cgroupNsPod,omitempty"`
|
||||
|
||||
// IDs of dependency containers.
|
||||
// These containers must be started before this container is started.
|
||||
Dependencies []string
|
||||
|
@ -328,6 +341,10 @@ type ContainerConfig struct {
|
|||
// LocalVolumes are the built-in volumes we get from the --volumes-from flag
|
||||
// It picks up the built-in volumes of the container used by --volumes-from
|
||||
LocalVolumes []string
|
||||
|
||||
// IsPause is a bool indicating whether this container is a pause container used for
|
||||
// sharing kernel namespaces in a pod
|
||||
IsPause bool `json:"pause"`
|
||||
}
|
||||
|
||||
// ContainerStatus returns a string representation for users
|
||||
|
@ -956,3 +973,8 @@ func (c *Container) RootGID() int {
|
|||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// IsPause returns whether the container is a pause container
|
||||
func (c *Container) IsPause() bool {
|
||||
return c.config.IsPause
|
||||
}
|
||||
|
|
|
@ -194,6 +194,62 @@ func (j *ContainerConfig) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
|
|||
fflib.WriteJsonString(buf, string(j.CgroupNsCtr))
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.IPCNsPod != false {
|
||||
if j.IPCNsPod {
|
||||
buf.WriteString(`"ipcNsPod":true`)
|
||||
} else {
|
||||
buf.WriteString(`"ipcNsPod":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.MountNsPod != false {
|
||||
if j.MountNsPod {
|
||||
buf.WriteString(`"mountNsPod":true`)
|
||||
} else {
|
||||
buf.WriteString(`"mountNsPod":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.NetNsPod != false {
|
||||
if j.NetNsPod {
|
||||
buf.WriteString(`"netNsPod":true`)
|
||||
} else {
|
||||
buf.WriteString(`"netNsPod":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.PIDNsPod != false {
|
||||
if j.PIDNsPod {
|
||||
buf.WriteString(`"pidNsPod":true`)
|
||||
} else {
|
||||
buf.WriteString(`"pidNsPod":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.UserNsPod != false {
|
||||
if j.UserNsPod {
|
||||
buf.WriteString(`"userNsPod":true`)
|
||||
} else {
|
||||
buf.WriteString(`"userNsPod":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.UTSNsPod != false {
|
||||
if j.UTSNsPod {
|
||||
buf.WriteString(`"utsNsPod":true`)
|
||||
} else {
|
||||
buf.WriteString(`"utsNsPod":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.CgroupNsPod != false {
|
||||
if j.CgroupNsPod {
|
||||
buf.WriteString(`"cgroupNsPod":true`)
|
||||
} else {
|
||||
buf.WriteString(`"cgroupNsPod":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
buf.WriteString(`"Dependencies":`)
|
||||
if j.Dependencies != nil {
|
||||
buf.WriteString(`[`)
|
||||
|
@ -461,6 +517,11 @@ func (j *ContainerConfig) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
|
|||
} else {
|
||||
buf.WriteString(`null`)
|
||||
}
|
||||
if j.IsPause {
|
||||
buf.WriteString(`,"pause":true`)
|
||||
} else {
|
||||
buf.WriteString(`,"pause":false`)
|
||||
}
|
||||
buf.WriteByte('}')
|
||||
return nil
|
||||
}
|
||||
|
@ -521,6 +582,20 @@ const (
|
|||
|
||||
ffjtContainerConfigCgroupNsCtr
|
||||
|
||||
ffjtContainerConfigIPCNsPod
|
||||
|
||||
ffjtContainerConfigMountNsPod
|
||||
|
||||
ffjtContainerConfigNetNsPod
|
||||
|
||||
ffjtContainerConfigPIDNsPod
|
||||
|
||||
ffjtContainerConfigUserNsPod
|
||||
|
||||
ffjtContainerConfigUTSNsPod
|
||||
|
||||
ffjtContainerConfigCgroupNsPod
|
||||
|
||||
ffjtContainerConfigDependencies
|
||||
|
||||
ffjtContainerConfigCreateNetNS
|
||||
|
@ -564,6 +639,8 @@ const (
|
|||
ffjtContainerConfigExitCommand
|
||||
|
||||
ffjtContainerConfigLocalVolumes
|
||||
|
||||
ffjtContainerConfigIsPause
|
||||
)
|
||||
|
||||
var ffjKeyContainerConfigSpec = []byte("spec")
|
||||
|
@ -618,6 +695,20 @@ var ffjKeyContainerConfigUTSNsCtr = []byte("utsNsCtr")
|
|||
|
||||
var ffjKeyContainerConfigCgroupNsCtr = []byte("cgroupNsCtr")
|
||||
|
||||
var ffjKeyContainerConfigIPCNsPod = []byte("ipcNsPod")
|
||||
|
||||
var ffjKeyContainerConfigMountNsPod = []byte("mountNsPod")
|
||||
|
||||
var ffjKeyContainerConfigNetNsPod = []byte("netNsPod")
|
||||
|
||||
var ffjKeyContainerConfigPIDNsPod = []byte("pidNsPod")
|
||||
|
||||
var ffjKeyContainerConfigUserNsPod = []byte("userNsPod")
|
||||
|
||||
var ffjKeyContainerConfigUTSNsPod = []byte("utsNsPod")
|
||||
|
||||
var ffjKeyContainerConfigCgroupNsPod = []byte("cgroupNsPod")
|
||||
|
||||
var ffjKeyContainerConfigDependencies = []byte("Dependencies")
|
||||
|
||||
var ffjKeyContainerConfigCreateNetNS = []byte("createNetNS")
|
||||
|
@ -662,6 +753,8 @@ var ffjKeyContainerConfigExitCommand = []byte("exitCommand")
|
|||
|
||||
var ffjKeyContainerConfigLocalVolumes = []byte("LocalVolumes")
|
||||
|
||||
var ffjKeyContainerConfigIsPause = []byte("pause")
|
||||
|
||||
// UnmarshalJSON umarshall json - template of ffjson
|
||||
func (j *ContainerConfig) UnmarshalJSON(input []byte) error {
|
||||
fs := fflib.NewFFLexer(input)
|
||||
|
@ -770,6 +863,11 @@ mainparse:
|
|||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigCgroupNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigCgroupNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigCreateNetNS, kn) {
|
||||
currentKey = ffjtContainerConfigCreateNetNS
|
||||
state = fflib.FFParse_want_colon
|
||||
|
@ -864,6 +962,11 @@ mainparse:
|
|||
currentKey = ffjtContainerConfigIPCNsCtr
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigIPCNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigIPCNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
case 'l':
|
||||
|
@ -890,6 +993,11 @@ mainparse:
|
|||
currentKey = ffjtContainerConfigMountNsCtr
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigMountNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigMountNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
case 'n':
|
||||
|
@ -909,6 +1017,11 @@ mainparse:
|
|||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigNetNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigNetNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigNetworks, kn) {
|
||||
currentKey = ffjtContainerConfigNetworks
|
||||
state = fflib.FFParse_want_colon
|
||||
|
@ -932,6 +1045,11 @@ mainparse:
|
|||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigPIDNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigPIDNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigPortMappings, kn) {
|
||||
currentKey = ffjtContainerConfigPortMappings
|
||||
state = fflib.FFParse_want_colon
|
||||
|
@ -941,6 +1059,11 @@ mainparse:
|
|||
currentKey = ffjtContainerConfigPostConfigureNetNS
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigIsPause, kn) {
|
||||
currentKey = ffjtContainerConfigIsPause
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
case 'r':
|
||||
|
@ -1011,6 +1134,16 @@ mainparse:
|
|||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigUserNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigUserNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigUTSNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigUTSNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyContainerConfigUserVolumes, kn) {
|
||||
currentKey = ffjtContainerConfigUserVolumes
|
||||
state = fflib.FFParse_want_colon
|
||||
|
@ -1019,6 +1152,12 @@ mainparse:
|
|||
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigIsPause, kn) {
|
||||
currentKey = ffjtContainerConfigIsPause
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigLocalVolumes, kn) {
|
||||
currentKey = ffjtContainerConfigLocalVolumes
|
||||
state = fflib.FFParse_want_colon
|
||||
|
@ -1151,6 +1290,48 @@ mainparse:
|
|||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigCgroupNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigCgroupNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigUTSNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigUTSNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigUserNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigUserNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigPIDNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigPIDNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigNetNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigNetNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigMountNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigMountNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigIPCNsPod, kn) {
|
||||
currentKey = ffjtContainerConfigIPCNsPod
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyContainerConfigCgroupNsCtr, kn) {
|
||||
currentKey = ffjtContainerConfigCgroupNsCtr
|
||||
state = fflib.FFParse_want_colon
|
||||
|
@ -1402,6 +1583,27 @@ mainparse:
|
|||
case ffjtContainerConfigCgroupNsCtr:
|
||||
goto handle_CgroupNsCtr
|
||||
|
||||
case ffjtContainerConfigIPCNsPod:
|
||||
goto handle_IPCNsPod
|
||||
|
||||
case ffjtContainerConfigMountNsPod:
|
||||
goto handle_MountNsPod
|
||||
|
||||
case ffjtContainerConfigNetNsPod:
|
||||
goto handle_NetNsPod
|
||||
|
||||
case ffjtContainerConfigPIDNsPod:
|
||||
goto handle_PIDNsPod
|
||||
|
||||
case ffjtContainerConfigUserNsPod:
|
||||
goto handle_UserNsPod
|
||||
|
||||
case ffjtContainerConfigUTSNsPod:
|
||||
goto handle_UTSNsPod
|
||||
|
||||
case ffjtContainerConfigCgroupNsPod:
|
||||
goto handle_CgroupNsPod
|
||||
|
||||
case ffjtContainerConfigDependencies:
|
||||
goto handle_Dependencies
|
||||
|
||||
|
@ -1468,6 +1670,9 @@ mainparse:
|
|||
case ffjtContainerConfigLocalVolumes:
|
||||
goto handle_LocalVolumes
|
||||
|
||||
case ffjtContainerConfigIsPause:
|
||||
goto handle_IsPause
|
||||
|
||||
case ffjtContainerConfignosuchkey:
|
||||
err = fs.SkipField(tok)
|
||||
if err != nil {
|
||||
|
@ -2264,6 +2469,251 @@ handle_CgroupNsCtr:
|
|||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_IPCNsPod:
|
||||
|
||||
/* handler: j.IPCNsPod type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.IPCNsPod = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.IPCNsPod = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_MountNsPod:
|
||||
|
||||
/* handler: j.MountNsPod type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.MountNsPod = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.MountNsPod = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_NetNsPod:
|
||||
|
||||
/* handler: j.NetNsPod type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.NetNsPod = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.NetNsPod = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_PIDNsPod:
|
||||
|
||||
/* handler: j.PIDNsPod type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.PIDNsPod = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.PIDNsPod = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_UserNsPod:
|
||||
|
||||
/* handler: j.UserNsPod type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UserNsPod = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UserNsPod = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_UTSNsPod:
|
||||
|
||||
/* handler: j.UTSNsPod type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UTSNsPod = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UTSNsPod = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_CgroupNsPod:
|
||||
|
||||
/* handler: j.CgroupNsPod type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.CgroupNsPod = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.CgroupNsPod = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_Dependencies:
|
||||
|
||||
/* handler: j.Dependencies type=[]string kind=slice quoted=false*/
|
||||
|
@ -3523,6 +3973,41 @@ handle_LocalVolumes:
|
|||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_IsPause:
|
||||
|
||||
/* handler: j.IsPause type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.IsPause = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.IsPause = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
wantedvalue:
|
||||
return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
|
||||
wrongtokenerror:
|
||||
|
|
|
@ -104,6 +104,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data)
|
|||
IPv6Gateway: "",
|
||||
MacAddress: "", // TODO
|
||||
},
|
||||
IsPause: c.IsPause(),
|
||||
}
|
||||
|
||||
// Copy port mappings into network settings
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/containers/libpod/pkg/chrootuser"
|
||||
"github.com/containers/libpod/pkg/hooks"
|
||||
|
@ -23,13 +22,11 @@ import (
|
|||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/chrootarchive"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
"github.com/opencontainers/selinux/go-selinux/label"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/ulule/deepcopier"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
|
@ -174,38 +171,6 @@ func (c *Container) syncContainer() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Make a new container
|
||||
func newContainer(rspec *spec.Spec, lockDir string) (*Container, error) {
|
||||
if rspec == nil {
|
||||
return nil, errors.Wrapf(ErrInvalidArg, "must provide a valid runtime spec to create container")
|
||||
}
|
||||
|
||||
ctr := new(Container)
|
||||
ctr.config = new(ContainerConfig)
|
||||
ctr.state = new(containerState)
|
||||
|
||||
ctr.config.ID = stringid.GenerateNonCryptoID()
|
||||
|
||||
ctr.config.Spec = new(spec.Spec)
|
||||
deepcopier.Copy(rspec).To(ctr.config.Spec)
|
||||
ctr.config.CreatedTime = time.Now()
|
||||
|
||||
ctr.config.ShmSize = DefaultShmSize
|
||||
|
||||
ctr.state.BindMounts = make(map[string]string)
|
||||
|
||||
// Path our lock file will reside at
|
||||
lockPath := filepath.Join(lockDir, ctr.config.ID)
|
||||
// Grab a lockfile at the given path
|
||||
lock, err := storage.GetLockfile(lockPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error creating lockfile for new container")
|
||||
}
|
||||
ctr.lock = lock
|
||||
|
||||
return ctr, nil
|
||||
}
|
||||
|
||||
// Create container root filesystem for use
|
||||
func (c *Container) setupStorage(ctx context.Context) error {
|
||||
if !c.valid {
|
||||
|
|
|
@ -168,42 +168,91 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
|
|||
}
|
||||
}
|
||||
|
||||
var podInfraContainer string
|
||||
if c.config.Pod != "" {
|
||||
pod, err := c.runtime.state.LookupPod(c.config.Pod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if pod.SharesNamespaces() {
|
||||
if err := pod.updatePod(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
podInfraContainer = pod.state.PauseContainerID
|
||||
}
|
||||
}
|
||||
|
||||
// Add shared namespaces from other containers
|
||||
if c.config.IPCNsCtr != "" {
|
||||
if err := c.addNamespaceContainer(&g, IPCNS, c.config.IPCNsCtr, spec.IPCNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.IPCNsPod && podInfraContainer != "" {
|
||||
if err := c.addNamespaceContainer(&g, IPCNS, podInfraContainer, spec.IPCNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.MountNsCtr != "" {
|
||||
if err := c.addNamespaceContainer(&g, MountNS, c.config.MountNsCtr, spec.MountNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.MountNsPod && podInfraContainer != "" {
|
||||
if err := c.addNamespaceContainer(&g, MountNS, podInfraContainer, spec.MountNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.NetNsCtr != "" {
|
||||
if err := c.addNamespaceContainer(&g, NetNS, c.config.NetNsCtr, spec.NetworkNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.NetNsPod && podInfraContainer != "" {
|
||||
if err := c.addNamespaceContainer(&g, NetNS, podInfraContainer, spec.NetworkNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.PIDNsCtr != "" {
|
||||
if err := c.addNamespaceContainer(&g, PIDNS, c.config.PIDNsCtr, string(spec.PIDNamespace)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.PIDNsPod && podInfraContainer != "" {
|
||||
if err := c.addNamespaceContainer(&g, PIDNS, podInfraContainer, string(spec.PIDNamespace)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.UserNsCtr != "" {
|
||||
if err := c.addNamespaceContainer(&g, UserNS, c.config.UserNsCtr, spec.UserNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.UserNsPod && podInfraContainer != "" {
|
||||
if err := c.addNamespaceContainer(&g, UserNS, podInfraContainer, spec.UserNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.UTSNsCtr != "" {
|
||||
if err := c.addNamespaceContainer(&g, UTSNS, c.config.UTSNsCtr, spec.UTSNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.UTSNsPod && podInfraContainer != "" {
|
||||
if err := c.addNamespaceContainer(&g, UTSNS, podInfraContainer, spec.UTSNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.CgroupNsCtr != "" {
|
||||
if err := c.addNamespaceContainer(&g, CgroupNS, c.config.CgroupNsCtr, spec.CgroupNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.config.CgroupNsPod && podInfraContainer != "" {
|
||||
if err := c.addNamespaceContainer(&g, CgroupNS, podInfraContainer, spec.CgroupNamespace); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if c.config.Rootfs == "" {
|
||||
if err := idtools.MkdirAllAs(c.state.RealMountpoint, 0700, c.RootUID(), c.RootGID()); err != nil {
|
||||
|
|
|
@ -304,6 +304,37 @@ func WithNamespace(ns string) RuntimeOption {
|
|||
}
|
||||
}
|
||||
|
||||
// WithDefaultPauseImage sets the pause image for libpod.
|
||||
// A pause image is used for inter-container kernel
|
||||
// namespace sharing within a pod. Typically, a pause
|
||||
// container is lightweight and is there to reap
|
||||
// zombie processes within its pid namespace.
|
||||
func WithDefaultPauseImage(img string) RuntimeOption {
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return ErrRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.PauseImage = img
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithDefaultPauseCommand sets the command to
|
||||
// run on pause container start up.
|
||||
func WithDefaultPauseCommand(cmd string) RuntimeOption {
|
||||
return func(rt *Runtime) error {
|
||||
if rt.valid {
|
||||
return ErrRuntimeFinalized
|
||||
}
|
||||
|
||||
rt.config.PauseCommand = cmd
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Container Creation Options
|
||||
|
||||
// WithShmDir sets the directory that should be mounted on /dev/shm.
|
||||
|
@ -518,6 +549,132 @@ func WithExitCommand(exitCommand []string) CtrCreateOption {
|
|||
}
|
||||
}
|
||||
|
||||
// WithIPCNSFromPod indicates the the container should join the IPC namespace of
|
||||
// its pod
|
||||
func WithIPCNSFromPod() CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return ErrCtrFinalized
|
||||
}
|
||||
|
||||
if ctr.config.Pod == "" {
|
||||
return errors.Wrapf(ErrInvalidArg, "container is not a member of any pod")
|
||||
}
|
||||
|
||||
ctr.config.IPCNsPod = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithMountNSFromPod indicates the the container should join the Mount namespace of
|
||||
// its pod
|
||||
func WithMountNSFromPod() CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return ErrCtrFinalized
|
||||
}
|
||||
|
||||
if ctr.config.Pod == "" {
|
||||
return errors.Wrapf(ErrInvalidArg, "container is not a member of any pod")
|
||||
}
|
||||
|
||||
ctr.config.MountNsPod = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithNetNSFromPod indicates the the container should join the network namespace of
|
||||
// its pod
|
||||
func WithNetNSFromPod() CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return ErrCtrFinalized
|
||||
}
|
||||
|
||||
if ctr.config.Pod == "" {
|
||||
return errors.Wrapf(ErrInvalidArg, "container is not a member of any pod")
|
||||
}
|
||||
|
||||
ctr.config.NetNsPod = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPIDNSFromPod indicates the the container should join the PID namespace of
|
||||
// its pod
|
||||
func WithPIDNSFromPod() CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return ErrCtrFinalized
|
||||
}
|
||||
|
||||
if ctr.config.Pod == "" {
|
||||
return errors.Wrapf(ErrInvalidArg, "container is not a member of any pod")
|
||||
}
|
||||
|
||||
ctr.config.PIDNsPod = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithUTSNSFromPod indicates the the container should join the UTS namespace of
|
||||
// its pod
|
||||
func WithUTSNSFromPod() CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return ErrCtrFinalized
|
||||
}
|
||||
|
||||
if ctr.config.Pod == "" {
|
||||
return errors.Wrapf(ErrInvalidArg, "container is not a member of any pod")
|
||||
}
|
||||
|
||||
ctr.config.UTSNsPod = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithUserNSFromPod indicates the the container should join the User namespace of
|
||||
// its pod
|
||||
func WithUserNSFromPod() CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return ErrCtrFinalized
|
||||
}
|
||||
|
||||
if ctr.config.Pod == "" {
|
||||
return errors.Wrapf(ErrInvalidArg, "container is not a member of any pod")
|
||||
}
|
||||
|
||||
ctr.config.UserNsPod = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCgroupNSFromPod indicates the the container should join the Cgroup namespace of
|
||||
// its pod
|
||||
func WithCgroupNSFromPod() CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return ErrCtrFinalized
|
||||
}
|
||||
|
||||
if ctr.config.Pod == "" {
|
||||
return errors.Wrapf(ErrInvalidArg, "container is not a member of any pod")
|
||||
}
|
||||
|
||||
ctr.config.CgroupNsPod = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithIPCNSFrom indicates the the container should join the IPC namespace of
|
||||
// the given container.
|
||||
// If the container has joined a pod, it can only join the namespaces of
|
||||
|
@ -999,6 +1156,20 @@ func WithCtrNamespace(ns string) CtrCreateOption {
|
|||
}
|
||||
}
|
||||
|
||||
// withIsPause sets the container to be a pause container. This means the container will be sometimes hidden
|
||||
// and expected to be the first container in the pod.
|
||||
func withIsPause() CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return ErrCtrFinalized
|
||||
}
|
||||
|
||||
ctr.config.IsPause = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Pod Creation Options
|
||||
|
||||
// WithPodName sets the name of the pod.
|
||||
|
@ -1080,3 +1251,112 @@ func WithPodNamespace(ns string) PodCreateOption {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPodIPC tells containers in this pod to use the ipc namespace
|
||||
// created for this pod.
|
||||
// Containers in a pod will inherit the kernel namespaces from the
|
||||
// first container added.
|
||||
func WithPodIPC() PodCreateOption {
|
||||
return func(pod *Pod) error {
|
||||
if pod.valid {
|
||||
return ErrPodFinalized
|
||||
}
|
||||
|
||||
pod.config.UsePodIPC = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPodNet tells containers in this pod to use the network namespace
|
||||
// created for this pod.
|
||||
// Containers in a pod will inherit the kernel namespaces from the
|
||||
// first container added.
|
||||
func WithPodNet() PodCreateOption {
|
||||
return func(pod *Pod) error {
|
||||
if pod.valid {
|
||||
return ErrPodFinalized
|
||||
}
|
||||
|
||||
pod.config.UsePodNet = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPodMNT tells containers in this pod to use the mount namespace
|
||||
// created for this pod.
|
||||
// Containers in a pod will inherit the kernel namespaces from the
|
||||
// first container added.
|
||||
func WithPodMNT() PodCreateOption {
|
||||
return func(pod *Pod) error {
|
||||
if pod.valid {
|
||||
return ErrPodFinalized
|
||||
}
|
||||
|
||||
pod.config.UsePodMNT = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPodUser tells containers in this pod to use the user namespace
|
||||
// created for this pod.
|
||||
// Containers in a pod will inherit the kernel namespaces from the
|
||||
// first container added.
|
||||
func WithPodUser() PodCreateOption {
|
||||
return func(pod *Pod) error {
|
||||
if pod.valid {
|
||||
return ErrPodFinalized
|
||||
}
|
||||
|
||||
pod.config.UsePodUser = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPodPID tells containers in this pod to use the pid namespace
|
||||
// created for this pod.
|
||||
// Containers in a pod will inherit the kernel namespaces from the
|
||||
// first container added.
|
||||
func WithPodPID() PodCreateOption {
|
||||
return func(pod *Pod) error {
|
||||
if pod.valid {
|
||||
return ErrPodFinalized
|
||||
}
|
||||
|
||||
pod.config.UsePodPID = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPodUTS tells containers in this pod to use the uts namespace
|
||||
// created for this pod.
|
||||
// Containers in a pod will inherit the kernel namespaces from the
|
||||
// first container added.
|
||||
func WithPodUTS() PodCreateOption {
|
||||
return func(pod *Pod) error {
|
||||
if pod.valid {
|
||||
return ErrPodFinalized
|
||||
}
|
||||
|
||||
pod.config.UsePodUTS = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithPauseContainer tells the pod to create a pause container
|
||||
func WithPauseContainer() PodCreateOption {
|
||||
return func(pod *Pod) error {
|
||||
if pod.valid {
|
||||
return ErrPodFinalized
|
||||
}
|
||||
|
||||
pod.config.PauseContainer.HasPauseContainer = true
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// KernelNamespaces is a list of the kernel namespaces a pod can share
|
||||
KernelNamespaces = []string{"ipc", "net", "pid", "user", "mnt", "uts", "cgroup"}
|
||||
)
|
||||
|
||||
// Pod represents a group of containers that are managed together.
|
||||
// Any operations on a Pod that access state must begin with a call to
|
||||
// updatePod().
|
||||
|
@ -18,6 +23,7 @@ import (
|
|||
// function takes the pod lock and accesses any part of state, it should
|
||||
// updatePod() immediately after locking.
|
||||
// ffjson: skip
|
||||
// Pod represents a group of containers that may share namespaces
|
||||
type Pod struct {
|
||||
config *PodConfig
|
||||
state *podState
|
||||
|
@ -38,11 +44,23 @@ type PodConfig struct {
|
|||
Labels map[string]string `json:"labels"`
|
||||
// CgroupParent contains the pod's CGroup parent
|
||||
CgroupParent string `json:"cgroupParent"`
|
||||
|
||||
// UsePodCgroup indicates whether the pod will create its own CGroup and
|
||||
// join containers to it.
|
||||
// If true, all containers joined to the pod will use the pod cgroup as
|
||||
// their cgroup parent, and cannot set a different cgroup parent
|
||||
UsePodCgroup bool `json:"usePodCgroup"`
|
||||
UsePodCgroup bool `json:"sharesCgroup,omitempty"`
|
||||
|
||||
// The following UsePod{kernelNamespace} indicate whether the containers
|
||||
// in the pod will inherit the namespace from the first container in the pod.
|
||||
UsePodPID bool `json:"sharesPid,omitempty"`
|
||||
UsePodIPC bool `json:"sharesIpc,omitempty"`
|
||||
UsePodNet bool `json:"sharesNet,omitempty"`
|
||||
UsePodMNT bool `json:"sharesMnt,omitempty"`
|
||||
UsePodUser bool `json:"sharesUser,omitempty"`
|
||||
UsePodUTS bool `json:"sharesUts,omitempty"`
|
||||
|
||||
PauseContainer *PauseContainerConfig `json:"pauseConfig"`
|
||||
|
||||
// Time pod was created
|
||||
CreatedTime time.Time `json:"created"`
|
||||
|
@ -52,6 +70,9 @@ type PodConfig struct {
|
|||
type podState struct {
|
||||
// CgroupPath is the path to the pod's CGroup
|
||||
CgroupPath string `json:"cgroupPath"`
|
||||
// PauseContainerID is the container that holds pod namespace information
|
||||
// Most often a pause container
|
||||
PauseContainerID string
|
||||
}
|
||||
|
||||
// PodInspect represents the data we want to display for
|
||||
|
@ -64,7 +85,8 @@ type PodInspect struct {
|
|||
|
||||
// PodInspectState contains inspect data on the pod's state
|
||||
type PodInspectState struct {
|
||||
CgroupPath string `json:"cgroupPath"`
|
||||
CgroupPath string `json:"cgroupPath"`
|
||||
PauseContainerID string `json:"pauseContainerID"`
|
||||
}
|
||||
|
||||
// PodContainerInfo keeps information on a container in a pod
|
||||
|
@ -73,6 +95,11 @@ type PodContainerInfo struct {
|
|||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// PauseContainerConfig is the configuration for the pod's pause container
|
||||
type PauseContainerConfig struct {
|
||||
HasPauseContainer bool `json:"makePauseContainer"`
|
||||
}
|
||||
|
||||
// ID retrieves the pod's ID
|
||||
func (p *Pod) ID() string {
|
||||
return p.config.ID
|
||||
|
@ -109,9 +136,45 @@ func (p *Pod) CgroupParent() string {
|
|||
return p.config.CgroupParent
|
||||
}
|
||||
|
||||
// UsePodCgroup returns whether containers in the pod will default to this pod's
|
||||
// SharesPID returns whether containers in pod
|
||||
// default to use PID namespace of first container in pod
|
||||
func (p *Pod) SharesPID() bool {
|
||||
return p.config.UsePodPID
|
||||
}
|
||||
|
||||
// SharesIPC returns whether containers in pod
|
||||
// default to use IPC namespace of first container in pod
|
||||
func (p *Pod) SharesIPC() bool {
|
||||
return p.config.UsePodIPC
|
||||
}
|
||||
|
||||
// SharesNet returns whether containers in pod
|
||||
// default to use network namespace of first container in pod
|
||||
func (p *Pod) SharesNet() bool {
|
||||
return p.config.UsePodNet
|
||||
}
|
||||
|
||||
// SharesMNT returns whether containers in pod
|
||||
// default to use PID namespace of first container in pod
|
||||
func (p *Pod) SharesMNT() bool {
|
||||
return p.config.UsePodMNT
|
||||
}
|
||||
|
||||
// SharesUser returns whether containers in pod
|
||||
// default to use user namespace of first container in pod
|
||||
func (p *Pod) SharesUser() bool {
|
||||
return p.config.UsePodUser
|
||||
}
|
||||
|
||||
// SharesUTS returns whether containers in pod
|
||||
// default to use UTS namespace of first container in pod
|
||||
func (p *Pod) SharesUTS() bool {
|
||||
return p.config.UsePodUTS
|
||||
}
|
||||
|
||||
// SharesCgroup returns whether containers in the pod will default to this pod's
|
||||
// cgroup instead of the default libpod parent
|
||||
func (p *Pod) UsePodCgroup() bool {
|
||||
func (p *Pod) SharesCgroup() bool {
|
||||
return p.config.UsePodCgroup
|
||||
}
|
||||
|
||||
|
@ -161,6 +224,30 @@ func (p *Pod) allContainers() ([]*Container, error) {
|
|||
return p.runtime.state.PodContainers(p)
|
||||
}
|
||||
|
||||
// HasPauseContainer returns whether the pod will create a pause container
|
||||
func (p *Pod) HasPauseContainer() bool {
|
||||
return p.config.PauseContainer.HasPauseContainer
|
||||
}
|
||||
|
||||
// SharesNamespaces checks if the pod has any kernel namespaces set as shared. A pause container will not be
|
||||
// created if no kernel namespaces are shared.
|
||||
func (p *Pod) SharesNamespaces() bool {
|
||||
return p.SharesPID() || p.SharesIPC() || p.SharesNet() || p.SharesMNT() || p.SharesUser() || p.SharesUTS()
|
||||
}
|
||||
|
||||
// PauseContainerID returns a the pause container ID for a pod.
|
||||
// If the container returned is "", the pod has no pause container.
|
||||
func (p *Pod) PauseContainerID() (string, error) {
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
if err := p.updatePod(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return p.state.PauseContainerID, nil
|
||||
}
|
||||
|
||||
// TODO add pod batching
|
||||
// Lock pod to avoid lock contention
|
||||
// Store and lock all containers (no RemoveContainer in batch guarantees cache will not become stale)
|
||||
|
|
|
@ -426,13 +426,18 @@ func (p *Pod) Inspect() (*PodInspect, error) {
|
|||
}
|
||||
podContainers = append(podContainers, pc)
|
||||
}
|
||||
pauseContainerID := p.state.PauseContainerID
|
||||
if err != nil {
|
||||
return &PodInspect{}, err
|
||||
}
|
||||
|
||||
config := new(PodConfig)
|
||||
deepcopier.Copy(p.config).To(config)
|
||||
inspectData := PodInspect{
|
||||
Config: config,
|
||||
State: &PodInspectState{
|
||||
CgroupPath: p.state.CgroupPath,
|
||||
CgroupPath: p.state.CgroupPath,
|
||||
PauseContainerID: pauseContainerID,
|
||||
},
|
||||
Containers: podContainers,
|
||||
}
|
||||
|
|
|
@ -11,6 +11,212 @@ import (
|
|||
fflib "github.com/pquerna/ffjson/fflib/v1"
|
||||
)
|
||||
|
||||
// MarshalJSON marshal bytes to json - template
|
||||
func (j *PauseContainerConfig) MarshalJSON() ([]byte, error) {
|
||||
var buf fflib.Buffer
|
||||
if j == nil {
|
||||
buf.WriteString("null")
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
err := j.MarshalJSONBuf(&buf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// MarshalJSONBuf marshal buff to json - template
|
||||
func (j *PauseContainerConfig) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
|
||||
if j == nil {
|
||||
buf.WriteString("null")
|
||||
return nil
|
||||
}
|
||||
var err error
|
||||
var obj []byte
|
||||
_ = obj
|
||||
_ = err
|
||||
if j.HasPauseContainer {
|
||||
buf.WriteString(`{"makePauseContainer":true`)
|
||||
} else {
|
||||
buf.WriteString(`{"makePauseContainer":false`)
|
||||
}
|
||||
buf.WriteByte('}')
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
ffjtPauseContainerConfigbase = iota
|
||||
ffjtPauseContainerConfignosuchkey
|
||||
|
||||
ffjtPauseContainerConfigHasPauseContainer
|
||||
)
|
||||
|
||||
var ffjKeyPauseContainerConfigHasPauseContainer = []byte("makePauseContainer")
|
||||
|
||||
// UnmarshalJSON umarshall json - template of ffjson
|
||||
func (j *PauseContainerConfig) UnmarshalJSON(input []byte) error {
|
||||
fs := fflib.NewFFLexer(input)
|
||||
return j.UnmarshalJSONFFLexer(fs, fflib.FFParse_map_start)
|
||||
}
|
||||
|
||||
// UnmarshalJSONFFLexer fast json unmarshall - template ffjson
|
||||
func (j *PauseContainerConfig) UnmarshalJSONFFLexer(fs *fflib.FFLexer, state fflib.FFParseState) error {
|
||||
var err error
|
||||
currentKey := ffjtPauseContainerConfigbase
|
||||
_ = currentKey
|
||||
tok := fflib.FFTok_init
|
||||
wantedTok := fflib.FFTok_init
|
||||
|
||||
mainparse:
|
||||
for {
|
||||
tok = fs.Scan()
|
||||
// println(fmt.Sprintf("debug: tok: %v state: %v", tok, state))
|
||||
if tok == fflib.FFTok_error {
|
||||
goto tokerror
|
||||
}
|
||||
|
||||
switch state {
|
||||
|
||||
case fflib.FFParse_map_start:
|
||||
if tok != fflib.FFTok_left_bracket {
|
||||
wantedTok = fflib.FFTok_left_bracket
|
||||
goto wrongtokenerror
|
||||
}
|
||||
state = fflib.FFParse_want_key
|
||||
continue
|
||||
|
||||
case fflib.FFParse_after_value:
|
||||
if tok == fflib.FFTok_comma {
|
||||
state = fflib.FFParse_want_key
|
||||
} else if tok == fflib.FFTok_right_bracket {
|
||||
goto done
|
||||
} else {
|
||||
wantedTok = fflib.FFTok_comma
|
||||
goto wrongtokenerror
|
||||
}
|
||||
|
||||
case fflib.FFParse_want_key:
|
||||
// json {} ended. goto exit. woo.
|
||||
if tok == fflib.FFTok_right_bracket {
|
||||
goto done
|
||||
}
|
||||
if tok != fflib.FFTok_string {
|
||||
wantedTok = fflib.FFTok_string
|
||||
goto wrongtokenerror
|
||||
}
|
||||
|
||||
kn := fs.Output.Bytes()
|
||||
if len(kn) <= 0 {
|
||||
// "" case. hrm.
|
||||
currentKey = ffjtPauseContainerConfignosuchkey
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
} else {
|
||||
switch kn[0] {
|
||||
|
||||
case 'm':
|
||||
|
||||
if bytes.Equal(ffjKeyPauseContainerConfigHasPauseContainer, kn) {
|
||||
currentKey = ffjtPauseContainerConfigHasPauseContainer
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPauseContainerConfigHasPauseContainer, kn) {
|
||||
currentKey = ffjtPauseContainerConfigHasPauseContainer
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
currentKey = ffjtPauseContainerConfignosuchkey
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
case fflib.FFParse_want_colon:
|
||||
if tok != fflib.FFTok_colon {
|
||||
wantedTok = fflib.FFTok_colon
|
||||
goto wrongtokenerror
|
||||
}
|
||||
state = fflib.FFParse_want_value
|
||||
continue
|
||||
case fflib.FFParse_want_value:
|
||||
|
||||
if tok == fflib.FFTok_left_brace || tok == fflib.FFTok_left_bracket || tok == fflib.FFTok_integer || tok == fflib.FFTok_double || tok == fflib.FFTok_string || tok == fflib.FFTok_bool || tok == fflib.FFTok_null {
|
||||
switch currentKey {
|
||||
|
||||
case ffjtPauseContainerConfigHasPauseContainer:
|
||||
goto handle_HasPauseContainer
|
||||
|
||||
case ffjtPauseContainerConfignosuchkey:
|
||||
err = fs.SkipField(tok)
|
||||
if err != nil {
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
}
|
||||
} else {
|
||||
goto wantedvalue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handle_HasPauseContainer:
|
||||
|
||||
/* handler: j.HasPauseContainer type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.HasPauseContainer = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.HasPauseContainer = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
wantedvalue:
|
||||
return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
|
||||
wrongtokenerror:
|
||||
return fs.WrapErr(fmt.Errorf("ffjson: wanted token: %v, but got token: %v output=%s", wantedTok, tok, fs.Output.String()))
|
||||
tokerror:
|
||||
if fs.BigError != nil {
|
||||
return fs.WrapErr(fs.BigError)
|
||||
}
|
||||
err = fs.Error.ToError()
|
||||
if err != nil {
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
panic("ffjson-generated: unreachable, please report bug.")
|
||||
done:
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON marshal bytes to json - template
|
||||
func (j *PodConfig) MarshalJSON() ([]byte, error) {
|
||||
var buf fflib.Buffer
|
||||
|
@ -60,10 +266,76 @@ func (j *PodConfig) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
|
|||
}
|
||||
buf.WriteString(`,"cgroupParent":`)
|
||||
fflib.WriteJsonString(buf, string(j.CgroupParent))
|
||||
if j.UsePodCgroup {
|
||||
buf.WriteString(`,"usePodCgroup":true`)
|
||||
buf.WriteByte(',')
|
||||
if j.UsePodCgroup != false {
|
||||
if j.UsePodCgroup {
|
||||
buf.WriteString(`"sharesCgroup":true`)
|
||||
} else {
|
||||
buf.WriteString(`"sharesCgroup":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.UsePodPID != false {
|
||||
if j.UsePodPID {
|
||||
buf.WriteString(`"sharesPid":true`)
|
||||
} else {
|
||||
buf.WriteString(`"sharesPid":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.UsePodIPC != false {
|
||||
if j.UsePodIPC {
|
||||
buf.WriteString(`"sharesIpc":true`)
|
||||
} else {
|
||||
buf.WriteString(`"sharesIpc":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.UsePodNet != false {
|
||||
if j.UsePodNet {
|
||||
buf.WriteString(`"sharesNet":true`)
|
||||
} else {
|
||||
buf.WriteString(`"sharesNet":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.UsePodMNT != false {
|
||||
if j.UsePodMNT {
|
||||
buf.WriteString(`"sharesMnt":true`)
|
||||
} else {
|
||||
buf.WriteString(`"sharesMnt":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.UsePodUser != false {
|
||||
if j.UsePodUser {
|
||||
buf.WriteString(`"sharesUser":true`)
|
||||
} else {
|
||||
buf.WriteString(`"sharesUser":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.UsePodUTS != false {
|
||||
if j.UsePodUTS {
|
||||
buf.WriteString(`"sharesUts":true`)
|
||||
} else {
|
||||
buf.WriteString(`"sharesUts":false`)
|
||||
}
|
||||
buf.WriteByte(',')
|
||||
}
|
||||
if j.PauseContainer != nil {
|
||||
buf.WriteString(`"pauseConfig":`)
|
||||
|
||||
{
|
||||
|
||||
err = j.PauseContainer.MarshalJSONBuf(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
buf.WriteString(`,"usePodCgroup":false`)
|
||||
buf.WriteString(`"pauseConfig":null`)
|
||||
}
|
||||
buf.WriteString(`,"created":`)
|
||||
|
||||
|
@ -96,6 +368,20 @@ const (
|
|||
|
||||
ffjtPodConfigUsePodCgroup
|
||||
|
||||
ffjtPodConfigUsePodPID
|
||||
|
||||
ffjtPodConfigUsePodIPC
|
||||
|
||||
ffjtPodConfigUsePodNet
|
||||
|
||||
ffjtPodConfigUsePodMNT
|
||||
|
||||
ffjtPodConfigUsePodUser
|
||||
|
||||
ffjtPodConfigUsePodUTS
|
||||
|
||||
ffjtPodConfigPauseContainer
|
||||
|
||||
ffjtPodConfigCreatedTime
|
||||
)
|
||||
|
||||
|
@ -109,7 +395,21 @@ var ffjKeyPodConfigLabels = []byte("labels")
|
|||
|
||||
var ffjKeyPodConfigCgroupParent = []byte("cgroupParent")
|
||||
|
||||
var ffjKeyPodConfigUsePodCgroup = []byte("usePodCgroup")
|
||||
var ffjKeyPodConfigUsePodCgroup = []byte("sharesCgroup")
|
||||
|
||||
var ffjKeyPodConfigUsePodPID = []byte("sharesPid")
|
||||
|
||||
var ffjKeyPodConfigUsePodIPC = []byte("sharesIpc")
|
||||
|
||||
var ffjKeyPodConfigUsePodNet = []byte("sharesNet")
|
||||
|
||||
var ffjKeyPodConfigUsePodMNT = []byte("sharesMnt")
|
||||
|
||||
var ffjKeyPodConfigUsePodUser = []byte("sharesUser")
|
||||
|
||||
var ffjKeyPodConfigUsePodUTS = []byte("sharesUts")
|
||||
|
||||
var ffjKeyPodConfigPauseContainer = []byte("pauseConfig")
|
||||
|
||||
var ffjKeyPodConfigCreatedTime = []byte("created")
|
||||
|
||||
|
@ -216,12 +516,50 @@ mainparse:
|
|||
goto mainparse
|
||||
}
|
||||
|
||||
case 'u':
|
||||
case 'p':
|
||||
|
||||
if bytes.Equal(ffjKeyPodConfigPauseContainer, kn) {
|
||||
currentKey = ffjtPodConfigPauseContainer
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
case 's':
|
||||
|
||||
if bytes.Equal(ffjKeyPodConfigUsePodCgroup, kn) {
|
||||
currentKey = ffjtPodConfigUsePodCgroup
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyPodConfigUsePodPID, kn) {
|
||||
currentKey = ffjtPodConfigUsePodPID
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyPodConfigUsePodIPC, kn) {
|
||||
currentKey = ffjtPodConfigUsePodIPC
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyPodConfigUsePodNet, kn) {
|
||||
currentKey = ffjtPodConfigUsePodNet
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyPodConfigUsePodMNT, kn) {
|
||||
currentKey = ffjtPodConfigUsePodMNT
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyPodConfigUsePodUser, kn) {
|
||||
currentKey = ffjtPodConfigUsePodUser
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
|
||||
} else if bytes.Equal(ffjKeyPodConfigUsePodUTS, kn) {
|
||||
currentKey = ffjtPodConfigUsePodUTS
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -232,6 +570,48 @@ mainparse:
|
|||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodConfigPauseContainer, kn) {
|
||||
currentKey = ffjtPodConfigPauseContainer
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodConfigUsePodUTS, kn) {
|
||||
currentKey = ffjtPodConfigUsePodUTS
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodConfigUsePodUser, kn) {
|
||||
currentKey = ffjtPodConfigUsePodUser
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodConfigUsePodMNT, kn) {
|
||||
currentKey = ffjtPodConfigUsePodMNT
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodConfigUsePodNet, kn) {
|
||||
currentKey = ffjtPodConfigUsePodNet
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodConfigUsePodIPC, kn) {
|
||||
currentKey = ffjtPodConfigUsePodIPC
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodConfigUsePodPID, kn) {
|
||||
currentKey = ffjtPodConfigUsePodPID
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodConfigUsePodCgroup, kn) {
|
||||
currentKey = ffjtPodConfigUsePodCgroup
|
||||
state = fflib.FFParse_want_colon
|
||||
|
@ -303,6 +683,27 @@ mainparse:
|
|||
case ffjtPodConfigUsePodCgroup:
|
||||
goto handle_UsePodCgroup
|
||||
|
||||
case ffjtPodConfigUsePodPID:
|
||||
goto handle_UsePodPID
|
||||
|
||||
case ffjtPodConfigUsePodIPC:
|
||||
goto handle_UsePodIPC
|
||||
|
||||
case ffjtPodConfigUsePodNet:
|
||||
goto handle_UsePodNet
|
||||
|
||||
case ffjtPodConfigUsePodMNT:
|
||||
goto handle_UsePodMNT
|
||||
|
||||
case ffjtPodConfigUsePodUser:
|
||||
goto handle_UsePodUser
|
||||
|
||||
case ffjtPodConfigUsePodUTS:
|
||||
goto handle_UsePodUTS
|
||||
|
||||
case ffjtPodConfigPauseContainer:
|
||||
goto handle_PauseContainer
|
||||
|
||||
case ffjtPodConfigCreatedTime:
|
||||
goto handle_CreatedTime
|
||||
|
||||
|
@ -564,6 +965,242 @@ handle_UsePodCgroup:
|
|||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_UsePodPID:
|
||||
|
||||
/* handler: j.UsePodPID type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodPID = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodPID = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_UsePodIPC:
|
||||
|
||||
/* handler: j.UsePodIPC type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodIPC = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodIPC = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_UsePodNet:
|
||||
|
||||
/* handler: j.UsePodNet type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodNet = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodNet = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_UsePodMNT:
|
||||
|
||||
/* handler: j.UsePodMNT type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodMNT = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodMNT = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_UsePodUser:
|
||||
|
||||
/* handler: j.UsePodUser type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodUser = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodUser = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_UsePodUTS:
|
||||
|
||||
/* handler: j.UsePodUTS type=bool kind=bool quoted=false*/
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_bool && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for bool", tok))
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
tmpb := fs.Output.Bytes()
|
||||
|
||||
if bytes.Compare([]byte{'t', 'r', 'u', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodUTS = true
|
||||
|
||||
} else if bytes.Compare([]byte{'f', 'a', 'l', 's', 'e'}, tmpb) == 0 {
|
||||
|
||||
j.UsePodUTS = false
|
||||
|
||||
} else {
|
||||
err = errors.New("unexpected bytes for true/false value")
|
||||
return fs.WrapErr(err)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_PauseContainer:
|
||||
|
||||
/* handler: j.PauseContainer type=libpod.PauseContainerConfig kind=struct quoted=false*/
|
||||
|
||||
{
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
j.PauseContainer = nil
|
||||
|
||||
} else {
|
||||
|
||||
if j.PauseContainer == nil {
|
||||
j.PauseContainer = new(PauseContainerConfig)
|
||||
}
|
||||
|
||||
err = j.PauseContainer.UnmarshalJSONFFLexer(fs, fflib.FFParse_want_key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
state = fflib.FFParse_after_value
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_CreatedTime:
|
||||
|
||||
/* handler: j.CreatedTime type=time.Time kind=struct quoted=false*/
|
||||
|
@ -1586,6 +2223,8 @@ func (j *PodInspectState) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
|
|||
_ = err
|
||||
buf.WriteString(`{"cgroupPath":`)
|
||||
fflib.WriteJsonString(buf, string(j.CgroupPath))
|
||||
buf.WriteString(`,"pauseContainerID":`)
|
||||
fflib.WriteJsonString(buf, string(j.PauseContainerID))
|
||||
buf.WriteByte('}')
|
||||
return nil
|
||||
}
|
||||
|
@ -1595,10 +2234,14 @@ const (
|
|||
ffjtPodInspectStatenosuchkey
|
||||
|
||||
ffjtPodInspectStateCgroupPath
|
||||
|
||||
ffjtPodInspectStatePauseContainerID
|
||||
)
|
||||
|
||||
var ffjKeyPodInspectStateCgroupPath = []byte("cgroupPath")
|
||||
|
||||
var ffjKeyPodInspectStatePauseContainerID = []byte("pauseContainerID")
|
||||
|
||||
// UnmarshalJSON umarshall json - template of ffjson
|
||||
func (j *PodInspectState) UnmarshalJSON(input []byte) error {
|
||||
fs := fflib.NewFFLexer(input)
|
||||
|
@ -1668,6 +2311,20 @@ mainparse:
|
|||
goto mainparse
|
||||
}
|
||||
|
||||
case 'p':
|
||||
|
||||
if bytes.Equal(ffjKeyPodInspectStatePauseContainerID, kn) {
|
||||
currentKey = ffjtPodInspectStatePauseContainerID
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeyPodInspectStatePauseContainerID, kn) {
|
||||
currentKey = ffjtPodInspectStatePauseContainerID
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.SimpleLetterEqualFold(ffjKeyPodInspectStateCgroupPath, kn) {
|
||||
|
@ -1696,6 +2353,9 @@ mainparse:
|
|||
case ffjtPodInspectStateCgroupPath:
|
||||
goto handle_CgroupPath
|
||||
|
||||
case ffjtPodInspectStatePauseContainerID:
|
||||
goto handle_PauseContainerID
|
||||
|
||||
case ffjtPodInspectStatenosuchkey:
|
||||
err = fs.SkipField(tok)
|
||||
if err != nil {
|
||||
|
@ -1736,6 +2396,32 @@ handle_CgroupPath:
|
|||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_PauseContainerID:
|
||||
|
||||
/* handler: j.PauseContainerID type=string kind=string quoted=false*/
|
||||
|
||||
{
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
|
||||
}
|
||||
}
|
||||
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
|
||||
outBuf := fs.Output.Bytes()
|
||||
|
||||
j.PauseContainerID = string(string(outBuf))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
wantedvalue:
|
||||
return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
|
||||
wrongtokenerror:
|
||||
|
@ -1780,6 +2466,8 @@ func (j *podState) MarshalJSONBuf(buf fflib.EncodingBuffer) error {
|
|||
_ = err
|
||||
buf.WriteString(`{"cgroupPath":`)
|
||||
fflib.WriteJsonString(buf, string(j.CgroupPath))
|
||||
buf.WriteString(`,"PauseContainerID":`)
|
||||
fflib.WriteJsonString(buf, string(j.PauseContainerID))
|
||||
buf.WriteByte('}')
|
||||
return nil
|
||||
}
|
||||
|
@ -1789,10 +2477,14 @@ const (
|
|||
ffjtpodStatenosuchkey
|
||||
|
||||
ffjtpodStateCgroupPath
|
||||
|
||||
ffjtpodStatePauseContainerID
|
||||
)
|
||||
|
||||
var ffjKeypodStateCgroupPath = []byte("cgroupPath")
|
||||
|
||||
var ffjKeypodStatePauseContainerID = []byte("PauseContainerID")
|
||||
|
||||
// UnmarshalJSON umarshall json - template of ffjson
|
||||
func (j *podState) UnmarshalJSON(input []byte) error {
|
||||
fs := fflib.NewFFLexer(input)
|
||||
|
@ -1854,6 +2546,14 @@ mainparse:
|
|||
} else {
|
||||
switch kn[0] {
|
||||
|
||||
case 'P':
|
||||
|
||||
if bytes.Equal(ffjKeypodStatePauseContainerID, kn) {
|
||||
currentKey = ffjtpodStatePauseContainerID
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
case 'c':
|
||||
|
||||
if bytes.Equal(ffjKeypodStateCgroupPath, kn) {
|
||||
|
@ -1864,6 +2564,12 @@ mainparse:
|
|||
|
||||
}
|
||||
|
||||
if fflib.EqualFoldRight(ffjKeypodStatePauseContainerID, kn) {
|
||||
currentKey = ffjtpodStatePauseContainerID
|
||||
state = fflib.FFParse_want_colon
|
||||
goto mainparse
|
||||
}
|
||||
|
||||
if fflib.SimpleLetterEqualFold(ffjKeypodStateCgroupPath, kn) {
|
||||
currentKey = ffjtpodStateCgroupPath
|
||||
state = fflib.FFParse_want_colon
|
||||
|
@ -1890,6 +2596,9 @@ mainparse:
|
|||
case ffjtpodStateCgroupPath:
|
||||
goto handle_CgroupPath
|
||||
|
||||
case ffjtpodStatePauseContainerID:
|
||||
goto handle_PauseContainerID
|
||||
|
||||
case ffjtpodStatenosuchkey:
|
||||
err = fs.SkipField(tok)
|
||||
if err != nil {
|
||||
|
@ -1930,6 +2639,32 @@ handle_CgroupPath:
|
|||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
handle_PauseContainerID:
|
||||
|
||||
/* handler: j.PauseContainerID type=string kind=string quoted=false*/
|
||||
|
||||
{
|
||||
|
||||
{
|
||||
if tok != fflib.FFTok_string && tok != fflib.FFTok_null {
|
||||
return fs.WrapErr(fmt.Errorf("cannot unmarshal %s into Go value for string", tok))
|
||||
}
|
||||
}
|
||||
|
||||
if tok == fflib.FFTok_null {
|
||||
|
||||
} else {
|
||||
|
||||
outBuf := fs.Output.Bytes()
|
||||
|
||||
j.PauseContainerID = string(string(outBuf))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
state = fflib.FFParse_after_value
|
||||
goto mainparse
|
||||
|
||||
wantedvalue:
|
||||
return fs.WrapErr(fmt.Errorf("wanted value token, but got token: %v", tok))
|
||||
wrongtokenerror:
|
||||
|
|
|
@ -20,6 +20,7 @@ func newPod(lockDir string, runtime *Runtime) (*Pod, error) {
|
|||
pod.config.ID = stringid.GenerateNonCryptoID()
|
||||
pod.config.Labels = make(map[string]string)
|
||||
pod.config.CreatedTime = time.Now()
|
||||
pod.config.PauseContainer = new(PauseContainerConfig)
|
||||
pod.state = new(podState)
|
||||
pod.runtime = runtime
|
||||
|
||||
|
|
|
@ -56,6 +56,11 @@ const (
|
|||
// configuration file. If OverrideConfigPath exists, it will be used in
|
||||
// place of the configuration file pointed to by ConfigPath.
|
||||
OverrideConfigPath = "/etc/containers/libpod.conf"
|
||||
|
||||
// DefaultPauseImage to use for pause container
|
||||
DefaultPauseImage = "k8s.gcr.io/pause:3.1"
|
||||
// DefaultPauseCommand to be run in a pause container
|
||||
DefaultPauseCommand = "/pause"
|
||||
)
|
||||
|
||||
// A RuntimeOption is a functional option which alters the Runtime created by
|
||||
|
@ -152,6 +157,10 @@ type RuntimeConfig struct {
|
|||
// and all containers and pods will be visible.
|
||||
// The default namespace is "".
|
||||
Namespace string `toml:"namespace,omitempty"`
|
||||
// PauseImage is the image a pod pause container will use to manage namespaces
|
||||
PauseImage string `toml:"pause_image"`
|
||||
// PauseCommand is the command run to start up a pod pause container
|
||||
PauseCommand string `toml:"pause_command"`
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -186,6 +195,8 @@ var (
|
|||
NoPivotRoot: false,
|
||||
CNIConfigDir: "/etc/cni/net.d/",
|
||||
CNIPluginDir: []string{"/usr/libexec/cni", "/usr/lib/cni", "/opt/cni/bin"},
|
||||
PauseCommand: DefaultPauseCommand,
|
||||
PauseImage: DefaultPauseImage,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
@ -8,9 +8,12 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
spec "github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/ulule/deepcopier"
|
||||
)
|
||||
|
||||
// CtrRemoveTimeout is the default number of seconds to wait after stopping a container
|
||||
|
@ -35,11 +38,37 @@ func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options ..
|
|||
if !r.valid {
|
||||
return nil, ErrRuntimeStopped
|
||||
}
|
||||
return r.newContainer(ctx, rSpec, options...)
|
||||
}
|
||||
|
||||
ctr, err := newContainer(rSpec, r.lockDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options ...CtrCreateOption) (c *Container, err error) {
|
||||
if rSpec == nil {
|
||||
return nil, errors.Wrapf(ErrInvalidArg, "must provide a valid runtime spec to create container")
|
||||
}
|
||||
|
||||
ctr := new(Container)
|
||||
ctr.config = new(ContainerConfig)
|
||||
ctr.state = new(containerState)
|
||||
|
||||
ctr.config.ID = stringid.GenerateNonCryptoID()
|
||||
|
||||
ctr.config.Spec = new(spec.Spec)
|
||||
deepcopier.Copy(rSpec).To(ctr.config.Spec)
|
||||
ctr.config.CreatedTime = time.Now()
|
||||
|
||||
ctr.config.ShmSize = DefaultShmSize
|
||||
|
||||
ctr.state.BindMounts = make(map[string]string)
|
||||
|
||||
// Path our lock file will reside at
|
||||
lockPath := filepath.Join(r.lockDir, ctr.config.ID)
|
||||
// Grab a lockfile at the given path
|
||||
lock, err := storage.GetLockfile(lockPath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "error creating lockfile for new container")
|
||||
}
|
||||
ctr.lock = lock
|
||||
|
||||
ctr.config.StopTimeout = CtrRemoveTimeout
|
||||
|
||||
// Set namespace based on current runtime namespace
|
||||
|
@ -59,6 +88,7 @@ func (r *Runtime) NewContainer(ctx context.Context, rSpec *spec.Spec, options ..
|
|||
ctr.runtime = r
|
||||
|
||||
var pod *Pod
|
||||
|
||||
if ctr.config.Pod != "" {
|
||||
// Get the pod from state
|
||||
pod, err = r.state.Pod(ctr.config.Pod)
|
||||
|
@ -194,6 +224,14 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool)
|
|||
// Lock the pod while we're removing container
|
||||
pod.lock.Lock()
|
||||
defer pod.lock.Unlock()
|
||||
if err := pod.updatePod(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pauseID := pod.state.PauseContainerID
|
||||
if c.ID() == pauseID {
|
||||
return errors.Errorf("a pause container cannot be removed without removing pod %s", pod.ID())
|
||||
}
|
||||
}
|
||||
|
||||
c.lock.Lock()
|
||||
|
|
|
@ -26,6 +26,16 @@ type PodFilter func(*Pod) bool
|
|||
// being removed
|
||||
// Otherwise, the pod will not be removed if any containers are running
|
||||
func (r *Runtime) RemovePod(ctx context.Context, p *Pod, removeCtrs, force bool) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
if !r.valid {
|
||||
return ErrRuntimeStopped
|
||||
}
|
||||
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
return r.removePod(ctx, p, removeCtrs, force)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
// NewPod makes a new, empty pod
|
||||
func (r *Runtime) NewPod(options ...PodCreateOption) (*Pod, error) {
|
||||
func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (*Pod, error) {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
|
@ -87,38 +87,42 @@ func (r *Runtime) NewPod(options ...PodCreateOption) (*Pod, error) {
|
|||
if pod.config.UsePodCgroup {
|
||||
logrus.Debugf("Got pod cgroup as %s", pod.state.CgroupPath)
|
||||
}
|
||||
if pod.HasPauseContainer() != pod.SharesNamespaces() {
|
||||
return nil, errors.Errorf("Pods must have a pause container to share namespaces")
|
||||
}
|
||||
|
||||
if err := r.state.AddPod(pod); err != nil {
|
||||
return nil, errors.Wrapf(err, "error adding pod to state")
|
||||
}
|
||||
|
||||
if pod.HasPauseContainer() {
|
||||
ctr, err := r.createPauseContainer(ctx, pod)
|
||||
if err != nil {
|
||||
// Tear down pod, as it is assumed a the pod will contain
|
||||
// a pause container, and it does not.
|
||||
if err2 := r.removePod(ctx, pod, true, true); err2 != nil {
|
||||
logrus.Errorf("Error removing pod after pause container creation failure: %v", err2)
|
||||
}
|
||||
return nil, errors.Wrapf(err, "error adding Pause Container")
|
||||
}
|
||||
pod.state.PauseContainerID = ctr.ID()
|
||||
if err := pod.save(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool) error {
|
||||
r.lock.Lock()
|
||||
defer r.lock.Unlock()
|
||||
|
||||
if !r.valid {
|
||||
return ErrRuntimeStopped
|
||||
}
|
||||
|
||||
if !p.valid {
|
||||
if ok, _ := r.state.HasPod(p.ID()); !ok {
|
||||
// Pod was either already removed, or never existed to
|
||||
// begin with
|
||||
// Pod probably already removed
|
||||
// Or was never in the runtime to begin with
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
p.lock.Lock()
|
||||
defer p.lock.Unlock()
|
||||
|
||||
// Force a pod update
|
||||
if err := p.updatePod(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctrs, err := r.state.PodContainers(p)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -126,6 +130,15 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool)
|
|||
|
||||
numCtrs := len(ctrs)
|
||||
|
||||
// If the only container in the pod is the pause container, remove the pod and container unconditionally.
|
||||
if err := p.updatePod(); err != nil {
|
||||
return err
|
||||
}
|
||||
pauseCtrID := p.state.PauseContainerID
|
||||
if numCtrs == 1 && ctrs[0].ID() == pauseCtrID {
|
||||
removeCtrs = true
|
||||
force = true
|
||||
}
|
||||
if !removeCtrs && numCtrs > 0 {
|
||||
return errors.Wrapf(ErrCtrExists, "pod %s contains containers and cannot be removed", p.ID())
|
||||
}
|
||||
|
|
60
libpod/runtime_pod_pause_linux.go
Normal file
60
libpod/runtime_pod_pause_linux.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
// +build linux
|
||||
|
||||
package libpod
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/containers/libpod/libpod/image"
|
||||
"github.com/opencontainers/runtime-tools/generate"
|
||||
)
|
||||
|
||||
const (
|
||||
// IDTruncLength is the length of the pod's id that will be used to make the
|
||||
// pause container name
|
||||
IDTruncLength = 12
|
||||
)
|
||||
|
||||
func (r *Runtime) makePauseContainer(ctx context.Context, p *Pod, imgName, imgID string) (*Container, error) {
|
||||
|
||||
// Set up generator for pause container defaults
|
||||
g, err := generate.New("linux")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
g.SetRootReadonly(true)
|
||||
g.SetProcessArgs([]string{r.config.PauseCommand})
|
||||
|
||||
containerName := p.ID()[:IDTruncLength] + "-infra"
|
||||
var options []CtrCreateOption
|
||||
options = append(options, r.WithPod(p))
|
||||
options = append(options, WithRootFSFromImage(imgID, imgName, false))
|
||||
options = append(options, WithName(containerName))
|
||||
options = append(options, withIsPause())
|
||||
|
||||
return r.newContainer(ctx, g.Config, options...)
|
||||
}
|
||||
|
||||
// createPauseContainer wrap creates a pause container for a pod.
|
||||
// A pause container becomes the basis for kernel namespace sharing between
|
||||
// containers in the pod.
|
||||
func (r *Runtime) createPauseContainer(ctx context.Context, p *Pod) (*Container, error) {
|
||||
if !r.valid {
|
||||
return nil, ErrRuntimeStopped
|
||||
}
|
||||
|
||||
newImage, err := r.ImageRuntime().New(ctx, r.config.PauseImage, "", "", nil, nil, image.SigningOptions{}, false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := newImage.Inspect(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
imageName := newImage.Names()[0]
|
||||
imageID := data.ID
|
||||
|
||||
return r.makePauseContainer(ctx, p, imageName, imageID)
|
||||
}
|
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
// NewPod makes a new, empty pod
|
||||
func (r *Runtime) NewPod(options ...PodCreateOption) (*Pod, error) {
|
||||
func (r *Runtime) NewPod(ctx context.Context, options ...PodCreateOption) (*Pod, error) {
|
||||
return nil, ErrOSNotSupported
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ type ContainerInspectData struct {
|
|||
NetworkSettings *NetworkSettings `json:"NetworkSettings"` //TODO
|
||||
ExitCommand []string `json:"ExitCommand"`
|
||||
Namespace string `json:"Namespace"`
|
||||
IsPause bool `json:"IsPause"`
|
||||
}
|
||||
|
||||
// ContainerInspectState represents the state of a container.
|
||||
|
|
|
@ -364,6 +364,9 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
|
|||
|
||||
networks := make([]string, 0)
|
||||
userNetworks := c.NetMode.UserDefined()
|
||||
if IsPod(userNetworks) {
|
||||
userNetworks = ""
|
||||
}
|
||||
if userNetworks != "" {
|
||||
for _, netName := range strings.Split(userNetworks, ",") {
|
||||
if netName == "" {
|
||||
|
@ -381,6 +384,8 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
|
|||
return nil, errors.Wrapf(err, "container %q not found", c.NetMode.ConnectedContainer())
|
||||
}
|
||||
options = append(options, libpod.WithNetNSFrom(connectedCtr))
|
||||
} else if IsPod(string(c.NetMode)) {
|
||||
options = append(options, libpod.WithNetNSFromPod())
|
||||
} else if !c.NetMode.IsHost() && !c.NetMode.IsNone() {
|
||||
isRootless := rootless.IsRootless()
|
||||
postConfigureNetNS := isRootless || (len(c.IDMappings.UIDMap) > 0 || len(c.IDMappings.GIDMap) > 0) && !c.UsernsMode.IsHost()
|
||||
|
@ -398,6 +403,10 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
|
|||
|
||||
options = append(options, libpod.WithPIDNSFrom(connectedCtr))
|
||||
}
|
||||
if IsPod(string(c.PidMode)) {
|
||||
options = append(options, libpod.WithPIDNSFromPod())
|
||||
}
|
||||
|
||||
if c.IpcMode.IsContainer() {
|
||||
connectedCtr, err := c.Runtime.LookupContainer(c.IpcMode.Container())
|
||||
if err != nil {
|
||||
|
@ -406,7 +415,15 @@ func (c *CreateConfig) GetContainerCreateOptions(runtime *libpod.Runtime) ([]lib
|
|||
|
||||
options = append(options, libpod.WithIPCNSFrom(connectedCtr))
|
||||
}
|
||||
if IsPod(string(c.IpcMode)) {
|
||||
options = append(options, libpod.WithIPCNSFromPod())
|
||||
}
|
||||
|
||||
if IsPod(string(c.UtsMode)) {
|
||||
options = append(options, libpod.WithUTSNSFromPod())
|
||||
}
|
||||
|
||||
// TODO: MNT, USER, CGROUP
|
||||
options = append(options, libpod.WithStopSignal(c.StopSignal))
|
||||
options = append(options, libpod.WithStopTimeout(c.StopTimeout))
|
||||
if len(c.DNSSearch) > 0 {
|
||||
|
|
|
@ -18,12 +18,29 @@ func (w *weightDevice) String() string {
|
|||
return fmt.Sprintf("%s:%d", w.path, w.weight)
|
||||
}
|
||||
|
||||
// LinuxNS is a struct that contains namespace information
|
||||
// It implemented Valid to show it is a valid namespace
|
||||
type LinuxNS interface {
|
||||
Valid() bool
|
||||
}
|
||||
|
||||
// IsNS returns if the specified string has a ns: prefix
|
||||
func IsNS(s string) bool {
|
||||
parts := strings.SplitN(s, ":", 2)
|
||||
return len(parts) > 1 && parts[0] == "ns"
|
||||
}
|
||||
|
||||
// IsPod returns if the specified string is pod
|
||||
func IsPod(s string) bool {
|
||||
return s == "pod"
|
||||
}
|
||||
|
||||
// Valid checks the validity of a linux namespace
|
||||
// s should be the string representation of ns
|
||||
func Valid(s string, ns LinuxNS) bool {
|
||||
return IsPod(s) || IsNS(s) || ns.Valid()
|
||||
}
|
||||
|
||||
// NS is the path to the namespace to join.
|
||||
func NS(s string) string {
|
||||
parts := strings.SplitN(s, ":", 2)
|
||||
|
|
|
@ -349,6 +349,9 @@ func addPidNS(config *CreateConfig, g *generate.Generator) error {
|
|||
if pidMode.IsContainer() {
|
||||
logrus.Debug("using container pidmode")
|
||||
}
|
||||
if IsPod(string(pidMode)) {
|
||||
logrus.Debug("using pod pidmode")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -384,6 +387,9 @@ func addNetNS(config *CreateConfig, g *generate.Generator) error {
|
|||
} else if IsNS(string(netMode)) {
|
||||
logrus.Debug("Using ns netmode")
|
||||
return g.AddOrReplaceLinuxNamespace(spec.NetworkNamespace, NS(string(netMode)))
|
||||
} else if IsPod(string(netMode)) {
|
||||
logrus.Debug("Using pod netmode, unless pod is not sharing")
|
||||
return nil
|
||||
} else if netMode.IsUserDefined() {
|
||||
logrus.Debug("Using user defined netmode")
|
||||
return nil
|
||||
|
|
|
@ -23,7 +23,7 @@ func (i *LibpodAPI) CreatePod(call iopodman.VarlinkCall, create iopodman.PodCrea
|
|||
}
|
||||
options = append(options, libpod.WithPodCgroups())
|
||||
|
||||
pod, err := i.Runtime.NewPod(options...)
|
||||
pod, err := i.Runtime.NewPod(getContext(), options...)
|
||||
if err != nil {
|
||||
return call.ReplyErrorOccurred(err.Error())
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ var (
|
|||
CGROUP_MANAGER = "systemd"
|
||||
STORAGE_OPTIONS = "--storage-driver vfs"
|
||||
ARTIFACT_DIR = "/tmp/.artifacts"
|
||||
CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, nginx, redis, registry}
|
||||
CACHE_IMAGES = []string{ALPINE, BB, fedoraMinimal, nginx, redis, registry, pause}
|
||||
RESTORE_IMAGES = []string{ALPINE, BB}
|
||||
ALPINE = "docker.io/library/alpine:latest"
|
||||
BB = "docker.io/library/busybox:latest"
|
||||
|
@ -41,6 +41,7 @@ var (
|
|||
nginx = "quay.io/baude/alpine_nginx:latest"
|
||||
redis = "docker.io/library/redis:alpine"
|
||||
registry = "docker.io/library/registry:2"
|
||||
pause = "k8s.gcr.io/pause:3.1"
|
||||
defaultWaitTimeout = 90
|
||||
)
|
||||
|
||||
|
@ -422,6 +423,18 @@ func (p *PodmanTest) RestoreAllArtifacts() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// CreatePod creates a pod with no pause container
|
||||
// it optionally takes a pod name
|
||||
func (p *PodmanTest) CreatePod(name string) (*PodmanSession, int, string) {
|
||||
var podmanArgs = []string{"pod", "create", "--pause=false", "--share", ""}
|
||||
if name != "" {
|
||||
podmanArgs = append(podmanArgs, "--name", name)
|
||||
}
|
||||
session := p.Podman(podmanArgs)
|
||||
session.WaitWithDefaultTimeout()
|
||||
return session, session.ExitCode(), session.OutputToString()
|
||||
}
|
||||
|
||||
//RunTopContainer runs a simple container in the background that
|
||||
// runs top. If the name passed != "", it will have a name
|
||||
func (p *PodmanTest) RunTopContainer(name string) *PodmanSession {
|
||||
|
|
|
@ -32,23 +32,20 @@ var _ = Describe("Podman pod create", func() {
|
|||
})
|
||||
|
||||
It("podman create pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
cid := session.OutputToString()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, podID := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
match, _ := check.GrepString(cid)
|
||||
match, _ := check.GrepString(podID)
|
||||
Expect(match).To(BeTrue())
|
||||
Expect(len(check.OutputToStringArray())).To(Equal(1))
|
||||
})
|
||||
|
||||
It("podman create pod with name", func() {
|
||||
name := "test"
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", name})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, _ := podmanTest.CreatePod(name)
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
|
@ -58,13 +55,11 @@ var _ = Describe("Podman pod create", func() {
|
|||
|
||||
It("podman create pod with doubled name", func() {
|
||||
name := "test"
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", name})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, _ := podmanTest.CreatePod(name)
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create", "--name", name})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Not(Equal(1)))
|
||||
_, ec2, _ := podmanTest.CreatePod(name)
|
||||
Expect(ec2).To(Not(Equal(0)))
|
||||
|
||||
check := podmanTest.Podman([]string{"pod", "ps", "-q"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
|
@ -77,9 +72,8 @@ var _ = Describe("Podman pod create", func() {
|
|||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create", "--name", name})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Not(Equal(1)))
|
||||
_, ec, _ := podmanTest.CreatePod(name)
|
||||
Expect(ec).To(Not(Equal(0)))
|
||||
|
||||
check := podmanTest.Podman([]string{"pod", "ps", "-q"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
|
|
|
@ -38,12 +38,10 @@ var _ = Describe("Podman pod inspect", func() {
|
|||
})
|
||||
|
||||
It("podman inspect a pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
|
|
@ -38,12 +38,10 @@ var _ = Describe("Podman pod kill", func() {
|
|||
})
|
||||
|
||||
It("podman pod kill a pod by id", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -58,12 +56,10 @@ var _ = Describe("Podman pod kill", func() {
|
|||
})
|
||||
|
||||
It("podman pod kill a pod by id with TERM", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -74,12 +70,10 @@ var _ = Describe("Podman pod kill", func() {
|
|||
})
|
||||
|
||||
It("podman pod kill a pod by name", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("test1")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -90,12 +84,10 @@ var _ = Describe("Podman pod kill", func() {
|
|||
})
|
||||
|
||||
It("podman pod kill a pod by id with a bogus signal", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("test1")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -106,19 +98,15 @@ var _ = Describe("Podman pod kill", func() {
|
|||
})
|
||||
|
||||
It("podman pod kill latest pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create", "--name", "test2"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid2 := session.OutputToString()
|
||||
_, ec, podid2 := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid2)
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -135,23 +123,19 @@ var _ = Describe("Podman pod kill", func() {
|
|||
})
|
||||
|
||||
It("podman pod kill all", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create", "--name", "test2"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid2 := session.OutputToString()
|
||||
_, ec, podid2 := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid2)
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -159,6 +143,7 @@ var _ = Describe("Podman pod kill", func() {
|
|||
|
||||
result := podmanTest.Podman([]string{"pod", "kill", "-a"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
fmt.Println(result.OutputToString(), result.ErrorToString())
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
})
|
||||
|
|
285
test/e2e/pod_pause_container_test.go
Normal file
285
test/e2e/pod_pause_container_test.go
Normal file
|
@ -0,0 +1,285 @@
|
|||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Podman pod create", func() {
|
||||
var (
|
||||
tempdir string
|
||||
err error
|
||||
podmanTest PodmanTest
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
tempdir, err = CreateTempDirInTempDir()
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
podmanTest = PodmanCreate(tempdir)
|
||||
podmanTest.RestoreAllArtifacts()
|
||||
podmanTest.RestoreArtifact(pause)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
podmanTest.CleanupPod()
|
||||
f := CurrentGinkgoTestDescription()
|
||||
timedResult := fmt.Sprintf("Test: %s completed in %f seconds", f.TestText, f.Duration.Seconds())
|
||||
GinkgoWriter.Write([]byte(timedResult))
|
||||
})
|
||||
|
||||
It("podman create pause container", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
check := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
match, _ := check.GrepString(podID)
|
||||
Expect(match).To(BeTrue())
|
||||
Expect(len(check.OutputToStringArray())).To(Equal(1))
|
||||
|
||||
check = podmanTest.Podman([]string{"ps", "-qa", "--no-trunc"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(len(check.OutputToStringArray())).To(Equal(1))
|
||||
})
|
||||
|
||||
It("podman start pause container", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"ps", "-qa", "--no-trunc", "--filter", "status=running"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
Expect(len(check.OutputToStringArray())).To(Equal(1))
|
||||
})
|
||||
|
||||
It("podman pause container namespaces", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podID)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"ps", "-a", "--no-trunc", "--ns", "--format", "{{.IPC}} {{.NET}}"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
Expect(len(check.OutputToStringArray())).To(Equal(2))
|
||||
Expect(check.OutputToStringArray()[0]).To(Equal(check.OutputToStringArray()[1]))
|
||||
|
||||
})
|
||||
|
||||
It("podman pod correctly sets up NetNS", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "net"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
podmanTest.RestoreArtifact(nginx)
|
||||
session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, nginx})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
podmanTest.RestoreArtifact(fedoraMinimal)
|
||||
session = podmanTest.Podman([]string{"run", "--pod", podID, fedoraMinimal, "curl", "localhost:80"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"run", fedoraMinimal, "curl", "localhost"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Not(Equal(0)))
|
||||
})
|
||||
|
||||
It("podman pod correctly sets up PIDNS", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "pid", "--name", "test-pod"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test-ctr", podID)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"top", "test-ctr", "pid"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(check.ExitCode()).To(Equal(0))
|
||||
PIDs := check.OutputToStringArray()
|
||||
Expect(len(PIDs)).To(Equal(4))
|
||||
|
||||
ctrPID, _ := strconv.Atoi(PIDs[1])
|
||||
pausePID, _ := strconv.Atoi(PIDs[2])
|
||||
Expect(ctrPID).To(BeNumerically("<", pausePID))
|
||||
})
|
||||
|
||||
It("podman pod doesn't share PIDNS if requested to not", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "net", "--name", "test-pod"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test-ctr", podID)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"top", "test-ctr", "pid"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(check.ExitCode()).To(Equal(0))
|
||||
ctrTop := check.OutputToStringArray()
|
||||
|
||||
check = podmanTest.Podman([]string{"top", podID[:12] + "-infra", "pid"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(check.ExitCode()).To(Equal(0))
|
||||
pauseTop := check.OutputToStringArray()
|
||||
|
||||
ctrPID, _ := strconv.Atoi(ctrTop[1])
|
||||
pausePID, _ := strconv.Atoi(pauseTop[1])
|
||||
Expect(ctrPID).To(Equal(pausePID))
|
||||
})
|
||||
|
||||
It("podman pod container can override pod net NS", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "net"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
podmanTest.RestoreArtifact(nginx)
|
||||
session = podmanTest.Podman([]string{"run", "-d", "--pod", podID, nginx})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
podmanTest.RestoreArtifact(fedoraMinimal)
|
||||
session = podmanTest.Podman([]string{"run", "--pod", podID, "--network", "bridge", fedoraMinimal, "curl", "localhost"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Not(Equal(0)))
|
||||
})
|
||||
|
||||
It("podman pod container can override pod pid NS", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "pid"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "--pod", podID, "--pid", "host", "-d", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.PIDNS}}"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(check.ExitCode()).To(Equal(0))
|
||||
outputArray := check.OutputToStringArray()
|
||||
Expect(len(outputArray)).To(Equal(2))
|
||||
|
||||
PID1 := outputArray[0]
|
||||
PID2 := outputArray[1]
|
||||
Expect(PID1).To(Not(Equal(PID2)))
|
||||
})
|
||||
|
||||
It("podman pod container can override pod not sharing pid", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "net"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "--pod", podID, "--pid", "pod", "-d", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.PIDNS}}"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(check.ExitCode()).To(Equal(0))
|
||||
outputArray := check.OutputToStringArray()
|
||||
Expect(len(outputArray)).To(Equal(2))
|
||||
|
||||
PID1 := outputArray[0]
|
||||
PID2 := outputArray[1]
|
||||
Expect(PID1).To(Equal(PID2))
|
||||
})
|
||||
|
||||
It("podman pod container can override pod ipc NS", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "ipc"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "--pod", podID, "--ipc", "host", "-d", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
check := podmanTest.Podman([]string{"ps", "-a", "--ns", "--format", "{{.IPC}}"})
|
||||
check.WaitWithDefaultTimeout()
|
||||
Expect(check.ExitCode()).To(Equal(0))
|
||||
outputArray := check.OutputToStringArray()
|
||||
Expect(len(outputArray)).To(Equal(2))
|
||||
|
||||
PID1 := outputArray[0]
|
||||
PID2 := outputArray[1]
|
||||
Expect(PID1).To(Not(Equal(PID2)))
|
||||
})
|
||||
|
||||
It("podman pod pause container deletion", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--share", "ipc"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"ps", "-aq"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
pauseID := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"rm", pauseID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Not(Equal(0)))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "rm", podID})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
})
|
||||
})
|
|
@ -46,10 +46,8 @@ var _ = Describe("Podman pod pause", func() {
|
|||
})
|
||||
|
||||
It("podman pod pause a created pod by id", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "pause", podid})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
@ -57,12 +55,10 @@ var _ = Describe("Podman pod pause", func() {
|
|||
})
|
||||
|
||||
It("podman pod pause a running pod by id", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -80,12 +76,10 @@ var _ = Describe("Podman pod pause", func() {
|
|||
})
|
||||
|
||||
It("podman unpause a running pod by id", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -97,11 +91,10 @@ var _ = Describe("Podman pod pause", func() {
|
|||
})
|
||||
|
||||
It("podman pod pause a running pod by name", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, _ := podmanTest.CreatePod("test1")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "test1")
|
||||
session := podmanTest.RunTopContainerInPod("", "test1")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
|
|
@ -39,12 +39,10 @@ var _ = Describe("Podman ps", func() {
|
|||
})
|
||||
|
||||
It("podman pod ps default", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
podid := session.OutputToString()
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -55,12 +53,10 @@ var _ = Describe("Podman ps", func() {
|
|||
})
|
||||
|
||||
It("podman pod ps quiet flag", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
podid := session.OutputToString()
|
||||
_, ec, _ := podmanTest.RunLsContainerInPod("", podid)
|
||||
_, ec, _ = podmanTest.RunLsContainerInPod("", podid)
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "ps", "-q"})
|
||||
|
@ -71,14 +67,12 @@ var _ = Describe("Podman ps", func() {
|
|||
})
|
||||
|
||||
It("podman pod ps no-trunc", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
podid := session.OutputToString()
|
||||
_, ec, _ := podmanTest.RunLsContainerInPod("", podid)
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
_, ec2, _ := podmanTest.RunLsContainerInPod("", podid)
|
||||
Expect(ec2).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
|
@ -87,17 +81,11 @@ var _ = Describe("Podman ps", func() {
|
|||
})
|
||||
|
||||
It("podman pod ps latest", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, podid1 := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
podid1 := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
podid2 := session.OutputToString()
|
||||
_, ec2, podid2 := podmanTest.CreatePod("")
|
||||
Expect(ec2).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--latest"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
@ -106,11 +94,10 @@ var _ = Describe("Podman ps", func() {
|
|||
Expect(result.OutputToString()).To(Not(ContainSubstring(podid1)))
|
||||
})
|
||||
It("podman pod ps id filter flag", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "ps", "--filter", fmt.Sprintf("id=%s", session.OutputToString())})
|
||||
result := podmanTest.Podman([]string{"pod", "ps", "--filter", fmt.Sprintf("id=%s", podid)})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
})
|
||||
|
@ -123,19 +110,16 @@ var _ = Describe("Podman ps", func() {
|
|||
})
|
||||
|
||||
It("podman pod ps --sort by name", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, _ := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec2, _ := podmanTest.CreatePod("")
|
||||
Expect(ec2).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec3, _ := podmanTest.CreatePod("")
|
||||
Expect(ec3).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "ps", "--sort=name", "--format", "{{.Name}}"})
|
||||
session := podmanTest.Podman([]string{"pod", "ps", "--sort=name", "--format", "{{.Name}}"})
|
||||
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
@ -146,16 +130,14 @@ var _ = Describe("Podman ps", func() {
|
|||
})
|
||||
|
||||
It("podman pod ps --ctr-names", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test1", podid)
|
||||
session := podmanTest.RunTopContainerInPod("test1", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
_, ec, _ := podmanTest.RunLsContainerInPod("test2", podid)
|
||||
_, ec, _ = podmanTest.RunLsContainerInPod("test2", podid)
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "ps", "--format={{.ContainerInfo}}", "--ctr-names"})
|
||||
|
@ -166,23 +148,19 @@ var _ = Describe("Podman ps", func() {
|
|||
})
|
||||
|
||||
It("podman pod ps filter ctr attributes", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid1 := session.OutputToString()
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test1", podid1)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid2 := session.OutputToString()
|
||||
|
||||
_, ec, cid := podmanTest.RunLsContainerInPod("test2", podid2)
|
||||
_, ec, podid1 := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session := podmanTest.RunTopContainerInPod("test1", podid1)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
_, ec2, podid2 := podmanTest.CreatePod("")
|
||||
Expect(ec2).To(Equal(0))
|
||||
|
||||
_, ec3, cid := podmanTest.RunLsContainerInPod("test2", podid2)
|
||||
Expect(ec3).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-names=test1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
@ -195,10 +173,8 @@ var _ = Describe("Podman ps", func() {
|
|||
Expect(session.OutputToString()).To(ContainSubstring(podid2))
|
||||
Expect(session.OutputToString()).To(Not(ContainSubstring(podid1)))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid3 := session.OutputToString()
|
||||
_, ec3, podid3 := podmanTest.CreatePod("")
|
||||
Expect(ec3).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "ps", "-q", "--no-trunc", "--filter", "ctr-number=1"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
|
|
@ -38,22 +38,19 @@ var _ = Describe("Podman pod restart", func() {
|
|||
})
|
||||
|
||||
It("podman pod restart single empty pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
cid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "restart", cid})
|
||||
session := podmanTest.Podman([]string{"pod", "restart", podid})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
})
|
||||
|
||||
It("podman pod restart single pod by name", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test1", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("test1", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -70,15 +67,15 @@ var _ = Describe("Podman pod restart", func() {
|
|||
})
|
||||
|
||||
It("podman pod restart multiple pods", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test1", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("test1", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
_, ec, _ = podmanTest.CreatePod("foobar100")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test2", "foobar100")
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -108,15 +105,15 @@ var _ = Describe("Podman pod restart", func() {
|
|||
})
|
||||
|
||||
It("podman pod restart all pods", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test1", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("test1", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
_, ec, _ = podmanTest.CreatePod("foobar100")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test2", "foobar100")
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -136,15 +133,15 @@ var _ = Describe("Podman pod restart", func() {
|
|||
})
|
||||
|
||||
It("podman pod restart latest pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test1", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("test1", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
_, ec, _ = podmanTest.CreatePod("foobar100")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("test2", "foobar100")
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -164,15 +161,14 @@ var _ = Describe("Podman pod restart", func() {
|
|||
})
|
||||
|
||||
It("podman pod restart multiple pods with bogus", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
cid1 := session.OutputToString()
|
||||
_, ec, podid1 := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "restart", cid1, "doesnotexist"})
|
||||
session = podmanTest.Podman([]string{"pod", "restart", podid1, "doesnotexist"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
})
|
||||
|
|
|
@ -32,9 +32,8 @@ var _ = Describe("Podman pod rm", func() {
|
|||
})
|
||||
|
||||
It("podman pod rm empty pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "rm", podid})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
@ -42,13 +41,11 @@ var _ = Describe("Podman pod rm", func() {
|
|||
})
|
||||
|
||||
It("podman pod rm latest pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
podid2 := session.OutputToString()
|
||||
_, ec2, podid2 := podmanTest.CreatePod("")
|
||||
Expect(ec2).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "rm", "--latest"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
@ -62,14 +59,11 @@ var _ = Describe("Podman pod rm", func() {
|
|||
})
|
||||
|
||||
It("podman pod rm doesn't remove a pod with a container", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", podid, ALPINE, "ls"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec2, _ := podmanTest.RunLsContainerInPod("", podid)
|
||||
Expect(ec2).To(Equal(0))
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "rm", podid})
|
||||
result.WaitWithDefaultTimeout()
|
||||
|
@ -81,12 +75,10 @@ var _ = Describe("Podman pod rm", func() {
|
|||
})
|
||||
|
||||
It("podman pod rm -f does remove a running container", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
podid := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "-d", "--pod", podid, ALPINE, "top"})
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -100,15 +92,13 @@ var _ = Describe("Podman pod rm", func() {
|
|||
})
|
||||
|
||||
It("podman pod rm -a doesn't remove a running container", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, podid1 := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
podid1 := session.OutputToString()
|
||||
_, ec, _ = podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "-d", "--pod", podid1, ALPINE, "top"})
|
||||
session := podmanTest.RunTopContainerInPod("", podid1)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -127,20 +117,16 @@ var _ = Describe("Podman pod rm", func() {
|
|||
})
|
||||
|
||||
It("podman pod rm -fa removes everything", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, podid1 := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
podid1 := session.OutputToString()
|
||||
_, ec, podid2 := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, _ = podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
podid2 := session.OutputToString()
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "-d", "--pod", podid1, ALPINE, "top"})
|
||||
session := podmanTest.RunTopContainerInPod("", podid1)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -148,13 +134,13 @@ var _ = Describe("Podman pod rm", func() {
|
|||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "-d", "--pod", podid2, ALPINE, "ls"})
|
||||
_, ec, _ = podmanTest.RunLsContainerInPod("", podid2)
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid2)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"run", "-d", "--pod", podid2, ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
||||
result := podmanTest.Podman([]string{"pod", "rm", "-fa"})
|
||||
result.WaitWithDefaultTimeout()
|
||||
Expect(result.ExitCode()).To(Equal(0))
|
||||
|
|
|
@ -38,22 +38,19 @@ var _ = Describe("Podman pod start", func() {
|
|||
})
|
||||
|
||||
It("podman pod start single empty pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
cid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", cid})
|
||||
session := podmanTest.Podman([]string{"pod", "start", podid})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
})
|
||||
|
||||
It("podman pod start single pod by name", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "ls"})
|
||||
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "ls"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -63,38 +60,36 @@ var _ = Describe("Podman pod start", func() {
|
|||
})
|
||||
|
||||
It("podman pod start multiple pods", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
cid1 := session.OutputToString()
|
||||
_, ec, podid1 := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
|
||||
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
cid2 := session2.OutputToString()
|
||||
_, ec2, podid2 := podmanTest.CreatePod("foobar100")
|
||||
Expect(ec2).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", cid1, cid2})
|
||||
session = podmanTest.Podman([]string{"pod", "start", podid1, podid2})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(2))
|
||||
})
|
||||
|
||||
It("podman pod start all pods", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
|
||||
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
_, ec, _ = podmanTest.CreatePod("foobar100")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -107,15 +102,15 @@ var _ = Describe("Podman pod start", func() {
|
|||
})
|
||||
|
||||
It("podman pod start latest pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
|
||||
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
_, ec, _ = podmanTest.CreatePod("foobar100")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", "foobar100", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -128,15 +123,14 @@ var _ = Describe("Podman pod start", func() {
|
|||
})
|
||||
|
||||
It("podman pod start multiple pods with bogus", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
cid1 := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
|
||||
session := podmanTest.Podman([]string{"create", "--pod", "foobar99", ALPINE, "top"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "start", cid1, "doesnotexist"})
|
||||
session = podmanTest.Podman([]string{"pod", "start", podid, "doesnotexist"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
|
||||
|
|
|
@ -38,22 +38,19 @@ var _ = Describe("Podman pod stop", func() {
|
|||
})
|
||||
|
||||
It("podman pod stop single empty pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
cid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "stop", cid})
|
||||
session := podmanTest.Podman([]string{"pod", "stop", podid})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("podman pod stop single pod by name", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
@ -64,38 +61,36 @@ var _ = Describe("Podman pod stop", func() {
|
|||
})
|
||||
|
||||
It("podman pod stop multiple pods", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
cid1 := session.OutputToString()
|
||||
_, ec, podid1 := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
cid2 := session2.OutputToString()
|
||||
_, ec2, podid2 := podmanTest.CreatePod("foobar100")
|
||||
Expect(ec2).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar100")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "stop", cid1, cid2})
|
||||
session = podmanTest.Podman([]string{"pod", "stop", podid1, podid2})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
})
|
||||
|
||||
It("podman pod stop all pods", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
_, ec, _ = podmanTest.CreatePod("foobar100")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar100")
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -108,15 +103,15 @@ var _ = Describe("Podman pod stop", func() {
|
|||
})
|
||||
|
||||
It("podman pod stop latest pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
_, ec, _ := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session2 := podmanTest.Podman([]string{"pod", "create", "--name", "foobar100"})
|
||||
session2.WaitWithDefaultTimeout()
|
||||
_, ec, _ = podmanTest.CreatePod("foobar100")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar100")
|
||||
session.WaitWithDefaultTimeout()
|
||||
|
@ -129,15 +124,14 @@ var _ = Describe("Podman pod stop", func() {
|
|||
})
|
||||
|
||||
It("podman pod stop multiple pods with bogus", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create", "--name", "foobar99"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
cid1 := session.OutputToString()
|
||||
_, ec, podid1 := podmanTest.CreatePod("foobar99")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session := podmanTest.RunTopContainerInPod("", "foobar99")
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
session = podmanTest.Podman([]string{"pod", "stop", cid1, "doesnotexist"})
|
||||
session = podmanTest.Podman([]string{"pod", "stop", podid1, "doesnotexist"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(125))
|
||||
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
|
||||
|
|
|
@ -248,12 +248,10 @@ var _ = Describe("Podman ps", func() {
|
|||
})
|
||||
|
||||
It("podman --pod", func() {
|
||||
session := podmanTest.Podman([]string{"pod", "create"})
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
podid := session.OutputToString()
|
||||
_, ec, podid := podmanTest.CreatePod("")
|
||||
Expect(ec).To(Equal(0))
|
||||
|
||||
session = podmanTest.RunTopContainerInPod("", podid)
|
||||
session := podmanTest.RunTopContainerInPod("", podid)
|
||||
session.WaitWithDefaultTimeout()
|
||||
Expect(session.ExitCode()).To(Equal(0))
|
||||
|
||||
|
|
Loading…
Reference in a new issue