Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

podman-generate-systemd --new for pods #6415

Merged
merged 14 commits into from
Jun 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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