diff options
51 files changed, 562 insertions, 279 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b1b166fef..3778d6d7d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -329,10 +329,16 @@ author hold special privileges on the github repository. Others can be used by unintentionally. Instead, just write ``LGTM``, or spell it out. -* ``[skip ci]``: Within the HEAD commit will cause Cirrus CI to ***NOT*** execute - tests on the PR. This is useful in basically two cases: 1) You're still working - and don't want to waste resources. 2) You haven't modified any code that would - be exercised by the tests. For example, documentation updates (outside of code). +* ``/hold`` and ``/unhold``: Override the automatic handling of a request. Either + put it on hold (no handling) or remove the hold (normal handling). + +* ``[ci skip]``: [Adding `[ci skip]` within the HEAD commit](https://cirrus-ci.org/guide/writing-tasks/#conditional-task-execution) + will cause Cirrus CI to ***NOT*** execute tests for the PR or after merge. This + is useful in only one instance: Your changes are absolutely not exercised by + any test. For example, documentation changes. ***IMPORTANT NOTE*** **Other + automation may interpret the lack of test results as "PASSED" and unintentionall + merge a PR. Consider also using `/hold` in a comment, to add additional + protection.** [The complete list may be found on the command-help page.](https://prow.k8s.io/command-help) However, not all commands are implemented for this repository. If in doubt, ask a maintainer. diff --git a/cmd/podman/build.go b/cmd/podman/build.go index 8ea9e6957..cfeabfb4e 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -53,7 +53,7 @@ func init() { flags.SetInterspersed(false) budFlags := buildahcli.GetBudFlags(&budFlagsValues) - flag := budFlags.Lookup("pull-always") + flag := budFlags.Lookup("pull") flag.Value.Set("true") flag.DefValue = "true" layerFlags := buildahcli.GetLayerFlags(&layerValues) diff --git a/cmd/podman/checkpoint.go b/cmd/podman/checkpoint.go index 8c4b8ad3c..367065766 100644 --- a/cmd/podman/checkpoint.go +++ b/cmd/podman/checkpoint.go @@ -32,9 +32,9 @@ var ( Args: func(cmd *cobra.Command, args []string) error { return checkAllAndLatest(cmd, args, false) }, - Example: `podman checkpoint --keep ctrID - podman checkpoint --all - podman checkpoint --leave-running --latest`, + Example: `podman container checkpoint --keep ctrID + podman container checkpoint --all + podman container checkpoint --leave-running --latest`, } ) diff --git a/cmd/podman/cliconfig/commands.go b/cmd/podman/cliconfig/commands.go index 7d1e762d9..3361c14b8 100644 --- a/cmd/podman/cliconfig/commands.go +++ b/cmd/podman/cliconfig/commands.go @@ -1,5 +1,7 @@ package cliconfig +import "github.com/sirupsen/logrus" + // GlobalIsSet is a compatibility method for urfave func (p *PodmanCommand) GlobalIsSet(opt string) bool { flag := p.PersistentFlags().Lookup(opt) @@ -22,9 +24,13 @@ func (p *PodmanCommand) IsSet(opt string) bool { func (p *PodmanCommand) Bool(opt string) bool { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return false } - val, _ := p.Flags().GetBool(opt) + val, err := p.Flags().GetBool(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } @@ -32,9 +38,13 @@ func (p *PodmanCommand) Bool(opt string) bool { func (p *PodmanCommand) String(opt string) string { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return "" } - val, _ := p.Flags().GetString(opt) + val, err := p.Flags().GetString(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } @@ -42,9 +52,13 @@ func (p *PodmanCommand) String(opt string) string { func (p *PodmanCommand) StringArray(opt string) []string { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return []string{} } - val, _ := p.Flags().GetStringArray(opt) + val, err := p.Flags().GetStringArray(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } @@ -52,9 +66,13 @@ func (p *PodmanCommand) StringArray(opt string) []string { func (p *PodmanCommand) StringSlice(opt string) []string { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return []string{} } - val, _ := p.Flags().GetStringSlice(opt) + val, err := p.Flags().GetStringSlice(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } @@ -62,9 +80,13 @@ func (p *PodmanCommand) StringSlice(opt string) []string { func (p *PodmanCommand) Int(opt string) int { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return 0 } - val, _ := p.Flags().GetInt(opt) + val, err := p.Flags().GetInt(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } @@ -72,9 +94,13 @@ func (p *PodmanCommand) Int(opt string) int { func (p *PodmanCommand) Uint(opt string) uint { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return 0 } - val, _ := p.Flags().GetUint(opt) + val, err := p.Flags().GetUint(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } @@ -82,9 +108,13 @@ func (p *PodmanCommand) Uint(opt string) uint { func (p *PodmanCommand) Int64(opt string) int64 { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return 0 } - val, _ := p.Flags().GetInt64(opt) + val, err := p.Flags().GetInt64(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } @@ -92,9 +122,13 @@ func (p *PodmanCommand) Int64(opt string) int64 { func (p *PodmanCommand) Uint64(opt string) uint64 { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return 0 } - val, _ := p.Flags().GetUint64(opt) + val, err := p.Flags().GetUint64(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } @@ -102,8 +136,12 @@ func (p *PodmanCommand) Uint64(opt string) uint64 { func (p *PodmanCommand) Float64(opt string) float64 { flag := p.Flags().Lookup(opt) if flag == nil { + logrus.Errorf("Could not find flag %s", opt) return 0 } - val, _ := p.Flags().GetFloat64(opt) + val, err := p.Flags().GetFloat64(opt) + if err != nil { + logrus.Errorf("Error getting flag %s: %v", opt, err) + } return val } diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go index fd36e77d5..2f9a9cfe2 100644 --- a/cmd/podman/commands.go +++ b/cmd/podman/commands.go @@ -18,7 +18,7 @@ func getMainCommands() []*cobra.Command { _execCommand, _generateCommand, _playCommand, - _psCommand, + &_psCommand, _loginCommand, _logoutCommand, _logsCommand, @@ -54,6 +54,10 @@ func getImageSubCommands() []*cobra.Command { // Commands that the local client implements func getContainerSubCommands() []*cobra.Command { + + var _listSubCommand = _psCommand + _listSubCommand.Use = "list" + return []*cobra.Command{ _attachCommand, _checkpointCommand, @@ -64,8 +68,8 @@ func getContainerSubCommands() []*cobra.Command { _execCommand, _exportCommand, _killCommand, + &_listSubCommand, _logsCommand, - _psCommand, _mountCommand, _pauseCommand, _portCommand, diff --git a/cmd/podman/common.go b/cmd/podman/common.go index 1fb06cf91..d3387b8f4 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -423,7 +423,7 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "stop-signal", "", "Signal to stop a container. Default is SIGTERM", ) - createFlags.Int( + createFlags.Uint( "stop-timeout", libpod.CtrRemoveTimeout, "Timeout (in seconds) to stop a container. Default is 10", ) @@ -527,7 +527,6 @@ func scrubServer(server string) string { func UsageTemplate() string { return `Usage:{{if .Runnable}} {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}} - {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}} Aliases: diff --git a/cmd/podman/container.go b/cmd/podman/container.go index d2450fdd3..338bb005c 100644 --- a/cmd/podman/container.go +++ b/cmd/podman/container.go @@ -18,11 +18,13 @@ var containerCommand = cliconfig.PodmanCommand{ // Commands that are universally implemented. var containerCommands = []*cobra.Command{ _containerExistsCommand, + _inspectCommand, } func init() { containerCommand.AddCommand(containerCommands...) containerCommand.AddCommand(getContainerSubCommands()...) containerCommand.SetUsageTemplate(UsageTemplate()) + rootCmd.AddCommand(containerCommand.Command) } diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 2d93c149a..95cb732d9 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -67,7 +67,7 @@ func init() { getCreateFlags(&createCommand.PodmanCommand) flags := createCommand.Flags() - flags.SetInterspersed(true) + flags.SetInterspersed(false) } @@ -408,7 +408,7 @@ func parseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l return nil, err } - if err = parseVolumesFrom(c.StringArray("volumes-from")); err != nil { + if err = parseVolumesFrom(c.StringSlice("volumes-from")); err != nil { return nil, err } @@ -707,23 +707,23 @@ func parseCreateOpts(ctx context.Context, c *cliconfig.PodmanCommand, runtime *l Entrypoint: entrypoint, Env: env, //ExposedPorts: ports, - GroupAdd: c.StringSlice("group-add"), - Hostname: c.String("hostname"), - HostAdd: c.StringSlice("add-host"), - IDMappings: idmappings, - Image: imageName, - ImageID: imageID, - Interactive: c.Bool("interactive"), - IP6Address: c.String("ipv6"), - IPAddress: c.String("ip"), - Labels: labels, - LinkLocalIP: c.StringSlice("link-local-ip"), - LogDriver: c.String("log-driver"), - LogDriverOpt: c.StringSlice("log-opt"), - MacAddress: c.String("mac-address"), - Name: c.String("name"), - Network: network, - NetworkAlias: c.StringSlice("network-alias"), + GroupAdd: c.StringSlice("group-add"), + Hostname: c.String("hostname"), + HostAdd: c.StringSlice("add-host"), + IDMappings: idmappings, + Image: imageName, + ImageID: imageID, + Interactive: c.Bool("interactive"), + //IP6Address: c.String("ipv6"), // Not implemented yet - needs CNI support for static v6 + IPAddress: c.String("ip"), + Labels: labels, + //LinkLocalIP: c.StringSlice("link-local-ip"), // Not implemented yet + LogDriver: c.String("log-driver"), + LogDriverOpt: c.StringSlice("log-opt"), + MacAddress: c.String("mac-address"), + Name: c.String("name"), + Network: network, + //NetworkAlias: c.StringSlice("network-alias"), // Not implemented - does this make sense in Podman? IpcMode: ipcMode, NetMode: netMode, UtsMode: utsMode, diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go index 032262497..4917fb606 100644 --- a/cmd/podman/exec.go +++ b/cmd/podman/exec.go @@ -105,5 +105,13 @@ func execCmd(c *cliconfig.ExecValues) error { envs = append(envs, fmt.Sprintf("%s=%s", k, v)) } - return ctr.Exec(c.Tty, c.Privileged, envs, cmd, c.User, c.Workdir) + streams := new(libpod.AttachStreams) + streams.OutputStream = os.Stdout + streams.ErrorStream = os.Stderr + streams.InputStream = os.Stdin + streams.AttachOutput = true + streams.AttachError = true + streams.AttachInput = true + + return ctr.Exec(c.Tty, c.Privileged, envs, cmd, c.User, c.Workdir, streams) } diff --git a/cmd/podman/exists.go b/cmd/podman/exists.go index c01a6a081..109831e74 100644 --- a/cmd/podman/exists.go +++ b/cmd/podman/exists.go @@ -40,7 +40,8 @@ var ( imageExistsCommand.GlobalFlags = MainGlobalOpts return imageExistsCmd(&imageExistsCommand) }, - Example: `podman image exists imageID`, + Example: `podman image exists imageID + podman image exists alpine || podman pull alpine`, } _containerExistsCommand = &cobra.Command{ @@ -53,7 +54,8 @@ var ( return containerExistsCmd(&containerExistsCommand) }, - Example: `podman container exists containerID`, + Example: `podman container exists containerID + podman container exists myctr || podman run --name myctr [etc...]`, } _podExistsCommand = &cobra.Command{ @@ -65,7 +67,8 @@ var ( podExistsCommand.GlobalFlags = MainGlobalOpts return podExistsCmd(&podExistsCommand) }, - Example: `podman pod exists podID`, + Example: `podman pod exists podID + podman pod exists mypod || podman pod create --name mypod`, } ) diff --git a/cmd/podman/generate_kube.go b/cmd/podman/generate_kube.go index 090f99495..fa2872b77 100644 --- a/cmd/podman/generate_kube.go +++ b/cmd/podman/generate_kube.go @@ -17,7 +17,7 @@ var ( containerKubeCommand cliconfig.GenerateKubeValues containerKubeDescription = "Generate Kubernetes Pod YAML" _containerKubeCommand = &cobra.Command{ - Use: "kube CONTAINER | POD", + Use: "kube [flags] CONTAINER | POD", Short: "Generate Kubernetes pod YAML for a container or pod", Long: containerKubeDescription, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/image.go b/cmd/podman/image.go index aaa1866c4..b5c1c3ccf 100644 --- a/cmd/podman/image.go +++ b/cmd/podman/image.go @@ -15,6 +15,7 @@ var ( }, } _imagesSubCommand = _imagesCommand + _rmSubCommand = _rmiCommand ) //imageSubCommands are implemented both in local and remote clients @@ -28,7 +29,6 @@ var imageSubCommands = []*cobra.Command{ _pruneImagesCommand, _pullCommand, _pushCommand, - _rmiCommand, _saveCommand, _tagCommand, } @@ -38,7 +38,12 @@ func init() { imageCommand.AddCommand(imageSubCommands...) imageCommand.AddCommand(getImageSubCommands()...) - _imagesSubCommand.Aliases = []string{"ls", "list"} + // Setup of "images" to appear as "list" + _imagesSubCommand.Use = "list" + _imagesSubCommand.Aliases = []string{"ls"} imageCommand.AddCommand(&_imagesSubCommand) + // Setup of "rmi" to appears as "rm" + _rmSubCommand.Use = "rm" + imageCommand.AddCommand(&_rmSubCommand) } diff --git a/cmd/podman/images.go b/cmd/podman/images.go index c7f80c34a..e6f4d9a60 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -88,7 +88,7 @@ var ( imagesDescription = "lists locally stored images." _imagesCommand = cobra.Command{ - Use: "images", + Use: "images [flags] [IMAGE]", Short: "List images in local storage", Long: imagesDescription, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/cmd/podman/main.go b/cmd/podman/main.go index d36270853..98e2f23ca 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -47,7 +47,7 @@ var mainCommands = []*cobra.Command{ podCommand.Command, _pullCommand, _pushCommand, - _rmiCommand, + &_rmiCommand, _saveCommand, _tagCommand, _versionCommand, diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go index 6f23e340e..ac46ad5c6 100644 --- a/cmd/podman/play_kube.go +++ b/cmd/podman/play_kube.go @@ -90,8 +90,17 @@ func playKubeYAMLCmd(c *cliconfig.KubePlayValues) error { return errors.Wrapf(err, "unable to read %s as YAML", args[0]) } + // check for name collision between pod and container + podName := podYAML.ObjectMeta.Name + for _, n := range podYAML.Spec.Containers { + if n.Name == podName { + fmt.Printf("a container exists with the same name (%s) as the pod in your YAML file; changing pod name to %s_pod\n", podName, podName) + podName = fmt.Sprintf("%s_pod", podName) + } + } + podOptions = append(podOptions, libpod.WithInfraContainer()) - podOptions = append(podOptions, libpod.WithPodName(podYAML.ObjectMeta.Name)) + podOptions = append(podOptions, libpod.WithPodName(podName)) // TODO for now we just used the default kernel namespaces; we need to add/subtract this from yaml nsOptions, err := shared.GetNamespaceOptions(strings.Split(DefaultKernelNamespaces, ",")) diff --git a/cmd/podman/port.go b/cmd/podman/port.go index 1c3086536..ffb5749fb 100644 --- a/cmd/podman/port.go +++ b/cmd/podman/port.go @@ -128,9 +128,6 @@ func portCmd(c *cliconfig.PortValues) error { if state, _ := con.State(); state != libpod.ContainerStateRunning { continue } - if c.All { - fmt.Println(con.ID()) - } portmappings, err := con.PortMappings() if err != nil { @@ -143,6 +140,9 @@ func portCmd(c *cliconfig.PortValues) error { if hostIP == "" { hostIP = "0.0.0.0" } + if c.All { + fmt.Printf("%s\t", con.ID()[:12]) + } // If not searching by port or port/proto, then dump what we see if port == "" { fmt.Printf("%d/%s -> %s:%d\n", v.ContainerPort, v.Protocol, hostIP, v.HostPort) diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index d6edcabcb..acb5fd7da 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -157,7 +157,7 @@ func (a psSortedSize) Less(i, j int) bool { var ( psCommand cliconfig.PsValues psDescription = "Prints out information about the containers" - _psCommand = &cobra.Command{ + _psCommand = cobra.Command{ Use: "ps", Args: noSubArgs, Short: "List containers", @@ -174,7 +174,7 @@ var ( ) func init() { - psCommand.Command = _psCommand + psCommand.Command = &_psCommand psCommand.SetUsageTemplate(UsageTemplate()) flags := psCommand.Flags() flags.BoolVarP(&psCommand.All, "all", "a", false, "Show all the containers, default is only running containers") diff --git a/cmd/podman/refresh.go b/cmd/podman/refresh.go index 2eb3d25a8..1e4a31a52 100644 --- a/cmd/podman/refresh.go +++ b/cmd/podman/refresh.go @@ -27,6 +27,7 @@ var ( ) func init() { + _refreshCommand.Hidden = true refreshCommand.Command = _refreshCommand refreshCommand.SetUsageTemplate(UsageTemplate()) } diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go index 2bebde4f9..5aa12070e 100644 --- a/cmd/podman/restart.go +++ b/cmd/podman/restart.go @@ -73,7 +73,7 @@ func restartCmd(c *cliconfig.RestartValues) error { defer runtime.Shutdown(false) timeout := c.Timeout - useTimeout := c.Flag("timeout").Changed + useTimeout := c.Flag("timeout").Changed || c.Flag("time").Changed // Handle --latest if c.Latest { diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index e5bb9b486..5b8bf1ea3 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -14,7 +14,7 @@ import ( var ( rmiCommand cliconfig.RmiValues rmiDescription = "Removes one or more locally stored images." - _rmiCommand = &cobra.Command{ + _rmiCommand = cobra.Command{ Use: "rmi [flags] IMAGE [IMAGE...]", Short: "Removes one or more images from local storage", Long: rmiDescription, @@ -30,7 +30,7 @@ var ( ) func init() { - rmiCommand.Command = _rmiCommand + rmiCommand.Command = &_rmiCommand rmiCommand.SetUsageTemplate(UsageTemplate()) flags := rmiCommand.Flags() flags.BoolVarP(&rmiCommand.All, "all", "a", false, "Remove all images") diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go index d86894a6f..ab9a2cf38 100644 --- a/cmd/podman/stop.go +++ b/cmd/podman/stop.go @@ -73,21 +73,29 @@ func stopCmd(c *cliconfig.StopValues) error { fmt.Println(err.Error()) } + if c.Flag("timeout").Changed && c.Flag("time").Changed { + return errors.New("the --timeout and --time flags are mutually exclusive") + } + var stopFuncs []shared.ParallelWorkerInput for _, ctr := range containers { con := ctr var stopTimeout uint - if c.Flag("timeout").Changed { + if c.Flag("timeout").Changed || c.Flag("time").Changed { stopTimeout = c.Timeout } else { stopTimeout = ctr.StopTimeout() + logrus.Debugf("Set timeout to container %s default (%d)", ctr.ID(), stopTimeout) } f := func() error { - if err := con.StopWithTimeout(stopTimeout); err != nil && errors.Cause(err) != libpod.ErrCtrStopped { + if err := con.StopWithTimeout(stopTimeout); err != nil { + if errors.Cause(err) == libpod.ErrCtrStopped { + logrus.Debugf("Container %s already stopped", con.ID()) + return nil + } return err } return nil - } stopFuncs = append(stopFuncs, shared.ParallelWorkerInput{ ContainerID: con.ID(), diff --git a/cmd/podman/trust_set_show.go b/cmd/podman/trust_set_show.go index 0a4783d0a..746854249 100644 --- a/cmd/podman/trust_set_show.go +++ b/cmd/podman/trust_set_show.go @@ -23,7 +23,7 @@ var ( showTrustCommand cliconfig.ShowTrustValues setTrustDescription = "Set default trust policy or add a new trust policy for a registry" _setTrustCommand = &cobra.Command{ - Use: "set", + Use: "set [flags] REGISTRY", Short: "Set default trust policy or a new trust policy for a registry", Long: setTrustDescription, Example: "", @@ -36,7 +36,7 @@ var ( showTrustDescription = "Display trust policy for the system" _showTrustCommand = &cobra.Command{ - Use: "show", + Use: "show [flags] [REGISTRY]", Short: "Display trust policy for the system", Long: showTrustDescription, RunE: func(cmd *cobra.Command, args []string) error { diff --git a/docs/podman-container-refresh.1.md b/docs/podman-container-refresh.1.md deleted file mode 100644 index 26552faa6..000000000 --- a/docs/podman-container-refresh.1.md +++ /dev/null @@ -1,25 +0,0 @@ -% podman-container-refresh(1) - -## NAME -podman\-container\-refresh - Refresh all containers - -## SYNOPSIS -**podman container refresh** - -## DESCRIPTION -The refresh command refreshes the state of all containers to pick up database -schema or general configuration changes. It is not necessary during normal -operation, and will typically be invoked by package managers after finishing an -upgrade of the Podman package. - -As part of refresh, all running containers will be restarted. - -## EXAMPLES ## - -``` -$ podman container refresh -[root@localhost /]# -``` - -## SEE ALSO -podman(1), podman-run(1) diff --git a/docs/podman-container.1.md b/docs/podman-container.1.md index 31ea88570..1ba957480 100644 --- a/docs/podman-container.1.md +++ b/docs/podman-container.1.md @@ -11,40 +11,37 @@ The container command allows you to manage containers ## COMMANDS -| Command | Man Page | Description | -| ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- | -| attach | [podman-attach(1)](podman-attach.1.md) | Attach to a running container. | -| checkpoint | [podman-container-checkpoint(1)](podman-container-checkpoint.1.md) | Checkpoints one or more containers. | -| cleanup | [podman-container-cleanup(1)](podman-container-cleanup.1.md) | Cleanup containers network and mountpoints. | -| commit | [podman-commit(1)](podman-commit.1.md) | Create new image based on the changed container. | -| create | [podman-create(1)](podman-create.1.md) | Create a new container. | -| diff | [podman-diff(1)](podman-diff.1.md) | Inspect changes on a container or image's filesystem. | -| exec | [podman-exec(1)](podman-exec.1.md) | Execute a command in a running container. | -| exists | [podman-exists(1)](podman-container-exists.1.md) | Check if a container exists in local storage | -| export | [podman-export(1)](podman-export.1.md) | Export a container's filesystem contents as a tar archive. | -| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a container or image's configuration. | -| kill | [podman-kill(1)](podman-kill.1.md) | Kill the main process in one or more containers. | -| list | [podman-ps(1)](podman-ps.1.md) | List the containers on the system. | -| logs | [podman-logs(1)](podman-logs.1.md) | Display the logs of a container. | -| ls | [podman-ps(1)](podman-ps.1.md) | List the containers on the system. | -| mount | [podman-mount(1)](podman-mount.1.md) | Mount a working container's root filesystem. | -| pause | [podman-pause(1)](podman-pause.1.md) | Pause one or more containers. | -| port | [podman-port(1)](podman-port.1.md) | List port mappings for the container. | -| prune | [podman-container-prune(1)](podman-container-prune.1.md) | Remove all stopped containers from local storage | -| ps | [podman-ps(1)](podman-ps.1.md) | List the containers on the system. | -| refresh | [podman-refresh(1)](podman-container-refresh.1.md) | Refresh the state of all containers | -| restart | [podman-restart(1)](podman-restart.1.md) | Restart one or more containers. | -| restore | [podman-container-restore(1)](podman-container-restore.1.md) | Restores one or more containers from a checkpoint. | -| rm | [podman-rm(1)](podman-rm.1.md) | Remove one or more containers. | -| run | [podman-run(1)](podman-run.1.md) | Run a command in a container. | -| start | [podman-start(1)](podman-start.1.md) | Starts one or more containers. | -| stats | [podman-stats(1)](podman-stats.1.md) | Display a live stream of one or more container's resource usage statistics. | -| stop | [podman-stop(1)](podman-stop.1.md) | Stop one or more running containers. | -| top | [podman-top(1)](podman-top.1.md) | Display the running processes of a container. | -| umount | [podman-umount(1)](podman-umount.1.md) | Unmount a working container's root filesystem. | -| unmount | [podman-umount(1)](podman-umount.1.md) | Unmount a working container's root filesystem. | -| unpause | [podman-unpause(1)](podman-unpause.1.md) | Unpause one or more containers. | -| wait | [podman-wait(1)](podman-wait.1.md) | Wait on one or more containers to stop and print their exit codes. | +| Command | Man Page | Description | +| --------- | --------------------------------------------------- | ---------------------------------------------------------------------------- | +| attach | [podman-attach(1)](podman-attach.1.md) | Attach to a running container. | +| checkpoint | [podman-container-checkpoint(1)](podman-container-checkpoint.1.md) | Checkpoints one or more containers. | +| cleanup | [podman-container-cleanup(1)](podman-container-cleanup.1.md) | Cleanup containers network and mountpoints. | +| commit | [podman-commit(1)](podman-commit.1.md) | Create new image based on the changed container. | +| create | [podman-create(1)](podman-create.1.md) | Create a new container. | +| diff | [podman-diff(1)](podman-diff.1.md) | Inspect changes on a container or image's filesystem. | +| exec | [podman-exec(1)](podman-exec.1.md) | Execute a command in a running container. | +| exists | [podman-container-exists(1)](podman-container-exists.1.md) | Check if a container exists in local storage | +| export | [podman-export(1)](podman-export.1.md) | Export a container's filesystem contents as a tar archive. | +| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a container or image's configuration. | +| kill | [podman-kill(1)](podman-kill.1.md) | Kill the main process in one or more containers. | +| list | [podman-ps(1)](podman-ps.1.md) | List the containers on the system.(alias ls) | +| logs | [podman-logs(1)](podman-logs.1.md) | Display the logs of a container. | +| mount | [podman-mount(1)](podman-mount.1.md) | Mount a working container's root filesystem. | +| pause | [podman-pause(1)](podman-pause.1.md) | Pause one or more containers. | +| port | [podman-port(1)](podman-port.1.md) | List port mappings for the container. | +| prune | [podman-container-prune(1)](podman-container-prune.1.md)| Remove all stopped containers from local storage. | +| restart | [podman-restart(1)](podman-restart.1.md) | Restart one or more containers. | +| restore | [podman-container-restore(1)](podman-container-restore.1.md) | Restores one or more containers from a checkpoint. | +| rm | [podman-rm(1)](podman-rm.1.md) | Remove one or more containers. | +| run | [podman-run(1)](podman-run.1.md) | Run a command in a container. | +| runlabel | [podman-container-runlabel(1)](podman-container-runlabel.1.md) | Executes a command as described by a container image label. | +| start | [podman-start(1)](podman-start.1.md) | Starts one or more containers. | +| stats | [podman-stats(1)](podman-stats.1.md) | Display a live stream of one or more container's resource usage statistics. | +| stop | [podman-stop(1)](podman-stop.1.md) | Stop one or more running containers. | +| top | [podman-top(1)](podman-top.1.md) | Display the running processes of a container. | +| umount | [podman-umount(1)](podman-umount.1.md) | Unmount a working container's root filesystem.(Alias unmount) | +| unpause | [podman-unpause(1)](podman-unpause.1.md) | Unpause one or more containers. | +| wait | [podman-wait(1)](podman-wait.1.md) | Wait on one or more containers to stop and print their exit codes. | ## SEE ALSO podman, podman-exec, podman-run diff --git a/docs/podman-generate.1.md b/docs/podman-generate.1.md index f19f48511..66afacd0b 100644 --- a/docs/podman-generate.1.md +++ b/docs/podman-generate.1.md @@ -13,7 +13,7 @@ The generate command will create structured output (like YAML) based on a contai | Command | Man Page | Description | | ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- | -| kube | [podman-generate-kube(1)](podman-generate-kube.1.md) | Generate Kubernetes YAML based on a pod or container +| kube | [podman-generate-kube(1)](podman-generate-kube.1.md)| Generate Kubernetes YAML based on a pod or container. | ## SEE ALSO podman, podman-pod, podman-container diff --git a/docs/podman-image.1.md b/docs/podman-image.1.md index 5a0c4e5f9..b4ae752f6 100644 --- a/docs/podman-image.1.md +++ b/docs/podman-image.1.md @@ -11,24 +11,23 @@ The image command allows you to manage images ## COMMANDS -| Command | Man Page | Description | -| -------- | ----------------------------------------- | ------------------------------------------------------------------------------ | -| build | [podman-build(1)](podman-build.1.md) | Build a container using a Dockerfile. | -| exists | [podman-exists(1)](podman-image-exists.1.md) | Check if a image exists in local storage | -| history | [podman-history(1)](podman-history.1.md) | Show the history of an image. | -| import | [podman-import(1)](podman-import.1.md) | Import a tarball and save it as a filesystem image. | -| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a image or image's configuration. | -| list | [podman-images(1)](podman-images.1.md) | List the container images on the system. | -| load | [podman-load(1)](podman-load.1.md) | Load an image from the docker archive. | -| ls | [podman-images(1)](podman-images.1.md) | List the container images on the system. | -| pull | [podman-pull(1)](podman-pull.1.md) | Pull an image from a registry. | -| prune| [podman-container-prune(1)](podman-container-prune.1.md) | Removed all unused images from the local store | -| push | [podman-push(1)](podman-push.1.md) | Push an image from local storage to elsewhere. | -| rm | [podman-rm(1)](podman-rmi.1.md) | Removes one or more locally stored images. | -| save | [podman-save(1)](podman-save.1.md) | Save an image to docker-archive or oci. | -| tag | [podman-tag(1)](podman-tag.1.md) | Add an additional name to a local image. | -| trust | [podman-image-trust(1)](podman-image-trust.1.md) | Manage container image trust policy. | -| sign | [podman-image-sign(1)](podman-image-sign.1.md) | Sign an image. | +| Command | Man Page | Description | +| -------- | ----------------------------------------------- | --------------------------------------------------------------------------- | +| build | [podman-build(1)](podman-build.1.md) | Build a container using a Dockerfile. | +| exists | [podman-image-exists(1)](podman-image-exists.1.md) | Check if a image exists in local storage. | +| history | [podman-history(1)](podman-history.1.md) | Show the history of an image. | +| import | [podman-import(1)](podman-import.1.md) | Import a tarball and save it as a filesystem image. | +| inspect | [podman-inspect(1)](podman-inspect.1.md) | Display a image or image's configuration. | +| list | [podman-images(1)](podman-images.1.md) | List the container images on the system.(alias ls) | +| load | [podman-load(1)](podman-load.1.md) | Load an image from the docker archive. | +| prune | [podman-image-prune(1)](podman-image-prune.1.md)| Removed all unused images from the local store. | +| pull | [podman-pull(1)](podman-pull.1.md) | Pull an image from a registry. | +| push | [podman-push(1)](podman-push.1.md) | Push an image from local storage to elsewhere. | +| rm | [podman-rmi(1)](podman-rmi.1.md) | Removes one or more locally stored images. | +| save | [podman-save(1)](podman-save.1.md) | Save an image to docker-archive or oci. | +| sign | [podman-image-sign(1)](podman-image-sign.1.md) | Sign an image. | +| tag | [podman-tag(1)](podman-tag.1.md) | Add an additional name to a local image. | +| trust | [podman-image-trust(1)](podman-image-trust.1.md)| Manage container image trust policy. | ## SEE ALSO podman diff --git a/docs/podman-play.1.md b/docs/podman-play.1.md index c703c1455..6d2a7beba 100644 --- a/docs/podman-play.1.md +++ b/docs/podman-play.1.md @@ -14,7 +14,7 @@ file input. Containers will be automatically started. | Command | Man Page | Description | | ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- | -| kube | [podman-play-kube(1)](podman-play-kube.1.md) | Recreate pods and containers based on Kubernetes YAML. +| kube | [podman-play-kube(1)](podman-play-kube.1.md) | Recreate pods and containers based on Kubernetes YAML. | ## SEE ALSO podman, podman-pod(1), podman-container(1), podman-generate(1), podman-play(1), podman-play-kube(1) diff --git a/docs/podman-pod-stats.1.md b/docs/podman-pod-stats.1.md new file mode 100644 index 000000000..be32f05be --- /dev/null +++ b/docs/podman-pod-stats.1.md @@ -0,0 +1,92 @@ +% podman-pod-stats "1" + +## NAME +podman\-pod\-stats - Display a live stream of resource usage statistics for the containers in one or more pods + +## SYNOPSIS +**podman pod stats** [*options*] [*pod*] + +## DESCRIPTION +Display a live stream of containers in one or more pods resource usage statistics + +## OPTIONS + +**--all, -a** + +Show all containers. Only running containers are shown by default + +**--latest, -l** + +Instead of providing the pod name or ID, use the last created pod. + +The latest option is not supported on the remote client. + +**--no-reset** + +Do not clear the terminal/screen in between reporting intervals + +**--no-stream** + +Disable streaming pod stats and only pull the first result, default setting is false + +**--format="TEMPLATE"** + +Pretty-print container statistics to JSON or using a Go template + +Valid placeholders for the Go template are listed below: + +| **Placeholder** | **Description** | +| --------------- | --------------- | +| .Pod | Pod ID | +| .CID | Container ID | +| .Name | Container Name | +| .CPU | CPU percentage | +| .MemUsage | Memory usage | +| .Mem | Memory percentage | +| .NetIO | Network IO | +| .BlockIO | Block IO | +| .PIDS | Number of PIDs | + +When using a GO template, you may preceed the format with `table` to print headers. +## EXAMPLE + +``` +# podman pod stats -a --no-stream +ID NAME CPU % MEM USAGE / LIMIT MEM % NET IO BLOCK IO PIDS +a9f807ffaacd frosty_hodgkin -- 3.092MB / 16.7GB 0.02% -- / -- -- / -- 2 +3b33001239ee sleepy_stallman -- -- / -- -- -- / -- -- / -- -- +``` + +``` +# podman pod stats --no-stream a9f80 +ID NAME CPU % MEM USAGE / LIMIT MEM % NET IO BLOCK IO PIDS +a9f807ffaacd frosty_hodgkin -- 3.092MB / 16.7GB 0.02% -- / -- -- / -- 2 +``` + +``` +# podman pod stats --no-stream --format=json a9f80 +[ + { + "id": "a9f807ffaacd", + "name": "frosty_hodgkin", + "cpu_percent": "--", + "mem_usage": "3.092MB / 16.7GB", + "mem_percent": "0.02%", + "netio": "-- / --", + "blocki": "-- / --", + "pids": "2" + } +] +``` + +``` +# podman pod-stats --no-stream --format "table {{.ID}} {{.Name}} {{.MemUsage}}" 6eae +ID NAME MEM USAGE / LIMIT +6eae9e25a564 clever_bassi 3.031MB / 16.7GB +``` + +## SEE ALSO +podman-pod(1), podman(1) + +## HISTORY +February 2019, Originally compiled by Dan Walsh <dwalsh@redhat.com> diff --git a/docs/podman-pod.1.md b/docs/podman-pod.1.md index 621348c03..8f8403a40 100644 --- a/docs/podman-pod.1.md +++ b/docs/podman-pod.1.md @@ -11,16 +11,24 @@ podman pod is a set of subcommands that manage pods, or groups of containers. ## SUBCOMMANDS -| Subcommand | Description | -| ------------------------------------------------- | ------------------------------------------------------------------------------ | -| [podman-pod-create(1)](podman-pod-create.1.md) | Create a new pod. | -| [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in pod. | -| [podman-pod-pause(1)](podman-pod-pause.1.md) | Pause one or more pods. | -| [podman-pod-ps(1)](podman-pod-ps.1.md) | Prints out information about pods. | -| [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more pods. | -| [podman-pod-start(1)](podman-pod-start.1.md) | Start one or more pods. | -| [podman-pod-stop(1)](podman-pod-stop.1.md) | Stop one or more pods. | -| [podman-pod-unpause(1)](podman-pod-unpause.1.md) | Unpause one or more pods. | +| Command | Man Page | Description | +| ------- | ------------------------------------------------- | ------------------------------------------------------------------------------ | +| create | [podman-pod-create(1)](podman-pod-create.1.md) | Create a new pod. | +| exists | [podman-pod-exists(1)](podman-pod-exists.1.md) | Check if a pod exists in local storage. | +| inspect | [podman-pod-inspect(1)](podman-pod-inspect.1.md) | Displays information describing a pod. | +| kill | [podman-pod-kill(1)](podman-pod-kill.1.md) | Kill the main process of each container in pod. | +| pause | [podman-pod-pause(1)](podman-pod-pause.1.md) | Pause one or more pods. | +| ps | [podman-pod-ps(1)](podman-pod-ps.1.md) | Prints out information about pods. | +| restart | [podman-pod-restart(1)](podman-pod-restart.1.md) | Restart one or mode pods. | +| rm | [podman-pod-rm(1)](podman-pod-rm.1.md) | Remove one or more pods. | +| start | [podman-pod-start(1)](podman-pod-start.1.md) | Start one or more pods. | +| stats | [podman-pod-stats(1)](podman-pod-stats.1.md) | Display live stream resource usage stats for containers in one or more pods. | +| stop | [podman-pod-stop(1)](podman-pod-stop.1.md) | Stop one or more pods. | +| top | [podman-pod-top(1)](podman-pod-top.1.md) | Display the running processes of containers in a pod. | +| unpause | [podman-pod-unpause(1)](podman-pod-unpause.1.md) | Unpause one or more pods. | + +## SEE ALSO +podman(1) ## HISTORY July 2018, Originally compiled by Peter Hunt <pehunt@redhat.com> diff --git a/docs/podman-system.1.md b/docs/podman-system.1.md index 1b4bccdb9..6d87648e8 100644 --- a/docs/podman-system.1.md +++ b/docs/podman-system.1.md @@ -13,8 +13,9 @@ The system command allows you to manage the podman systems | Command | Man Page | Description | | ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- | -| info | [podman-system-info(1)](podman-info.1.md) | Displays Podman related system information. | +| info | [podman-info(1)](podman-info.1.md) | Displays Podman related system information. | | prune | [podman-system-prune(1)](podman-system-prune.1.md) | Remove all unused data | +| renumber | [podman-system-renumber(1)](podman-system-renumber.1.md)| Migrate lock numbers to handle a change in maximum number of locks. | ## SEE ALSO -podman +podman(1) diff --git a/docs/podman-volume.1.md b/docs/podman-volume.1.md index ac32abbd6..77728b2b5 100644 --- a/docs/podman-volume.1.md +++ b/docs/podman-volume.1.md @@ -11,13 +11,16 @@ podman volume is a set of subcommands that manage volumes. ## SUBCOMMANDS -| Subcommand | Description | -| ------------------------------------------------- | ------------------------------------------------------------------------------ | -| [podman-volume-create(1)](podman-volume-create.1.md) | Create a new volume. | -| [podman-volume-inspect(1)](podman-volume-inspect.1.md) | Get detailed information on one or more volumes. | -| [podman-volume-ls(1)](podman-volume-ls.1.md) | List all the available volumes. | -| [podman-volume-rm(1)](podman-volume-rm.1.md) | Remove one or more volumes. | -| [podman-volume-prune(1)](podman-volume-prune.1.md) | Remove all unused volumes. | +| Command | Man Page | Description | +| ------- | ------------------------------------------------------ | ------------------------------------------------------------------------------ | +| create | [podman-volume-create(1)](podman-volume-create.1.md) | Create a new volume. | +| inspect | [podman-volume-inspect(1)](podman-volume-inspect.1.md) | Get detailed information on one or more volumes. | +| ls | [podman-volume-ls(1)](podman-volume-ls.1.md) | List all the available volumes. | +| prune | [podman-volume-prune(1)](podman-volume-prune.1.md) | Remove all unused volumes. | +| rm | [podman-volume-rm(1)](podman-volume-rm.1.md) | Remove one or more volumes. | + +## SEE ALSO +podman(1) ## HISTORY November 2018, Originally compiled by Urvashi Mohnani <umohnani@redhat.com> diff --git a/docs/podman.1.md b/docs/podman.1.md index 760f27310..bc03d3c5a 100644 --- a/docs/podman.1.md +++ b/docs/podman.1.md @@ -72,7 +72,7 @@ Default state dir is configured in /etc/containers/storage.conf. Name of the OCI runtime as specified in libpod.conf or absolute path to the OCI compatible binary used to run containers. -**--storage-driver, -s**=**value** +**--storage-driver**=**value** Storage driver. The default storage driver for UID 0 is configured in /etc/containers/storage.conf (`$HOME/.config/containers/storage.conf` in rootless mode), and is *vfs* for non-root users when *fuse-overlayfs* is not available. The `STORAGE_DRIVER` environment variable overrides the default. The --storage-driver specified driver overrides all. @@ -136,6 +136,7 @@ the exit codes follow the `chroot` standard, see below: | [podman-diff(1)](podman-diff.1.md) | Inspect changes on a container or image's filesystem. | | [podman-exec(1)](podman-exec.1.md) | Execute a command in a running container. | | [podman-export(1)](podman-export.1.md) | Export a container's filesystem contents as a tar archive. | +| [podman-generate(1)](podman-generate.1.md)| Generate structured data based for a containers and pods. | | [podman-history(1)](podman-history.1.md) | Show the history of an image. | | [podman-image(1)](podman-image.1.md) | Manage Images. | | [podman-images(1)](podman-images.1.md) | List images in local storage. | @@ -149,6 +150,8 @@ the exit codes follow the `chroot` standard, see below: | [podman-logs(1)](podman-logs.1.md) | Display the logs of a container. | | [podman-mount(1)](podman-mount.1.md) | Mount a working container's root filesystem. | | [podman-pause(1)](podman-pause.1.md) | Pause one or more containers. | +| [podman-play(1)](podman-play.1.md) | Play pods and containers based on a structured input file. | +| [podman-pod(1)](podman-pod.1.md) | Management tool for groups of containers, called pods. | | [podman-port(1)](podman-port.1.md) | List port mappings for the container. | | [podman-ps(1)](podman-ps.1.md) | Prints out information about containers. | | [podman-pull(1)](podman-pull.1.md) | Pull an image from a registry. | @@ -167,8 +170,9 @@ the exit codes follow the `chroot` standard, see below: | [podman-top(1)](podman-top.1.md) | Display the running processes of a container. | | [podman-umount(1)](podman-umount.1.md) | Unmount a working container's root filesystem. | | [podman-unpause(1)](podman-unpause.1.md) | Unpause one or more containers. | -| [podman-version(1)](podman-version.1.md) | Display the Podman version information. | -| [podman-volume(1)](podman-volume.1.md) | Manage Volumes. | +| [podman-varlink(1)](podman-varlink.1.md) | Display the Podman version information. | +| [podman-version(1)](podman-version.1.md) | Runs the varlink backend interface. | +| [podman-volume(1)](podman-volume.1.md) | Manage Volumes. | | [podman-wait(1)](podman-wait.1.md) | Wait on one or more containers to stop and print their exit codes. | ## FILES diff --git a/hack/podman-commands.sh b/hack/podman-commands.sh new file mode 100755 index 000000000..754f2923d --- /dev/null +++ b/hack/podman-commands.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# +# Compare commands listed by 'podman help' against those in 'man podman'. +# Recurse into subcommands as well. +# +# Because we read metadoc files in the `docs` directory, this script +# must run from the top level of a git checkout. FIXME: if necessary, +# it could instead run 'man podman-XX'; my thinking is that this +# script should run early in CI. +# + +# override with, e.g., PODMAN=./bin/podman-remote +PODMAN=${PODMAN:-./bin/podman} + +function die() { + echo "FATAL: $*" >&2 + exit 1 +} + + +# Run 'podman help' (possibly against a subcommand, e.g. 'podman help image') +# and return a list of each first word under 'Available Commands', that is, +# the command name but not its description. +function podman_commands() { + $PODMAN help "$@" |\ + awk '/^Available Commands:/{ok=1;next}/^Flags:/{ok=0}ok { print $1 }' |\ + grep . +} + +# Read a list of subcommands from a command's metadoc +function podman_man() { + if [ "$@" = "podman" ]; then + # podman itself. + # This md file has a table of the form: + # | [podman-cmd(1)\[(podman-cmd.1.md) | Description ... | + # For all such, print the 'cmd' portion (the one in brackets). + sed -ne 's/^|\s\+\[podman-\([a-z]\+\)(1.*/\1/p' <docs/$1.1.md + elif [ "$@" = "podman-image-trust" ]; then + # Special case: set and show aren't actually in a table in the man page + echo set + echo show + else + # podman subcommand. + # Each md file has a table of the form: + # | cmd | [podman-cmd(1)](podman-cmd.1.md) | Description ... | + # For all such we find, with 'podman- in the second column, print the + # first column (with whitespace trimmed) + awk -F\| '$3 ~ /podman-/ { gsub(" ","",$2); print $2 }' < docs/$1.1.md + fi +} + +# The main thing. Compares help and man page; if we find subcommands, recurse. +rc=0 +function compare_help_and_man() { + echo + echo "checking: podman $@" + + # e.g. podman, podman-image, podman-volume + local basename=$(echo podman "$@" | sed -e 's/ /-/g') + + podman_commands "$@" | sort > /tmp/${basename}_help.txt + podman_man $basename | sort > /tmp/${basename}_man.txt + + diff -u /tmp/${basename}_help.txt /tmp/${basename}_man.txt || rc=1 + + # Now look for subcommands, e.g. container, image + for cmd in $(< /tmp/${basename}_help.txt); do + usage=$($PODMAN "$@" $cmd --help | grep -A1 '^Usage:' | tail -1) + + # if string ends in '[command]', recurse into its subcommands + if expr "$usage" : '.*\[command\]$' >/dev/null; then + compare_help_and_man "$@" $cmd + fi + done + + rm -f /tmp/${basename}_{help,man}.txt +} + + +compare_help_and_man + +exit $rc diff --git a/libpod/container_api.go b/libpod/container_api.go index 09d7f220d..6bef3c47d 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -203,9 +203,8 @@ func (c *Container) Kill(signal uint) error { } // Exec starts a new process inside the container -// TODO allow specifying streams to attach to // TODO investigate allowing exec without attaching -func (c *Container) Exec(tty, privileged bool, env, cmd []string, user, workDir string) error { +func (c *Container) Exec(tty, privileged bool, env, cmd []string, user, workDir string, streams *AttachStreams) error { var capList []string locked := false @@ -267,7 +266,7 @@ func (c *Container) Exec(tty, privileged bool, env, cmd []string, user, workDir logrus.Debugf("Creating new exec session in container %s with session id %s", c.ID(), sessionID) - execCmd, err := c.runtime.ociRuntime.execContainer(c, cmd, capList, env, tty, workDir, hostUser, sessionID) + execCmd, err := c.runtime.ociRuntime.execContainer(c, cmd, capList, env, tty, workDir, hostUser, sessionID, streams) if err != nil { return errors.Wrapf(err, "error exec %s", c.ID()) } diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index b074efa3a..0e9a5124e 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -472,10 +472,19 @@ func (c *Container) addNamespaceContainer(g *generate.Generator, ns LinuxNS, ctr return nil } -func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointOptions) (err error) { - +func (c *Container) checkpointRestoreSupported() (err error) { if !criu.CheckForCriu() { - return errors.Errorf("checkpointing a container requires at least CRIU %d", criu.MinCriuVersion) + return errors.Errorf("Checkpoint/Restore requires at least CRIU %d", criu.MinCriuVersion) + } + if !c.runtime.ociRuntime.featureCheckCheckpointing() { + return errors.Errorf("Configured runtime does not support checkpoint/restore") + } + return nil +} + +func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointOptions) (err error) { + if err := c.checkpointRestoreSupported(); err != nil { + return err } if c.state.State != ContainerStateRunning { @@ -532,8 +541,8 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO func (c *Container) restore(ctx context.Context, options ContainerCheckpointOptions) (err error) { - if !criu.CheckForCriu() { - return errors.Errorf("restoring a container requires at least CRIU %d", criu.MinCriuVersion) + if err := c.checkpointRestoreSupported(); err != nil { + return err } if (c.state.State != ContainerStateConfigured) && (c.state.State != ContainerStateExited) { diff --git a/libpod/oci.go b/libpod/oci.go index 26d2c6ef1..2b3cc5db5 100644 --- a/libpod/oci.go +++ b/libpod/oci.go @@ -733,7 +733,7 @@ func (r *OCIRuntime) unpauseContainer(ctr *Container) error { // TODO: Add --detach support // TODO: Convert to use conmon // TODO: add --pid-file and use that to generate exec session tracking -func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty bool, cwd, user, sessionID string) (*exec.Cmd, error) { +func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty bool, cwd, user, sessionID string, streams *AttachStreams) (*exec.Cmd, error) { if len(cmd) == 0 { return nil, errors.Wrapf(ErrInvalidArg, "must provide a command to execute") } @@ -789,9 +789,17 @@ func (r *OCIRuntime) execContainer(c *Container, cmd, capAdd, env []string, tty logrus.Debugf("Starting runtime %s with following arguments: %v", r.path, args) execCmd := exec.Command(r.path, args...) - execCmd.Stdout = os.Stdout - execCmd.Stderr = os.Stderr - execCmd.Stdin = os.Stdin + + if streams.AttachOutput { + execCmd.Stdout = streams.OutputStream + } + if streams.AttachInput { + execCmd.Stdin = streams.InputStream + } + if streams.AttachError { + execCmd.Stderr = streams.ErrorStream + } + execCmd.Env = append(execCmd.Env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", runtimeDir)) if err := execCmd.Start(); err != nil { @@ -890,3 +898,16 @@ func (r *OCIRuntime) checkpointContainer(ctr *Container, options ContainerCheckp args = append(args, ctr.ID()) return utils.ExecCmdWithStdStreams(os.Stdin, os.Stdout, os.Stderr, nil, r.path, args...) } + +func (r *OCIRuntime) featureCheckCheckpointing() bool { + // Check if the runtime implements checkpointing. Currently only + // runc's checkpoint/restore implementation is supported. + cmd := exec.Command(r.path, "checkpoint", "-h") + if err := cmd.Start(); err != nil { + return false + } + if err := cmd.Wait(); err == nil { + return true + } + return false +} diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index 9a192c0fa..98692707f 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -93,7 +93,8 @@ func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap) Args: args, } - if err := cmd.Run(); err != nil { + if output, err := cmd.CombinedOutput(); err != nil { + logrus.Debugf("error from %s: %s", tool, output) return errors.Wrapf(err, "cannot setup namespace using %s", tool) } return nil diff --git a/pkg/secrets/secrets.go b/pkg/secrets/secrets.go index 242953609..3b64f8952 100644 --- a/pkg/secrets/secrets.go +++ b/pkg/secrets/secrets.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/containers/libpod/pkg/rootless" + "github.com/containers/storage/pkg/idtools" rspec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" @@ -176,7 +177,7 @@ func SecretMountsWithUIDGID(mountLabel, containerWorkingDir, mountFile, mountPre // Add FIPS mode secret if /etc/system-fips exists on the host _, err := os.Stat("/etc/system-fips") if err == nil { - if err := addFIPSModeSecret(&secretMounts, containerWorkingDir); err != nil { + if err := addFIPSModeSecret(&secretMounts, containerWorkingDir, mountPrefix, mountLabel, uid, gid); err != nil { logrus.Errorf("error adding FIPS mode secret to container: %v", err) } } else if os.IsNotExist(err) { @@ -264,13 +265,16 @@ func addSecretsFromMountsFile(filePath, mountLabel, containerWorkingDir, mountPr // root filesystem if /etc/system-fips exists on hosts. // This enables the container to be FIPS compliant and run openssl in // FIPS mode as the host is also in FIPS mode. -func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir string) error { +func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir, mountPrefix, mountLabel string, uid, gid int) error { secretsDir := "/run/secrets" ctrDirOnHost := filepath.Join(containerWorkingDir, secretsDir) if _, err := os.Stat(ctrDirOnHost); os.IsNotExist(err) { - if err = os.MkdirAll(ctrDirOnHost, 0755); err != nil { + if err = idtools.MkdirAllAs(ctrDirOnHost, 0755, uid, gid); err != nil { return errors.Wrapf(err, "making container directory on host failed") } + if err = label.Relabel(ctrDirOnHost, mountLabel, false); err != nil { + return errors.Wrap(err, "error applying correct labels") + } } fipsFile := filepath.Join(ctrDirOnHost, "system-fips") // In the event of restart, it is possible for the FIPS mode file to already exist @@ -284,7 +288,7 @@ func addFIPSModeSecret(mounts *[]rspec.Mount, containerWorkingDir string) error if !mountExists(*mounts, secretsDir) { m := rspec.Mount{ - Source: ctrDirOnHost, + Source: filepath.Join(mountPrefix, secretsDir), Destination: secretsDir, Type: "bind", Options: []string{"bind", "rprivate"}, diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go index fda6eb085..583432df1 100644 --- a/test/e2e/checkpoint_test.go +++ b/test/e2e/checkpoint_test.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "os" + "os/exec" "github.com/containers/libpod/pkg/criu" . "github.com/containers/libpod/test/utils" @@ -27,9 +28,26 @@ var _ = Describe("Podman checkpoint", func() { } podmanTest = PodmanTestCreate(tempdir) podmanTest.RestoreAllArtifacts() + // Check if the runtime implements checkpointing. Currently only + // runc's checkpoint/restore implementation is supported. + cmd := exec.Command(podmanTest.OCIRuntime, "checkpoint", "-h") + if err := cmd.Start(); err != nil { + Skip("OCI runtime does not support checkpoint/restore") + } + if err := cmd.Wait(); err != nil { + Skip("OCI runtime does not support checkpoint/restore") + } + if !criu.CheckForCriu() { Skip("CRIU is missing or too old.") } + // TODO: Remove the skip when the current CRIU SELinux problem is solved. + // See: https://github.com/containers/libpod/issues/2334 + hostInfo := podmanTest.Host + if hostInfo.Distribution == "fedora" { + Skip("Checkpointing containers on Fedora currently broken.") + } + }) AfterEach(func() { diff --git a/test/e2e/load_test.go b/test/e2e/load_test.go index c85810454..571754347 100644 --- a/test/e2e/load_test.go +++ b/test/e2e/load_test.go @@ -59,7 +59,7 @@ var _ = Describe("Podman load", func() { Expect(save.ExitCode()).To(Equal(0)) compress := SystemExec("gzip", []string{outfile}) - compress.WaitWithDefaultTimeout() + Expect(compress.ExitCode()).To(Equal(0)) outfile = outfile + ".gz" rmi := podmanTest.Podman([]string{"rmi", ALPINE}) @@ -174,7 +174,6 @@ var _ = Describe("Podman load", func() { It("podman load localhost registry from scratch", func() { outfile := filepath.Join(podmanTest.TempDir, "load_test.tar.gz") - setup := podmanTest.Podman([]string{"tag", ALPINE, "hello:world"}) setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) @@ -255,7 +254,6 @@ var _ = Describe("Podman load", func() { save.WaitWithDefaultTimeout() Expect(save.ExitCode()).To(Equal(0)) session := SystemExec("xz", []string{outfile}) - session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) rmi := podmanTest.Podman([]string{"rmi", BB}) diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go index cb2b0e7b0..4717267a1 100644 --- a/test/e2e/pod_create_test.go +++ b/test/e2e/pod_create_test.go @@ -95,7 +95,6 @@ var _ = Describe("Podman pod create", func() { Expect(webserver.ExitCode()).To(Equal(0)) check := SystemExec("nc", []string{"-z", "localhost", "80"}) - check.WaitWithDefaultTimeout() Expect(check.ExitCode()).To(Equal(1)) }) @@ -111,7 +110,6 @@ var _ = Describe("Podman pod create", func() { Expect(webserver.ExitCode()).To(Equal(0)) check := SystemExec("nc", []string{"-z", "localhost", "80"}) - check.WaitWithDefaultTimeout() Expect(check.ExitCode()).To(Equal(0)) }) diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go index faad8202e..d9b9c7213 100644 --- a/test/e2e/pull_test.go +++ b/test/e2e/pull_test.go @@ -6,10 +6,12 @@ import ( "os" "fmt" + "path/filepath" + "strings" + . "github.com/containers/libpod/test/utils" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" - "strings" ) var _ = Describe("Podman pull", func() { @@ -92,58 +94,56 @@ var _ = Describe("Podman pull", func() { }) It("podman pull from docker-archive", func() { - session := podmanTest.Podman([]string{"save", "-o", "/tmp/alp.tar", "alpine"}) + tarfn := filepath.Join(podmanTest.TempDir, "alp.tar") + session := podmanTest.Podman([]string{"save", "-o", tarfn, "alpine"}) session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"rmi", "alpine"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"pull", "docker-archive:/tmp/alp.tar"}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("docker-archive:%s", tarfn)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"rmi", "alpine"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - clean := SystemExec("rm", []string{"/tmp/alp.tar"}) - clean.WaitWithDefaultTimeout() - Expect(clean.ExitCode()).To(Equal(0)) }) It("podman pull from oci-archive", func() { - session := podmanTest.Podman([]string{"save", "--format", "oci-archive", "-o", "/tmp/oci-alp.tar", "alpine"}) + tarfn := filepath.Join(podmanTest.TempDir, "oci-alp.tar") + session := podmanTest.Podman([]string{"save", "--format", "oci-archive", "-o", tarfn, "alpine"}) session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"rmi", "alpine"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"pull", "oci-archive:/tmp/oci-alp.tar"}) + session = podmanTest.Podman([]string{"pull", fmt.Sprintf("oci-archive:%s", tarfn)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"rmi", "alpine"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - clean := SystemExec("rm", []string{"/tmp/oci-alp.tar"}) - clean.WaitWithDefaultTimeout() }) It("podman pull from local directory", func() { - setup := SystemExec("mkdir", []string{"-p", "/tmp/podmantestdir"}) - setup.WaitWithDefaultTimeout() - session := podmanTest.Podman([]string{"push", "alpine", "dir:/tmp/podmantestdir"}) + dirpath := filepath.Join(podmanTest.TempDir, "alpine") + os.MkdirAll(dirpath, os.ModePerm) + imgPath := fmt.Sprintf("dir:%s", dirpath) + + session := podmanTest.Podman([]string{"push", "alpine", imgPath}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) session = podmanTest.Podman([]string{"rmi", "alpine"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"pull", "dir:/tmp/podmantestdir"}) + session = podmanTest.Podman([]string{"pull", imgPath}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"rmi", "podmantestdir"}) + session = podmanTest.Podman([]string{"rmi", "alpine"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - - clean := SystemExec("rm", []string{"-fr", "/tmp/podmantestdir"}) - clean.WaitWithDefaultTimeout() }) It("podman pull check quiet", func() { diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go index 42aefd1f7..fee117783 100644 --- a/test/e2e/push_test.go +++ b/test/e2e/push_test.go @@ -51,13 +51,11 @@ var _ = Describe("Podman push", func() { }) It("podman push to dir", func() { - session := podmanTest.Podman([]string{"push", "--remove-signatures", ALPINE, "dir:/tmp/busybox"}) + bbdir := filepath.Join(podmanTest.TempDir, "busybox") + session := podmanTest.Podman([]string{"push", "--remove-signatures", ALPINE, + fmt.Sprintf("dir:%s", bbdir)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - - clean := SystemExec("rm", []string{"-fr", "/tmp/busybox"}) - clean.WaitWithDefaultTimeout() - Expect(clean.ExitCode()).To(Equal(0)) }) It("podman push to local registry", func() { @@ -85,20 +83,21 @@ var _ = Describe("Podman push", func() { authPath := filepath.Join(podmanTest.TempDir, "auth") os.Mkdir(authPath, os.ModePerm) os.MkdirAll("/etc/containers/certs.d/localhost:5000", os.ModePerm) - debug := SystemExec("ls", []string{"-l", podmanTest.TempDir}) - debug.WaitWithDefaultTimeout() + defer os.RemoveAll("/etc/containers/certs.d/localhost:5000") cwd, _ := os.Getwd() certPath := filepath.Join(cwd, "../", "certs") if IsCommandAvailable("getenforce") { ge := SystemExec("getenforce", []string{}) - ge.WaitWithDefaultTimeout() + Expect(ge.ExitCode()).To(Equal(0)) if ge.OutputToString() == "Enforcing" { se := SystemExec("setenforce", []string{"0"}) - se.WaitWithDefaultTimeout() - - defer SystemExec("setenforce", []string{"1"}) + Expect(se.ExitCode()).To(Equal(0)) + defer func() { + se2 := SystemExec("setenforce", []string{"1"}) + Expect(se2.ExitCode()).To(Equal(0)) + }() } } podmanTest.RestoreArtifact(registry) @@ -111,8 +110,6 @@ var _ = Describe("Podman push", func() { f.WriteString(session.OutputToString()) f.Sync() - debug = SystemExec("cat", []string{filepath.Join(authPath, "htpasswd")}) - debug.WaitWithDefaultTimeout() session = podmanTest.Podman([]string{"run", "-d", "-p", "5000:5000", "--name", "registry", "-v", strings.Join([]string{authPath, "/auth"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e", @@ -138,8 +135,7 @@ var _ = Describe("Podman push", func() { Expect(push.ExitCode()).To(Equal(0)) setup := SystemExec("cp", []string{filepath.Join(certPath, "domain.crt"), "/etc/containers/certs.d/localhost:5000/ca.crt"}) - setup.WaitWithDefaultTimeout() - defer os.RemoveAll("/etc/containers/certs.d/localhost:5000") + Expect(setup.ExitCode()).To(Equal(0)) push = podmanTest.Podman([]string{"push", "--creds=podmantest:wrongpasswd", ALPINE, "localhost:5000/credstest"}) push.WaitWithDefaultTimeout() @@ -155,23 +151,22 @@ var _ = Describe("Podman push", func() { }) It("podman push to docker-archive", func() { - session := podmanTest.Podman([]string{"push", ALPINE, "docker-archive:/tmp/alp:latest"}) + tarfn := filepath.Join(podmanTest.TempDir, "alp.tar") + session := podmanTest.Podman([]string{"push", ALPINE, + fmt.Sprintf("docker-archive:%s:latest", tarfn)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - clean := SystemExec("rm", []string{"/tmp/alp"}) - clean.WaitWithDefaultTimeout() - Expect(clean.ExitCode()).To(Equal(0)) }) It("podman push to docker daemon", func() { setup := SystemExec("bash", []string{"-c", "systemctl status docker 2>&1"}) - setup.WaitWithDefaultTimeout() if setup.LineInOutputContains("Active: inactive") { setup = SystemExec("systemctl", []string{"start", "docker"}) - setup.WaitWithDefaultTimeout() - - defer SystemExec("systemctl", []string{"stop", "docker"}) + defer func() { + stop := SystemExec("systemctl", []string{"stop", "docker"}) + Expect(stop.ExitCode()).To(Equal(0)) + }() } else if setup.ExitCode() != 0 { Skip("Docker is not available") } @@ -181,22 +176,19 @@ var _ = Describe("Podman push", func() { Expect(session.ExitCode()).To(Equal(0)) check := SystemExec("docker", []string{"images", "--format", "{{.Repository}}:{{.Tag}}"}) - check.WaitWithDefaultTimeout() Expect(check.ExitCode()).To(Equal(0)) Expect(check.OutputToString()).To(ContainSubstring("alpine:podmantest")) clean := SystemExec("docker", []string{"rmi", "alpine:podmantest"}) - clean.WaitWithDefaultTimeout() Expect(clean.ExitCode()).To(Equal(0)) }) It("podman push to oci-archive", func() { - session := podmanTest.Podman([]string{"push", ALPINE, "oci-archive:/tmp/alp.tar:latest"}) + tarfn := filepath.Join(podmanTest.TempDir, "alp.tar") + session := podmanTest.Podman([]string{"push", ALPINE, + fmt.Sprintf("oci-archive:%s:latest", tarfn)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - clean := SystemExec("rm", []string{"/tmp/alp.tar"}) - clean.WaitWithDefaultTimeout() - Expect(clean.ExitCode()).To(Equal(0)) }) It("podman push to local ostree", func() { @@ -208,33 +200,29 @@ var _ = Describe("Podman push", func() { os.MkdirAll(ostreePath, os.ModePerm) setup := SystemExec("ostree", []string{strings.Join([]string{"--repo=", ostreePath}, ""), "init"}) - setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) session := podmanTest.Podman([]string{"push", ALPINE, strings.Join([]string{"ostree:alp@", ostreePath}, "")}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - clean := SystemExec("rm", []string{"-rf", ostreePath}) - clean.WaitWithDefaultTimeout() - Expect(clean.ExitCode()).To(Equal(0)) }) It("podman push to docker-archive no reference", func() { - session := podmanTest.Podman([]string{"push", ALPINE, "docker-archive:/tmp/alp"}) + tarfn := filepath.Join(podmanTest.TempDir, "alp.tar") + session := podmanTest.Podman([]string{"push", ALPINE, + fmt.Sprintf("docker-archive:%s", tarfn)}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - clean := SystemExec("rm", []string{"/tmp/alp"}) - clean.WaitWithDefaultTimeout() - Expect(clean.ExitCode()).To(Equal(0)) }) It("podman push to oci-archive no reference", func() { - session := podmanTest.Podman([]string{"push", ALPINE, "oci-archive:/tmp/alp-oci"}) + ociarc := filepath.Join(podmanTest.TempDir, "alp-oci") + session := podmanTest.Podman([]string{"push", ALPINE, + fmt.Sprintf("oci-archive:%s", ociarc)}) + session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - clean := SystemExec("rm", []string{"/tmp/alp-oci"}) - clean.WaitWithDefaultTimeout() - Expect(clean.ExitCode()).To(Equal(0)) }) }) diff --git a/test/e2e/run_cleanup_test.go b/test/e2e/run_cleanup_test.go index aa823b4e6..1f2a4085d 100644 --- a/test/e2e/run_cleanup_test.go +++ b/test/e2e/run_cleanup_test.go @@ -36,14 +36,16 @@ var _ = Describe("Podman run exit", func() { It("podman run -d mount cleanup test", func() { mount := SystemExec("mount", nil) - mount.WaitWithDefaultTimeout() + Expect(mount.ExitCode()).To(Equal(0)) + out1 := mount.OutputToString() result := podmanTest.Podman([]string{"create", "-dt", ALPINE, "echo", "hello"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(0)) mount = SystemExec("mount", nil) - mount.WaitWithDefaultTimeout() + Expect(mount.ExitCode()).To(Equal(0)) + out2 := mount.OutputToString() Expect(out1).To(Equal(out2)) }) diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go index a07e4d047..c89a4f487 100644 --- a/test/e2e/run_networking_test.go +++ b/test/e2e/run_networking_test.go @@ -58,7 +58,6 @@ var _ = Describe("Podman run networking", func() { session.Wait(30) Expect(session.ExitCode()).To(Equal(0)) results := SystemExec("iptables", []string{"-t", "nat", "-L"}) - results.Wait(30) Expect(results.ExitCode()).To(Equal(0)) Expect(results.OutputToString()).To(ContainSubstring("222")) Expect(results.OutputToString()).To(ContainSubstring("223")) @@ -69,12 +68,10 @@ var _ = Describe("Podman run networking", func() { session.Wait(30) Expect(session.ExitCode()).To(Equal(0)) results := SystemExec("iptables", []string{"-t", "nat", "-L"}) - results.Wait(30) Expect(results.ExitCode()).To(Equal(0)) Expect(results.OutputToString()).To(ContainSubstring("8000")) ncBusy := SystemExec("nc", []string{"-l", "-p", "80"}) - ncBusy.Wait(10) Expect(ncBusy.ExitCode()).ToNot(Equal(0)) }) @@ -183,26 +180,40 @@ var _ = Describe("Podman run networking", func() { if Containerized() { Skip("Can not be run within a container.") } - SystemExec("ip", []string{"netns", "add", "xxx"}) + addXXX := SystemExec("ip", []string{"netns", "add", "xxx"}) + Expect(addXXX.ExitCode()).To(Equal(0)) + defer func() { + delXXX := SystemExec("ip", []string{"netns", "delete", "xxx"}) + Expect(delXXX.ExitCode()).To(Equal(0)) + }() + session := podmanTest.Podman([]string{"run", "-dt", "--net", "ns:/run/netns/xxx", ALPINE, "wget", "www.podman.io"}) session.Wait(90) Expect(session.ExitCode()).To(Equal(0)) - SystemExec("ip", []string{"netns", "delete", "xxx"}) }) It("podman run n user created network namespace with resolv.conf", func() { if Containerized() { Skip("Can not be run within a container.") } - SystemExec("ip", []string{"netns", "add", "xxx"}) - SystemExec("mkdir", []string{"-p", "/etc/netns/xxx"}) - SystemExec("bash", []string{"-c", "echo nameserver 11.11.11.11 > /etc/netns/xxx/resolv.conf"}) - session := podmanTest.Podman([]string{"run", "--net", "ns:/run/netns/xxx", ALPINE, "cat", "/etc/resolv.conf"}) + addXXX2 := SystemExec("ip", []string{"netns", "add", "xxx2"}) + Expect(addXXX2.ExitCode()).To(Equal(0)) + defer func() { + delXXX2 := SystemExec("ip", []string{"netns", "delete", "xxx2"}) + Expect(delXXX2.ExitCode()).To(Equal(0)) + }() + + mdXXX2 := SystemExec("mkdir", []string{"-p", "/etc/netns/xxx2"}) + Expect(mdXXX2.ExitCode()).To(Equal(0)) + defer os.RemoveAll("/etc/netns/xxx2") + + nsXXX2 := SystemExec("bash", []string{"-c", "echo nameserver 11.11.11.11 > /etc/netns/xxx2/resolv.conf"}) + Expect(nsXXX2.ExitCode()).To(Equal(0)) + + session := podmanTest.Podman([]string{"run", "--net", "ns:/run/netns/xxx2", ALPINE, "cat", "/etc/resolv.conf"}) session.Wait(90) Expect(session.ExitCode()).To(Equal(0)) Expect(session.OutputToString()).To(ContainSubstring("11.11.11.11")) - SystemExec("ip", []string{"netns", "delete", "xxx"}) - SystemExec("rm", []string{"-rf", "/etc/netns/xxx"}) }) It("podman run network in bogus user created network namespace", func() { diff --git a/test/e2e/run_ns_test.go b/test/e2e/run_ns_test.go index 9962185f2..3d95c3a0b 100644 --- a/test/e2e/run_ns_test.go +++ b/test/e2e/run_ns_test.go @@ -53,7 +53,6 @@ var _ = Describe("Podman run ns", func() { It("podman run ipcns test", func() { setup := SystemExec("ls", []string{"--inode", "-d", "/dev/shm"}) - setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) hostShm := setup.OutputToString() @@ -65,7 +64,6 @@ var _ = Describe("Podman run ns", func() { It("podman run ipcns ipcmk host test", func() { setup := SystemExec("ipcmk", []string{"-M", "1024"}) - setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) output := strings.Split(setup.OutputToString(), " ") ipc := output[len(output)-1] @@ -74,7 +72,6 @@ var _ = Describe("Podman run ns", func() { Expect(session.ExitCode()).To(Equal(0)) setup = SystemExec("ipcrm", []string{"-m", ipc}) - setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) }) diff --git a/test/e2e/run_privileged_test.go b/test/e2e/run_privileged_test.go index 0c0de30c5..ee6e8e950 100644 --- a/test/e2e/run_privileged_test.go +++ b/test/e2e/run_privileged_test.go @@ -46,7 +46,6 @@ var _ = Describe("Podman privileged container tests", func() { It("podman privileged CapEff", func() { cap := SystemExec("grep", []string{"CapEff", "/proc/self/status"}) - cap.WaitWithDefaultTimeout() Expect(cap.ExitCode()).To(Equal(0)) session := podmanTest.Podman([]string{"run", "--privileged", "busybox", "grep", "CapEff", "/proc/self/status"}) @@ -57,7 +56,6 @@ var _ = Describe("Podman privileged container tests", func() { It("podman cap-add CapEff", func() { cap := SystemExec("grep", []string{"CapEff", "/proc/self/status"}) - cap.WaitWithDefaultTimeout() Expect(cap.ExitCode()).To(Equal(0)) session := podmanTest.Podman([]string{"run", "--cap-add", "all", "busybox", "grep", "CapEff", "/proc/self/status"}) @@ -97,7 +95,6 @@ var _ = Describe("Podman privileged container tests", func() { } cap := SystemExec("grep", []string{"NoNewPrivs", "/proc/self/status"}) - cap.WaitWithDefaultTimeout() if cap.ExitCode() != 0 { Skip("Can't determine NoNewPrivs") } diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 6bd49de33..93ee5036f 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -387,7 +387,6 @@ var _ = Describe("Podman run", func() { err = ioutil.WriteFile(keyFile, []byte(mountString), 0755) Expect(err).To(BeNil()) execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")}) - execSession.WaitWithDefaultTimeout() Expect(execSession.ExitCode()).To(Equal(0)) session := podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "cat", "/run/secrets/test.txt"}) diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go index a7e7a1500..252361288 100644 --- a/test/e2e/systemd_test.go +++ b/test/e2e/systemd_test.go @@ -53,31 +53,27 @@ WantedBy=multi-user.target sys_file := ioutil.WriteFile("/etc/systemd/system/redis.service", []byte(systemd_unit_file), 0644) Expect(sys_file).To(BeNil()) + defer func() { + stop := SystemExec("bash", []string{"-c", "systemctl stop redis"}) + os.Remove("/etc/systemd/system/redis.service") + SystemExec("bash", []string{"-c", "systemctl daemon-reload"}) + Expect(stop.ExitCode()).To(Equal(0)) + }() create := podmanTest.Podman([]string{"create", "-d", "--name", "redis", "redis"}) create.WaitWithDefaultTimeout() Expect(create.ExitCode()).To(Equal(0)) - enable := SystemExec("bash", []string{"-c", "systemctl daemon-reload && systemctl enable --now redis"}) - enable.WaitWithDefaultTimeout() + enable := SystemExec("bash", []string{"-c", "systemctl daemon-reload"}) Expect(enable.ExitCode()).To(Equal(0)) start := SystemExec("bash", []string{"-c", "systemctl start redis"}) - start.WaitWithDefaultTimeout() + Expect(start.ExitCode()).To(Equal(0)) logs := SystemExec("bash", []string{"-c", "journalctl -n 20 -u redis"}) - logs.WaitWithDefaultTimeout() + Expect(logs.ExitCode()).To(Equal(0)) status := SystemExec("bash", []string{"-c", "systemctl status redis"}) - status.WaitWithDefaultTimeout() Expect(status.OutputToString()).To(ContainSubstring("active (running)")) - - cleanup := SystemExec("bash", []string{"-c", "systemctl stop redis && systemctl disable redis"}) - cleanup.WaitWithDefaultTimeout() - Expect(cleanup.ExitCode()).To(Equal(0)) - os.Remove("/etc/systemd/system/redis.service") - sys_clean := SystemExec("bash", []string{"-c", "systemctl daemon-reload"}) - sys_clean.WaitWithDefaultTimeout() - Expect(sys_clean.ExitCode()).To(Equal(0)) }) }) diff --git a/test/test_podman_baseline.sh b/test/test_podman_baseline.sh index 8a878b4e7..664fd2b03 100755 --- a/test/test_podman_baseline.sh +++ b/test/test_podman_baseline.sh @@ -195,7 +195,7 @@ podman rmi --all ######## # 1.004608 MB is 1,004,608 bytes. The container overhead is 4608 bytes (or 9 512 byte pages), so this allocates 1 MB of usable storage -PODMANBASE="-s overlay --storage-opt overlay.size=1.004608M --root /tmp/podman_test/crio" +PODMANBASE="--storage-driver overlay --storage-opt overlay.size=1.004608M --root /tmp/podman_test/crio" TMPDIR=/tmp/podman_test mkdir $TMPDIR dd if=/dev/zero of=$TMPDIR/virtfs bs=1024 count=30720 diff --git a/test/utils/utils.go b/test/utils/utils.go index 098779321..499466f5a 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -326,6 +326,7 @@ func SystemExec(command string, args []string) *PodmanSession { if err != nil { Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " "))) } + session.Wait(defaultWaitTimeout) return &PodmanSession{session} } |