summaryrefslogtreecommitdiff
path: root/cmd/podman/pods
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman/pods')
-rw-r--r--cmd/podman/pods/create.go155
-rw-r--r--cmd/podman/pods/logs.go140
-rw-r--r--cmd/podman/pods/ps.go2
-rw-r--r--cmd/podman/pods/rm.go3
-rw-r--r--cmd/podman/pods/start.go3
-rw-r--r--cmd/podman/pods/stop.go3
6 files changed, 228 insertions, 78 deletions
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index bf5b9e350..b3f84dcd8 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -11,14 +11,17 @@ import (
"strings"
"github.com/containers/common/pkg/completion"
+ "github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/sysinfo"
"github.com/containers/podman/v3/cmd/podman/common"
+ "github.com/containers/podman/v3/cmd/podman/containers"
"github.com/containers/podman/v3/cmd/podman/parse"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/specgen"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/containers/podman/v3/pkg/util"
"github.com/docker/docker/pkg/parsers"
"github.com/pkg/errors"
@@ -44,11 +47,11 @@ var (
var (
createOptions entities.PodCreateOptions
+ infraOptions entities.ContainerCreateOptions
labels, labelFile []string
podIDFile string
replace bool
share string
- userns string
)
func init() {
@@ -58,62 +61,19 @@ func init() {
})
flags := createCommand.Flags()
flags.SetInterspersed(false)
-
+ infraOptions.IsInfra = true
+ common.DefineCreateFlags(createCommand, &infraOptions, true)
common.DefineNetFlags(createCommand)
- cpusetflagName := "cpuset-cpus"
- flags.StringVar(&createOptions.CpusetCpus, cpusetflagName, "", "CPUs in which to allow execution")
- _ = createCommand.RegisterFlagCompletionFunc(cpusetflagName, completion.AutocompleteDefault)
-
- cpusflagName := "cpus"
- flags.Float64Var(&createOptions.Cpus, cpusflagName, 0.000, "set amount of CPUs for the pod")
- _ = createCommand.RegisterFlagCompletionFunc(cpusflagName, completion.AutocompleteDefault)
-
- cgroupParentflagName := "cgroup-parent"
- flags.StringVar(&createOptions.CGroupParent, cgroupParentflagName, "", "Set parent cgroup for the pod")
- _ = createCommand.RegisterFlagCompletionFunc(cgroupParentflagName, completion.AutocompleteDefault)
-
- usernsFlagName := "userns"
- flags.StringVar(&userns, usernsFlagName, os.Getenv("PODMAN_USERNS"), "User namespace to use")
- _ = createCommand.RegisterFlagCompletionFunc(usernsFlagName, common.AutocompleteUserNamespace)
-
flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with")
- infraConmonPidfileFlagName := "infra-conmon-pidfile"
- flags.StringVar(&createOptions.InfraConmonPidFile, infraConmonPidfileFlagName, "", "Path to the file that will receive the POD of the infra container's conmon")
- _ = createCommand.RegisterFlagCompletionFunc(infraConmonPidfileFlagName, completion.AutocompleteDefault)
-
- infraImageFlagName := "infra-image"
- flags.String(infraImageFlagName, containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
- _ = createCommand.RegisterFlagCompletionFunc(infraImageFlagName, common.AutocompleteImages)
-
- infraCommandFlagName := "infra-command"
- flags.String(infraCommandFlagName, containerConfig.Engine.InfraCommand, "The command to run on the infra container when the pod is started")
- _ = createCommand.RegisterFlagCompletionFunc(infraCommandFlagName, completion.AutocompleteNone)
-
- infraNameFlagName := "infra-name"
- flags.StringVarP(&createOptions.InfraName, infraNameFlagName, "", "", "The name used as infra container name")
- _ = createCommand.RegisterFlagCompletionFunc(infraNameFlagName, completion.AutocompleteNone)
-
- labelFileFlagName := "label-file"
- flags.StringSliceVar(&labelFile, labelFileFlagName, []string{}, "Read in a line delimited file of labels")
- _ = createCommand.RegisterFlagCompletionFunc(labelFileFlagName, completion.AutocompleteDefault)
-
- labelFlagName := "label"
- flags.StringSliceVarP(&labels, labelFlagName, "l", []string{}, "Set metadata on pod (default [])")
- _ = createCommand.RegisterFlagCompletionFunc(labelFlagName, completion.AutocompleteNone)
-
nameFlagName := "name"
flags.StringVarP(&createOptions.Name, nameFlagName, "n", "", "Assign a name to the pod")
_ = createCommand.RegisterFlagCompletionFunc(nameFlagName, completion.AutocompleteNone)
- hostnameFlagName := "hostname"
- flags.StringVarP(&createOptions.Hostname, hostnameFlagName, "", "", "Set a hostname to the pod")
- _ = createCommand.RegisterFlagCompletionFunc(hostnameFlagName, completion.AutocompleteNone)
-
- pidFlagName := "pid"
- flags.StringVar(&createOptions.Pid, pidFlagName, "", "PID namespace to use")
- _ = createCommand.RegisterFlagCompletionFunc(pidFlagName, common.AutocompleteNamespace)
+ infraImageFlagName := "infra-image"
+ flags.String(infraImageFlagName, containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
+ _ = createCommand.RegisterFlagCompletionFunc(infraImageFlagName, common.AutocompleteImages)
podIDFileFlagName := "pod-id-file"
flags.StringVar(&podIDFile, podIDFileFlagName, "", "Write the pod ID to the file")
@@ -137,25 +97,30 @@ func aliasNetworkFlag(_ *pflag.FlagSet, name string) pflag.NormalizedName {
func create(cmd *cobra.Command, args []string) error {
var (
- err error
- podIDFD *os.File
+ err error
+ podIDFD *os.File
+ imageName string
+ rawImageName string
)
+ labelFile = infraOptions.LabelFile
+ labels = infraOptions.Label
createOptions.Labels, err = parse.GetAllLabels(labelFile, labels)
if err != nil {
return errors.Wrapf(err, "unable to process labels")
}
+ imageName = config.DefaultInfraImage
+ img := imageName
if !createOptions.Infra {
- logrus.Debugf("Not creating an infra container")
- if cmd.Flag("infra-conmon-pidfile").Changed {
- return errors.New("cannot set infra-conmon-pid without an infra container")
+ if cmd.Flag("no-hosts").Changed {
+ return fmt.Errorf("cannot specify no-hosts without an infra container")
}
- if cmd.Flag("infra-command").Changed {
- return errors.New("cannot set infra-command without an infra container")
- }
- if cmd.Flag("infra-image").Changed {
- return errors.New("cannot set infra-image without an infra container")
+ flags := cmd.Flags()
+ createOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, false)
+ if err != nil {
+ return err
}
+ logrus.Debugf("Not creating an infra container")
createOptions.InfraImage = ""
if createOptions.InfraName != "" {
return errors.New("cannot set infra-name without an infra container")
@@ -166,28 +131,43 @@ func create(cmd *cobra.Command, args []string) error {
}
createOptions.Share = nil
} else {
+ // reassign certain optios for lbpod api, these need to be populated in spec
+ createOptions.InfraConmonPidFile = infraOptions.ConmonPIDFile
+ createOptions.InfraName = infraOptions.Name
+ createOptions.Hostname = infraOptions.Hostname
+ createOptions.Cpus = infraOptions.CPUS
+ createOptions.CpusetCpus = infraOptions.CPUSetCPUs
+ createOptions.Pid = infraOptions.PID
+ flags := cmd.Flags()
+ infraOptions.Net, err = common.NetFlagsToNetOptions(nil, *flags, false)
+ if err != nil {
+ return err
+ }
+ infraOptions, err = containers.CreateInit(cmd, infraOptions, true)
+ if err != nil {
+ return err
+ }
+ createOptions.Net = infraOptions.Net
createOptions.Share = strings.Split(share, ",")
if cmd.Flag("infra-command").Changed {
// Only send content to server side if user changed defaults
- createOptions.InfraCommand, err = cmd.Flags().GetString("infra-command")
+ cmdIn, err := cmd.Flags().GetString("infra-command")
+ infraOptions.Entrypoint = &cmdIn
+ createOptions.InfraCommand = cmdIn
if err != nil {
return err
}
}
if cmd.Flag("infra-image").Changed {
// Only send content to server side if user changed defaults
- createOptions.InfraImage, err = cmd.Flags().GetString("infra-image")
+ img, err = cmd.Flags().GetString("infra-image")
+ imageName = img
if err != nil {
return err
}
}
}
- createOptions.Userns, err = specgen.ParseUserNamespace(userns)
- if err != nil {
- return err
- }
-
if cmd.Flag("pod-id-file").Changed {
podIDFD, err = util.OpenExclusiveFile(podIDFile)
if err != nil && os.IsExist(err) {
@@ -200,13 +180,6 @@ func create(cmd *cobra.Command, args []string) error {
defer errorhandling.SyncQuiet(podIDFD)
}
- createOptions.Pid = cmd.Flag("pid").Value.String()
-
- createOptions.Net, err = common.NetFlagsToNetOptions(cmd, createOptions.Infra)
- if err != nil {
- return err
- }
-
if len(createOptions.Net.PublishPorts) > 0 {
if !createOptions.Infra {
return errors.Errorf("you must have an infra container to publish port bindings to the host")
@@ -261,10 +234,44 @@ func create(cmd *cobra.Command, args []string) error {
copy = "" + strconv.Itoa(core)
}
}
- response, err := registry.ContainerEngine().PodCreate(context.Background(), createOptions)
+ podSpec := specgen.NewPodSpecGenerator()
+ podSpec, err = entities.ToPodSpecGen(*podSpec, &createOptions)
if err != nil {
return err
}
+ if createOptions.Infra {
+ rawImageName = img
+ if !infraOptions.RootFS {
+ curr := infraOptions.Quiet
+ infraOptions.Quiet = true
+ name, err := containers.PullImage(imageName, infraOptions)
+ if err != nil {
+ fmt.Println(err)
+ }
+ imageName = name
+ infraOptions.Quiet = curr
+ }
+ podSpec.InfraImage = imageName
+ if infraOptions.Entrypoint != nil {
+ createOptions.InfraCommand = *infraOptions.Entrypoint
+ }
+ infraOptions.CPUS = createOptions.Cpus
+ infraOptions.CPUSetCPUs = createOptions.CpusetCpus
+ infraOptions.PID = createOptions.Pid
+ podSpec.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false)
+ podSpec.InfraContainerSpec.RawImageName = rawImageName
+ podSpec.InfraContainerSpec.NetworkOptions = podSpec.NetworkOptions
+ err = specgenutil.FillOutSpecGen(podSpec.InfraContainerSpec, &infraOptions, []string{})
+ if err != nil {
+ return err
+ }
+ }
+ PodSpec := entities.PodSpec{PodSpecGen: *podSpec}
+ response, err := registry.ContainerEngine().PodCreate(context.Background(), PodSpec)
+ if err != nil {
+ return err
+ }
+
if len(podIDFile) > 0 {
if err = ioutil.WriteFile(podIDFile, []byte(response.Id), 0644); err != nil {
return errors.Wrapf(err, "failed to write pod ID to file")
diff --git a/cmd/podman/pods/logs.go b/cmd/podman/pods/logs.go
new file mode 100644
index 000000000..fe5205669
--- /dev/null
+++ b/cmd/podman/pods/logs.go
@@ -0,0 +1,140 @@
+package pods
+
+import (
+ "os"
+
+ "github.com/containers/common/pkg/completion"
+ "github.com/containers/podman/v3/cmd/podman/common"
+ "github.com/containers/podman/v3/cmd/podman/registry"
+ "github.com/containers/podman/v3/cmd/podman/validate"
+ "github.com/containers/podman/v3/libpod/define"
+ "github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/util"
+ "github.com/pkg/errors"
+ "github.com/spf13/cobra"
+)
+
+// logsOptionsWrapper wraps entities.LogsOptions and prevents leaking
+// CLI-only fields into the API types.
+type logsOptionsWrapper struct {
+ entities.PodLogsOptions
+
+ SinceRaw string
+
+ UntilRaw string
+}
+
+var (
+ logsPodOptions logsOptionsWrapper
+ logsPodDescription = `Displays logs for pod with one or more containers.`
+ logsPodCommand = &cobra.Command{
+ Use: "logs [options] POD",
+ Short: "Fetch logs for pod with one or more containers",
+ Long: logsPodDescription,
+ // We dont want users to invoke latest and pod togather
+ Args: func(cmd *cobra.Command, args []string) error {
+ switch {
+ case registry.IsRemote() && logsPodOptions.Latest:
+ return errors.New(cmd.Name() + " does not support 'latest' when run remotely")
+ case len(args) > 1:
+ return errors.New("requires exactly 1 arg")
+ case logsPodOptions.Latest && len(args) > 0:
+ return errors.New("--latest and pods cannot be used together")
+ case !logsPodOptions.Latest && len(args) < 1:
+ return errors.New("specify at least one pod name or ID to log")
+ }
+ return nil
+ },
+ RunE: logs,
+ ValidArgsFunction: common.AutocompletePods,
+ Example: `podman pod logs podID
+ podman pod logs -c ctrname podName
+ podman pod logs --tail 2 mywebserver
+ podman pod logs --follow=true --since 10m podID
+ podman pod logs mywebserver`,
+ }
+
+ containerLogsCommand = &cobra.Command{
+ Use: logsPodCommand.Use,
+ Short: logsPodCommand.Short,
+ Long: logsPodCommand.Long,
+ Args: logsPodCommand.Args,
+ RunE: logsPodCommand.RunE,
+ ValidArgsFunction: logsPodCommand.ValidArgsFunction,
+ Example: `podman pod logs podId
+ podman pod logs -c ctrname podName
+ podman pod logs --tail 2 mywebserver
+ podman pod logs --follow=true --since 10m podID`,
+ }
+)
+
+func init() {
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: logsPodCommand,
+ })
+ logsFlags(logsPodCommand)
+ validate.AddLatestFlag(logsPodCommand, &logsPodOptions.Latest)
+
+ // container logs
+ registry.Commands = append(registry.Commands, registry.CliCommand{
+ Command: containerLogsCommand,
+ Parent: podCmd,
+ })
+ logsFlags(containerLogsCommand)
+ validate.AddLatestFlag(containerLogsCommand, &logsPodOptions.Latest)
+}
+
+func logsFlags(cmd *cobra.Command) {
+ flags := cmd.Flags()
+
+ flags.BoolVar(&logsPodOptions.Details, "details", false, "Show extra details provided to the logs")
+ flags.BoolVarP(&logsPodOptions.Follow, "follow", "f", false, "Follow log output.")
+
+ containerNameFlag := "container"
+ flags.StringVarP(&logsPodOptions.ContainerName, containerNameFlag, "c", "", "Filter logs by container name or id which belongs to pod")
+ _ = cmd.RegisterFlagCompletionFunc(containerNameFlag, common.AutocompleteContainers)
+
+ sinceFlagName := "since"
+ flags.StringVar(&logsPodOptions.SinceRaw, sinceFlagName, "", "Show logs since TIMESTAMP")
+ _ = cmd.RegisterFlagCompletionFunc(sinceFlagName, completion.AutocompleteNone)
+
+ untilFlagName := "until"
+ flags.StringVar(&logsPodOptions.UntilRaw, untilFlagName, "", "Show logs until TIMESTAMP")
+ _ = cmd.RegisterFlagCompletionFunc(untilFlagName, completion.AutocompleteNone)
+
+ tailFlagName := "tail"
+ flags.Int64Var(&logsPodOptions.Tail, tailFlagName, -1, "Output the specified number of LINES at the end of the logs.")
+ _ = cmd.RegisterFlagCompletionFunc(tailFlagName, completion.AutocompleteNone)
+
+ flags.BoolVarP(&logsPodOptions.Timestamps, "timestamps", "t", false, "Output the timestamps in the log")
+ flags.SetInterspersed(false)
+ _ = flags.MarkHidden("details")
+}
+
+func logs(_ *cobra.Command, args []string) error {
+ if logsPodOptions.SinceRaw != "" {
+ // parse time, error out if something is wrong
+ since, err := util.ParseInputTime(logsPodOptions.SinceRaw, true)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing --since %q", logsPodOptions.SinceRaw)
+ }
+ logsPodOptions.Since = since
+ }
+ if logsPodOptions.UntilRaw != "" {
+ // parse time, error out if something is wrong
+ until, err := util.ParseInputTime(logsPodOptions.UntilRaw, false)
+ if err != nil {
+ return errors.Wrapf(err, "error parsing --until %q", logsPodOptions.UntilRaw)
+ }
+ logsPodOptions.Until = until
+ }
+
+ // Remote can only process one container at a time
+ if registry.IsRemote() && logsPodOptions.ContainerName == "" {
+ return errors.Wrapf(define.ErrInvalidArg, "-c or --container cannot be empty")
+ }
+
+ logsPodOptions.StdoutWriter = os.Stdout
+ logsPodOptions.StderrWriter = os.Stderr
+ return registry.ContainerEngine().PodLogs(registry.GetContext(), args[0], logsPodOptions.PodLogsOptions)
+}
diff --git a/cmd/podman/pods/ps.go b/cmd/podman/pods/ps.go
index 14e3e2ea9..60aadf224 100644
--- a/cmd/podman/pods/ps.go
+++ b/cmd/podman/pods/ps.go
@@ -57,7 +57,7 @@ func init() {
formatFlagName := "format"
flags.StringVar(&psInput.Format, formatFlagName, "", "Pretty-print pods to JSON or using a Go template")
- _ = psCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(ListPodReporter{}))
+ _ = psCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(ListPodReporter{ListPodsReport: &entities.ListPodsReport{}}))
flags.Bool("noheading", false, "Do not print headers")
flags.BoolVar(&psInput.Namespace, "namespace", false, "Display namespace information of the pod")
diff --git a/cmd/podman/pods/rm.go b/cmd/podman/pods/rm.go
index fbaf64c1f..dc4c7eb83 100644
--- a/cmd/podman/pods/rm.go
+++ b/cmd/podman/pods/rm.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -66,7 +67,7 @@ func init() {
}
func rm(_ *cobra.Command, args []string) error {
- ids, err := common.ReadPodIDFiles(rmOptions.PodIDFiles)
+ ids, err := specgenutil.ReadPodIDFiles(rmOptions.PodIDFiles)
if err != nil {
return err
}
diff --git a/cmd/podman/pods/start.go b/cmd/podman/pods/start.go
index e39891a9b..e5f9eaa84 100644
--- a/cmd/podman/pods/start.go
+++ b/cmd/podman/pods/start.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/spf13/cobra"
)
@@ -64,7 +65,7 @@ func start(cmd *cobra.Command, args []string) error {
errs utils.OutputErrors
)
- ids, err := common.ReadPodIDFiles(startOptions.PodIDFiles)
+ ids, err := specgenutil.ReadPodIDFiles(startOptions.PodIDFiles)
if err != nil {
return err
}
diff --git a/cmd/podman/pods/stop.go b/cmd/podman/pods/stop.go
index bcc054b8e..41325649f 100644
--- a/cmd/podman/pods/stop.go
+++ b/cmd/podman/pods/stop.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/utils"
"github.com/containers/podman/v3/cmd/podman/validate"
"github.com/containers/podman/v3/pkg/domain/entities"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/spf13/cobra"
)
@@ -78,7 +79,7 @@ func stop(cmd *cobra.Command, args []string) error {
stopOptions.Timeout = int(stopOptions.TimeoutCLI)
}
- ids, err := common.ReadPodIDFiles(stopOptions.PodIDFiles)
+ ids, err := specgenutil.ReadPodIDFiles(stopOptions.PodIDFiles)
if err != nil {
return err
}