Skip to content

Commit

Permalink
Merge pull request #6415 from vrothberg/systemd-new-pod
Browse files Browse the repository at this point in the history
podman-generate-systemd --new for pods
  • Loading branch information
openshift-merge-robot authored Jun 11, 2020
2 parents f1b6840 + c7c81a8 commit 39ad038
Show file tree
Hide file tree
Showing 41 changed files with 1,806 additions and 769 deletions.
5 changes: 5 additions & 0 deletions cmd/podman/common/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,11 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"pod", "",
"Run container in an existing pod",
)
createFlags.StringVar(
&cf.PodIDFile,
"pod-id-file", "",
"Read the pod ID from the file",
)
createFlags.BoolVar(
&cf.Privileged,
"privileged", false,
Expand Down
1 change: 1 addition & 0 deletions cmd/podman/common/create_opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type ContainerCLIOpts struct {
PID string
PIDsLimit int64
Pod string
PodIDFile string
Privileged bool
PublishAll bool
Pull string
Expand Down
11 changes: 11 additions & 0 deletions cmd/podman/common/specgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,17 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.PublishExposedPorts = c.PublishAll
s.Pod = c.Pod

if len(c.PodIDFile) > 0 {
if len(s.Pod) > 0 {
return errors.New("Cannot specify both --pod and --pod-id-file")
}
podID, err := ReadPodIDFile(c.PodIDFile)
if err != nil {
return err
}
s.Pod = podID
}

expose, err := createExpose(c.Expose)
if err != nil {
return err
Expand Down
25 changes: 25 additions & 0 deletions cmd/podman/common/util.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package common

import (
"io/ioutil"
"net"
"strconv"
"strings"
Expand All @@ -10,6 +11,30 @@ import (
"github.com/sirupsen/logrus"
)

// ReadPodIDFile reads the specified file and returns its content (i.e., first
// line).
func ReadPodIDFile(path string) (string, error) {
content, err := ioutil.ReadFile(path)
if err != nil {
return "", errors.Wrap(err, "error reading pod ID file")
}
return strings.Split(string(content), "\n")[0], nil
}

// ReadPodIDFiles reads the specified files and returns their content (i.e.,
// first line).
func ReadPodIDFiles(files []string) ([]string, error) {
ids := []string{}
for _, file := range files {
id, err := ReadPodIDFile(file)
if err != nil {
return nil, err
}
ids = append(ids, id)
}
return ids, nil
}

// createExpose parses user-provided exposed port definitions and converts them
// into SpecGen format.
// TODO: The SpecGen format should really handle ranges more sanely - we could
Expand Down
55 changes: 55 additions & 0 deletions cmd/podman/parse/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import (
"github.com/spf13/cobra"
)

// TODO: the two functions here are almost identical. It may be worth looking
// into generalizing the two a bit more and share code but time is scarce and
// we only live once.

// CheckAllLatestAndCIDFile checks that --all and --latest are used correctly.
// If cidfile is set, also check for the --cidfile flag.
func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool, cidfile bool) error {
Expand Down Expand Up @@ -55,3 +59,54 @@ func CheckAllLatestAndCIDFile(c *cobra.Command, args []string, ignoreArgLen bool
}
return nil
}

// CheckAllLatestAndPodIDFile checks that --all and --latest are used correctly.
// If withIDFile is set, also check for the --pod-id-file flag.
func CheckAllLatestAndPodIDFile(c *cobra.Command, args []string, ignoreArgLen bool, withIDFile bool) error {
argLen := len(args)
if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil {
if !withIDFile {
return errors.New("unable to lookup values for 'latest' or 'all'")
} else if c.Flags().Lookup("pod-id-file") == nil {
return errors.New("unable to lookup values for 'latest', 'all' or 'pod-id-file'")
}
}

specifiedAll, _ := c.Flags().GetBool("all")
specifiedLatest, _ := c.Flags().GetBool("latest")
specifiedPodIDFile := false
if pid, _ := c.Flags().GetStringArray("pod-id-file"); len(pid) > 0 {
specifiedPodIDFile = true
}

if specifiedPodIDFile && (specifiedAll || specifiedLatest) {
return errors.Errorf("--all, --latest and --pod-id-file cannot be used together")
} else if specifiedAll && specifiedLatest {
return errors.Errorf("--all and --latest cannot be used together")
}

if (argLen > 0) && specifiedAll {
return errors.Errorf("no arguments are needed with --all")
}

if ignoreArgLen {
return nil
}

if argLen > 0 {
if specifiedLatest {
return errors.Errorf("no arguments are needed with --latest")
} else if withIDFile && (specifiedLatest || specifiedPodIDFile) {
return errors.Errorf("no arguments are needed with --latest or --pod-id-file")
}
}

if specifiedPodIDFile {
return nil
}

if argLen < 1 && !specifiedAll && !specifiedLatest && !specifiedPodIDFile {
return errors.Errorf("you must provide at least one name or id")
}
return nil
}
4 changes: 4 additions & 0 deletions cmd/podman/pods/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func init() {
flags.AddFlagSet(common.GetNetFlags())
flags.StringVar(&createOptions.CGroupParent, "cgroup-parent", "", "Set parent cgroup for the pod")
flags.BoolVar(&createOptions.Infra, "infra", true, "Create an infra container associated with the pod to share namespaces with")
flags.StringVar(&createOptions.InfraConmonPidFile, "infra-conmon-pidfile", "", "Path to the file that will receive the POD of the infra container's conmon")
flags.StringVar(&createOptions.InfraImage, "infra-image", containerConfig.Engine.InfraImage, "The image of the infra container to associate with the pod")
flags.StringVar(&createOptions.InfraCommand, "infra-command", containerConfig.Engine.InfraCommand, "The command to run on the infra container when the pod is started")
flags.StringSliceVar(&labelFile, "label-file", []string{}, "Read in a line delimited file of labels")
Expand Down Expand Up @@ -83,6 +84,9 @@ func create(cmd *cobra.Command, args []string) error {

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("infra-command").Changed {
return errors.New("cannot set infra-command without an infra container")
}
Expand Down
25 changes: 19 additions & 6 deletions cmd/podman/pods/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,23 @@ import (
"context"
"fmt"

"github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/parse"
"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/cmd/podman/utils"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/spf13/cobra"
)

// allows for splitting API and CLI-only options
type podRmOptionsWrapper struct {
entities.PodRmOptions

PodIDFiles []string
}

var (
rmOptions = podRmOptionsWrapper{}
podRmDescription = fmt.Sprintf(`podman rm will remove one or more stopped pods and their containers from the host.
The pod name or ID can be used. A pod with containers will not be removed without --force. If --force is specified, all containers will be stopped, then removed.`)
Expand All @@ -21,18 +30,14 @@ var (
Long: podRmDescription,
RunE: rm,
Args: func(cmd *cobra.Command, args []string) error {
return parse.CheckAllLatestAndCIDFile(cmd, args, false, false)
return parse.CheckAllLatestAndPodIDFile(cmd, args, false, true)
},
Example: `podman pod rm mywebserverpod
podman pod rm -f 860a4b23
podman pod rm -f -a`,
}
)

var (
rmOptions = entities.PodRmOptions{}
)

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Expand All @@ -45,6 +50,7 @@ func init() {
flags.BoolVarP(&rmOptions.Force, "force", "f", false, "Force removal of a running pod by first stopping all containers, then removing all containers in the pod. The default is false")
flags.BoolVarP(&rmOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing")
flags.BoolVarP(&rmOptions.Latest, "latest", "l", false, "Remove the latest pod podman is aware of")
flags.StringArrayVarP(&rmOptions.PodIDFiles, "pod-id-file", "", nil, "Read the pod ID from the file")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
_ = flags.MarkHidden("ignore")
Expand All @@ -55,7 +61,14 @@ func rm(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
responses, err := registry.ContainerEngine().PodRm(context.Background(), args, rmOptions)

ids, err := common.ReadPodIDFiles(rmOptions.PodIDFiles)
if err != nil {
return err
}
args = append(args, ids...)

responses, err := registry.ContainerEngine().PodRm(context.Background(), args, rmOptions.PodRmOptions)
if err != nil {
return err
}
Expand Down
22 changes: 19 additions & 3 deletions cmd/podman/pods/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ import (
"context"
"fmt"

"github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/parse"
"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/cmd/podman/utils"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/spf13/cobra"
)

// allows for splitting API and CLI-only options
type podStartOptionsWrapper struct {
entities.PodStartOptions

PodIDFiles []string
}

var (
podStartDescription = `The pod name or ID can be used.
Expand All @@ -21,7 +29,7 @@ var (
Long: podStartDescription,
RunE: start,
Args: func(cmd *cobra.Command, args []string) error {
return parse.CheckAllLatestAndCIDFile(cmd, args, false, false)
return parse.CheckAllLatestAndPodIDFile(cmd, args, false, true)
},
Example: `podman pod start podID
podman pod start --latest
Expand All @@ -30,7 +38,7 @@ var (
)

var (
startOptions = entities.PodStartOptions{}
startOptions = podStartOptionsWrapper{}
)

func init() {
Expand All @@ -43,6 +51,7 @@ func init() {
flags := startCommand.Flags()
flags.BoolVarP(&startOptions.All, "all", "a", false, "Restart all running pods")
flags.BoolVarP(&startOptions.Latest, "latest", "l", false, "Restart the latest pod podman is aware of")
flags.StringArrayVarP(&startOptions.PodIDFiles, "pod-id-file", "", nil, "Read the pod ID from the file")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
}
Expand All @@ -52,7 +61,14 @@ func start(cmd *cobra.Command, args []string) error {
var (
errs utils.OutputErrors
)
responses, err := registry.ContainerEngine().PodStart(context.Background(), args, startOptions)

ids, err := common.ReadPodIDFiles(startOptions.PodIDFiles)
if err != nil {
return err
}
args = append(args, ids...)

responses, err := registry.ContainerEngine().PodStart(context.Background(), args, startOptions.PodStartOptions)
if err != nil {
return err
}
Expand Down
35 changes: 24 additions & 11 deletions cmd/podman/pods/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,26 @@ import (
"context"
"fmt"

"github.com/containers/libpod/cmd/podman/common"
"github.com/containers/libpod/cmd/podman/parse"
"github.com/containers/libpod/cmd/podman/registry"
"github.com/containers/libpod/cmd/podman/utils"
"github.com/containers/libpod/pkg/domain/entities"
"github.com/spf13/cobra"
)

// allows for splitting API and CLI-only options
type podStopOptionsWrapper struct {
entities.PodStopOptions

PodIDFiles []string
TimeoutCLI uint
}

var (
stopOptions = podStopOptionsWrapper{
PodStopOptions: entities.PodStopOptions{Timeout: -1},
}
podStopDescription = `The pod name or ID can be used.
This command will stop all running containers in each of the specified pods.`
Expand All @@ -22,21 +34,14 @@ var (
Long: podStopDescription,
RunE: stop,
Args: func(cmd *cobra.Command, args []string) error {
return parse.CheckAllLatestAndCIDFile(cmd, args, false, false)
return parse.CheckAllLatestAndPodIDFile(cmd, args, false, true)
},
Example: `podman pod stop mywebserverpod
podman pod stop --latest
podman pod stop --time 0 490eb 3557fb`,
}
)

var (
stopOptions = entities.PodStopOptions{
Timeout: -1,
}
timeout uint
)

func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Expand All @@ -47,7 +52,8 @@ func init() {
flags.BoolVarP(&stopOptions.All, "all", "a", false, "Stop all running pods")
flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified pod is missing")
flags.BoolVarP(&stopOptions.Latest, "latest", "l", false, "Stop the latest pod podman is aware of")
flags.UintVarP(&timeout, "time", "t", containerConfig.Engine.StopTimeout, "Seconds to wait for pod stop before killing the container")
flags.UintVarP(&stopOptions.TimeoutCLI, "time", "t", containerConfig.Engine.StopTimeout, "Seconds to wait for pod stop before killing the container")
flags.StringArrayVarP(&stopOptions.PodIDFiles, "pod-id-file", "", nil, "Read the pod ID from the file")
if registry.IsRemote() {
_ = flags.MarkHidden("latest")
_ = flags.MarkHidden("ignore")
Expand All @@ -60,9 +66,16 @@ func stop(cmd *cobra.Command, args []string) error {
errs utils.OutputErrors
)
if cmd.Flag("time").Changed {
stopOptions.Timeout = int(timeout)
stopOptions.Timeout = int(stopOptions.TimeoutCLI)
}

ids, err := common.ReadPodIDFiles(stopOptions.PodIDFiles)
if err != nil {
return err
}
responses, err := registry.ContainerEngine().PodStop(context.Background(), args, stopOptions)
args = append(args, ids...)

responses, err := registry.ContainerEngine().PodStop(context.Background(), args, stopOptions.PodStopOptions)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 39ad038

Please sign in to comment.