mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-08-29 03:37:54 +00:00
prevent opening the same file twice, since we re-exec podman in rootless mode. While at it, also solve a possible race between the check for the file and writing to it. Another process could have created the file in the meanwhile and we would just end up overwriting it. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
154 lines
4.1 KiB
Go
154 lines
4.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
|
"github.com/containers/libpod/cmd/podman/shared"
|
|
"github.com/containers/libpod/libpod"
|
|
"github.com/pkg/errors"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/urfave/cli"
|
|
)
|
|
|
|
var (
|
|
// Kernel namespaces shared by default within a pod
|
|
DefaultKernelNamespaces = "cgroup,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" +
|
|
" initial state 'created'."
|
|
|
|
var podCreateFlags = []cli.Flag{
|
|
cli.StringFlag{
|
|
Name: "cgroup-parent",
|
|
Usage: "Set parent cgroup for the pod",
|
|
},
|
|
cli.BoolTFlag{
|
|
Name: "infra",
|
|
Usage: "Create an infra container associated with the pod to share namespaces with",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "infra-image",
|
|
Usage: "The image of the infra container to associate with the pod",
|
|
Value: libpod.DefaultInfraImage,
|
|
},
|
|
cli.StringFlag{
|
|
Name: "infra-command",
|
|
Usage: "The command to run on the infra container when the pod is started",
|
|
Value: libpod.DefaultInfraCommand,
|
|
},
|
|
cli.StringSliceFlag{
|
|
Name: "label-file",
|
|
Usage: "Read in a line delimited file of labels (default [])",
|
|
},
|
|
cli.StringSliceFlag{
|
|
Name: "label, l",
|
|
Usage: "Set metadata on pod (default [])",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "name, n",
|
|
Usage: "Assign a name to the pod",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "pod-id-file",
|
|
Usage: "Write the pod ID to the file",
|
|
},
|
|
cli.StringFlag{
|
|
Name: "share",
|
|
Usage: "A comma delimited list of kernel namespaces the pod will share",
|
|
Value: DefaultKernelNamespaces,
|
|
},
|
|
}
|
|
|
|
var podCreateCommand = cli.Command{
|
|
Name: "create",
|
|
Usage: "Create a new empty pod",
|
|
Description: podCreateDescription,
|
|
Flags: sortFlags(podCreateFlags),
|
|
Action: podCreateCmd,
|
|
SkipArgReorder: true,
|
|
UseShortOptionHandling: true,
|
|
OnUsageError: usageErrorHandler,
|
|
}
|
|
|
|
func podCreateCmd(c *cli.Context) error {
|
|
var options []libpod.PodCreateOption
|
|
var err error
|
|
|
|
if err = validateFlags(c, createFlags); err != nil {
|
|
return err
|
|
}
|
|
|
|
runtime, err := libpodruntime.GetRuntime(c)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "error creating libpod runtime")
|
|
}
|
|
defer runtime.Shutdown(false)
|
|
|
|
var podIdFile *os.File
|
|
if c.IsSet("pod-id-file") && os.Geteuid() == 0 {
|
|
podIdFile, err = libpod.OpenExclusiveFile(c.String("pod-id-file"))
|
|
if err != nil && os.IsExist(err) {
|
|
return errors.Errorf("pod id file exists. Ensure another pod is not using it or delete %s", c.String("pod-id-file"))
|
|
}
|
|
if err != nil {
|
|
return errors.Errorf("error opening pod-id-file %s", c.String("pod-id-file"))
|
|
}
|
|
defer podIdFile.Close()
|
|
defer podIdFile.Sync()
|
|
}
|
|
if !c.BoolT("infra") && c.IsSet("share") && c.String("share") != "none" && c.String("share") != "" {
|
|
return errors.Errorf("You cannot share kernel namespaces on the pod level without an infra container")
|
|
}
|
|
|
|
if c.IsSet("cgroup-parent") {
|
|
options = append(options, libpod.WithPodCgroupParent(c.String("cgroup-parent")))
|
|
}
|
|
|
|
labels, err := getAllLabels(c.StringSlice("label-file"), c.StringSlice("label"))
|
|
if err != nil {
|
|
return errors.Wrapf(err, "unable to process labels")
|
|
}
|
|
if len(labels) != 0 {
|
|
options = append(options, libpod.WithPodLabels(labels))
|
|
}
|
|
|
|
if c.IsSet("name") {
|
|
options = append(options, libpod.WithPodName(c.String("name")))
|
|
}
|
|
|
|
if c.BoolT("infra") {
|
|
options = append(options, libpod.WithInfraContainer())
|
|
nsOptions, err := shared.GetNamespaceOptions(strings.Split(c.String("share"), ","))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
options = append(options, nsOptions...)
|
|
}
|
|
|
|
// always have containers use pod cgroups
|
|
// User Opt out is not yet supported
|
|
options = append(options, libpod.WithPodCgroups())
|
|
|
|
ctx := getContext()
|
|
pod, err := runtime.NewPod(ctx, options...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if podIdFile != nil {
|
|
_, err = podIdFile.WriteString(pod.ID())
|
|
if err != nil {
|
|
logrus.Error(err)
|
|
}
|
|
}
|
|
|
|
fmt.Printf("%s\n", pod.ID())
|
|
|
|
return nil
|
|
}
|