diff options
Diffstat (limited to 'cmd/podman')
-rw-r--r-- | cmd/podman/containers/ps.go | 12 | ||||
-rw-r--r-- | cmd/podman/containers/runlabel.go | 5 | ||||
-rw-r--r-- | cmd/podman/generate/systemd.go | 71 | ||||
-rw-r--r-- | cmd/podman/images/build.go | 28 | ||||
-rw-r--r-- | cmd/podman/images/save.go | 14 | ||||
-rw-r--r-- | cmd/podman/manifest/add.go | 49 | ||||
-rw-r--r-- | cmd/podman/networks/create.go | 3 | ||||
-rw-r--r-- | cmd/podman/networks/inspect.go | 3 | ||||
-rw-r--r-- | cmd/podman/networks/list.go | 3 | ||||
-rw-r--r-- | cmd/podman/networks/rm.go | 3 | ||||
-rw-r--r-- | cmd/podman/root.go | 8 | ||||
-rw-r--r-- | cmd/podman/system/df.go | 8 | ||||
-rw-r--r-- | cmd/podman/utils/alias.go | 2 |
13 files changed, 167 insertions, 42 deletions
diff --git a/cmd/podman/containers/ps.go b/cmd/podman/containers/ps.go index ebb6ed98f..2aa3b3a9b 100644 --- a/cmd/podman/containers/ps.go +++ b/cmd/podman/containers/ps.go @@ -13,6 +13,7 @@ import ( tm "github.com/buger/goterm" "github.com/containers/buildah/pkg/formats" "github.com/containers/podman/v2/cmd/podman/registry" + "github.com/containers/podman/v2/cmd/podman/utils" "github.com/containers/podman/v2/cmd/podman/validate" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/cri-o/ocicni/pkg/ocicni" @@ -56,9 +57,9 @@ func init() { func listFlagSet(flags *pflag.FlagSet) { flags.BoolVarP(&listOpts.All, "all", "a", false, "Show all the containers, default is only running containers") flags.StringSliceVarP(&filters, "filter", "f", []string{}, "Filter output based on conditions given") + flags.BoolVar(&listOpts.Storage, "storage", false, "Show containers in storage not controlled by Podman") flags.StringVar(&listOpts.Format, "format", "", "Pretty-print containers to JSON or using a Go template") flags.IntVarP(&listOpts.Last, "last", "n", -1, "Print the n last created containers (all states)") - flags.BoolVar(&listOpts.Namespace, "namespace", false, "Display namespace information") flags.BoolVar(&listOpts.Namespace, "ns", false, "Display namespace information") flags.BoolVar(&noTrunc, "no-trunc", false, "Display the extended information") flags.BoolVarP(&listOpts.Pod, "pod", "p", false, "Print the ID and name of the pod the containers are associated with") @@ -69,6 +70,7 @@ func listFlagSet(flags *pflag.FlagSet) { sort := validate.Value(&listOpts.Sort, "command", "created", "id", "image", "names", "runningfor", "size", "status") flags.Var(sort, "sort", "Sort output by: "+sort.Choices()) + flags.SetNormalizeFunc(utils.AliasFlags) } func checkFlags(c *cobra.Command) error { // latest, and last are mutually exclusive. @@ -102,6 +104,14 @@ func checkFlags(c *cobra.Command) error { if listOpts.Watch > 0 && listOpts.Latest { return errors.New("the watch and latest flags cannot be used together") } + cfg := registry.PodmanConfig() + if cfg.Engine.Namespace != "" { + if c.Flag("storage").Changed && listOpts.Storage { + return errors.New("--namespace and --storage flags can not both be set") + } + listOpts.Storage = false + } + return nil } diff --git a/cmd/podman/containers/runlabel.go b/cmd/podman/containers/runlabel.go index 81eec2a42..5ee8c9d6c 100644 --- a/cmd/podman/containers/runlabel.go +++ b/cmd/podman/containers/runlabel.go @@ -30,7 +30,7 @@ var ( RunE: runlabel, Args: cobra.MinimumNArgs(2), Example: `podman container runlabel run imageID - podman container runlabel --pull install imageID arg1 arg2 + podman container runlabel install imageID arg1 arg2 podman container runlabel --display run myImage`, } ) @@ -51,7 +51,7 @@ func init() { flags.StringVar(&runlabelOptions.Optional1, "opt1", "", "Optional parameter to pass for install") flags.StringVar(&runlabelOptions.Optional2, "opt2", "", "Optional parameter to pass for install") flags.StringVar(&runlabelOptions.Optional3, "opt3", "", "Optional parameter to pass for install") - flags.BoolP("pull", "p", false, "Pull the image if it does not exist locally prior to executing the label contents") + flags.BoolVarP(&runlabelOptions.Pull, "pull", "p", true, "Pull the image if it does not exist locally prior to executing the label contents") flags.BoolVarP(&runlabelOptions.Quiet, "quiet", "q", false, "Suppress output information when installing images") flags.BoolVar(&runlabelOptions.Replace, "replace", false, "Replace existing container with a new one from the image") flags.StringVar(&runlabelOptions.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") @@ -61,6 +61,7 @@ func init() { _ = flags.MarkHidden("opt1") _ = flags.MarkHidden("opt2") _ = flags.MarkHidden("opt3") + _ = flags.MarkHidden("pull") _ = flags.MarkHidden("signature-policy") if err := flags.MarkDeprecated("pull", "podman will pull if not found in local storage"); err != nil { diff --git a/cmd/podman/generate/systemd.go b/cmd/podman/generate/systemd.go index 851a104bc..f690836a4 100644 --- a/cmd/podman/generate/systemd.go +++ b/cmd/podman/generate/systemd.go @@ -1,15 +1,22 @@ package pods import ( + "encoding/json" "fmt" + "os" + "path/filepath" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/utils" "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var ( + files bool + format string systemdTimeout uint systemdOptions = entities.GenerateSystemdOptions{} systemdDescription = `Generate systemd units for a pod or container. @@ -29,19 +36,20 @@ var ( func init() { registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode}, + Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, Command: systemdCmd, Parent: generateCmd, }) flags := systemdCmd.Flags() flags.BoolVarP(&systemdOptions.Name, "name", "n", false, "Use container/pod names instead of IDs") - flags.BoolVarP(&systemdOptions.Files, "files", "f", false, "Generate .service files instead of printing to stdout") + flags.BoolVarP(&files, "files", "f", false, "Generate .service files instead of printing to stdout") flags.UintVarP(&systemdTimeout, "time", "t", containerConfig.Engine.StopTimeout, "Stop timeout override") flags.StringVar(&systemdOptions.RestartPolicy, "restart-policy", "on-failure", "Systemd restart-policy") flags.BoolVarP(&systemdOptions.New, "new", "", false, "Create a new container instead of starting an existing one") flags.StringVar(&systemdOptions.ContainerPrefix, "container-prefix", "container", "Systemd unit name prefix for containers") flags.StringVar(&systemdOptions.PodPrefix, "pod-prefix", "pod", "Systemd unit name prefix for pods") flags.StringVar(&systemdOptions.Separator, "separator", "-", "Systemd unit name separator between name/id and prefix") + flags.StringVar(&format, "format", "", "Print the created units in specified format (json)") flags.SetNormalizeFunc(utils.AliasFlags) } @@ -50,11 +58,68 @@ func systemd(cmd *cobra.Command, args []string) error { systemdOptions.StopTimeout = &systemdTimeout } + if registry.IsRemote() { + logrus.Warnln("The generated units should be placed on your remote system") + } + report, err := registry.ContainerEngine().GenerateSystemd(registry.GetContext(), args[0], systemdOptions) if err != nil { return err } - fmt.Println(report.Output) + if files { + cwd, err := os.Getwd() + if err != nil { + return errors.Wrap(err, "error getting current working directory") + } + for name, content := range report.Units { + path := filepath.Join(cwd, fmt.Sprintf("%s.service", name)) + f, err := os.Create(path) + if err != nil { + return err + } + _, err = f.WriteString(content) + if err != nil { + return err + } + err = f.Close() + if err != nil { + return err + } + + // add newline if default format is given + if format == "" { + path += "\n" + } + // modify in place so we can print the + // paths when --files is set + report.Units[name] = path + } + } + + switch format { + case "json": + return printJSON(report.Units) + case "": + return printDefault(report.Units) + default: + return errors.Errorf("unknown --format argument: %s", format) + } + +} + +func printDefault(units map[string]string) error { + for _, content := range units { + fmt.Print(content) + } + return nil +} + +func printJSON(units map[string]string) error { + b, err := json.MarshalIndent(units, "", " ") + if err != nil { + return err + } + fmt.Println(string(b)) return nil } diff --git a/cmd/podman/images/build.go b/cmd/podman/images/build.go index 400f960cc..923109b15 100644 --- a/cmd/podman/images/build.go +++ b/cmd/podman/images/build.go @@ -211,7 +211,16 @@ func build(cmd *cobra.Command, args []string) error { return err } - apiBuildOpts, err := buildFlagsWrapperToOptions(cmd, contextDir, &buildOpts) + var logfile *os.File + if cmd.Flag("logfile").Changed { + logfile, err = os.OpenFile(buildOpts.Logfile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) + if err != nil { + return errors.Errorf("error opening logfile %q: %v", buildOpts.Logfile, err) + } + defer logfile.Close() + } + + apiBuildOpts, err := buildFlagsWrapperToOptions(cmd, contextDir, &buildOpts, logfile) if err != nil { return err } @@ -225,7 +234,7 @@ func build(cmd *cobra.Command, args []string) error { // conversion here prevents the API from doing that (redundantly). // // TODO: this code should really be in Buildah. -func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buildFlagsWrapper) (*entities.BuildOptions, error) { +func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buildFlagsWrapper, logfile *os.File) (*entities.BuildOptions, error) { output := "" tags := []string{} if c.Flag("tag").Changed { @@ -284,16 +293,11 @@ func buildFlagsWrapperToOptions(c *cobra.Command, contextDir string, flags *buil stderr = os.Stderr reporter = os.Stderr - if c.Flag("logfile").Changed { - f, err := os.OpenFile(flags.Logfile, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600) - if err != nil { - return nil, errors.Errorf("error opening logfile %q: %v", flags.Logfile, err) - } - defer f.Close() - logrus.SetOutput(f) - stdout = f - stderr = f - reporter = f + if logfile != nil { + logrus.SetOutput(logfile) + stdout = logfile + stderr = logfile + reporter = logfile } var memoryLimit, memorySwap int64 diff --git a/cmd/podman/images/save.go b/cmd/podman/images/save.go index 82a3513f5..c57f61221 100644 --- a/cmd/podman/images/save.go +++ b/cmd/podman/images/save.go @@ -16,7 +16,10 @@ import ( "golang.org/x/crypto/ssh/terminal" ) -var validFormats = []string{define.OCIManifestDir, define.OCIArchive, define.V2s2ManifestDir, define.V2s2Archive} +var ( + validFormats = []string{define.OCIManifestDir, define.OCIArchive, define.V2s2ManifestDir, define.V2s2Archive} + containerConfig = registry.PodmanConfig() +) var ( saveDescription = `Save an image to docker-archive or oci-archive on the local machine. Default is docker-archive.` @@ -79,7 +82,7 @@ func saveFlags(flags *pflag.FlagSet) { flags.StringVar(&saveOpts.Format, "format", define.V2s2Archive, "Save image to oci-archive, oci-dir (directory with oci manifest type), docker-archive, docker-dir (directory with v2s2 manifest type)") flags.StringVarP(&saveOpts.Output, "output", "o", "", "Write to a specified file (default: stdout, which must be redirected)") flags.BoolVarP(&saveOpts.Quiet, "quiet", "q", false, "Suppress the output") - + flags.BoolVarP(&saveOpts.MultiImageArchive, "multi-image-archive", "m", containerConfig.Engine.MultiImageArchive, "Interpret additional arguments as images not tags and create a multi-image-archive (only for docker-archive)") } func save(cmd *cobra.Command, args []string) (finalErr error) { @@ -118,6 +121,13 @@ func save(cmd *cobra.Command, args []string) (finalErr error) { if len(args) > 1 { tags = args[1:] } + + // Decide whether c/image's progress bars should use stderr or stdout. + // If the output is set of stdout, any log message there would corrupt + // the tarfile. + if saveOpts.Output == os.Stdout.Name() { + saveOpts.Quiet = true + } err := registry.ImageEngine().Save(context.Background(), args[0], tags, saveOpts) if err == nil { succeeded = true diff --git a/cmd/podman/manifest/add.go b/cmd/podman/manifest/add.go index ca633263d..128bf66a7 100644 --- a/cmd/podman/manifest/add.go +++ b/cmd/podman/manifest/add.go @@ -4,14 +4,26 @@ import ( "context" "fmt" + "github.com/containers/common/pkg/auth" + "github.com/containers/image/v5/types" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/pkg/domain/entities" + "github.com/containers/podman/v2/pkg/util" "github.com/pkg/errors" "github.com/spf13/cobra" ) +// manifestAddOptsWrapper wraps entities.ManifestAddOptions and prevents leaking +// CLI-only fields into the API types. +type manifestAddOptsWrapper struct { + entities.ManifestAddOptions + + TLSVerifyCLI bool // CLI only + CredentialsCLI string +} + var ( - manifestAddOpts = entities.ManifestAddOptions{} + manifestAddOpts = manifestAddOptsWrapper{} addCmd = &cobra.Command{ Use: "add [flags] LIST LIST", Short: "Add images to a manifest list or image index", @@ -33,15 +45,48 @@ func init() { flags.BoolVar(&manifestAddOpts.All, "all", false, "add all of the list's images if the image is a list") flags.StringSliceVar(&manifestAddOpts.Annotation, "annotation", nil, "set an `annotation` for the specified image") flags.StringVar(&manifestAddOpts.Arch, "arch", "", "override the `architecture` of the specified image") + flags.StringVar(&manifestAddOpts.Authfile, "authfile", auth.GetDefaultAuthFile(), "path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") + flags.StringVar(&manifestAddOpts.CertDir, "cert-dir", "", "use certificates at the specified path to access the registry") + flags.StringVar(&manifestAddOpts.CredentialsCLI, "creds", "", "use `[username[:password]]` for accessing the registry") + flags.StringSliceVar(&manifestAddOpts.Features, "features", nil, "override the `features` of the specified image") flags.StringVar(&manifestAddOpts.OS, "os", "", "override the `OS` of the specified image") flags.StringVar(&manifestAddOpts.OSVersion, "os-version", "", "override the OS `version` of the specified image") + flags.BoolVar(&manifestAddOpts.TLSVerifyCLI, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry") flags.StringVar(&manifestAddOpts.Variant, "variant", "", "override the `Variant` of the specified image") + + if registry.IsRemote() { + _ = flags.MarkHidden("authfile") + _ = flags.MarkHidden("cert-dir") + _ = flags.MarkHidden("tls-verify") + } } func add(cmd *cobra.Command, args []string) error { + if err := auth.CheckAuthFile(manifestPushOpts.Authfile); err != nil { + return err + } + manifestAddOpts.Images = []string{args[1], args[0]} - listID, err := registry.ImageEngine().ManifestAdd(context.Background(), manifestAddOpts) + + if manifestAddOpts.CredentialsCLI != "" { + creds, err := util.ParseRegistryCreds(manifestAddOpts.CredentialsCLI) + if err != nil { + return err + } + manifestAddOpts.Username = creds.Username + manifestAddOpts.Password = creds.Password + } + + // TLS verification in c/image is controlled via a `types.OptionalBool` + // which allows for distinguishing among set-true, set-false, unspecified + // which is important to implement a sane way of dealing with defaults of + // boolean CLI flags. + if cmd.Flags().Changed("tls-verify") { + manifestAddOpts.SkipTLSVerify = types.NewOptionalBool(!manifestAddOpts.TLSVerifyCLI) + } + + listID, err := registry.ImageEngine().ManifestAdd(context.Background(), manifestAddOpts.ManifestAddOptions) if err != nil { return errors.Wrapf(err, "error adding to manifest list %s", args[0]) } diff --git a/cmd/podman/networks/create.go b/cmd/podman/networks/create.go index dabf6f0d2..68a577ae1 100644 --- a/cmd/podman/networks/create.go +++ b/cmd/podman/networks/create.go @@ -21,9 +21,6 @@ var ( RunE: networkCreate, Args: cobra.MaximumNArgs(1), Example: `podman network create podman1`, - Annotations: map[string]string{ - registry.ParentNSRequired: "", - }, } ) diff --git a/cmd/podman/networks/inspect.go b/cmd/podman/networks/inspect.go index f00d6b63c..c5872def7 100644 --- a/cmd/podman/networks/inspect.go +++ b/cmd/podman/networks/inspect.go @@ -22,9 +22,6 @@ var ( RunE: networkInspect, Example: `podman network inspect podman`, Args: cobra.MinimumNArgs(1), - Annotations: map[string]string{ - registry.ParentNSRequired: "", - }, } ) diff --git a/cmd/podman/networks/list.go b/cmd/podman/networks/list.go index 3a2651cbc..b6fb2bb80 100644 --- a/cmd/podman/networks/list.go +++ b/cmd/podman/networks/list.go @@ -25,9 +25,6 @@ var ( Long: networklistDescription, RunE: networkList, Example: `podman network list`, - Annotations: map[string]string{ - registry.ParentNSRequired: "", - }, } ) diff --git a/cmd/podman/networks/rm.go b/cmd/podman/networks/rm.go index dfbb5d081..ac49993b7 100644 --- a/cmd/podman/networks/rm.go +++ b/cmd/podman/networks/rm.go @@ -19,9 +19,6 @@ var ( RunE: networkRm, Example: `podman network rm podman`, Args: cobra.MinimumNArgs(1), - Annotations: map[string]string{ - registry.ParentNSRequired: "", - }, } ) diff --git a/cmd/podman/root.go b/cmd/podman/root.go index 749a5fbe7..6cf369f0a 100644 --- a/cmd/podman/root.go +++ b/cmd/podman/root.go @@ -104,8 +104,8 @@ func persistentPreRunE(cmd *cobra.Command, args []string) error { // TODO: Remove trace statement in podman V2.1 logrus.Debugf("Called %s.PersistentPreRunE(%s)", cmd.Name(), strings.Join(os.Args, " ")) - // Help is a special case, no need for more setup - if cmd.Name() == "help" { + // Help and commands with subcommands are special cases, no need for more setup + if cmd.Name() == "help" || cmd.HasSubCommands() { return nil } @@ -204,8 +204,8 @@ func persistentPostRunE(cmd *cobra.Command, args []string) error { // TODO: Remove trace statement in podman V2.1 logrus.Debugf("Called %s.PersistentPostRunE(%s)", cmd.Name(), strings.Join(os.Args, " ")) - // Help is a special case, no need for more cleanup - if cmd.Name() == "help" { + // Help and commands with subcommands are special cases, no need for more cleanup + if cmd.Name() == "help" || cmd.HasSubCommands() { return nil } diff --git a/cmd/podman/system/df.go b/cmd/podman/system/df.go index 03991101e..b262c8478 100644 --- a/cmd/podman/system/df.go +++ b/cmd/podman/system/df.go @@ -134,7 +134,7 @@ func printSummary(reports *entities.SystemDfReport, userFormat string) error { for _, v := range reports.Volumes { activeVolumes += v.Links volumesSize += v.Size - volumesReclaimable += v.Size + volumesReclaimable += v.ReclaimableSize } volumeSummary := dfSummary{ Type: "Local Volumes", @@ -182,7 +182,7 @@ func printVerbose(reports *entities.SystemDfReport) error { dfContainers = append(dfContainers, &dfContainer{SystemDfContainerReport: d}) } containerHeaders := "CONTAINER ID\tIMAGE\tCOMMAND\tLOCAL VOLUMES\tSIZE\tCREATED\tSTATUS\tNAMES\n" - containerRow := "{{.ContainerID}}\t{{.Image}}\t{{.Command}}\t{{.LocalVolumes}}\t{{.Size}}\t{{.Created}}\t{{.Status}}\t{{.Names}}\n" + containerRow := "{{.ContainerID}}\t{{.Image}}\t{{.Command}}\t{{.LocalVolumes}}\t{{.RWSize}}\t{{.Created}}\t{{.Status}}\t{{.Names}}\n" format = containerHeaders + "{{range . }}" + containerRow + "{{end}}" if err := writeTemplate(w, format, dfContainers); err != nil { return nil @@ -257,8 +257,8 @@ func (d *dfContainer) Command() string { return strings.Join(d.SystemDfContainerReport.Command, " ") } -func (d *dfContainer) Size() string { - return units.HumanSize(float64(d.SystemDfContainerReport.Size)) +func (d *dfContainer) RWSize() string { + return units.HumanSize(float64(d.SystemDfContainerReport.RWSize)) } func (d *dfContainer) Created() string { diff --git a/cmd/podman/utils/alias.go b/cmd/podman/utils/alias.go index e484461c5..ff31e82ea 100644 --- a/cmd/podman/utils/alias.go +++ b/cmd/podman/utils/alias.go @@ -19,6 +19,8 @@ func AliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName { name = "network" case "timeout": name = "time" + case "namespace": + name = "ns" } return pflag.NormalizedName(name) } |