Merge pull request #2252 from rhatdan/system

Add podman system prune and info commands
This commit is contained in:
OpenShift Merge Robot
2019-02-06 23:03:21 +01:00
committed by GitHub
55 changed files with 490 additions and 150 deletions

View File

@ -21,7 +21,7 @@ var (
},
cli.BoolTFlag{
Name: "sig-proxy",
Usage: "proxy received signals to the process (default true)",
Usage: "Proxy received signals to the process (default true)",
},
LatestFlag,
}

View File

@ -25,7 +25,7 @@ var (
},
cli.BoolTFlag{
Name: "layers",
Usage: "cache intermediate layers during build. Use BUILDAH_LAYERS environment variable to override. ",
Usage: "Cache intermediate layers during build. Use BUILDAH_LAYERS environment variable to override. ",
},
}
buildDescription = "Builds an OCI or Docker image using instructions from one\n" +

View File

@ -21,19 +21,19 @@ var (
checkpointFlags = []cli.Flag{
cli.BoolFlag{
Name: "keep, k",
Usage: "keep all temporary checkpoint files",
Usage: "Keep all temporary checkpoint files",
},
cli.BoolFlag{
Name: "leave-running, R",
Usage: "leave the container running after writing checkpoint to disk",
Usage: "Leave the container running after writing checkpoint to disk",
},
cli.BoolFlag{
Name: "tcp-established",
Usage: "checkpoint a container with established TCP connections",
Usage: "Checkpoint a container with established TCP connections",
},
cli.BoolFlag{
Name: "all, a",
Usage: "checkpoint all running containers",
Usage: "Checkpoint all running containers",
},
LatestFlag,
}

View File

@ -53,6 +53,10 @@ func getImageSubCommands() []cli.Command {
}
}
func getSystemSubCommands() []cli.Command {
return []cli.Command{infoCommand}
}
func getContainerSubCommands() []cli.Command {
return []cli.Command{
attachCommand,
@ -91,58 +95,58 @@ func getMainAppFlags() []cli.Flag {
return []cli.Flag{
cli.StringFlag{
Name: "cgroup-manager",
Usage: "cgroup manager to use (cgroupfs or systemd, default systemd)",
Usage: "Cgroup manager to use (cgroupfs or systemd, default systemd)",
},
cli.StringFlag{
Name: "cni-config-dir",
Usage: "path of the configuration directory for CNI networks",
Usage: "Path of the configuration directory for CNI networks",
},
cli.StringFlag{
Name: "conmon",
Usage: "path of the conmon binary",
Usage: "Path of the conmon binary",
},
cli.StringFlag{
Name: "default-mounts-file",
Usage: "path to default mounts file",
Usage: "Path to default mounts file",
Hidden: true,
},
cli.StringSliceFlag{
Name: "hooks-dir",
Usage: "set the OCI hooks directory path (may be set multiple times)",
Usage: "Set the OCI hooks directory path (may be set multiple times)",
},
cli.IntFlag{
Name: "max-workers",
Usage: "the maximum number of workers for parallel operations",
Usage: "The maximum number of workers for parallel operations",
Hidden: true,
},
cli.StringFlag{
Name: "namespace",
Usage: "set the libpod namespace, used to create separate views of the containers and pods on the system",
Usage: "Set the libpod namespace, used to create separate views of the containers and pods on the system",
Value: "",
},
cli.StringFlag{
Name: "root",
Usage: "path to the root directory in which data, including images, is stored",
Usage: "Path to the root directory in which data, including images, is stored",
},
cli.StringFlag{
Name: "runroot",
Usage: "path to the 'run directory' where all state information is stored",
Usage: "Path to the 'run directory' where all state information is stored",
},
cli.StringFlag{
Name: "runtime",
Usage: "path to the OCI-compatible binary used to run containers, default is /usr/bin/runc",
Usage: "Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc",
},
cli.StringFlag{
Name: "storage-driver, s",
Usage: "select which storage driver is used to manage storage of images and containers (default is overlay)",
Usage: "Select which storage driver is used to manage storage of images and containers (default is overlay)",
},
cli.StringSliceFlag{
Name: "storage-opt",
Usage: "used to pass an option to the storage driver",
Usage: "Used to pass an option to the storage driver",
},
cli.BoolFlag{
Name: "syslog",
Usage: "output logging information to syslog as well as the console",
Usage: "Output logging information to syslog as well as the console",
},
}
}

View File

@ -16,6 +16,10 @@ func getContainerSubCommands() []cli.Command {
return []cli.Command{}
}
func getSystemSubCommands() []cli.Command {
return []cli.Command{}
}
func getMainAppFlags() []cli.Flag {
return []cli.Flag{}
}

View File

@ -22,11 +22,11 @@ var (
stores = make(map[storage.Store]struct{})
LatestFlag = cli.BoolFlag{
Name: "latest, l",
Usage: "act on the latest container podman is aware of",
Usage: "Act on the latest container podman is aware of",
}
LatestPodFlag = cli.BoolFlag{
Name: "latest, l",
Usage: "act on the latest pod podman is aware of",
Usage: "Act on the latest pod podman is aware of",
}
WorkDirFlag = cli.StringFlag{
Name: "workdir, w",
@ -213,7 +213,7 @@ var createFlags = []cli.Flag{
},
cli.StringFlag{
Name: "conmon-pidfile",
Usage: "path to the file that will receive the PID of conmon",
Usage: "Path to the file that will receive the PID of conmon",
},
cli.Uint64Flag{
Name: "cpu-period",

View File

@ -1,9 +1,11 @@
package main
import (
"github.com/containers/libpod/cmd/podman/libpodruntime"
"context"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/adapter"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@ -25,20 +27,11 @@ var (
}
)
func pruneContainersCmd(c *cli.Context) error {
var (
deleteFuncs []shared.ParallelWorkerInput
)
ctx := getContext()
runtime, err := libpodruntime.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
func pruneContainers(runtime *adapter.LocalRuntime, ctx context.Context, maxWorkers int, force bool) error {
var deleteFuncs []shared.ParallelWorkerInput
filter := func(c *libpod.Container) bool {
state, _ := c.State()
state, err := c.State()
if state == libpod.ContainerStateStopped || (state == libpod.ContainerStateExited && err == nil && c.PodID() == "") {
return true
}
@ -54,7 +47,7 @@ func pruneContainersCmd(c *cli.Context) error {
for _, container := range delContainers {
con := container
f := func() error {
return runtime.RemoveContainer(ctx, con, c.Bool("force"))
return runtime.RemoveContainer(ctx, con, force)
}
deleteFuncs = append(deleteFuncs, shared.ParallelWorkerInput{
@ -62,13 +55,23 @@ func pruneContainersCmd(c *cli.Context) error {
ParallelFunc: f,
})
}
// Run the parallel funcs
deleteErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, deleteFuncs)
return printParallelOutput(deleteErrors, errCount)
}
func pruneContainersCmd(c *cli.Context) error {
runtime, err := adapter.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
maxWorkers := shared.Parallelize("rm")
if c.GlobalIsSet("max-workers") {
maxWorkers = c.GlobalInt("max-workers")
}
logrus.Debugf("Setting maximum workers to %d", maxWorkers)
// Run the parallel funcs
deleteErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, deleteFuncs)
return printParallelOutput(deleteErrors, errCount)
return pruneContainers(runtime, getContext(), maxWorkers, c.Bool("force"))
}

View File

@ -9,10 +9,10 @@ var (
containerKubeCommand,
}
generateDescription = "generate structured data based for a containers and pods"
generateDescription = "Generate structured data based for a containers and pods"
kubeCommand = cli.Command{
Name: "generate",
Usage: "generated structured data",
Usage: "Generate structured data",
Description: generateDescription,
ArgsUsage: "",
Subcommands: generateSubCommands,

View File

@ -17,7 +17,7 @@ var (
containerKubeFlags = []cli.Flag{
cli.BoolFlag{
Name: "service, s",
Usage: "generate YAML for kubernetes service object",
Usage: "Generate YAML for kubernetes service object",
},
}
containerKubeDescription = "Generate Kubernetes Pod YAML"

View File

@ -90,11 +90,11 @@ var (
},
cli.BoolFlag{
Name: "digests",
Usage: "show digests",
Usage: "Show digests",
},
cli.StringSliceFlag{
Name: "filter, f",
Usage: "filter output based on conditions provided (default [])",
Usage: "Filter output based on conditions provided (default [])",
},
cli.StringFlag{
Name: "format",
@ -102,20 +102,20 @@ var (
},
cli.BoolFlag{
Name: "noheading, n",
Usage: "do not print column headings",
Usage: "Do not print column headings",
},
cli.BoolFlag{
Name: "no-trunc, notruncate",
Usage: "do not truncate output",
Usage: "Do not truncate output",
},
cli.BoolFlag{
Name: "quiet, q",
Usage: "display only image IDs",
Usage: "Display only image IDs",
},
cli.StringFlag{
Name: "sort",
Usage: "Sort by created, id, repository, size, or tag",
Value: "created",
Value: "Created",
},
}
@ -133,7 +133,7 @@ var (
lsImagesCommand = cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "list images in local storage",
Usage: "List images in local storage",
Description: imagesDescription,
Flags: imagesFlags,
Action: imagesCmd,

View File

@ -2,6 +2,7 @@ package main
import (
"fmt"
"github.com/containers/libpod/libpod/adapter"
"github.com/pkg/errors"
"github.com/urfave/cli"
@ -16,7 +17,7 @@ var (
pruneImageFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "remove all unused images, not just dangling ones",
Usage: "Remove all unused images, not just dangling ones",
},
}
pruneImagesCommand = cli.Command{

View File

@ -26,7 +26,7 @@ var (
infoFlags = []cli.Flag{
cli.BoolFlag{
Name: "debug, D",
Usage: "display additional debug information",
Usage: "Display additional debug information",
},
cli.StringFlag{
Name: "format, f",

View File

@ -97,6 +97,7 @@ func main() {
inspectCommand,
pullCommand,
rmiCommand,
systemCommand,
tagCommand,
versionCommand,
}
@ -187,21 +188,21 @@ func main() {
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "config, c",
Usage: "path of a libpod config file detailing container server configuration options",
Usage: "Path of a libpod config file detailing container server configuration options",
Hidden: true,
},
cli.StringFlag{
Name: "cpu-profile",
Usage: "path for the cpu profiling results",
Usage: "Path for the cpu profiling results",
},
cli.StringFlag{
Name: "log-level",
Usage: "log messages above specified level: debug, info, warn, error (default), fatal or panic",
Usage: "Log messages above specified level: debug, info, warn, error (default), fatal or panic",
Value: "error",
},
cli.StringFlag{
Name: "tmpdir",
Usage: "path to the tmp directory",
Usage: "Path to the tmp directory",
},
}

View File

@ -33,7 +33,7 @@ var (
},
cli.BoolFlag{
Name: "notruncate",
Usage: "do not truncate output",
Usage: "Do not truncate output",
},
LatestFlag,
}

View File

@ -15,7 +15,7 @@ var (
pauseFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "pause all running containers",
Usage: "Pause all running containers",
},
}
pauseDescription = `

View File

@ -12,7 +12,7 @@ var (
playDescription = "Play a pod and its containers from a structured file."
playCommand = cli.Command{
Name: "play",
Usage: "play a container or pod",
Usage: "Play a container or pod",
Description: playDescription,
ArgsUsage: "",
Subcommands: playSubCommands,

View File

@ -32,11 +32,11 @@ var (
},
cli.StringFlag{
Name: "cert-dir",
Usage: "`pathname` of a directory containing TLS certificates and keys",
Usage: "`Pathname` of a directory containing TLS certificates and keys",
},
cli.StringFlag{
Name: "creds",
Usage: "`credentials` (USERNAME:PASSWORD) to use for authenticating to a registry",
Usage: "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry",
},
cli.BoolFlag{
Name: "quiet, q",
@ -44,11 +44,11 @@ var (
},
cli.StringFlag{
Name: "signature-policy",
Usage: "`pathname` of signature policy file (not usually used)",
Usage: "`Pathname` of signature policy file (not usually used)",
},
cli.BoolTFlag{
Name: "tls-verify",
Usage: "require HTTPS and verify certificates when contacting registries (default: true)",
Usage: "Require HTTPS and verify certificates when contacting registries (default: true)",
},
}
playKubeDescription = "Play a Pod and its containers based on a Kubrernetes YAML"
@ -58,7 +58,7 @@ var (
Description: playKubeDescription,
Action: playKubeYAMLCmd,
Flags: sortFlags(playKubeFlags),
ArgsUsage: "kubernetes YAML file",
ArgsUsage: "Kubernetes YAML file",
UseShortOptionHandling: true,
OnUsageError: usageErrorHandler,
}

View File

@ -14,10 +14,10 @@ var (
podInspectFlags = []cli.Flag{
LatestPodFlag,
}
podInspectDescription = "display the configuration for a pod by name or id"
podInspectDescription = "Display the configuration for a pod by name or id"
podInspectCommand = cli.Command{
Name: "inspect",
Usage: "displays a pod configuration",
Usage: "Displays a pod configuration",
Description: podInspectDescription,
Flags: sortFlags(podInspectFlags),
Action: podInspectCmd,

View File

@ -13,7 +13,7 @@ var (
podPauseFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "pause all running pods",
Usage: "Pause all running pods",
},
LatestPodFlag,
}

View File

@ -13,7 +13,7 @@ var (
podRestartFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "restart all pods",
Usage: "Restart all pods",
},
LatestPodFlag,
}

View File

@ -13,7 +13,7 @@ var (
podStartFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "start all running pods",
Usage: "Start all running pods",
},
LatestPodFlag,
}

View File

@ -19,22 +19,22 @@ var (
podStatsFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "show stats for all pods. Only running pods are shown by default.",
Usage: "Show stats for all pods. Only running pods are shown by default.",
},
cli.BoolFlag{
Name: "no-stream",
Usage: "disable streaming stats and only pull the first result, default setting is false",
Usage: "Disable streaming stats and only pull the first result, default setting is false",
},
cli.BoolFlag{
Name: "no-reset",
Usage: "disable resetting the screen between intervals",
Usage: "Disable resetting the screen between intervals",
},
cli.StringFlag{
Name: "format",
Usage: "pretty-print container statistics to JSON or using a Go template",
Usage: "Pretty-print container statistics to JSON or using a Go template",
}, LatestPodFlag,
}
podStatsDescription = "display a live stream of resource usage statistics for the containers in or more pods"
podStatsDescription = "Display a live stream of resource usage statistics for the containers in or more pods"
podStatsCommand = cli.Command{
Name: "stats",
Usage: "Display percentage of CPU, memory, network I/O, block I/O and PIDs for containers in one or more pods",

View File

@ -12,7 +12,7 @@ var (
podStopFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "stop all running pods",
Usage: "Stop all running pods",
},
LatestPodFlag,
cli.UintFlag{

View File

@ -13,7 +13,7 @@ var (
podUnpauseFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "unpause all paused pods",
Usage: "Unpause all paused pods",
},
LatestPodFlag,
}

View File

@ -15,7 +15,7 @@ var (
portFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "display port information for all containers",
Usage: "Display port information for all containers",
},
LatestFlag,
}

View File

@ -41,7 +41,7 @@ var (
},
cli.BoolTFlag{
Name: "tls-verify",
Usage: "require HTTPS and verify certificates when contacting registries (default: true)",
Usage: "Require HTTPS and verify certificates when contacting registries (default: true)",
},
}

View File

@ -21,40 +21,40 @@ var (
pushFlags = []cli.Flag{
cli.StringFlag{
Name: "signature-policy",
Usage: "`pathname` of signature policy file (not usually used)",
Usage: "`Pathname` of signature policy file (not usually used)",
Hidden: true,
},
cli.StringFlag{
Name: "creds",
Usage: "`credentials` (USERNAME:PASSWORD) to use for authenticating to a registry",
Usage: "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry",
},
cli.StringFlag{
Name: "cert-dir",
Usage: "`pathname` of a directory containing TLS certificates and keys",
Usage: "`Pathname` of a directory containing TLS certificates and keys",
},
cli.BoolFlag{
Name: "compress",
Usage: "compress tarball image layers when pushing to a directory using the 'dir' transport. (default is same compression type as source)",
Usage: "Compress tarball image layers when pushing to a directory using the 'dir' transport. (default is same compression type as source)",
},
cli.StringFlag{
Name: "format, f",
Usage: "manifest type (oci, v2s1, or v2s2) to use when pushing an image using the 'dir:' transport (default is manifest type of source)",
Usage: "Manifest type (oci, v2s1, or v2s2) to use when pushing an image using the 'dir:' transport (default is manifest type of source)",
},
cli.BoolTFlag{
Name: "tls-verify",
Usage: "require HTTPS and verify certificates when contacting registries (default: true)",
Usage: "Require HTTPS and verify certificates when contacting registries (default: true)",
},
cli.BoolFlag{
Name: "remove-signatures",
Usage: "discard any pre-existing signatures in the image",
Usage: "Discard any pre-existing signatures in the image",
},
cli.StringFlag{
Name: "sign-by",
Usage: "add a signature at the destination using the specified key",
Usage: "Add a signature at the destination using the specified key",
},
cli.BoolFlag{
Name: "quiet, q",
Usage: "don't output progress information when pushing images",
Usage: "Don't output progress information when pushing images",
},
cli.StringFlag{
Name: "authfile",

View File

@ -17,11 +17,11 @@ var (
restartFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "restart all non-running containers",
Usage: "Restart all non-running containers",
},
cli.BoolFlag{
Name: "running",
Usage: "restart only running containers when --all is used",
Usage: "Restart only running containers when --all is used",
},
cli.UintFlag{
Name: "timeout, time, t",

View File

@ -21,18 +21,18 @@ var (
restoreFlags = []cli.Flag{
cli.BoolFlag{
Name: "keep, k",
Usage: "keep all temporary checkpoint files",
Usage: "Keep all temporary checkpoint files",
},
// restore --all would make more sense if there would be
// dedicated state for container which are checkpointed.
// TODO: add ContainerStateCheckpointed
cli.BoolFlag{
Name: "tcp-established",
Usage: "checkpoint a container with established TCP connections",
Usage: "Checkpoint a container with established TCP connections",
},
cli.BoolFlag{
Name: "all, a",
Usage: "restore all checkpointed containers",
Usage: "Restore all checkpointed containers",
},
LatestFlag,
}

View File

@ -15,11 +15,11 @@ var (
rmiFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "remove all images",
Usage: "Remove all images",
},
cli.BoolFlag{
Name: "force, f",
Usage: "force removal of the image",
Usage: "Force removal of the image",
},
}
rmiCommand = cli.Command{
@ -34,7 +34,7 @@ var (
}
rmImageCommand = cli.Command{
Name: "rm",
Usage: "removes one or more images from local storage",
Usage: "Removes one or more images from local storage",
Description: rmiDescription,
Action: rmiCmd,
ArgsUsage: "IMAGE-NAME-OR-ID [...]",

View File

@ -20,7 +20,7 @@ var runDescription = "Runs a command in a new container from the given image"
var runFlags []cli.Flag = append(createFlags, cli.BoolTFlag{
Name: "sig-proxy",
Usage: "proxy received signals to the process (default true)",
Usage: "Proxy received signals to the process (default true)",
})
var runCommand = cli.Command{
@ -131,6 +131,7 @@ func runCmd(c *cli.Context) error {
ctrExitCode, err := readExitFile(runtime.GetConfig().TmpDir, ctr.ID())
if err != nil {
logrus.Errorf("Cannot get exit code: %v", err)
exitCode = 127
} else {
exitCode = ctrExitCode
}

View File

@ -24,15 +24,15 @@ var (
},
cli.BoolFlag{
Name: "display",
Usage: "preview the command that the label would run",
Usage: "Preview the command that the label would run",
},
cli.StringFlag{
Name: "cert-dir",
Usage: "`pathname` of a directory containing TLS certificates and keys",
Usage: "`Pathname` of a directory containing TLS certificates and keys",
},
cli.StringFlag{
Name: "creds",
Usage: "`credentials` (USERNAME:PASSWORD) to use for authenticating to a registry",
Usage: "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry",
},
cli.StringFlag{
Name: "name",
@ -59,15 +59,15 @@ var (
},
cli.BoolFlag{
Name: "pull, p",
Usage: "pull the image if it does not exist locally prior to executing the label contents",
Usage: "Pull the image if it does not exist locally prior to executing the label contents",
},
cli.StringFlag{
Name: "signature-policy",
Usage: "`pathname` of signature policy file (not usually used)",
Usage: "`Pathname` of signature policy file (not usually used)",
},
cli.BoolTFlag{
Name: "tls-verify",
Usage: "require HTTPS and verify certificates when contacting registries (default: true)",
Usage: "Require HTTPS and verify certificates when contacting registries (default: true)",
},
}

View File

@ -29,7 +29,7 @@ var (
saveFlags = []cli.Flag{
cli.BoolFlag{
Name: "compress",
Usage: "compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)",
Usage: "Compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)",
},
cli.StringFlag{
Name: "output, o",

View File

@ -30,23 +30,23 @@ var (
},
cli.StringSliceFlag{
Name: "filter, f",
Usage: "filter output based on conditions provided (default [])",
Usage: "Filter output based on conditions provided (default [])",
},
cli.StringFlag{
Name: "format",
Usage: "change the output format to a Go template",
Usage: "Change the output format to a Go template",
},
cli.IntFlag{
Name: "limit",
Usage: "limit the number of results",
Usage: "Limit the number of results",
},
cli.BoolFlag{
Name: "no-trunc",
Usage: "do not truncate the output",
Usage: "Do not truncate the output",
},
cli.BoolTFlag{
Name: "tls-verify",
Usage: "require HTTPS and verify certificates when contacting registries (default: true)",
Usage: "Require HTTPS and verify certificates when contacting registries (default: true)",
},
}
searchDescription = `

View File

@ -29,7 +29,7 @@ var (
},
cli.BoolTFlag{
Name: "sig-proxy",
Usage: "proxy received signals to the process (default true if attaching, false otherwise)",
Usage: "Proxy received signals to the process (default true if attaching, false otherwise)",
},
LatestFlag,
}

View File

@ -31,23 +31,23 @@ var (
statsFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "show all containers. Only running containers are shown by default. The default is false",
Usage: "Show all containers. Only running containers are shown by default. The default is false",
},
cli.BoolFlag{
Name: "no-stream",
Usage: "disable streaming stats and only pull the first result, default setting is false",
Usage: "Disable streaming stats and only pull the first result, default setting is false",
},
cli.StringFlag{
Name: "format",
Usage: "pretty-print container statistics to JSON or using a Go template",
Usage: "Pretty-print container statistics to JSON or using a Go template",
},
cli.BoolFlag{
Name: "no-reset",
Usage: "disable resetting the screen between intervals",
Usage: "Disable resetting the screen between intervals",
}, LatestFlag,
}
statsDescription = "display a live stream of one or more containers' resource usage statistics"
statsDescription = "Display a live stream of one or more containers' resource usage statistics"
statsCommand = cli.Command{
Name: "stats",
Usage: "Display percentage of CPU, memory, network I/O, block I/O and PIDs for one or more containers",

View File

@ -21,7 +21,7 @@ var (
},
cli.BoolFlag{
Name: "all, a",
Usage: "stop all running containers",
Usage: "Stop all running containers",
}, LatestFlag,
}
stopDescription = `

29
cmd/podman/system.go Normal file
View File

@ -0,0 +1,29 @@
package main
import (
"sort"
"github.com/urfave/cli"
)
var (
systemSubCommands = []cli.Command{
pruneSystemCommand,
}
systemDescription = "Manage podman"
systemCommand = cli.Command{
Name: "system",
Usage: "Manage podman",
Description: systemDescription,
ArgsUsage: "",
Subcommands: getSystemSubCommandsSorted(),
UseShortOptionHandling: true,
OnUsageError: usageErrorHandler,
}
)
func getSystemSubCommandsSorted() []cli.Command {
systemSubCommands = append(systemSubCommands, getSystemSubCommands()...)
sort.Sort(commandSortedAlpha{systemSubCommands})
return systemSubCommands
}

107
cmd/podman/system_prune.go Normal file
View File

@ -0,0 +1,107 @@
package main
import (
"bufio"
"fmt"
"os"
"strings"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod/adapter"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
var (
pruneSystemDescription = `
podman system prune
Remove unused data
`
pruneSystemFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "Remove all unused data",
},
cli.BoolFlag{
Name: "force, f",
Usage: "Do not prompt for confirmation",
},
cli.BoolFlag{
Name: "volumes",
Usage: "Prune volumes",
},
}
pruneSystemCommand = cli.Command{
Name: "prune",
Usage: "Remove unused data",
Description: pruneSystemDescription,
Action: pruneSystemCmd,
OnUsageError: usageErrorHandler,
Flags: pruneSystemFlags,
}
)
func pruneSystemCmd(c *cli.Context) error {
// Prompt for confirmation if --force is not set
if !c.Bool("force") {
reader := bufio.NewReader(os.Stdin)
volumeString := ""
if c.Bool("volumes") {
volumeString = `
- all volumes not used by at least one container`
}
fmt.Printf(`
WARNING! This will remove:
- all stopped containers%s
- all dangling images
- all build cache
Are you sure you want to continue? [y/N] `, volumeString)
ans, err := reader.ReadString('\n')
if err != nil {
return errors.Wrapf(err, "error reading input")
}
if strings.ToLower(ans)[0] != 'y' {
return nil
}
}
runtime, err := adapter.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
ctx := getContext()
fmt.Println("Deleted Containers")
lasterr := pruneContainers(runtime, ctx, shared.Parallelize("rm"), false)
if c.Bool("volumes") {
fmt.Println("Deleted Volumes")
err := volumePrune(runtime, getContext())
if err != nil {
if lasterr != nil {
logrus.Errorf("%q", lasterr)
}
lasterr = err
}
}
// Call prune; if any cids are returned, print them and then
// return err in case an error also came up
pruneCids, err := runtime.PruneImages(c.Bool("all"))
if len(pruneCids) > 0 {
fmt.Println("Deleted Images")
for _, cid := range pruneCids {
fmt.Println(cid)
}
}
if err != nil {
if lasterr != nil {
logrus.Errorf("%q", lasterr)
}
lasterr = err
}
return lasterr
}

View File

@ -15,11 +15,11 @@ var (
umountFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "umount all of the currently mounted containers",
Usage: "Umount all of the currently mounted containers",
},
cli.BoolFlag{
Name: "force, f",
Usage: "force the complete umount all of the currently mounted containers",
Usage: "Force the complete umount all of the currently mounted containers",
},
LatestFlag,
}

View File

@ -15,7 +15,7 @@ var (
unpauseFlags = []cli.Flag{
cli.BoolFlag{
Name: "all, a",
Usage: "unpause all paused containers",
Usage: "Unpause all paused containers",
},
}
unpauseDescription = `

View File

@ -24,7 +24,7 @@ var (
varlinkFlags = []cli.Flag{
cli.IntFlag{
Name: "timeout, t",
Usage: "time until the varlink session expires in milliseconds. Use 0 to disable the timeout.",
Usage: "Time until the varlink session expires in milliseconds. Use 0 to disable the timeout.",
Value: 1000,
},
}

View File

@ -2,12 +2,13 @@ package main
import (
"bufio"
"context"
"fmt"
"os"
"strings"
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/adapter"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
@ -37,35 +38,9 @@ var volumePruneCommand = cli.Command{
UseShortOptionHandling: true,
}
func volumePruneCmd(c *cli.Context) error {
func volumePrune(runtime *adapter.LocalRuntime, ctx context.Context) error {
var lastError error
if err := validateFlags(c, volumePruneFlags); err != nil {
return err
}
runtime, err := libpodruntime.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
ctx := getContext()
// Prompt for confirmation if --force is not set
if !c.Bool("force") {
reader := bufio.NewReader(os.Stdin)
fmt.Println("WARNING! This will remove all volumes not used by at least one container.")
fmt.Print("Are you sure you want to continue? [y/N] ")
ans, err := reader.ReadString('\n')
if err != nil {
return errors.Wrapf(err, "error reading input")
}
if strings.ToLower(ans)[0] != 'y' {
return nil
}
}
volumes, err := runtime.GetAllVolumes()
if err != nil {
return err
@ -84,3 +59,32 @@ func volumePruneCmd(c *cli.Context) error {
}
return lastError
}
func volumePruneCmd(c *cli.Context) error {
if err := validateFlags(c, volumePruneFlags); err != nil {
return err
}
runtime, err := adapter.GetRuntime(c)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
}
defer runtime.Shutdown(false)
// Prompt for confirmation if --force is not set
if !c.Bool("force") {
reader := bufio.NewReader(os.Stdin)
fmt.Println("WARNING! This will remove all volumes not used by at least one container.")
fmt.Print("Are you sure you want to continue? [y/N] ")
ans, err := reader.ReadString('\n')
if err != nil {
return errors.Wrapf(err, "error reading input")
}
if strings.ToLower(ans)[0] != 'y' {
return nil
}
}
return volumePrune(runtime, getContext())
}

View File

@ -66,6 +66,7 @@
| [podman-start(1)](/docs/podman-start.1.md) | Starts one or more containers
| [podman-stats(1)](/docs/podman-stats.1.md) | Display a live stream of one or more containers' resource usage statistics|[![...](/docs/play.png)](https://asciinema.org/a/vfUPbAA5tsNWhsfB9p25T6xdr)|
| [podman-stop(1)](/docs/podman-stop.1.md) | Stops one or more running containers |[![...](/docs/play.png)](https://asciinema.org/a/KNRF9xVXeaeNTNjBQVogvZBcp)|
| [podman-system(1)](/docs/podman-system.1.md) | Manage podman ||
| [podman-tag(1)](/docs/podman-tag.1.md) | Add an additional name to a local image |[![...](/docs/play.png)](https://asciinema.org/a/133803)|
| [podman-top(1)](/docs/podman-top.1.md) | Display the running processes of a container |[![...](/docs/play.png)](https://asciinema.org/a/5WCCi1LXwSuRbvaO9cBUYf3fk)|
| [podman-umount(1)](/docs/podman-umount.1.md) | Unmount a working container's root filesystem |[![...](/docs/play.png)](https://asciinema.org/a/MZPTWD5CVs3dMREkBxQBY9C5z)|

View File

@ -979,6 +979,51 @@ _podman_container() {
esac
}
_podman_system_info() {
_podman_info
}
_podman_system_prune() {
local options_with_args="
"
local boolean_options="
-a
--all
-f
--force
-h
--help
--volumes
"
case "$cur" in
-*)
COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
;;
esac
}
_podman_system() {
local boolean_options="
--help
-h
"
subcommands="
info
prune
"
__podman_subcommands "$subcommands" && return
case "$cur" in
-*)
COMPREPLY=( $( compgen -W "--help" -- "$cur" ) )
;;
*)
COMPREPLY=( $( compgen -W "$subcommands" -- "$cur" ) )
;;
esac
}
_podman_commit() {
local options_with_args="
--author
@ -2482,6 +2527,11 @@ _podman_container_prune() {
-h
--help
"
case "$cur" in
-*)
COMPREPLY=($(compgen -W "$boolean_options $options_with_args" -- "$cur"))
;;
esac
}
_podman_container_exists() {

View File

@ -0,0 +1 @@
.so man1/podman-info.1

View File

@ -1,9 +1,9 @@
% podman-version(1)
% podman-info(1)
## NAME
podman\-system\-info - Display system information
podman\-info - Display system information
## SYNOPSIS
**podman info** [*options*]

View File

@ -0,0 +1,37 @@
% podman-system-prune(1) podman
## NAME
podman\-system\-prune - Remove all unused container, image and volume data
## SYNOPSIS
**podman system prune**
[**-all**|**--a**]
[**-force**|**--f**]
[**-help**|**--h**]
[**-volumes**|**--v**]
## DESCRIPTION
**podman system prune** removes all unused containers, (both dangling and unreferenced) from local storage and optionally, volumes.
With the `all` option, you can delete all unused images. Unused images are dangling images as well as any image that does not have any containers based on it.
By default, volumes are not removed to prevent important data from being deleted if there is currently no container using the volume. Use the --volumes flag when running the command to prune volumes as well.
## OPTIONS
**--all, -a**
Remove all unused images not just dangling ones.
**--force, -f**
Do not prompt for confirmation
**--volumes**
Prune volumes not used by at least one container
## SEE ALSO
podman(1), podman-image-prune(1), podman-container-prune(1), podman-volume-prune(1)
# HISTORY
February 2019, Originally compiled by Dan Walsh (dwalsh at redhat dot com)

20
docs/podman-system.1.md Normal file
View File

@ -0,0 +1,20 @@
% podman-system(1)
## NAME
podman\-system - Manage podman
## SYNOPSIS
**podman system** *subcommand*
## DESCRIPTION
The system command allows you to manage the podman systems
## COMMANDS
| Command | Man Page | Description |
| ------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
| info | [podman-system-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 |
## SEE ALSO
podman

View File

@ -162,6 +162,7 @@ the exit codes follow the `chroot` standard, see below:
| [podman-start(1)](podman-start.1.md) | Starts one or more containers. |
| [podman-stats(1)](podman-stats.1.md) | Display a live stream of one or more container's resource usage statistics. |
| [podman-stop(1)](podman-stop.1.md) | Stop one or more running containers. |
| [podman-system(1)](podman-system.1.md) | Manage podman. |
| [podman-tag(1)](podman-tag.1.md) | Add an additional name to a local image. |
| [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. |

View File

@ -407,3 +407,28 @@ func (r *LocalRuntime) Import(ctx context.Context, source, reference string, cha
}
return iopodman.ImportImage().Call(r.Conn, strings.TrimRight(tempFile, ":"), reference, history, changes, true)
}
// GetAllVolumes retrieves all the volumes
func (r *LocalRuntime) GetAllVolumes() ([]*libpod.Volume, error) {
return nil, libpod.ErrNotImplemented
}
// RemoveVolume removes a volumes
func (r *LocalRuntime) RemoveVolume(ctx context.Context, v *libpod.Volume, force, prune bool) error {
return libpod.ErrNotImplemented
}
// GetContainers retrieves all containers from the state
// Filters can be provided which will determine what containers are included in
// the output. Multiple filters are handled by ANDing their output, so only
// containers matching all filters are returned
func (r *LocalRuntime) GetContainers(filters ...libpod.ContainerFilter) ([]*libpod.Container, error) {
return nil, libpod.ErrNotImplemented
}
// RemoveContainer removes the given container
// If force is specified, the container will be stopped first
// Otherwise, RemoveContainer will return an error if the container is running
func (r *LocalRuntime) RemoveContainer(ctx context.Context, c *libpod.Container, force bool) error {
return libpod.ErrNotImplemented
}

View File

@ -39,4 +39,10 @@ var _ = Describe("Podman Info", func() {
Expect(session.ExitCode()).To(Equal(0))
})
It("podman system info json output", func() {
session := podmanTest.Podman([]string{"system", "info", "--format=json"})
session.Wait()
Expect(session.ExitCode()).To(Equal(0))
})
})

View File

@ -88,4 +88,17 @@ var _ = Describe("Podman rm", func() {
Expect(len(images.OutputToStringArray())).To(Equal(0))
})
It("podman system image prune unused images", func() {
SkipIfRemote()
podmanTest.BuildImage(pruneImage, "alpine_bash:latest", "true")
prune := podmanTest.Podman([]string{"system", "prune", "-a", "--force"})
prune.WaitWithDefaultTimeout()
Expect(prune.ExitCode()).To(Equal(0))
images := podmanTest.Podman([]string{"images", "-a"})
images.WaitWithDefaultTimeout()
// all images are unused, so they all should be deleted!
Expect(len(images.OutputToStringArray())).To(Equal(0))
})
})

View File

@ -63,4 +63,34 @@ var _ = Describe("Podman volume prune", func() {
podmanTest.Cleanup()
})
It("podman system prune --volume", func() {
session := podmanTest.Podman([]string{"volume", "create"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"volume", "create"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"create", "-v", "myvol:/myvol", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"volume", "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(4))
session = podmanTest.Podman([]string{"system", "prune", "--force", "--volumes"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
session = podmanTest.Podman([]string{"volume", "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(len(session.OutputToStringArray())).To(Equal(2))
podmanTest.Cleanup()
})
})

View File

@ -76,7 +76,10 @@ There are other equivalents for these tools
| `docker volume ls` | [`podman volume ls`](./docs/podman-volume-ls.1.md) |
| `docker volume prune` | [`podman volume prune`](./docs/podman-volume-prune.1.md) |
| `docker volume rm` | [`podman volume rm`](./docs/podman-volume-rm.1.md) |
| `docker wait` | [`podman wait`](./docs/podman-wait.1.md) |
| `docker system` | [`podman system`](./docs/podman-system.1.md) |
| `docker system prune` | [`podman system prune`](./docs/podman-system-prune.1.md) |
| `docker system info` | [`podman system info`](./docs/podman-system-info.1.md) |
| `docker wait` | [`podman wait`](./docs/podman-wait.1.md) |
**** Use mount to take advantage of the entire linux tool chain rather then just cp. Read [`here`](./docs/podman-cp.1.md) for more information.
@ -95,7 +98,6 @@ Those Docker commands currently do not have equivalents in `podman`:
| `docker service` ||
| `docker stack` ||
| `docker swarm` | podman does not support swarm. We support Kubernetes for orchestration using [CRI-O](https://github.com/kubernetes-sigs/cri-o).|
| `docker system` ||
| `docker volume` | podman currently supports file volumes. Future enhancement planned to support Docker Volumes Plugins
## Missing commands in Docker