diff options
-rw-r--r-- | cmd/podman/containers/mount.go | 21 | ||||
-rw-r--r-- | cmd/podman/images/history.go | 57 | ||||
-rw-r--r-- | cmd/podman/images/mount.go | 27 | ||||
-rw-r--r-- | cmd/podman/images/search.go | 51 | ||||
-rw-r--r-- | test/e2e/search_test.go | 6 | ||||
-rw-r--r-- | test/system/060-mount.bats | 2 |
6 files changed, 76 insertions, 88 deletions
diff --git a/cmd/podman/containers/mount.go b/cmd/podman/containers/mount.go index f2df5e99e..c4dfb513f 100644 --- a/cmd/podman/containers/mount.go +++ b/cmd/podman/containers/mount.go @@ -6,6 +6,7 @@ import ( "text/tabwriter" "text/template" + "github.com/containers/podman/v2/cmd/podman/parse" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/utils" "github.com/containers/podman/v2/cmd/podman/validate" @@ -75,9 +76,6 @@ func init() { } func mount(_ *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) if len(args) > 0 && mountOpts.Latest { return errors.Errorf("--latest and containers cannot be used together") } @@ -85,7 +83,9 @@ func mount(_ *cobra.Command, args []string) error { if err != nil { return err } + if len(args) > 0 || mountOpts.Latest || mountOpts.All { + var errs utils.OutputErrors for _, r := range reports { if r.Err == nil { fmt.Println(r.Path) @@ -96,21 +96,21 @@ func mount(_ *cobra.Command, args []string) error { return errs.PrintErrors() } - switch mountOpts.Format { - case "json": + switch { + case parse.MatchesJSONFormat(mountOpts.Format): return printJSON(reports) - case "": - // do nothing + case mountOpts.Format == "": + break // print defaults default: - return errors.Errorf("unknown --format argument: %s", mountOpts.Format) + return errors.Errorf("unknown --format argument: %q", mountOpts.Format) } mrs := make([]mountReporter, 0, len(reports)) for _, r := range reports { mrs = append(mrs, mountReporter{r}) } - row := "{{.ID}} {{.Path}}\n" - format := "{{range . }}" + row + "{{end}}" + + format := "{{range . }}{{.ID}}\t{{.Path}}\n{{end}}" tmpl, err := template.New("mounts").Parse(format) if err != nil { return err @@ -139,6 +139,7 @@ func printJSON(reports []*entities.ContainerMountReport) error { if err != nil { return err } + fmt.Println(string(b)) return nil } diff --git a/cmd/podman/images/history.go b/cmd/podman/images/history.go index 30abf0ada..fa4b368c6 100644 --- a/cmd/podman/images/history.go +++ b/cmd/podman/images/history.go @@ -10,7 +10,9 @@ import ( "time" "unicode" + "github.com/containers/podman/v2/cmd/podman/parse" "github.com/containers/podman/v2/cmd/podman/registry" + "github.com/containers/podman/v2/cmd/podman/report" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/docker/go-units" "github.com/pkg/errors" @@ -28,9 +30,9 @@ var ( Use: "history [flags] IMAGE", Short: "Show history of a specified image", Long: long, - Example: "podman history quay.io/fedora/fedora", Args: cobra.ExactArgs(1), RunE: history, + Example: "podman history quay.io/fedora/fedora", } imageHistoryCmd = &cobra.Command{ @@ -39,7 +41,7 @@ var ( Short: historyCmd.Short, Long: historyCmd.Long, RunE: historyCmd.RunE, - Example: `podman image history imageID`, + Example: `podman image history quay.io/fedora/fedora`, } opts = struct { @@ -79,7 +81,7 @@ func history(cmd *cobra.Command, args []string) error { return err } - if opts.format == "json" { + if parse.MatchesJSONFormat(opts.format) { var err error if len(results.Layers) == 0 { _, err = fmt.Fprintf(os.Stdout, "[]\n") @@ -100,69 +102,66 @@ func history(cmd *cobra.Command, args []string) error { } return err } - hr := make([]historyreporter, 0, len(results.Layers)) + + hr := make([]historyReporter, 0, len(results.Layers)) for _, l := range results.Layers { - hr = append(hr, historyreporter{l}) + hr = append(hr, historyReporter{l}) } + + hdrs := report.Headers(historyReporter{}, map[string]string{ + "CreatedBy": "CREATED BY", + }) + // Defaults - hdr := "ID\tCREATED\tCREATED BY\tSIZE\tCOMMENT\n" row := "{{.ID}}\t{{.Created}}\t{{.CreatedBy}}\t{{.Size}}\t{{.Comment}}\n" - switch { - case len(opts.format) > 0: - hdr = "" - row = opts.format - if !strings.HasSuffix(opts.format, "\n") { - row += "\n" - } + case cmd.Flags().Changed("format"): + row = report.NormalizeFormat(opts.format) case opts.quiet: - hdr = "" row = "{{.ID}}\n" - case opts.human: - row = "{{.ID}}\t{{.Created}}\t{{.CreatedBy}}\t{{.Size}}\t{{.Comment}}\n" - case opts.noTrunc: - row = "{{.ID}}\t{{.Created}}\t{{.CreatedBy}}\t{{.Size}}\t{{.Comment}}\n" } - format := hdr + "{{range . }}" + row + "{{end}}" + format := "{{range . }}" + row + "{{end}}" tmpl, err := template.New("report").Parse(format) if err != nil { return err } w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) - err = tmpl.Execute(w, hr) - if err != nil { - fmt.Fprintln(os.Stderr, errors.Wrapf(err, "failed to print report")) + defer w.Flush() + + if !opts.quiet && !cmd.Flags().Changed("format") { + if err := tmpl.Execute(w, hdrs); err != nil { + return errors.Wrapf(err, "failed to write report column headers") + } } - w.Flush() - return nil + return tmpl.Execute(w, hr) } -type historyreporter struct { +type historyReporter struct { entities.ImageHistoryLayer } -func (h historyreporter) Created() string { +func (h historyReporter) Created() string { if opts.human { return units.HumanDuration(time.Since(h.ImageHistoryLayer.Created)) + " ago" } return h.ImageHistoryLayer.Created.Format(time.RFC3339) } -func (h historyreporter) Size() string { +func (h historyReporter) Size() string { s := units.HumanSizeWithPrecision(float64(h.ImageHistoryLayer.Size), 3) i := strings.LastIndexFunc(s, unicode.IsNumber) return s[:i+1] + " " + s[i+1:] } -func (h historyreporter) CreatedBy() string { +func (h historyReporter) CreatedBy() string { if len(h.ImageHistoryLayer.CreatedBy) > 45 { return h.ImageHistoryLayer.CreatedBy[:45-3] + "..." } return h.ImageHistoryLayer.CreatedBy } -func (h historyreporter) ID() string { +func (h historyReporter) ID() string { if !opts.noTrunc && len(h.ImageHistoryLayer.ID) >= 12 { return h.ImageHistoryLayer.ID[0:12] } diff --git a/cmd/podman/images/mount.go b/cmd/podman/images/mount.go index fac06e324..0a972ea81 100644 --- a/cmd/podman/images/mount.go +++ b/cmd/podman/images/mount.go @@ -6,6 +6,7 @@ import ( "text/tabwriter" "text/template" + "github.com/containers/podman/v2/cmd/podman/parse" "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/cmd/podman/utils" "github.com/containers/podman/v2/pkg/domain/entities" @@ -24,7 +25,7 @@ var ( mountCommand = &cobra.Command{ Use: "mount [flags] [IMAGE...]", - Short: "Mount an images's root filesystem", + Short: "Mount an image's root filesystem", Long: mountDescription, RunE: mount, Example: `podman image mount imgID @@ -56,18 +57,18 @@ func init() { mountFlags(mountCommand.Flags()) } -func mount(_ *cobra.Command, args []string) error { - var ( - errs utils.OutputErrors - ) +func mount(cmd *cobra.Command, args []string) error { if len(args) > 0 && mountOpts.All { return errors.New("when using the --all switch, you may not pass any image names or IDs") } + reports, err := registry.ImageEngine().Mount(registry.GetContext(), args, mountOpts) if err != nil { return err } + if len(args) > 0 || mountOpts.All { + var errs utils.OutputErrors for _, r := range reports { if r.Err == nil { fmt.Println(r.Path) @@ -78,22 +79,22 @@ func mount(_ *cobra.Command, args []string) error { return errs.PrintErrors() } - switch mountOpts.Format { - case "json": + switch { + case parse.MatchesJSONFormat(mountOpts.Format): return printJSON(reports) - case "": - // do nothing + case mountOpts.Format == "": + break // default format default: - return errors.Errorf("unknown --format argument: %s", mountOpts.Format) + return errors.Errorf("unknown --format argument: %q", mountOpts.Format) } mrs := make([]mountReporter, 0, len(reports)) for _, r := range reports { mrs = append(mrs, mountReporter{r}) } - row := "{{.ID}} {{.Path}}\n" - format := "{{range . }}" + row + "{{end}}" - tmpl, err := template.New("mounts").Parse(format) + + row := "{{range . }}{{.ID}}\t{{.Path}}\n{{end}}" + tmpl, err := template.New("mounts").Parse(row) if err != nil { return err } diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go index b8d989d65..b8f590585 100644 --- a/cmd/podman/images/search.go +++ b/cmd/podman/images/search.go @@ -2,15 +2,14 @@ package images import ( "os" - "reflect" - "strings" + "text/tabwriter" + "text/template" - "github.com/containers/buildah/pkg/formats" "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/cmd/podman/report" "github.com/containers/podman/v2/pkg/domain/entities" - "github.com/containers/podman/v2/pkg/util/camelcase" "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -120,41 +119,29 @@ func imageSearch(cmd *cobra.Command, args []string) error { if err != nil { return err } - - format := genSearchFormat(searchOptions.Format) if len(searchReport) == 0 { return nil } - out := formats.StdoutTemplateArray{Output: searchToGeneric(searchReport), Template: format, Fields: searchHeaderMap()} - return out.Out() -} - -// searchHeaderMap returns the headers of a SearchResult. -func searchHeaderMap() map[string]string { - s := new(entities.ImageSearchReport) - v := reflect.Indirect(reflect.ValueOf(s)) - values := make(map[string]string, v.NumField()) - for i := 0; i < v.NumField(); i++ { - key := v.Type().Field(i).Name - value := key - values[key] = strings.ToUpper(strings.Join(camelcase.Split(value), " ")) + hdrs := report.Headers(entities.ImageSearchReport{}, nil) + row := "{{.Index}}\t{{.Name}}\t{{.Description}}\t{{.Stars}}\t{{.Official}}\t{{.Automated}}\n" + if cmd.Flags().Changed("format") { + row = report.NormalizeFormat(searchOptions.Format) } - return values -} + row = "{{range .}}" + row + "{{end}}" -func genSearchFormat(format string) string { - if format != "" { - // "\t" from the command line is not being recognized as a tab - // replacing the string "\t" to a tab character if the user passes in "\t" - return strings.Replace(format, `\t`, "\t", -1) + tmpl, err := template.New("search").Parse(row) + if err != nil { + return err } - return "table {{.Index}}\t{{.Name}}\t{{.Description}}\t{{.Stars}}\t{{.Official}}\t{{.Automated}}\t" -} + w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) + defer w.Flush() -func searchToGeneric(params []entities.ImageSearchReport) (genericParams []interface{}) { - for _, v := range params { - genericParams = append(genericParams, interface{}(v)) + if !cmd.Flags().Changed("format") { + if err := tmpl.Execute(w, hdrs); err != nil { + return errors.Wrapf(err, "failed to write search column headers") + } } - return genericParams + + return tmpl.Execute(w, searchReport) } diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go index 497949bbc..043da9059 100644 --- a/test/e2e/search_test.go +++ b/test/e2e/search_test.go @@ -237,7 +237,7 @@ registries = ['{{.Host}}:{{.Port}}']` }) It("podman search attempts HTTP if registry is in registries.insecure and force secure is false", func() { - SkipIfRemote("--tls-verify is not supportedon podman-remote search") + SkipIfRemote("--tls-verify is not supported on podman-remote search") if podmanTest.Host.Arch == "ppc64le" { Skip("No registry image for ppc64le") } @@ -278,7 +278,7 @@ registries = ['{{.Host}}:{{.Port}}']` }) It("podman search doesn't attempt HTTP if force secure is true", func() { - SkipIfRemote("--tls-verify is not supportedon podman-remote search") + SkipIfRemote("--tls-verify is not supported on podman-remote search") if podmanTest.Host.Arch == "ppc64le" { Skip("No registry image for ppc64le") } @@ -317,7 +317,7 @@ registries = ['{{.Host}}:{{.Port}}']` }) It("podman search doesn't attempt HTTP if registry is not listed as insecure", func() { - SkipIfRemote("--tls-verify is not supportedon podman-remote search") + SkipIfRemote("--tls-verify is not supported on podman-remote search") if podmanTest.Host.Arch == "ppc64le" { Skip("No registry image for ppc64le") } diff --git a/test/system/060-mount.bats b/test/system/060-mount.bats index 75c88e4ad..f11aff773 100644 --- a/test/system/060-mount.bats +++ b/test/system/060-mount.bats @@ -56,7 +56,7 @@ load helpers # 'image mount', no args, tells us what's mounted run_podman image mount - is "$output" "$IMAGE $mount_path" "podman image mount with no args" + is "$output" "$IMAGE *$mount_path" "podman image mount with no args" # Clean up run_podman image umount $IMAGE |