diff options
110 files changed, 574 insertions, 478 deletions
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go index 48a25a3e2..b78633ed6 100644 --- a/cmd/podman/attach.go +++ b/cmd/podman/attach.go @@ -51,6 +51,6 @@ func attachCmd(c *cliconfig.AttachValues) error { if err != nil { return errors.Wrapf(err, "error creating runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) return runtime.Attach(getContext(), c) } diff --git a/cmd/podman/build.go b/cmd/podman/build.go index 5e2b1aa82..bd7269390 100644 --- a/cmd/podman/build.go +++ b/cmd/podman/build.go @@ -57,14 +57,20 @@ func init() { budFlags := buildahcli.GetBudFlags(&budFlagsValues) flag := budFlags.Lookup("pull") - flag.Value.Set("true") + if err := flag.Value.Set("true"); err != nil { + logrus.Error("unable to set pull flag to true") + } flag.DefValue = "true" layerFlags := buildahcli.GetLayerFlags(&layerValues) flag = layerFlags.Lookup("layers") - flag.Value.Set(useLayers()) + if err := flag.Value.Set(useLayers()); err != nil { + logrus.Error("unable to set uselayers") + } flag.DefValue = useLayers() flag = layerFlags.Lookup("force-rm") - flag.Value.Set("true") + if err := flag.Value.Set("true"); err != nil { + logrus.Error("unable to set force-rm flag to true") + } flag.DefValue = "true" fromAndBugFlags := buildahcli.GetFromAndBudFlags(&fromAndBudValues, &userNSValues, &namespaceValues) @@ -72,7 +78,7 @@ func init() { flags.AddFlagSet(&budFlags) flags.AddFlagSet(&layerFlags) flags.AddFlagSet(&fromAndBugFlags) - flags.MarkHidden("signature-policy") + markFlagHidden(flags, "signature-policy") } func getDockerfiles(files []string) []string { @@ -177,7 +183,6 @@ func buildCmd(c *cliconfig.BuildValues) error { } contextDir = absDir } - cliArgs = Tail(cliArgs) } else { // No context directory or URL was specified. Try to use the // home of the first locally-available Dockerfile. @@ -218,7 +223,7 @@ func buildCmd(c *cliconfig.BuildValues) error { } // end from buildah - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) var stdout, stderr, reporter *os.File stdout = os.Stdout diff --git a/cmd/podman/checkpoint.go b/cmd/podman/checkpoint.go index bfb5b49d4..6755bb073 100644 --- a/cmd/podman/checkpoint.go +++ b/cmd/podman/checkpoint.go @@ -59,6 +59,6 @@ func checkpointCmd(c *cliconfig.CheckpointValues) error { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) return runtime.Checkpoint(c) } diff --git a/cmd/podman/cleanup.go b/cmd/podman/cleanup.go index 9544b75b0..c00654162 100644 --- a/cmd/podman/cleanup.go +++ b/cmd/podman/cleanup.go @@ -52,7 +52,7 @@ func cleanupCmd(c *cliconfig.CleanupValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ok, failures, err := runtime.CleanupContainers(getContext(), c) if err != nil { diff --git a/cmd/podman/commit.go b/cmd/podman/commit.go index c49645a1d..e98b71514 100644 --- a/cmd/podman/commit.go +++ b/cmd/podman/commit.go @@ -53,7 +53,7 @@ func commitCmd(c *cliconfig.CommitValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) args := c.InputArgs if len(args) != 2 { diff --git a/cmd/podman/common.go b/cmd/podman/common.go index 9d7c52273..50f3d9a7b 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -11,7 +11,6 @@ import ( "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/rootless" - "github.com/containers/storage" "github.com/fatih/camelcase" jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" @@ -19,8 +18,7 @@ import ( ) var ( - stores = make(map[storage.Store]struct{}) - json = jsoniter.ConfigCompatibleWithStandardLibrary + json = jsoniter.ConfigCompatibleWithStandardLibrary ) const ( diff --git a/cmd/podman/containers_prune.go b/cmd/podman/containers_prune.go index 97481fb35..b8a84a0e3 100644 --- a/cmd/podman/containers_prune.go +++ b/cmd/podman/containers_prune.go @@ -43,7 +43,7 @@ func pruneContainersCmd(c *cliconfig.PruneContainersValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) maxWorkers := shared.DefaultPoolSize("prune") if c.GlobalIsSet("max-workers") { diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go index f6ac5f8f7..7c28edd26 100644 --- a/cmd/podman/cp.go +++ b/cmd/podman/cp.go @@ -68,7 +68,7 @@ func cpCmd(c *cliconfig.CpValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) return copyBetweenHostAndContainer(runtime, args[0], args[1], c.Extract, c.Pause) } @@ -95,7 +95,11 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin if err != nil { return err } - defer ctr.Unmount(false) + defer func() { + if err := ctr.Unmount(false); err != nil { + logrus.Errorf("unable to umount container '%s': %q", ctr.ID(), err) + } + }() // We can't pause rootless containers. if pause && rootless.IsRootless() { diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 2351f5860..93141a800 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -57,7 +57,7 @@ func createCmd(c *cliconfig.CreateValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) cid, err := runtime.CreateContainer(getContext(), c) if err != nil { diff --git a/cmd/podman/diff.go b/cmd/podman/diff.go index 032c0f2c0..2b0c1d398 100644 --- a/cmd/podman/diff.go +++ b/cmd/podman/diff.go @@ -61,8 +61,7 @@ func init() { flags.BoolVar(&diffCommand.Archive, "archive", true, "Save the diff as a tar archive") flags.StringVar(&diffCommand.Format, "format", "", "Change the output format") flags.BoolVarP(&diffCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") - - flags.MarkHidden("archive") + markFlagHidden(flags, "archive") markFlagHiddenForRemoteClient("latest", flags) } @@ -93,7 +92,7 @@ func diffCmd(c *cliconfig.DiffValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) var to string if c.Latest { @@ -137,7 +136,5 @@ func diffCmd(c *cliconfig.DiffValues) error { } else { out = stdoutStruct{output: diffOutput} } - formats.Writer(out).Out() - - return nil + return formats.Writer(out).Out() } diff --git a/cmd/podman/events.go b/cmd/podman/events.go index 88c1010e3..18126e626 100644 --- a/cmd/podman/events.go +++ b/cmd/podman/events.go @@ -36,7 +36,7 @@ func init() { flags.BoolVar(&eventsCommand.Stream, "stream", true, "stream new events; for testing only") flags.StringVar(&eventsCommand.Since, "since", "", "show all events created since timestamp") flags.StringVar(&eventsCommand.Until, "until", "", "show all events until timestamp") - flags.MarkHidden("stream") + markFlagHidden(flags, "stream") } func eventsCmd(c *cliconfig.EventValues) error { @@ -44,7 +44,7 @@ func eventsCmd(c *cliconfig.EventValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) return runtime.Events(c) } diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go index bf8de69fc..799ed9f38 100644 --- a/cmd/podman/exec.go +++ b/cmd/podman/exec.go @@ -64,7 +64,7 @@ func execCmd(c *cliconfig.ExecValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) err = runtime.Exec(c, cmd) if errors.Cause(err) == define.ErrCtrStateInvalid { diff --git a/cmd/podman/exists.go b/cmd/podman/exists.go index 1e052e25f..f8b1f8e59 100644 --- a/cmd/podman/exists.go +++ b/cmd/podman/exists.go @@ -90,7 +90,7 @@ func imageExistsCmd(c *cliconfig.ImageExistsValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if _, err := runtime.NewImageFromLocal(args[0]); err != nil { //TODO we need to ask about having varlink defined errors exposed //so we can reuse them @@ -111,7 +111,7 @@ func containerExistsCmd(c *cliconfig.ContainerExistsValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if _, err := runtime.LookupContainer(args[0]); err != nil { if errors.Cause(err) == define.ErrNoSuchCtr || err.Error() == "io.podman.ContainerNotFound" { os.Exit(1) @@ -130,7 +130,7 @@ func podExistsCmd(c *cliconfig.PodExistsValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if _, err := runtime.LookupPod(args[0]); err != nil { if errors.Cause(err) == define.ErrNoSuchPod || err.Error() == "io.podman.PodNotFound" { diff --git a/cmd/podman/export.go b/cmd/podman/export.go index f2336167b..27948004c 100644 --- a/cmd/podman/export.go +++ b/cmd/podman/export.go @@ -45,7 +45,7 @@ func exportCmd(c *cliconfig.ExportValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) args := c.InputArgs if len(args) == 0 { diff --git a/cmd/podman/generate_kube.go b/cmd/podman/generate_kube.go index 3969e3132..6f04d6517 100644 --- a/cmd/podman/generate_kube.go +++ b/cmd/podman/generate_kube.go @@ -62,7 +62,7 @@ func generateKubeYAMLCmd(c *cliconfig.GenerateKubeValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) podYAML, serviceYAML, err := runtime.GenerateKube(c) if err != nil { diff --git a/cmd/podman/generate_systemd.go b/cmd/podman/generate_systemd.go index b4779e512..8be097c83 100644 --- a/cmd/podman/generate_systemd.go +++ b/cmd/podman/generate_systemd.go @@ -50,7 +50,7 @@ func generateSystemdCmd(c *cliconfig.GenerateSystemdValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) // User input stop timeout must be 0 or greater if c.Flag("timeout").Changed && c.StopTimeout < 0 { diff --git a/cmd/podman/healthcheck_run.go b/cmd/podman/healthcheck_run.go index aaeed93c6..66ca4580a 100644 --- a/cmd/podman/healthcheck_run.go +++ b/cmd/podman/healthcheck_run.go @@ -42,6 +42,7 @@ func healthCheckCmd(c *cliconfig.HealthCheckValues) error { if err != nil { return errors.Wrap(err, "could not get runtime") } + defer runtime.DeferredShutdown(false) status, err := runtime.HealthCheck(c) fmt.Println(status) return err diff --git a/cmd/podman/history.go b/cmd/podman/history.go index 0998a023c..fea2219bc 100644 --- a/cmd/podman/history.go +++ b/cmd/podman/history.go @@ -71,7 +71,7 @@ func historyCmd(c *cliconfig.HistoryValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) format := genHistoryFormat(c.Format, c.Quiet) diff --git a/cmd/podman/images.go b/cmd/podman/images.go index 33cf11ab7..f842573d9 100644 --- a/cmd/podman/images.go +++ b/cmd/podman/images.go @@ -138,7 +138,7 @@ func imagesCmd(c *cliconfig.ImagesValues) error { if err != nil { return errors.Wrapf(err, "Could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if len(c.InputArgs) == 1 { image = c.InputArgs[0] } diff --git a/cmd/podman/images_prune.go b/cmd/podman/images_prune.go index 1ac5bc65d..5745edd6b 100644 --- a/cmd/podman/images_prune.go +++ b/cmd/podman/images_prune.go @@ -41,7 +41,7 @@ func pruneImagesCmd(c *cliconfig.PruneImagesValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) // Call prune; if any cids are returned, print them and then // return err in case an error also came up diff --git a/cmd/podman/import.go b/cmd/podman/import.go index 167d9f2c9..70ea167cb 100644 --- a/cmd/podman/import.go +++ b/cmd/podman/import.go @@ -49,7 +49,7 @@ func importCmd(c *cliconfig.ImportValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) var ( source string diff --git a/cmd/podman/info.go b/cmd/podman/info.go index e24fe3c77..ed60970b6 100644 --- a/cmd/podman/info.go +++ b/cmd/podman/info.go @@ -55,7 +55,7 @@ func infoCmd(c *cliconfig.InfoValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) infoArr, err := runtime.Info() if err != nil { @@ -97,9 +97,7 @@ func infoCmd(c *cliconfig.InfoValues) error { out = formats.StdoutTemplate{Output: info, Template: infoOutputFormat} } - formats.Writer(out).Out() - - return nil + return formats.Writer(out).Out() } // top-level "debug" info diff --git a/cmd/podman/init.go b/cmd/podman/init.go index 68c80631d..3f97824fc 100644 --- a/cmd/podman/init.go +++ b/cmd/podman/init.go @@ -54,7 +54,7 @@ func initCmd(c *cliconfig.InitValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ok, failures, err := runtime.InitContainers(ctx, c) if err != nil { diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go index 24edfcb68..df597c868 100644 --- a/cmd/podman/inspect.go +++ b/cmd/podman/inspect.go @@ -88,7 +88,7 @@ func inspectCmd(c *cliconfig.InspectValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if !util.StringInSlice(inspectType, []string{inspectTypeContainer, inspectTypeImage, inspectAll}) { return errors.Errorf("the only recognized types are %q, %q, and %q", inspectTypeContainer, inspectTypeImage, inspectAll) @@ -193,8 +193,8 @@ func iterateInput(ctx context.Context, size bool, args []string, runtime *adapte inspectError = errors.Wrapf(err, "error getting libpod container inspect data %s", ctr.ID()) break } - artifact, inspectError := getArtifact(ctr) - if inspectError != nil { + artifact, err := getArtifact(ctr) + if err != nil { inspectError = err break } diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go index edf69ff2e..d5056d86d 100644 --- a/cmd/podman/kill.go +++ b/cmd/podman/kill.go @@ -63,7 +63,7 @@ func killCmd(c *cliconfig.KillValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ok, failures, err := runtime.KillContainers(getContext(), c, killSignal) if err != nil { diff --git a/cmd/podman/load.go b/cmd/podman/load.go index 0c41eb792..ed6a4e5fa 100644 --- a/cmd/podman/load.go +++ b/cmd/podman/load.go @@ -43,7 +43,7 @@ func init() { // Disabled flags for the remote client if !remote { flags.StringVar(&loadCommand.SignaturePolicy, "signature-policy", "", "Pathname of signature policy file (not usually used)") - flags.MarkHidden("signature-policy") + markFlagHidden(flags, "signature-policy") } } @@ -65,7 +65,7 @@ func loadCmd(c *cliconfig.LoadValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if len(c.Input) > 0 { if err := parse.ValidateFileName(c.Input); err != nil { diff --git a/cmd/podman/logs.go b/cmd/podman/logs.go index 25248db21..32605389e 100644 --- a/cmd/podman/logs.go +++ b/cmd/podman/logs.go @@ -54,8 +54,7 @@ func init() { flags.StringVar(&logsCommand.Since, "since", "", "Show logs since TIMESTAMP") flags.Uint64Var(&logsCommand.Tail, "tail", 0, "Output the specified number of LINES at the end of the logs. Defaults to 0, which prints all lines") flags.BoolVarP(&logsCommand.Timestamps, "timestamps", "t", false, "Output the timestamps in the log") - flags.MarkHidden("details") - + markFlagHidden(flags, "details") flags.SetInterspersed(false) markFlagHiddenForRemoteClient("latest", flags) @@ -68,7 +67,7 @@ func logsCmd(c *cliconfig.LogsValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) sinceTime := time.Time{} if c.Flag("since").Changed { diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go index d5f70a28f..e4f521bc4 100644 --- a/cmd/podman/main_local.go +++ b/cmd/podman/main_local.go @@ -45,14 +45,18 @@ func init() { rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.NetworkCmdPath, "network-cmd-path", "", "Path to the command for configuring the network") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.CniConfigDir, "cni-config-dir", "", "Path of the configuration directory for CNI networks") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.DefaultMountsFile, "default-mounts-file", "", "Path to default mounts file") - rootCmd.PersistentFlags().MarkHidden("defaults-mount-file") + if err := rootCmd.PersistentFlags().MarkHidden("default-mounts-file"); err != nil { + logrus.Error("unable to mark default-mounts-file flag as hidden") + } // Override default --help information of `--help` global flag var dummyHelp bool rootCmd.PersistentFlags().BoolVar(&dummyHelp, "help", false, "Help for podman") rootCmd.PersistentFlags().StringSliceVar(&MainGlobalOpts.HooksDir, "hooks-dir", []string{}, "Set the OCI hooks directory path (may be set multiple times)") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.LogLevel, "log-level", "error", "Log messages above specified level: debug, info, warn, error, fatal or panic") rootCmd.PersistentFlags().IntVar(&MainGlobalOpts.MaxWorks, "max-workers", 0, "The maximum number of workers for parallel operations") - rootCmd.PersistentFlags().MarkHidden("max-workers") + if err := rootCmd.PersistentFlags().MarkHidden("max-workers"); err != nil { + logrus.Error("unable to mark max-workers flag as hidden") + } rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Namespace, "namespace", "", "Set the libpod namespace, used to create separate views of the containers and pods on the system") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Root, "root", "", "Path to the root directory in which data, including images, is stored") rootCmd.PersistentFlags().StringVar(&MainGlobalOpts.Runroot, "runroot", "", "Path to the 'run directory' where all state information is stored") @@ -118,10 +122,10 @@ func setupRootless(cmd *cobra.Command, args []string) error { return nil } podmanCmd := cliconfig.PodmanCommand{ - cmd, - args, - MainGlobalOpts, - remoteclient, + Command: cmd, + InputArgs: args, + GlobalFlags: MainGlobalOpts, + Remote: remoteclient, } pausePidPath, err := util.GetRootlessPauseProcessPidPath() @@ -148,7 +152,7 @@ func setupRootless(cmd *cobra.Command, args []string) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ctrs, err := runtime.GetRunningContainers() if err != nil { diff --git a/cmd/podman/mount.go b/cmd/podman/mount.go index 662fb0a28..b14827592 100644 --- a/cmd/podman/mount.go +++ b/cmd/podman/mount.go @@ -65,7 +65,7 @@ func mountCmd(c *cliconfig.MountValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if os.Geteuid() != 0 { rtc, err := runtime.GetConfig() diff --git a/cmd/podman/pause.go b/cmd/podman/pause.go index ee5fd352d..3a8f4edb5 100644 --- a/cmd/podman/pause.go +++ b/cmd/podman/pause.go @@ -46,7 +46,7 @@ func pauseCmd(c *cliconfig.PauseValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) args := c.InputArgs if len(args) < 1 && !c.All { diff --git a/cmd/podman/play_kube.go b/cmd/podman/play_kube.go index afdb6cc9b..9a5cc3ec1 100644 --- a/cmd/podman/play_kube.go +++ b/cmd/podman/play_kube.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/pkg/adapter" @@ -45,7 +44,7 @@ func init() { flags.StringVar(&playKubeCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.StringVar(&playKubeCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.BoolVar(&playKubeCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - flags.MarkHidden("signature-policy") + markFlagHidden(flags, "signature-policy") } } @@ -63,7 +62,7 @@ func playKubeCmd(c *cliconfig.KubePlayValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) _, err = runtime.PlayKubeYAML(ctx, c, args[0]) return err diff --git a/cmd/podman/pod_create.go b/cmd/podman/pod_create.go index 0abf84756..b6154b4db 100644 --- a/cmd/podman/pod_create.go +++ b/cmd/podman/pod_create.go @@ -8,6 +8,7 @@ import ( "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/adapter" + "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/util" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -56,7 +57,6 @@ func init() { flags.StringVar(&podCreateCommand.Share, "share", shared.DefaultKernelNamespaces, "A comma delimited list of kernel namespaces the pod will share") } - func podCreateCmd(c *cliconfig.PodCreateValues) error { var ( err error @@ -67,7 +67,7 @@ func podCreateCmd(c *cliconfig.PodCreateValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if len(c.Publish) > 0 { if !c.Infra { @@ -86,8 +86,8 @@ func podCreateCmd(c *cliconfig.PodCreateValues) error { if err != nil { return errors.Errorf("error opening pod-id-file %s", c.PodIDFile) } - defer podIdFile.Close() - defer podIdFile.Sync() + defer errorhandling.CloseQuiet(podIdFile) + defer errorhandling.SyncQuiet(podIdFile) } labels, err := shared.GetAllLabels(c.LabelFile, c.Labels) diff --git a/cmd/podman/pod_inspect.go b/cmd/podman/pod_inspect.go index a22624078..03b5a8cc4 100644 --- a/cmd/podman/pod_inspect.go +++ b/cmd/podman/pod_inspect.go @@ -53,7 +53,7 @@ func podInspectCmd(c *cliconfig.PodInspectValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if c.Latest { pod, err = runtime.GetLatestPod() diff --git a/cmd/podman/pod_kill.go b/cmd/podman/pod_kill.go index 6be79363a..9bda77471 100644 --- a/cmd/podman/pod_kill.go +++ b/cmd/podman/pod_kill.go @@ -53,7 +53,7 @@ func podKillCmd(c *cliconfig.PodKillValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) killSignal := uint(syscall.SIGTERM) diff --git a/cmd/podman/pod_pause.go b/cmd/podman/pod_pause.go index e8574bfdc..75d179f52 100644 --- a/cmd/podman/pod_pause.go +++ b/cmd/podman/pod_pause.go @@ -49,7 +49,7 @@ func podPauseCmd(c *cliconfig.PodPauseValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) pauseIDs, conErrors, pauseErrors := runtime.PausePods(c) diff --git a/cmd/podman/pod_ps.go b/cmd/podman/pod_ps.go index fbea5124e..a525857de 100644 --- a/cmd/podman/pod_ps.go +++ b/cmd/podman/pod_ps.go @@ -20,7 +20,7 @@ import ( ) const ( - STOPPED = "Stopped" + STOPPED = "Stopped" //nolint RUNNING = "Running" PAUSED = "Paused" EXITED = "Exited" @@ -36,9 +36,9 @@ var ( ) type podPsCtrInfo struct { - Name string `"json:name,omitempty"` - Id string `"json:id,omitempty"` - Status string `"json:status,omitempty"` + Name string `json:"name,omitempty"` + Id string `json:"id,omitempty"` + Status string `json:"status,omitempty"` } type podPsOptions struct { @@ -161,7 +161,7 @@ func podPsCmd(c *cliconfig.PodPsValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) opts := podPsOptions{ NoTrunc: c.NoTrunc, diff --git a/cmd/podman/pod_restart.go b/cmd/podman/pod_restart.go index a1f4c8359..0b009e6c7 100644 --- a/cmd/podman/pod_restart.go +++ b/cmd/podman/pod_restart.go @@ -51,7 +51,7 @@ func podRestartCmd(c *cliconfig.PodRestartValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) restartIDs, conErrors, restartErrors := runtime.RestartPods(getContext(), c) diff --git a/cmd/podman/pod_rm.go b/cmd/podman/pod_rm.go index 218ed8154..82d0eb977 100644 --- a/cmd/podman/pod_rm.go +++ b/cmd/podman/pod_rm.go @@ -51,7 +51,7 @@ func podRmCmd(c *cliconfig.PodRmValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) podRmIds, podRmErrors := runtime.RemovePods(getContext(), c) for _, p := range podRmIds { diff --git a/cmd/podman/pod_start.go b/cmd/podman/pod_start.go index 5c9225428..64c951b43 100644 --- a/cmd/podman/pod_start.go +++ b/cmd/podman/pod_start.go @@ -49,7 +49,7 @@ func podStartCmd(c *cliconfig.PodStartValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) podStartIDs, podStartErrors := runtime.StartPods(getContext(), c) for _, p := range podStartIDs { diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go index 97aa52f5d..7984f08ee 100644 --- a/cmd/podman/pod_stats.go +++ b/cmd/podman/pod_stats.go @@ -74,16 +74,13 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error { if ctr > 1 { return errors.Errorf("--all, --latest and containers cannot be used together") - } else if ctr == 0 { - // If user didn't specify, imply --all - all = true } runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) times := -1 if c.NoStream { @@ -173,7 +170,9 @@ func podStatsCmd(c *cliconfig.PodStatsValues) error { tm.Flush() } if strings.ToLower(format) == formats.JSONString { - outputJson(newStats) + if err := outputJson(newStats); err != nil { + return err + } } else { results := podContainerStatsToPodStatOut(newStats) @@ -300,17 +299,3 @@ func outputJson(stats []*adapter.PodContainerStats) error { fmt.Println(string(b)) return nil } - -func getPodsByList(podList []string, r *libpod.Runtime) ([]*libpod.Pod, error) { - var ( - pods []*libpod.Pod - ) - for _, p := range podList { - pod, err := r.LookupPod(p) - if err != nil { - return nil, err - } - pods = append(pods, pod) - } - return pods, nil -} diff --git a/cmd/podman/pod_stop.go b/cmd/podman/pod_stop.go index b4b1718d9..edda99550 100644 --- a/cmd/podman/pod_stop.go +++ b/cmd/podman/pod_stop.go @@ -51,7 +51,7 @@ func podStopCmd(c *cliconfig.PodStopValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) podStopIds, podStopErrors := runtime.StopPods(getContext(), c) for _, p := range podStopIds { diff --git a/cmd/podman/pod_top.go b/cmd/podman/pod_top.go index 72137b5a7..fcd9c4f3c 100644 --- a/cmd/podman/pod_top.go +++ b/cmd/podman/pod_top.go @@ -44,8 +44,7 @@ func init() { flags := podTopCommand.Flags() flags.BoolVarP(&podTopCommand.Latest, "latest,", "l", false, "Act on the latest pod podman is aware of") flags.BoolVar(&podTopCommand.ListDescriptors, "list-descriptors", false, "") - flags.MarkHidden("list-descriptors") - + markFlagHidden(flags, "list-descriptors") } func podTopCmd(c *cliconfig.PodTopValues) error { @@ -71,7 +70,7 @@ func podTopCmd(c *cliconfig.PodTopValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if c.Latest { descriptors = args @@ -85,8 +84,9 @@ func podTopCmd(c *cliconfig.PodTopValues) error { return err } for _, proc := range psOutput { - fmt.Fprintln(w, proc) + if _, err := fmt.Fprintln(w, proc); err != nil { + return err + } } - w.Flush() - return nil + return w.Flush() } diff --git a/cmd/podman/pod_unpause.go b/cmd/podman/pod_unpause.go index c5b7e6a18..91c3bfdf8 100644 --- a/cmd/podman/pod_unpause.go +++ b/cmd/podman/pod_unpause.go @@ -50,7 +50,7 @@ func podUnpauseCmd(c *cliconfig.PodUnpauseValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) unpauseIDs, conErrors, unpauseErrors := runtime.UnpausePods(c) diff --git a/cmd/podman/pods_prune.go b/cmd/podman/pods_prune.go index bdd75f9de..d40e37bdb 100644 --- a/cmd/podman/pods_prune.go +++ b/cmd/podman/pods_prune.go @@ -40,8 +40,11 @@ func podPruneCmd(c *cliconfig.PodPruneValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ok, failures, err := runtime.PrunePods(getContext(), c) + if err != nil { + return err + } return printCmdResults(ok, failures) } diff --git a/cmd/podman/port.go b/cmd/podman/port.go index 1bd2d623e..5753c8e56 100644 --- a/cmd/podman/port.go +++ b/cmd/podman/port.go @@ -95,9 +95,12 @@ func portCmd(c *cliconfig.PortValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) containers, err := runtime.Port(c) + if err != nil { + return err + } for _, con := range containers { portmappings, err := con.PortMappings() if err != nil { diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go index 75e07d325..26cc55e5f 100644 --- a/cmd/podman/ps.go +++ b/cmd/podman/ps.go @@ -15,87 +15,32 @@ import ( "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/pkg/adapter" - "github.com/cri-o/ocicni/pkg/ocicni" "github.com/docker/go-units" "github.com/pkg/errors" "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/fields" ) const ( - mountTruncLength = 12 - hid = "CONTAINER ID" - himage = "IMAGE" - hcommand = "COMMAND" - hcreated = "CREATED" - hstatus = "STATUS" - hports = "PORTS" - hnames = "NAMES" - hsize = "SIZE" - hinfra = "IS INFRA" - hpod = "POD" - nspid = "PID" - nscgroup = "CGROUPNS" - nsipc = "IPC" - nsmnt = "MNT" - nsnet = "NET" - nspidns = "PIDNS" - nsuserns = "USERNS" - nsuts = "UTS" + hid = "CONTAINER ID" + himage = "IMAGE" + hcommand = "COMMAND" + hcreated = "CREATED" + hstatus = "STATUS" + hports = "PORTS" + hnames = "NAMES" + hsize = "SIZE" + hinfra = "IS INFRA" //nolint + hpod = "POD" + nspid = "PID" + nscgroup = "CGROUPNS" + nsipc = "IPC" + nsmnt = "MNT" + nsnet = "NET" + nspidns = "PIDNS" + nsuserns = "USERNS" + nsuts = "UTS" ) -type psTemplateParams struct { - ID string - Image string - Command string - CreatedAtTime time.Time - Created string - Status string - Ports string - Size string - Names string - Labels string - Mounts string - PID int - CGROUPNS string - IPC string - MNT string - NET string - PIDNS string - USERNS string - UTS string - Pod string - IsInfra bool -} - -// psJSONParams is used as a base structure for the psParams -// If template output is requested, psJSONParams will be converted to -// psTemplateParams. -// psJSONParams will be populated by data from libpod.Container, -// the members of the struct are the sama data types as their sources. -type psJSONParams struct { - ID string `json:"id"` - Image string `json:"image"` - ImageID string `json:"image_id"` - Command []string `json:"command"` - ExitCode int32 `json:"exitCode"` - Exited bool `json:"exited"` - CreatedAt time.Time `json:"createdAt"` - StartedAt time.Time `json:"startedAt"` - ExitedAt time.Time `json:"exitedAt"` - Status string `json:"status"` - PID int `json:"PID"` - Ports []ocicni.PortMapping `json:"ports"` - Size *shared.ContainerSize `json:"size,omitempty"` - Names string `json:"names"` - Labels fields.Set `json:"labels"` - Mounts []string `json:"mounts"` - ContainerRunning bool `json:"ctrRunning"` - Namespaces *shared.Namespace `json:"namespace,omitempty"` - Pod string `json:"pod,omitempty"` - IsInfra bool `json:"infra"` -} - // Type declaration and functions for sorting the PS output type psSorted []shared.PsContainerOutput @@ -223,7 +168,7 @@ func psCmd(c *cliconfig.PsValues) error { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if !watch { if err := psDisplay(c, runtime); err != nil { @@ -273,22 +218,6 @@ func checkFlagsPassed(c *cliconfig.PsValues) error { return nil } -// generate the accurate header based on template given -func (p *psTemplateParams) headerMap() map[string]string { - v := reflect.Indirect(reflect.ValueOf(p)) - values := make(map[string]string) - - for i := 0; i < v.NumField(); i++ { - key := v.Type().Field(i).Name - value := key - if value == "ID" { - value = "Container" + value - } - values[key] = strings.ToUpper(splitCamelCase(value)) - } - return values -} - func sortPsOutput(sortBy string, psOutput psSorted) (psSorted, error) { switch sortBy { case "id": diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go index 61cf1fd4d..0eee51e79 100644 --- a/cmd/podman/pull.go +++ b/cmd/podman/pull.go @@ -60,7 +60,7 @@ func init() { flags.StringVar(&pullCommand.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") flags.StringVar(&pullCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.BoolVar(&pullCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - flags.MarkHidden("signature-policy") + markFlagHidden(flags, "signature-policy") } } @@ -82,7 +82,7 @@ func pullCmd(c *cliconfig.PullValues) (retError error) { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) args := c.InputArgs if len(args) == 0 { diff --git a/cmd/podman/push.go b/cmd/podman/push.go index a15d8e699..43df8c2de 100644 --- a/cmd/podman/push.go +++ b/cmd/podman/push.go @@ -63,7 +63,7 @@ func init() { flags.BoolVar(&pushCommand.Compress, "compress", false, "Compress tarball image layers when pushing to a directory using the 'dir' transport. (default is same compression type as source)") flags.StringVar(&pushCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.BoolVar(&pushCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - flags.MarkHidden("signature-policy") + markFlagHidden(flags, "signature-policy") } } @@ -109,7 +109,7 @@ func pushCmd(c *cliconfig.PushValues) error { if err != nil { return errors.Wrapf(err, "could not create runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) var writer io.Writer if !c.Quiet { diff --git a/cmd/podman/refresh.go b/cmd/podman/refresh.go index 9f9cbf908..b21a4ff79 100644 --- a/cmd/podman/refresh.go +++ b/cmd/podman/refresh.go @@ -42,7 +42,7 @@ func refreshCmd(c *cliconfig.RefreshValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) allCtrs, err := runtime.GetAllContainers() if err != nil { diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go index 89bda7d6c..494a9ec06 100644 --- a/cmd/podman/restart.go +++ b/cmd/podman/restart.go @@ -55,7 +55,7 @@ func restartCmd(c *cliconfig.RestartValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ok, failures, err := runtime.Restart(getContext(), c) if err != nil { diff --git a/cmd/podman/restore.go b/cmd/podman/restore.go index fcac9855d..c4146eff0 100644 --- a/cmd/podman/restore.go +++ b/cmd/podman/restore.go @@ -58,7 +58,7 @@ func restoreCmd(c *cliconfig.RestoreValues, cmd *cobra.Command) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if c.Import == "" && c.Name != "" { return errors.Errorf("--name can only used with --import") diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go index 0f81a0d63..958ca1c60 100644 --- a/cmd/podman/rm.go +++ b/cmd/podman/rm.go @@ -54,7 +54,7 @@ func rmCmd(c *cliconfig.RmValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) // Storage conflicts with --all/--latest/--volumes if c.Storage { diff --git a/cmd/podman/rmi.go b/cmd/podman/rmi.go index 4c41a3ad5..9229d497e 100644 --- a/cmd/podman/rmi.go +++ b/cmd/podman/rmi.go @@ -55,7 +55,7 @@ func rmiCmd(c *cliconfig.RmiValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) args := c.InputArgs if len(args) == 0 && !removeAll { diff --git a/cmd/podman/run.go b/cmd/podman/run.go index 6f089e5a4..76ab3d944 100644 --- a/cmd/podman/run.go +++ b/cmd/podman/run.go @@ -37,7 +37,6 @@ func init() { flags.Bool("sig-proxy", true, "Proxy received signals to the process") getCreateFlags(&runCommand.PodmanCommand) markFlagHiddenForRemoteClient("authfile", flags) - flags.MarkHidden("signature-policy") } func runCmd(c *cliconfig.RunValues) error { @@ -54,7 +53,7 @@ func runCmd(c *cliconfig.RunValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) exitCode, err = runtime.Run(getContext(), c, exitCode) return err diff --git a/cmd/podman/runlabel.go b/cmd/podman/runlabel.go index fdbf7fa8f..db6d390d5 100644 --- a/cmd/podman/runlabel.go +++ b/cmd/podman/runlabel.go @@ -53,10 +53,9 @@ func init() { flags.StringVar(&runlabelCommand.Opt1, "opt1", "", "Optional parameter to pass for install") flags.StringVar(&runlabelCommand.Opt2, "opt2", "", "Optional parameter to pass for install") flags.StringVar(&runlabelCommand.Opt3, "opt3", "", "Optional parameter to pass for install") - flags.MarkHidden("opt1") - flags.MarkHidden("opt2") - flags.MarkHidden("opt3") - + markFlagHidden(flags, "opt1") + markFlagHidden(flags, "opt2") + markFlagHidden(flags, "opt3") flags.BoolP("pull", "p", false, "Pull the image if it does not exist locally prior to executing the label contents") flags.BoolVarP(&runlabelCommand.Quiet, "quiet", "q", false, "Suppress output information when installing images") // Disabled flags for the remote client @@ -66,10 +65,11 @@ func init() { flags.StringVar(&runlabelCommand.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") flags.BoolVar(&runlabelCommand.TlsVerify, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - flags.MarkDeprecated("pull", "podman will pull if not found in local storage") - flags.MarkHidden("signature-policy") + if err := flags.MarkDeprecated("pull", "podman will pull if not found in local storage"); err != nil { + logrus.Error("unable to mark pull flag deprecated") + } + markFlagHidden(flags, "signature-policy") } - markFlagHiddenForRemoteClient("authfile", flags) } // installCmd gets the data from the command line and calls installImage @@ -95,7 +95,7 @@ func runlabelCmd(c *cliconfig.RunlabelValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) args := c.InputArgs if len(args) < 2 { diff --git a/cmd/podman/save.go b/cmd/podman/save.go index e59c9df5f..237ebde03 100644 --- a/cmd/podman/save.go +++ b/cmd/podman/save.go @@ -74,7 +74,7 @@ func saveCmd(c *cliconfig.SaveValues) error { if err != nil { return errors.Wrapf(err, "could not create runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if c.Flag("compress").Changed && (c.Format != ociManifestDir && c.Format != v2s2ManifestDir && c.Format == "") { return errors.Errorf("--compress can only be set when --format is either 'oci-dir' or 'docker-dir'") diff --git a/cmd/podman/search.go b/cmd/podman/search.go index f1c625ee1..be75b6e37 100644 --- a/cmd/podman/search.go +++ b/cmd/podman/search.go @@ -13,11 +13,6 @@ import ( "github.com/spf13/cobra" ) -const ( - descriptionTruncLength = 44 - maxQueries = 25 -) - var ( searchCommand cliconfig.SearchValues searchDescription = `Search registries for a given image. Can search all the default registries or a specific registry. @@ -89,8 +84,7 @@ func searchCmd(c *cliconfig.SearchValues) error { return nil } out := formats.StdoutTemplateArray{Output: searchToGeneric(results), Template: format, Fields: searchHeaderMap()} - formats.Writer(out).Out() - return nil + return formats.Writer(out).Out() } // searchHeaderMap returns the headers of a SearchResult. diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go index 64cef1e89..f401d3cf5 100644 --- a/cmd/podman/shared/create.go +++ b/cmd/podman/shared/create.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/containers/libpod/pkg/errorhandling" "io" "os" "path/filepath" @@ -63,8 +64,8 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod. if err != nil { return nil, nil, errors.Errorf("error opening cidfile %s", c.String("cidfile")) } - defer cidFile.Close() - defer cidFile.Sync() + defer errorhandling.CloseQuiet(cidFile) + defer errorhandling.SyncQuiet(cidFile) } imageName := "" @@ -82,6 +83,9 @@ func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod. return nil, nil, err } data, err = newImage.Inspect(ctx) + if err != nil { + return nil, nil, err + } names := newImage.Names() if len(names) > 0 { imageName = names[0] diff --git a/cmd/podman/sign.go b/cmd/podman/sign.go index 0c25eec62..1333cf441 100644 --- a/cmd/podman/sign.go +++ b/cmd/podman/sign.go @@ -60,7 +60,7 @@ func signCmd(c *cliconfig.SignValues) error { if err != nil { return errors.Wrapf(err, "could not create runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) signby := c.SignBy if signby == "" { diff --git a/cmd/podman/start.go b/cmd/podman/start.go index 165273114..737a6d9f1 100644 --- a/cmd/podman/start.go +++ b/cmd/podman/start.go @@ -69,7 +69,7 @@ func startCmd(c *cliconfig.StartValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) exitCode, err = runtime.Start(getContext(), c, sigProxy) return err } diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go index d79eebc3d..a1ec20b37 100644 --- a/cmd/podman/stats.go +++ b/cmd/podman/stats.go @@ -93,7 +93,7 @@ func statsCmd(c *cliconfig.StatsValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) times := -1 if c.NoStream { @@ -175,7 +175,9 @@ func statsCmd(c *cliconfig.StatsValues) error { tm.MoveCursor(1, 1) tm.Flush() } - outputStats(reportStats, format) + if err := outputStats(reportStats, format); err != nil { + return err + } time.Sleep(time.Second) } return nil diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go index 5c93904ef..e04d8a12b 100644 --- a/cmd/podman/stop.go +++ b/cmd/podman/stop.go @@ -60,7 +60,7 @@ func stopCmd(c *cliconfig.StopValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ok, failures, err := runtime.StopContainers(getContext(), c) if err != nil { diff --git a/cmd/podman/system_df.go b/cmd/podman/system_df.go index ab67e4f07..85554bf05 100644 --- a/cmd/podman/system_df.go +++ b/cmd/podman/system_df.go @@ -106,7 +106,7 @@ func dfSystemCmd(c *cliconfig.SystemDfValues) error { if err != nil { return errors.Wrapf(err, "Could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ctx := getContext() @@ -131,11 +131,10 @@ func dfSystemCmd(c *cliconfig.SystemDfValues) error { if c.Format != "" { format = strings.Replace(c.Format, `\t`, "\t", -1) } - generateSysDfOutput(systemDfDiskUsages, format) - return nil + return generateSysDfOutput(systemDfDiskUsages, format) } -func generateSysDfOutput(systemDfDiskUsages []systemDfDiskUsage, format string) { +func generateSysDfOutput(systemDfDiskUsages []systemDfDiskUsage, format string) error { var systemDfHeader = map[string]string{ "Type": "TYPE", "Total": "TOTAL", @@ -144,7 +143,7 @@ func generateSysDfOutput(systemDfDiskUsages []systemDfDiskUsage, format string) "Reclaimable": "RECLAIMABLE", } out := formats.StdoutTemplateArray{Output: systemDfDiskUsageToGeneric(systemDfDiskUsages), Template: format, Fields: systemDfHeader} - formats.Writer(out).Out() + return formats.Writer(out).Out() } func getDiskUsage(ctx context.Context, runtime *libpod.Runtime, metaData dfMetaData) ([]systemDfDiskUsage, error) { @@ -554,10 +553,11 @@ func imagesVerboseOutput(ctx context.Context, metaData dfMetaData) error { if err != nil { return errors.Wrapf(err, "error getting verbose output of images") } - os.Stderr.WriteString("Images space usage:\n\n") + if _, err := os.Stderr.WriteString("Images space usage:\n\n"); err != nil { + return err + } out := formats.StdoutTemplateArray{Output: systemDfImageVerboseDiskUsageToGeneric(imagesVerboseDiskUsage), Template: imageVerboseFormat, Fields: imageVerboseHeader} - formats.Writer(out).Out() - return nil + return formats.Writer(out).Out() } func containersVerboseOutput(ctx context.Context, metaData dfMetaData) error { @@ -575,10 +575,12 @@ func containersVerboseOutput(ctx context.Context, metaData dfMetaData) error { if err != nil { return errors.Wrapf(err, "error getting verbose output of containers") } - os.Stderr.WriteString("\nContainers space usage:\n\n") + if _, err := os.Stderr.WriteString("\nContainers space usage:\n\n"); err != nil { + return err + } out := formats.StdoutTemplateArray{Output: systemDfContainerVerboseDiskUsageToGeneric(containersVerboseDiskUsage), Template: containerVerboseFormat, Fields: containerVerboseHeader} - formats.Writer(out).Out() - return nil + return formats.Writer(out).Out() + } func volumesVerboseOutput(ctx context.Context, metaData dfMetaData) error { @@ -591,10 +593,11 @@ func volumesVerboseOutput(ctx context.Context, metaData dfMetaData) error { if err != nil { return errors.Wrapf(err, "error getting verbose output of volumes") } - os.Stderr.WriteString("\nLocal Volumes space usage:\n\n") + if _, err := os.Stderr.WriteString("\nLocal Volumes space usage:\n\n"); err != nil { + return err + } out := formats.StdoutTemplateArray{Output: systemDfVolumeVerboseDiskUsageToGeneric(volumesVerboseDiskUsage), Template: volumeVerboseFormat, Fields: volumeVerboseHeader} - formats.Writer(out).Out() - return nil + return formats.Writer(out).Out() } func verboseOutput(ctx context.Context, metaData dfMetaData) error { diff --git a/cmd/podman/system_prune.go b/cmd/podman/system_prune.go index d5b218cd8..b499d8dd2 100644 --- a/cmd/podman/system_prune.go +++ b/cmd/podman/system_prune.go @@ -76,27 +76,33 @@ Are you sure you want to continue? [y/N] `, volumeString) if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) - - rmWorkers := shared.Parallelize("rm") - ctx := getContext() - fmt.Println("Deleted Containers") - ok, failures, lasterr := runtime.Prune(ctx, rmWorkers, false) - printCmdResults(ok, failures) + defer runtime.DeferredShutdown(false) + // We must clean out pods first because if they may have infra containers fmt.Println("Deleted Pods") pruneValues := cliconfig.PodPruneValues{ PodmanCommand: c.PodmanCommand, Force: c.Force, } - ok, failures, err = runtime.PrunePods(ctx, &pruneValues) + ctx := getContext() + ok, failures, lasterr := runtime.PrunePods(ctx, &pruneValues) + + if err := printCmdResults(ok, failures); err != nil { + return err + } + + rmWorkers := shared.Parallelize("rm") + fmt.Println("Deleted Containers") + ok, failures, err = runtime.Prune(ctx, rmWorkers, false) if err != nil { if lasterr != nil { - logrus.Errorf("%q", lasterr) + logrus.Errorf("%q", err) } lasterr = err } - printCmdResults(ok, failures) + if err := printCmdResults(ok, failures); err != nil { + return err + } if c.Bool("volumes") { fmt.Println("Deleted Volumes") diff --git a/cmd/podman/tag.go b/cmd/podman/tag.go index 58f221e26..eb43d695c 100644 --- a/cmd/podman/tag.go +++ b/cmd/podman/tag.go @@ -42,7 +42,7 @@ func tagCmd(c *cliconfig.TagValues) error { if err != nil { return errors.Wrapf(err, "could not create runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) newImage, err := runtime.NewImageFromLocal(args[0]) if err != nil { diff --git a/cmd/podman/top.go b/cmd/podman/top.go index ba6cbe72d..bfba90fc0 100644 --- a/cmd/podman/top.go +++ b/cmd/podman/top.go @@ -57,7 +57,7 @@ func init() { flags := topCommand.Flags() flags.SetInterspersed(false) flags.BoolVar(&topCommand.ListDescriptors, "list-descriptors", false, "") - flags.MarkHidden("list-descriptors") + markFlagHidden(flags, "list-descriptors") flags.BoolVarP(&topCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") markFlagHiddenForRemoteClient("latest", flags) } @@ -83,7 +83,7 @@ func topCmd(c *cliconfig.TopValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) psOutput, err := runtime.Top(c) if err != nil { @@ -91,8 +91,9 @@ func topCmd(c *cliconfig.TopValues) error { } w := tabwriter.NewWriter(os.Stdout, 5, 1, 3, ' ', 0) for _, proc := range psOutput { - fmt.Fprintln(w, proc) + if _, err := fmt.Fprintln(w, proc); err != nil { + return err + } } - w.Flush() - return nil + return w.Flush() } diff --git a/cmd/podman/tree.go b/cmd/podman/tree.go index 48e192990..c13dffd6e 100644 --- a/cmd/podman/tree.go +++ b/cmd/podman/tree.go @@ -55,7 +55,7 @@ func treeCmd(c *cliconfig.TreeValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) imageInfo, layerInfoMap, img, err := runtime.Tree(c) if err != nil { return err diff --git a/cmd/podman/trust_set_show.go b/cmd/podman/trust_set_show.go index b615f6266..d6f0eabd8 100644 --- a/cmd/podman/trust_set_show.go +++ b/cmd/podman/trust_set_show.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/containers/buildah/pkg/formats" - "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/libpod/image" @@ -57,7 +56,7 @@ func init() { showTrustCommand.SetUsageTemplate(UsageTemplate()) setFlags := setTrustCommand.Flags() setFlags.StringVar(&setTrustCommand.PolicyPath, "policypath", "", "") - setFlags.MarkHidden("policypath") + markFlagHidden(setFlags, "policypath") setFlags.StringSliceVarP(&setTrustCommand.PubKeysFile, "pubkeysfile", "f", []string{}, `Path of installed public key(s) to trust for TARGET. Absolute path to keys is added to policy.json. May used multiple times to define multiple public keys. @@ -68,9 +67,9 @@ File(s) must exist before using this command`) showFlags.BoolVarP(&showTrustCommand.Json, "json", "j", false, "Output as json") showFlags.StringVar(&showTrustCommand.PolicyPath, "policypath", "", "") showFlags.BoolVar(&showTrustCommand.Raw, "raw", false, "Output raw policy file") - showFlags.MarkHidden("policypath") + markFlagHidden(showFlags, "policypath") showFlags.StringVar(&showTrustCommand.RegistryPath, "registrypath", "", "") - showFlags.MarkHidden("registrypath") + markFlagHidden(showFlags, "registrypath") } func showTrustCmd(c *cliconfig.ShowTrustValues) error { @@ -238,10 +237,6 @@ func isValidTrustType(t string) bool { return false } -func getDefaultPolicyPath() string { - return trust.DefaultPolicyPath(&types.SystemContext{}) -} - func getPolicyJSON(policyContentStruct trust.PolicyContent, systemRegistriesDirPath string) (map[string]map[string]interface{}, error) { registryConfigs, err := trust.LoadAndMergeConfig(systemRegistriesDirPath) if err != nil { diff --git a/cmd/podman/umount.go b/cmd/podman/umount.go index ddbd00bd5..c3d81d3a8 100644 --- a/cmd/podman/umount.go +++ b/cmd/podman/umount.go @@ -52,7 +52,7 @@ func umountCmd(c *cliconfig.UmountValues) error { if err != nil { return errors.Wrapf(err, "error creating runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ok, failures, err := runtime.UmountRootFilesystems(getContext(), c) if err != nil { diff --git a/cmd/podman/unpause.go b/cmd/podman/unpause.go index 8126ebfbd..382b64e97 100644 --- a/cmd/podman/unpause.go +++ b/cmd/podman/unpause.go @@ -45,7 +45,7 @@ func unpauseCmd(c *cliconfig.UnpauseValues) error { if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) args := c.InputArgs if len(args) < 1 && !c.All { diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go index 986db469e..0790f673a 100644 --- a/cmd/podman/utils.go +++ b/cmd/podman/utils.go @@ -3,27 +3,12 @@ package main import ( "fmt" "reflect" + "runtime/debug" + "github.com/sirupsen/logrus" "github.com/spf13/pflag" ) -// printParallelOutput takes the map of parallel worker results and outputs them -// to stdout -func printParallelOutput(m map[string]error, errCount int) error { - var lastError error - for cid, result := range m { - if result != nil { - if errCount > 1 { - fmt.Println(result.Error()) - } - lastError = result - continue - } - fmt.Println(cid) - } - return lastError -} - // print results from CLI command func printCmdResults(ok []string, failures map[string]error) error { for _, id := range ok { @@ -48,6 +33,17 @@ func printCmdResults(ok []string, failures map[string]error) error { // on the remote-client func markFlagHiddenForRemoteClient(flagName string, flags *pflag.FlagSet) { if remoteclient { - flags.MarkHidden(flagName) + if err := flags.MarkHidden(flagName); err != nil { + debug.PrintStack() + logrus.Errorf("unable to mark %s as hidden in the remote-client", flagName) + } + } +} + +// markFlagHidden is a helper function to log an error if marking +// a flag as hidden happens to fail +func markFlagHidden(flags *pflag.FlagSet, flag string) { + if err := flags.MarkHidden(flag); err != nil { + logrus.Errorf("unable to mark flag '%s' as hidden: %q", flag, err) } } diff --git a/cmd/podman/varlink.go b/cmd/podman/varlink.go index 698a30d84..92315cd6b 100644 --- a/cmd/podman/varlink.go +++ b/cmd/podman/varlink.go @@ -83,7 +83,7 @@ func varlinkCmd(c *cliconfig.VarlinkValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) var varlinkInterfaces = []*iopodman.VarlinkInterface{varlinkapi.New(&c.PodmanCommand, runtime)} // Register varlink service. The metadata can be retrieved with: diff --git a/cmd/podman/version.go b/cmd/podman/version.go index a078ba2fe..6a88993c1 100644 --- a/cmd/podman/version.go +++ b/cmd/podman/version.go @@ -42,7 +42,7 @@ func init() { func versionCmd(c *cliconfig.VersionValues) error { clientVersion, err := define.GetVersion() if err != nil { - errors.Wrapf(err, "unable to determine version") + return errors.Wrapf(err, "unable to determine version") } versionOutputFormat := c.Format @@ -63,18 +63,22 @@ func versionCmd(c *cliconfig.VersionValues) error { defer w.Flush() if remote { - fmt.Fprintf(w, "Client:\n") + if _, err := fmt.Fprintf(w, "Client:\n"); err != nil { + return err + } } formatVersion(w, clientVersion) if remote { - fmt.Fprintf(w, "\nService:\n") + if _, err := fmt.Fprintf(w, "\nService:\n"); err != nil { + return err + } runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) serviceVersion, err := runtime.GetVersion() if err != nil { diff --git a/cmd/podman/volume_create.go b/cmd/podman/volume_create.go index 84f6bba94..0897ab705 100644 --- a/cmd/podman/volume_create.go +++ b/cmd/podman/volume_create.go @@ -46,7 +46,7 @@ func volumeCreateCmd(c *cliconfig.VolumeCreateValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) if len(c.InputArgs) > 1 { return errors.Errorf("too many arguments, create takes at most 1 argument") diff --git a/cmd/podman/volume_inspect.go b/cmd/podman/volume_inspect.go index e4b05f96a..1ebc5ce60 100644 --- a/cmd/podman/volume_inspect.go +++ b/cmd/podman/volume_inspect.go @@ -47,7 +47,7 @@ func volumeInspectCmd(c *cliconfig.VolumeInspectValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) vols, err := runtime.InspectVolumes(getContext(), c) if err != nil { diff --git a/cmd/podman/volume_ls.go b/cmd/podman/volume_ls.go index 581e595cb..7248caf0c 100644 --- a/cmd/podman/volume_ls.go +++ b/cmd/podman/volume_ls.go @@ -76,7 +76,7 @@ func volumeLsCmd(c *cliconfig.VolumeLsValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) opts := volumeLsOptions{ Quiet: c.Quiet, diff --git a/cmd/podman/volume_prune.go b/cmd/podman/volume_prune.go index 6dc9e2403..daea5a4d2 100644 --- a/cmd/podman/volume_prune.go +++ b/cmd/podman/volume_prune.go @@ -67,7 +67,7 @@ func volumePruneCmd(c *cliconfig.VolumePruneValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) // Prompt for confirmation if --force is not set if !c.Force { diff --git a/cmd/podman/volume_rm.go b/cmd/podman/volume_rm.go index 77137eb7a..0141d06da 100644 --- a/cmd/podman/volume_rm.go +++ b/cmd/podman/volume_rm.go @@ -51,7 +51,7 @@ func volumeRmCmd(c *cliconfig.VolumeRmValues) error { if err != nil { return errors.Wrapf(err, "error creating libpod runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) deletedVolumeNames, err := runtime.RemoveVolumes(getContext(), c) if err != nil { if len(deletedVolumeNames) > 0 { diff --git a/cmd/podman/wait.go b/cmd/podman/wait.go index 380e861ed..d6a707bb8 100644 --- a/cmd/podman/wait.go +++ b/cmd/podman/wait.go @@ -55,7 +55,7 @@ func waitCmd(c *cliconfig.WaitValues) error { if err != nil { return errors.Wrapf(err, "error creating runtime") } - defer runtime.Shutdown(false) + defer runtime.DeferredShutdown(false) ok, failures, err := runtime.WaitOnContainers(getContext(), c, interval) if err != nil { diff --git a/docs/podman-stats.1.md b/docs/podman-stats.1.md index b817662a8..b71d435fa 100644 --- a/docs/podman-stats.1.md +++ b/docs/podman-stats.1.md @@ -39,7 +39,7 @@ Valid placeholders for the Go template are listed below: | **Placeholder** | **Description** | | --------------- | --------------- | | .Pod | Pod ID | -| .CID | Container ID | +| .ID | Container ID | | .Name | Container Name | | .CPU | CPU percentage | | .MemUsage | Memory usage | diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go index 4dda3a7f0..176781f07 100644 --- a/libpod/boltdb_state.go +++ b/libpod/boltdb_state.go @@ -66,7 +66,7 @@ func NewBoltState(path string, runtime *Runtime) (State, error) { if err != nil { return nil, errors.Wrapf(err, "error opening database %s", path) } - // Everywhere else, we use s.closeDBCon(db) to ensure the state's DB + // Everywhere else, we use s.deferredCloseDBCon(db) to ensure the state's DB // mutex is also unlocked. // However, here, the mutex has not been locked, since we just created // the DB connection, and it hasn't left this function yet - no risk of @@ -141,7 +141,7 @@ func (s *BoltState) Refresh() error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { idBucket, err := getIDBucket(tx) @@ -253,7 +253,7 @@ func (s *BoltState) GetDBConfig() (*DBConfig, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { configBucket, err := getRuntimeConfigBucket(tx) @@ -298,7 +298,7 @@ func (s *BoltState) ValidateDBConfig(runtime *Runtime) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) // Check runtime configuration if err := checkRuntimeConfig(db, runtime); err != nil { @@ -342,7 +342,7 @@ func (s *BoltState) Container(id string) (*Container, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { ctrBucket, err := getCtrBucket(tx) @@ -378,7 +378,7 @@ func (s *BoltState) LookupContainer(idOrName string) (*Container, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { ctrBucket, err := getCtrBucket(tx) @@ -484,7 +484,7 @@ func (s *BoltState) HasContainer(id string) (bool, error) { if err != nil { return false, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) exists := false @@ -549,7 +549,7 @@ func (s *BoltState) RemoveContainer(ctr *Container) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { return s.removeContainer(ctr, nil, tx) @@ -580,7 +580,7 @@ func (s *BoltState) UpdateContainer(ctr *Container) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { ctrBucket, err := getCtrBucket(tx) @@ -651,7 +651,7 @@ func (s *BoltState) SaveContainer(ctr *Container) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { ctrBucket, err := getCtrBucket(tx) @@ -708,7 +708,7 @@ func (s *BoltState) ContainerInUse(ctr *Container) ([]string, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { ctrBucket, err := getCtrBucket(tx) @@ -759,7 +759,7 @@ func (s *BoltState) AllContainers() ([]*Container, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { allCtrsBucket, err := getAllCtrsBucket(tx) @@ -833,7 +833,7 @@ func (s *BoltState) RewriteContainerConfig(ctr *Container, newCfg *ContainerConf if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { ctrBkt, err := getCtrBucket(tx) @@ -877,7 +877,7 @@ func (s *BoltState) RewritePodConfig(pod *Pod, newCfg *PodConfig) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -920,7 +920,7 @@ func (s *BoltState) Pod(id string) (*Pod, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -955,7 +955,7 @@ func (s *BoltState) LookupPod(idOrName string) (*Pod, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -1062,7 +1062,7 @@ func (s *BoltState) HasPod(id string) (bool, error) { if err != nil { return false, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -1118,7 +1118,7 @@ func (s *BoltState) PodHasContainer(pod *Pod, id string) (bool, error) { if err != nil { return false, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -1180,7 +1180,7 @@ func (s *BoltState) PodContainersByID(pod *Pod) ([]string, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -1242,7 +1242,7 @@ func (s *BoltState) PodContainers(pod *Pod) ([]*Container, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -1312,7 +1312,7 @@ func (s *BoltState) AddVolume(volume *Volume) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { volBkt, err := getVolBucket(tx) @@ -1369,7 +1369,7 @@ func (s *BoltState) RemoveVolume(volume *Volume) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { volBkt, err := getVolBucket(tx) @@ -1451,7 +1451,7 @@ func (s *BoltState) AllVolumes() ([]*Volume, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { allVolsBucket, err := getAllVolsBucket(tx) @@ -1512,7 +1512,7 @@ func (s *BoltState) Volume(name string) (*Volume, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { volBkt, err := getVolBucket(tx) @@ -1547,7 +1547,7 @@ func (s *BoltState) HasVolume(name string) (bool, error) { if err != nil { return false, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { volBkt, err := getVolBucket(tx) @@ -1587,7 +1587,7 @@ func (s *BoltState) VolumeInUse(volume *Volume) ([]string, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { volBucket, err := getVolBucket(tx) @@ -1673,7 +1673,7 @@ func (s *BoltState) AddPod(pod *Pod) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -1782,7 +1782,7 @@ func (s *BoltState) RemovePod(pod *Pod) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -1877,7 +1877,7 @@ func (s *BoltState) RemovePodContainers(pod *Pod) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { podBkt, err := getPodBucket(tx) @@ -2038,7 +2038,7 @@ func (s *BoltState) RemoveContainerFromPod(pod *Pod, ctr *Container) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { return s.removeContainer(ctr, pod, tx) @@ -2066,7 +2066,7 @@ func (s *BoltState) UpdatePod(pod *Pod) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) podID := []byte(pod.ID()) @@ -2126,7 +2126,7 @@ func (s *BoltState) SavePod(pod *Pod) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) podID := []byte(pod.ID()) @@ -2168,7 +2168,7 @@ func (s *BoltState) AllPods() ([]*Pod, error) { if err != nil { return nil, err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.View(func(tx *bolt.Tx) error { allPodsBucket, err := getAllPodsBucket(tx) diff --git a/libpod/boltdb_state_internal.go b/libpod/boltdb_state_internal.go index ee2784cdd..408ef7224 100644 --- a/libpod/boltdb_state_internal.go +++ b/libpod/boltdb_state_internal.go @@ -247,6 +247,15 @@ func (s *BoltState) getDBCon() (*bolt.DB, error) { return db, nil } +// deferredCloseDBCon closes the bolt db but instead of returning an +// error it logs the error. it is meant to be used within the confines +// of a defer statement only +func (s *BoltState) deferredCloseDBCon(db *bolt.DB) { + if err := s.closeDBCon(db); err != nil { + logrus.Errorf("failed to close libpod db: %q", err) + } +} + // Close a connection to the database. // MUST be used in place of `db.Close()` to ensure proper unlocking of the // state. @@ -479,7 +488,7 @@ func (s *BoltState) addContainer(ctr *Container, pod *Pod) error { if err != nil { return err } - defer s.closeDBCon(db) + defer s.deferredCloseDBCon(db) err = db.Update(func(tx *bolt.Tx) error { idsBucket, err := getIDBucket(tx) diff --git a/libpod/container_attach_linux.go b/libpod/container_attach_linux.go index 17b09fccc..43dd7d579 100644 --- a/libpod/container_attach_linux.go +++ b/libpod/container_attach_linux.go @@ -10,6 +10,7 @@ import ( "path/filepath" "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/kubeutils" "github.com/containers/libpod/utils" "github.com/docker/docker/pkg/term" @@ -66,7 +67,7 @@ func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSi logrus.Debugf("Could not open ctl file: %v", err) return } - defer controlFile.Close() + defer errorhandling.CloseQuiet(controlFile) logrus.Debugf("Received a resize event: %+v", size) if _, err = fmt.Fprintf(controlFile, "%d %d %d\n", 1, size.Height, size.Width); err != nil { @@ -108,7 +109,9 @@ func (c *Container) attachContainerSocket(resize <-chan remotecommand.TerminalSi var err error if streams.AttachInput { _, err = utils.CopyDetachable(conn, streams.InputStream, detachKeys) - conn.CloseWrite() + if err := conn.CloseWrite(); err != nil { + logrus.Error("failed to close write in attach") + } } stdinDone <- err }() diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 686a595de..aa477611f 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -636,6 +636,7 @@ func (c *Container) checkpoint(ctx context.Context, options ContainerCheckpointO } } + c.state.FinishedTime = time.Now() return c.save() } diff --git a/libpod/image/image.go b/libpod/image/image.go index 76e46f74f..6509134ac 100644 --- a/libpod/image/image.go +++ b/libpod/image/image.go @@ -323,7 +323,7 @@ func (i *Image) Names() []string { // RepoDigests returns a string array of repodigests associated with the image func (i *Image) RepoDigests() ([]string, error) { var repoDigests []string - digest := i.Digest() + imageDigest := i.Digest() for _, name := range i.Names() { named, err := reference.ParseNormalizedNamed(name) @@ -331,7 +331,7 @@ func (i *Image) RepoDigests() ([]string, error) { return nil, err } - canonical, err := reference.WithDigest(reference.TrimNamed(named), digest) + canonical, err := reference.WithDigest(reference.TrimNamed(named), imageDigest) if err != nil { return nil, err } @@ -462,11 +462,11 @@ func getImageDigest(ctx context.Context, src types.ImageReference, sc *types.Sys return "", err } defer newImg.Close() - digest := newImg.ConfigInfo().Digest - if err = digest.Validate(); err != nil { + imageDigest := newImg.ConfigInfo().Digest + if err = imageDigest.Validate(); err != nil { return "", errors.Wrapf(err, "error getting config info") } - return "@" + digest.Hex(), nil + return "@" + imageDigest.Hex(), nil } // normalizedTag returns the canonical version of tag for use in Image.Names() @@ -495,7 +495,9 @@ func normalizedTag(tag string) (reference.Named, error) { // TagImage adds a tag to the given image func (i *Image) TagImage(tag string) error { - i.reloadImage() + if err := i.reloadImage(); err != nil { + return err + } ref, err := normalizedTag(tag) if err != nil { return err @@ -508,14 +510,18 @@ func (i *Image) TagImage(tag string) error { if err := i.imageruntime.store.SetNames(i.ID(), tags); err != nil { return err } - i.reloadImage() + if err := i.reloadImage(); err != nil { + return err + } defer i.newImageEvent(events.Tag) return nil } // UntagImage removes a tag from the given image func (i *Image) UntagImage(tag string) error { - i.reloadImage() + if err := i.reloadImage(); err != nil { + return err + } var newTags []string tags := i.Names() if !util.StringInSlice(tag, tags) { @@ -529,7 +535,9 @@ func (i *Image) UntagImage(tag string) error { if err := i.imageruntime.store.SetNames(i.ID(), newTags); err != nil { return err } - i.reloadImage() + if err := i.reloadImage(); err != nil { + return err + } defer i.newImageEvent(events.Untag) return nil } @@ -825,7 +833,7 @@ func (i *Image) GetLabel(ctx context.Context, label string) (string, error) { // Annotations returns the annotations of an image func (i *Image) Annotations(ctx context.Context) (map[string]string, error) { - manifest, manifestType, err := i.Manifest(ctx) + imageManifest, manifestType, err := i.Manifest(ctx) if err != nil { return nil, err } @@ -833,7 +841,7 @@ func (i *Image) Annotations(ctx context.Context) (map[string]string, error) { switch manifestType { case ociv1.MediaTypeImageManifest: var m ociv1.Manifest - if err := json.Unmarshal(manifest, &m); err == nil { + if err := json.Unmarshal(imageManifest, &m); err == nil { for k, v := range m.Annotations { annotations[k] = v } diff --git a/libpod/image/pull.go b/libpod/image/pull.go index e5765febc..ce8a19fbc 100644 --- a/libpod/image/pull.go +++ b/libpod/image/pull.go @@ -263,7 +263,9 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa copyOptions.SourceCtx.SystemRegistriesConfPath = systemRegistriesConfPath // FIXME: Set this more globally. Probably no reason not to have it in every types.SystemContext, and to compute the value just once in one place. // Print the following statement only when pulling from a docker or atomic registry if writer != nil && (imageInfo.srcRef.Transport().Name() == DockerTransport || imageInfo.srcRef.Transport().Name() == AtomicTransport) { - io.WriteString(writer, fmt.Sprintf("Trying to pull %s...", imageInfo.image)) + if _, err := io.WriteString(writer, fmt.Sprintf("Trying to pull %s...", imageInfo.image)); err != nil { + return nil, err + } } // If the label is not nil, check if the label exists and if not, return err if label != nil { @@ -277,7 +279,7 @@ func (ir *Runtime) doPullImage(ctx context.Context, sc *types.SystemContext, goa pullErrors = multierror.Append(pullErrors, err) logrus.Errorf("Error pulling image ref %s: %v", imageInfo.srcRef.StringWithinTransport(), err) if writer != nil { - io.WriteString(writer, "Failed\n") + _, _ = io.WriteString(writer, "Failed\n") } } else { if !goal.pullAllPairs { diff --git a/libpod/image/search.go b/libpod/image/search.go index 03a67636b..9984e5234 100644 --- a/libpod/image/search.go +++ b/libpod/image/search.go @@ -99,7 +99,9 @@ func SearchImages(term string, options SearchOptions) ([]SearchResult, error) { ctx := context.Background() for i := range registries { - sem.Acquire(ctx, 1) + if err := sem.Acquire(ctx, 1); err != nil { + return nil, err + } go searchImageInRegistryHelper(i, registries[i]) } diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index d978bceed..987c1fc5b 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -5,6 +5,7 @@ package libpod import ( "crypto/rand" "fmt" + "github.com/containers/libpod/pkg/errorhandling" "net" "os" "os/exec" @@ -168,8 +169,8 @@ func (r *Runtime) setupRootlessNetNS(ctr *Container) (err error) { if err != nil { return errors.Wrapf(err, "failed to open pipe") } - defer syncR.Close() - defer syncW.Close() + defer errorhandling.CloseQuiet(syncR) + defer errorhandling.CloseQuiet(syncW) havePortMapping := len(ctr.Config().PortMappings) > 0 apiSocket := filepath.Join(ctr.ociRuntime.tmpDir, fmt.Sprintf("%s.net", ctr.config.ID)) diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go index 802f4311b..ca13d5517 100644 --- a/libpod/oci_linux.go +++ b/libpod/oci_linux.go @@ -17,6 +17,7 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/pkg/cgroups" + "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/util" "github.com/containers/libpod/utils" @@ -117,7 +118,7 @@ func (r *OCIRuntime) createContainer(ctr *Container, cgroupParent string, restor if err != nil { return err } - defer fd.Close() + defer errorhandling.CloseQuiet(fd) // create a new mountns on the current thread if err = unix.Unshare(unix.CLONE_NEWNS); err != nil { @@ -207,8 +208,8 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res return errors.Wrapf(err, "error creating socket pair for start pipe") } - defer parentPipe.Close() - defer parentStartPipe.Close() + defer errorhandling.CloseQuiet(parentPipe) + defer errorhandling.CloseQuiet(parentStartPipe) ociLog := filepath.Join(ctr.state.RunDir, "oci-log") logLevel := logrus.GetLevel() @@ -364,20 +365,26 @@ func (r *OCIRuntime) createOCIContainer(ctr *Container, cgroupParent string, res err = cmd.Start() // Ignore error returned from SetProcessLabel("") call, // can't recover. - label.SetProcessLabel("") + if err := label.SetProcessLabel(""); err != nil { + _ = err + } runtime.UnlockOSThread() } else { err = cmd.Start() } if err != nil { - childPipe.Close() + errorhandling.CloseQuiet(childPipe) return err } defer cmd.Wait() // We don't need childPipe on the parent side - childPipe.Close() - childStartPipe.Close() + if err := childPipe.Close(); err != nil { + return err + } + if err := childStartPipe.Close(); err != nil { + return err + } // Move conmon to specified cgroup if err := r.moveConmonToCgroup(ctr, cgroupParent, cmd); err != nil { diff --git a/libpod/runtime.go b/libpod/runtime.go index 53c9a1209..9196547a2 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -1162,6 +1162,13 @@ func (r *Runtime) GetConfig() (*RuntimeConfig, error) { return config, nil } +// DeferredShutdown shuts down the runtime without exposing any +// errors. This is only meant to be used when the runtime is being +// shutdown within a defer statement; else use Shutdown +func (r *Runtime) DeferredShutdown(force bool) { + _ = r.Shutdown(force) +} + // Shutdown shuts down the runtime and associated containers and storage // If force is true, containers and mounted storage will be shut down before // cleaning up; if force is false, an error will be returned if there are diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index ae9b3e5bc..760a07daf 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -439,9 +439,12 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool, } } else { if err := r.state.RemoveContainer(c); err != nil { - cleanupErr = err + if cleanupErr == nil { + cleanupErr = err + } else { + logrus.Errorf("removing container: %v", err) + } } - logrus.Errorf("removing container: %v", err) } // Set container as invalid so it can no longer be used diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index 0ea89a72c..1cf9d686a 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -95,8 +95,8 @@ func (r *LocalRuntime) StopContainers(ctx context.Context, cli *cliconfig.StopVa } pool.Add(shared.Job{ - c.ID(), - func() error { + ID: c.ID(), + Fn: func() error { err := c.StopWithTimeout(*timeout) if err != nil { if errors.Cause(err) == define.ErrCtrStopped { @@ -134,8 +134,8 @@ func (r *LocalRuntime) KillContainers(ctx context.Context, cli *cliconfig.KillVa c := c pool.Add(shared.Job{ - c.ID(), - func() error { + ID: c.ID(), + Fn: func() error { return c.Kill(uint(signal)) }, }) @@ -163,8 +163,8 @@ func (r *LocalRuntime) InitContainers(ctx context.Context, cli *cliconfig.InitVa ctr := c pool.Add(shared.Job{ - ctr.ID(), - func() error { + ID: ctr.ID(), + Fn: func() error { err := ctr.Init(ctx) if err != nil { // If we're initializing all containers, ignore invalid state errors diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go index 800ed7569..db3f23629 100644 --- a/pkg/adapter/runtime_remote.go +++ b/pkg/adapter/runtime_remote.go @@ -97,6 +97,14 @@ func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*LocalRuntime, }, nil } +// DeferredShutdown is a bogus wrapper for compaat with the libpod +// runtime and should only be run when a defer is being used +func (r RemoteRuntime) DeferredShutdown(force bool) { + if err := r.Shutdown(force); err != nil { + logrus.Error("unable to shutdown runtime") + } +} + // Shutdown is a bogus wrapper for compat with the libpod runtime func (r RemoteRuntime) Shutdown(force bool) error { return nil diff --git a/pkg/adapter/sigproxy_linux.go b/pkg/adapter/sigproxy_linux.go index af968cb89..efa6afa7b 100644 --- a/pkg/adapter/sigproxy_linux.go +++ b/pkg/adapter/sigproxy_linux.go @@ -27,7 +27,9 @@ func ProxySignals(ctr *libpod.Container) { if err := ctr.Kill(uint(s.(syscall.Signal))); err != nil { logrus.Errorf("Error forwarding signal %d to container %s: %v", s, ctr.ID(), err) signal.StopCatch(sigBuffer) - syscall.Kill(syscall.Getpid(), s.(syscall.Signal)) + if err := syscall.Kill(syscall.Getpid(), s.(syscall.Signal)); err != nil { + logrus.Errorf("failed to kill pid %d", syscall.Getpid()) + } } } }() diff --git a/pkg/adapter/terminal_linux.go b/pkg/adapter/terminal_linux.go index 3c4c3bd38..be7dc0cb6 100644 --- a/pkg/adapter/terminal_linux.go +++ b/pkg/adapter/terminal_linux.go @@ -35,7 +35,9 @@ func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, } logrus.SetFormatter(&RawTtyFormatter{}) - term.SetRawTerminal(os.Stdin.Fd()) + if _, err := term.SetRawTerminal(os.Stdin.Fd()); err != nil { + return err + } defer restoreTerminal(oldTermState) } diff --git a/pkg/channelwriter/channelwriter.go b/pkg/channelwriter/channelwriter.go new file mode 100644 index 000000000..d51400eb3 --- /dev/null +++ b/pkg/channelwriter/channelwriter.go @@ -0,0 +1,34 @@ +package channelwriter + +import "github.com/pkg/errors" + +// Writer is an io.writer-like object that "writes" to a channel +// instead of a buffer or file, etc. It is handy for varlink endpoints when +// needing to handle endpoints that do logging "real-time" +type Writer struct { + ByteChannel chan []byte +} + +// NewChannelWriter creates a new channel writer and adds a +// byte slice channel into it. +func NewChannelWriter() *Writer { + byteChannel := make(chan []byte) + return &Writer{ + ByteChannel: byteChannel, + } +} + +// Write method for Writer +func (c *Writer) Write(w []byte) (int, error) { + if c.ByteChannel == nil { + return 0, errors.New("channel writer channel cannot be nil") + } + c.ByteChannel <- w + return len(w), nil +} + +// Close method for Writer +func (c *Writer) Close() error { + close(c.ByteChannel) + return nil +} diff --git a/pkg/errorhandling/errorhandling.go b/pkg/errorhandling/errorhandling.go new file mode 100644 index 000000000..970d47636 --- /dev/null +++ b/pkg/errorhandling/errorhandling.go @@ -0,0 +1,23 @@ +package errorhandling + +import ( + "os" + + "github.com/sirupsen/logrus" +) + +// SyncQuiet syncs a file and logs any error. Should only be used within +// a defer. +func SyncQuiet(f *os.File) { + if err := f.Sync(); err != nil { + logrus.Errorf("unable to sync file %s: %q", f.Name(), err) + } +} + +// CloseQuiet closes a file and logs any error. Should only be used within +// a defer. +func CloseQuiet(f *os.File) { + if err := f.Close(); err != nil { + logrus.Errorf("unable to close file %s: %q", f.Name(), err) + } +} diff --git a/pkg/firewall/firewalld.go b/pkg/firewall/firewalld.go index 32c2337a0..15e845cb7 100644 --- a/pkg/firewall/firewalld.go +++ b/pkg/firewall/firewalld.go @@ -18,6 +18,7 @@ package firewall import ( "fmt" + "github.com/sirupsen/logrus" "strings" "github.com/godbus/dbus" @@ -113,7 +114,9 @@ func (fb *fwdBackend) Del(conf *FirewallNetConf) error { // Remove firewalld rules which assigned the given source IP to the given zone firewalldObj := fb.conn.Object(firewalldName, firewalldPath) var res string - firewalldObj.Call(firewalldZoneInterface+"."+firewalldRemoveSourceMethod, 0, getFirewalldZone(conf), ipStr).Store(&res) + if err := firewalldObj.Call(firewalldZoneInterface+"."+firewalldRemoveSourceMethod, 0, getFirewalldZone(conf), ipStr).Store(&res); err != nil { + logrus.Errorf("unable to store firewallobj") + } } return nil } diff --git a/pkg/firewall/iptables.go b/pkg/firewall/iptables.go index 59d81b287..92d249f7b 100644 --- a/pkg/firewall/iptables.go +++ b/pkg/firewall/iptables.go @@ -21,6 +21,7 @@ package firewall import ( "fmt" + "github.com/sirupsen/logrus" "net" "github.com/coreos/go-iptables/iptables" @@ -53,7 +54,9 @@ func generateFilterRule(privChainName string) []string { func cleanupRules(ipt *iptables.IPTables, privChainName string, rules [][]string) { for _, rule := range rules { - ipt.Delete("filter", privChainName, rule...) + if err := ipt.Delete("filter", privChainName, rule...); err != nil { + logrus.Errorf("failed to delete iptables rule %s", privChainName) + } } } @@ -185,7 +188,9 @@ func (ib *iptablesBackend) Add(conf *FirewallNetConf) error { func (ib *iptablesBackend) Del(conf *FirewallNetConf) error { for proto, ipt := range ib.protos { - ib.delRules(conf, ipt, proto) + if err := ib.delRules(conf, ipt, proto); err != nil { + logrus.Errorf("failed to delete iptables backend rule %s", conf.IptablesAdminChainName) + } } return nil } diff --git a/pkg/hooks/exec/exec.go b/pkg/hooks/exec/exec.go index 0dd091561..4038e3d94 100644 --- a/pkg/hooks/exec/exec.go +++ b/pkg/hooks/exec/exec.go @@ -5,6 +5,7 @@ import ( "bytes" "context" "fmt" + "github.com/sirupsen/logrus" "io" osexec "os/exec" "time" @@ -54,7 +55,9 @@ func Run(ctx context.Context, hook *rspec.Hook, state []byte, stdout io.Writer, case err = <-exit: return err, err case <-ctx.Done(): - cmd.Process.Kill() + if err := cmd.Process.Kill(); err != nil { + logrus.Errorf("failed to kill pid %v", cmd.Process) + } timer := time.NewTimer(postKillTimeout) defer timer.Stop() select { diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go index 0f684750e..89e4e5686 100644 --- a/pkg/logs/logs.go +++ b/pkg/logs/logs.go @@ -30,6 +30,7 @@ import ( "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/errorhandling" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -153,7 +154,7 @@ func ReadLogs(logPath string, ctr *libpod.Container, opts *LogOptions) error { if err != nil { return errors.Wrapf(err, "failed to open log file %q", logPath) } - defer file.Close() + defer errorhandling.CloseQuiet(file) msg := &logMessage{} opts.bytes = -1 @@ -161,9 +162,9 @@ func ReadLogs(logPath string, ctr *libpod.Container, opts *LogOptions) error { reader := bufio.NewReader(file) if opts.Follow { - followLog(reader, writer, opts, ctr, msg, logPath) + err = followLog(reader, writer, opts, ctr, msg, logPath) } else { - dumpLog(reader, writer, opts, msg, logPath) + err = dumpLog(reader, writer, opts, msg, logPath) } return err } diff --git a/pkg/netns/netns_linux.go b/pkg/netns/netns_linux.go index a72a2d098..4a515c72a 100644 --- a/pkg/netns/netns_linux.go +++ b/pkg/netns/netns_linux.go @@ -83,7 +83,9 @@ func NewNS() (ns.NetNS, error) { if err != nil { return nil, err } - mountPointFd.Close() + if err := mountPointFd.Close(); err != nil { + return nil, err + } // Ensure the mount point is cleaned up on errors; if the namespace // was successfully mounted this will have no effect because the file diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go index 8028a359c..d7c2de81d 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -17,6 +17,7 @@ import ( "syscall" "unsafe" + "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/storage/pkg/idtools" "github.com/docker/docker/pkg/signal" "github.com/godbus/dbus" @@ -41,8 +42,7 @@ const ( ) func runInUser() error { - os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done") - return nil + return os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done") } var ( @@ -57,9 +57,15 @@ func IsRootless() bool { rootlessGIDInit := int(C.rootless_gid()) if rootlessUIDInit != 0 { // This happens if we joined the user+mount namespace as part of - os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done") - os.Setenv("_CONTAINERS_ROOTLESS_UID", fmt.Sprintf("%d", rootlessUIDInit)) - os.Setenv("_CONTAINERS_ROOTLESS_GID", fmt.Sprintf("%d", rootlessGIDInit)) + if err := os.Setenv("_CONTAINERS_USERNS_CONFIGURED", "done"); err != nil { + logrus.Errorf("failed to set environment variable %s as %s", "_CONTAINERS_USERNS_CONFIGURED", "done") + } + if err := os.Setenv("_CONTAINERS_ROOTLESS_UID", fmt.Sprintf("%d", rootlessUIDInit)); err != nil { + logrus.Errorf("failed to set environment variable %s as %d", "_CONTAINERS_ROOTLESS_UID", rootlessUIDInit) + } + if err := os.Setenv("_CONTAINERS_ROOTLESS_GID", fmt.Sprintf("%d", rootlessGIDInit)); err != nil { + logrus.Errorf("failed to set environment variable %s as %d", "_CONTAINERS_ROOTLESS_GID", rootlessGIDInit) + } } isRootless = os.Geteuid() != 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" }) @@ -185,18 +191,24 @@ func getUserNSFirstChild(fd uintptr) (*os.File, error) { } if ns == currentNS { - syscall.Close(int(nextFd)) + if err := syscall.Close(int(nextFd)); err != nil { + return nil, err + } // Drop O_CLOEXEC for the fd. _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, fd, syscall.F_SETFD, 0) if errno != 0 { - syscall.Close(int(fd)) + if err := syscall.Close(int(fd)); err != nil { + logrus.Errorf("failed to close file descriptor %d", fd) + } return nil, errno } return os.NewFile(fd, "userns child"), nil } - syscall.Close(int(fd)) + if err := syscall.Close(int(fd)); err != nil { + return nil, err + } fd = nextFd } } @@ -252,7 +264,9 @@ func EnableLinger() (string, error) { if lingerEnabled && lingerFile != "" { f, err := os.Create(lingerFile) if err == nil { - f.Close() + if err := f.Close(); err != nil { + logrus.Errorf("failed to close %s", f.Name()) + } } else { logrus.Debugf("could not create linger file: %v", err) } @@ -348,8 +362,8 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool, } r, w := os.NewFile(uintptr(fds[0]), "sync host"), os.NewFile(uintptr(fds[1]), "sync child") - defer r.Close() - defer w.Close() + defer errorhandling.CloseQuiet(r) + defer errorhandling.CloseQuiet(w) defer w.Write([]byte("0")) pidC := C.reexec_in_user_namespace(C.int(r.Fd()), cPausePid, cFileToRead, fileOutputFD) @@ -361,9 +375,9 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool, var uids, gids []idtools.IDMap username := os.Getenv("USER") if username == "" { - user, err := user.LookupId(fmt.Sprintf("%d", os.Getuid())) + userID, err := user.LookupId(fmt.Sprintf("%d", os.Getuid())) if err == nil { - username = user.Username + username = userID.Username } } mappings, err := idtools.NewIDMappings(username, username) @@ -458,7 +472,9 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool, continue } - syscall.Kill(int(pidC), s.(syscall.Signal)) + if err := syscall.Kill(int(pidC), s.(syscall.Signal)); err != nil { + logrus.Errorf("failed to kill %d", int(pidC)) + } } }() @@ -519,17 +535,19 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st r, w := os.NewFile(uintptr(fds[0]), "read file"), os.NewFile(uintptr(fds[1]), "write file") - defer w.Close() - defer r.Close() + defer errorhandling.CloseQuiet(w) + defer errorhandling.CloseQuiet(r) if _, _, err := becomeRootInUserNS("", path, w); err != nil { lastErr = err continue } - w.Close() + if err := w.Close(); err != nil { + return false, 0, err + } defer func() { - r.Close() + errorhandling.CloseQuiet(r) C.reexec_in_user_namespace_wait(-1, 0) }() diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index 06d1ac12d..5cc021bf5 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -475,7 +475,9 @@ func addPidNS(config *CreateConfig, g *generate.Generator) error { func addUserNS(config *CreateConfig, g *generate.Generator) error { if IsNS(string(config.UsernsMode)) { - g.AddOrReplaceLinuxNamespace(spec.UserNamespace, NS(string(config.UsernsMode))) + if err := g.AddOrReplaceLinuxNamespace(spec.UserNamespace, NS(string(config.UsernsMode))); err != nil { + return err + } // runc complains if no mapping is specified, even if we join another ns. So provide a dummy mapping g.AddLinuxUIDMapping(uint32(0), uint32(0), uint32(1)) @@ -483,7 +485,9 @@ func addUserNS(config *CreateConfig, g *generate.Generator) error { } if (len(config.IDMappings.UIDMap) > 0 || len(config.IDMappings.GIDMap) > 0) && !config.UsernsMode.IsHost() { - g.AddOrReplaceLinuxNamespace(spec.UserNamespace, "") + if err := g.AddOrReplaceLinuxNamespace(spec.UserNamespace, ""); err != nil { + return err + } } return nil } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index 9e49f08a0..fba34a337 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -12,12 +12,14 @@ import ( "github.com/BurntSushi/toml" "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/namespaces" "github.com/containers/libpod/pkg/rootless" "github.com/containers/storage" "github.com/containers/storage/pkg/idtools" "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/spf13/pflag" "golang.org/x/crypto/ssh/terminal" ) @@ -272,16 +274,20 @@ func getTomlStorage(storeOptions *storage.StoreOptions) *tomlConfig { // WriteStorageConfigFile writes the configuration to a file func WriteStorageConfigFile(storageOpts *storage.StoreOptions, storageConf string) error { - os.MkdirAll(filepath.Dir(storageConf), 0755) - file, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) + if err := os.MkdirAll(filepath.Dir(storageConf), 0755); err != nil { + return err + } + storageFile, err := os.OpenFile(storageConf, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) if err != nil { return errors.Wrapf(err, "cannot open %s", storageConf) } tomlConfiguration := getTomlStorage(storageOpts) - defer file.Close() - enc := toml.NewEncoder(file) + defer errorhandling.CloseQuiet(storageFile) + enc := toml.NewEncoder(storageFile) if err := enc.Encode(tomlConfiguration); err != nil { - os.Remove(storageConf) + if err := os.Remove(storageConf); err != nil { + logrus.Errorf("unable to remove file %s", storageConf) + } return err } return nil diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go index 99c9e4f1e..af55689a6 100644 --- a/pkg/util/utils_supported.go +++ b/pkg/util/utils_supported.go @@ -13,6 +13,7 @@ import ( "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" + "github.com/sirupsen/logrus" ) // GetRootlessRuntimeDir returns the runtime directory when running as non root @@ -24,7 +25,9 @@ func GetRootlessRuntimeDir() (string, error) { uid := fmt.Sprintf("%d", rootless.GetRootlessUID()) if runtimeDir == "" { tmpDir := filepath.Join("/run", "user", uid) - os.MkdirAll(tmpDir, 0700) + if err := os.MkdirAll(tmpDir, 0700); err != nil { + logrus.Errorf("unable to make temp dir %s", tmpDir) + } st, err := os.Stat(tmpDir) if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { runtimeDir = tmpDir @@ -32,7 +35,9 @@ func GetRootlessRuntimeDir() (string, error) { } if runtimeDir == "" { tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid)) - os.MkdirAll(tmpDir, 0700) + if err := os.MkdirAll(tmpDir, 0700); err != nil { + logrus.Errorf("unable to make temp dir %s", tmpDir) + } st, err := os.Stat(tmpDir) if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 { runtimeDir = tmpDir diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 0e2ad6bbf..2bebfd406 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -25,6 +25,7 @@ import ( "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/channelwriter" "github.com/containers/libpod/pkg/util" "github.com/containers/libpod/utils" "github.com/containers/storage/pkg/archive" @@ -495,9 +496,19 @@ func (i *LibpodAPI) DeleteUnusedImages(call iopodman.VarlinkCall) error { // Commit ... func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, changes []string, author, message string, pause bool, manifestType string) error { - var newImage *image.Image + var ( + newImage *image.Image + log []string + mimeType string + ) + output := channelwriter.NewChannelWriter() + channelClose := func() { + if err := output.Close(); err != nil { + logrus.Errorf("failed to close channel writer: %q", err) + } + } + defer channelClose() - output := bytes.NewBuffer([]byte{}) ctr, err := i.Runtime.LookupContainer(name) if err != nil { return call.ReplyContainerNotFound(name, err.Error()) @@ -507,7 +518,6 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch return call.ReplyErrorOccurred(err.Error()) } sc := image.GetSystemContext(rtc.SignaturePolicyPath, "", false) - var mimeType string switch manifestType { case "oci", "": //nolint mimeType = buildah.OCIv1ImageManifest @@ -535,6 +545,7 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch } c := make(chan error) + defer close(c) go func() { newImage, err = ctr.Commit(getContext(), imageName, options) @@ -542,48 +553,22 @@ func (i *LibpodAPI) Commit(call iopodman.VarlinkCall, name, imageName string, ch c <- err } c <- nil - close(c) }() - var log []string - done := false - for { - line, err := output.ReadString('\n') - if err == nil { - log = append(log, line) - continue - } else if err == io.EOF { - select { - case err := <-c: - if err != nil { - logrus.Errorf("reading of output during commit failed for %s", name) - return call.ReplyErrorOccurred(err.Error()) - } - done = true - default: - if !call.WantsMore() { - break - } - br := iopodman.MoreResponse{ - Logs: log, - } - call.ReplyCommit(br) - log = []string{} - } - } else { - return call.ReplyErrorOccurred(err.Error()) - } - if done { - break - } + // reply is the func being sent to the output forwarder. in this case it is replying + // with a more response struct + reply := func(br iopodman.MoreResponse) error { + return call.ReplyCommit(br) + } + log, err = forwardOutput(log, c, call.WantsMore(), output, reply) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) } call.Continues = false - br := iopodman.MoreResponse{ Logs: log, Id: newImage.ID(), } - return call.ReplyCommit(br) } @@ -636,6 +621,7 @@ func (i *LibpodAPI) ExportImage(call iopodman.VarlinkCall, name, destination str func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error { var ( imageID string + err error ) dockerRegistryOptions := image.DockerRegistryOptions{} so := image.SigningOptions{} @@ -643,8 +629,16 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error { if call.WantsMore() { call.Continues = true } - output := bytes.NewBuffer([]byte{}) + output := channelwriter.NewChannelWriter() + channelClose := func() { + if err := output.Close(); err != nil { + logrus.Errorf("failed to close channel writer: %q", err) + } + } + defer channelClose() c := make(chan error) + defer close(c) + go func() { if strings.HasPrefix(name, dockerarchive.Transport.Name()+":") { srcRef, err := alltransports.ParseImageName(name) @@ -666,43 +660,17 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error { } } c <- nil - close(c) }() var log []string - done := false - for { - line, err := output.ReadString('\n') - if err == nil { - log = append(log, line) - continue - } else if err == io.EOF { - select { - case err := <-c: - if err != nil { - logrus.Errorf("reading of output during pull failed for %s", name) - return call.ReplyErrorOccurred(err.Error()) - } - done = true - default: - if !call.WantsMore() { - break - } - br := iopodman.MoreResponse{ - Logs: log, - } - call.ReplyPullImage(br) - log = []string{} - } - } else { - return call.ReplyErrorOccurred(err.Error()) - } - if done { - break - } + reply := func(br iopodman.MoreResponse) error { + return call.ReplyPullImage(br) + } + log, err = forwardOutput(log, c, call.WantsMore(), output, reply) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) } call.Continues = false - br := iopodman.MoreResponse{ Logs: log, Id: imageID, diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go index a74105795..e8f74e6aa 100644 --- a/pkg/varlinkapi/util.go +++ b/pkg/varlinkapi/util.go @@ -13,6 +13,7 @@ import ( "github.com/containers/libpod/cmd/podman/varlink" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/define" + "github.com/containers/libpod/pkg/channelwriter" "github.com/containers/storage/pkg/archive" ) @@ -196,3 +197,42 @@ func makePsOpts(inOpts iopodman.PsOpts) shared.PsOptions { Sync: derefBool(inOpts.Sync), } } + +// forwardOutput is a helper method for varlink endpoints that employ both more and without +// more. it is capable of sending updates as the output writer gets them or append them +// all to a log. the chan error is the error from the libpod call so we can honor +// and error event in that case. +func forwardOutput(log []string, c chan error, wantsMore bool, output *channelwriter.Writer, reply func(br iopodman.MoreResponse) error) ([]string, error) { + done := false + for { + select { + // We need to check if the libpod func being called has returned an + // error yet + case err := <-c: + if err != nil { + return nil, err + } + done = true + // if no error is found, we pull what we can from the log writer and + // append it to log string slice + case line := <-output.ByteChannel: + log = append(log, string(line)) + // If the end point is being used in more mode, send what we have + if wantsMore { + br := iopodman.MoreResponse{ + Logs: log, + } + if err := reply(br); err != nil { + return nil, err + } + // "reset" the log to empty because we are sending what we + // get as we get it + log = []string{} + } + } + if done { + break + } + } + return log, nil +} diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go index 45511edb8..4000ab33a 100644 --- a/test/e2e/stats_test.go +++ b/test/e2e/stats_test.go @@ -65,7 +65,7 @@ var _ = Describe("Podman stats", func() { session := podmanTest.RunTopContainer("") session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) - session = podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "\"{{.Container}}\""}) + session = podmanTest.Podman([]string{"stats", "--all", "--no-stream", "--format", "\"{{.ID}}\""}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) }) diff --git a/vendor/modules.txt b/vendor/modules.txt index 62d2ebc9d..ad2f69976 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -537,18 +537,18 @@ gopkg.in/yaml.v2 # k8s.io/api v0.0.0-20190624085159-95846d7ef82a k8s.io/api/core/v1 # k8s.io/apimachinery v0.0.0-20190624085041-961b39a1baa0 -k8s.io/apimachinery/pkg/fields k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/apimachinery/pkg/util/wait k8s.io/apimachinery/pkg/util/runtime -k8s.io/apimachinery/pkg/selection k8s.io/apimachinery/pkg/api/resource k8s.io/apimachinery/pkg/runtime k8s.io/apimachinery/pkg/runtime/schema k8s.io/apimachinery/pkg/types k8s.io/apimachinery/pkg/util/intstr k8s.io/apimachinery/pkg/conversion +k8s.io/apimachinery/pkg/fields k8s.io/apimachinery/pkg/labels +k8s.io/apimachinery/pkg/selection k8s.io/apimachinery/pkg/watch k8s.io/apimachinery/pkg/util/httpstream k8s.io/apimachinery/pkg/util/remotecommand |