diff options
author | Brent Baude <bbaude@redhat.com> | 2020-04-16 12:25:26 -0500 |
---|---|---|
committer | Brent Baude <bbaude@redhat.com> | 2020-04-16 15:53:58 -0500 |
commit | 241326a9a8c20ad7f2bcf651416b836e7778e090 (patch) | |
tree | 4001e8e47a022bb1b9bfbf2332c42e1aeb802f9e /cmd/podmanV2/images | |
parent | 88c6fd06cd54fb9a8826306dfdf1a77e400de5de (diff) | |
download | podman-241326a9a8c20ad7f2bcf651416b836e7778e090.tar.gz podman-241326a9a8c20ad7f2bcf651416b836e7778e090.tar.bz2 podman-241326a9a8c20ad7f2bcf651416b836e7778e090.zip |
Podman V2 birth
remote podman v1 and replace with podman v2.
Signed-off-by: Brent Baude <bbaude@redhat.com>
Diffstat (limited to 'cmd/podmanV2/images')
-rw-r--r-- | cmd/podmanV2/images/diff.go | 62 | ||||
-rw-r--r-- | cmd/podmanV2/images/exists.go | 40 | ||||
-rw-r--r-- | cmd/podmanV2/images/history.go | 152 | ||||
-rw-r--r-- | cmd/podmanV2/images/image.go | 25 | ||||
-rw-r--r-- | cmd/podmanV2/images/images.go | 30 | ||||
-rw-r--r-- | cmd/podmanV2/images/import.go | 84 | ||||
-rw-r--r-- | cmd/podmanV2/images/inspect.go | 108 | ||||
-rw-r--r-- | cmd/podmanV2/images/list.go | 273 | ||||
-rw-r--r-- | cmd/podmanV2/images/load.go | 94 | ||||
-rw-r--r-- | cmd/podmanV2/images/prune.go | 86 | ||||
-rw-r--r-- | cmd/podmanV2/images/pull.go | 118 | ||||
-rw-r--r-- | cmd/podmanV2/images/push.go | 120 | ||||
-rw-r--r-- | cmd/podmanV2/images/rm.go | 71 | ||||
-rw-r--r-- | cmd/podmanV2/images/rmi.go | 28 | ||||
-rw-r--r-- | cmd/podmanV2/images/save.go | 86 | ||||
-rw-r--r-- | cmd/podmanV2/images/search.go | 156 | ||||
-rw-r--r-- | cmd/podmanV2/images/tag.go | 32 | ||||
-rw-r--r-- | cmd/podmanV2/images/untag.go | 31 |
18 files changed, 0 insertions, 1596 deletions
diff --git a/cmd/podmanV2/images/diff.go b/cmd/podmanV2/images/diff.go deleted file mode 100644 index b54cb39a8..000000000 --- a/cmd/podmanV2/images/diff.go +++ /dev/null @@ -1,62 +0,0 @@ -package images - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/cmd/podmanV2/report" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - // podman container _inspect_ - diffCmd = &cobra.Command{ - Use: "diff [flags] CONTAINER", - Args: registry.IdOrLatestArgs, - Short: "Inspect changes on image's file systems", - Long: `Displays changes on a image's filesystem. The image will be compared to its parent layer.`, - RunE: diff, - Example: `podman image diff myImage - podman image diff --format json redis:alpine`, - } - diffOpts *entities.DiffOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: diffCmd, - Parent: imageCmd, - }) - - diffOpts = &entities.DiffOptions{} - flags := diffCmd.Flags() - flags.BoolVar(&diffOpts.Archive, "archive", true, "Save the diff as a tar archive") - _ = flags.MarkHidden("archive") - flags.StringVar(&diffOpts.Format, "format", "", "Change the output format") -} - -func diff(cmd *cobra.Command, args []string) error { - if len(args) == 0 && !diffOpts.Latest { - return errors.New("image must be specified: podman image diff [options [...]] ID-NAME") - } - - results, err := registry.ImageEngine().Diff(registry.GetContext(), args[0], entities.DiffOptions{}) - if err != nil { - return err - } - - switch diffOpts.Format { - case "": - return report.ChangesToTable(results) - case "json": - return report.ChangesToJSON(results) - default: - return errors.New("only supported value for '--format' is 'json'") - } -} - -func Diff(cmd *cobra.Command, args []string, options entities.DiffOptions) error { - diffOpts = &options - return diff(cmd, args) -} diff --git a/cmd/podmanV2/images/exists.go b/cmd/podmanV2/images/exists.go deleted file mode 100644 index d35d6825e..000000000 --- a/cmd/podmanV2/images/exists.go +++ /dev/null @@ -1,40 +0,0 @@ -package images - -import ( - "os" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - existsCmd = &cobra.Command{ - Use: "exists IMAGE", - Short: "Check if an image exists in local storage", - Long: `If the named image exists in local storage, podman image exists exits with 0, otherwise the exit code will be 1.`, - Args: cobra.ExactArgs(1), - RunE: exists, - Example: `podman image exists ID - podman image exists IMAGE && podman pull IMAGE`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: existsCmd, - Parent: imageCmd, - }) -} - -func exists(cmd *cobra.Command, args []string) error { - found, err := registry.ImageEngine().Exists(registry.GetContext(), args[0]) - if err != nil { - return err - } - if !found.Value { - os.Exit(1) - } - return nil -} diff --git a/cmd/podmanV2/images/history.go b/cmd/podmanV2/images/history.go deleted file mode 100644 index d2e880ef7..000000000 --- a/cmd/podmanV2/images/history.go +++ /dev/null @@ -1,152 +0,0 @@ -package images - -import ( - "context" - "fmt" - "os" - "strings" - "text/tabwriter" - "text/template" - "time" - "unicode" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/docker/go-units" - jsoniter "github.com/json-iterator/go" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - long = `Displays the history of an image. - - The information can be printed out in an easy to read, or user specified format, and can be truncated.` - - // podman _history_ - historyCmd = &cobra.Command{ - 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, - } - - opts = struct { - human bool - noTrunc bool - quiet bool - format string - }{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: historyCmd, - }) - - flags := historyCmd.Flags() - flags.StringVar(&opts.format, "format", "", "Change the output to JSON or a Go template") - flags.BoolVarP(&opts.human, "human", "H", true, "Display sizes and dates in human readable format") - flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Do not truncate the output") - flags.BoolVar(&opts.noTrunc, "notruncate", false, "Do not truncate the output") - flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Display the numeric IDs only") -} - -func history(cmd *cobra.Command, args []string) error { - results, err := registry.ImageEngine().History(context.Background(), args[0], entities.ImageHistoryOptions{}) - if err != nil { - return err - } - - if opts.format == "json" { - var err error - if len(results.Layers) == 0 { - _, err = fmt.Fprintf(os.Stdout, "[]\n") - } else { - // ah-hoc change to "Created": type and format - type layer struct { - entities.ImageHistoryLayer - Created string `json:"Created"` - } - - layers := make([]layer, len(results.Layers)) - for i, l := range results.Layers { - layers[i].ImageHistoryLayer = l - layers[i].Created = l.Created.Format(time.RFC3339) - } - json := jsoniter.ConfigCompatibleWithStandardLibrary - enc := json.NewEncoder(os.Stdout) - err = enc.Encode(layers) - } - return err - } - var hr []historyreporter - for _, l := range results.Layers { - hr = append(hr, historyreporter{l}) - } - // Defaults - hdr := "ID\tCREATED\tCREATED BY\tSIZE\tCOMMENT\n" - row := "{{.ID}}\t{{.Created}}\t{{.CreatedBy}}\t{{.Size}}\t{{.Comment}}\n" - - if len(opts.format) > 0 { - hdr = "" - row = opts.format - if !strings.HasSuffix(opts.format, "\n") { - row += "\n" - } - } else { - switch { - 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" - case opts.quiet: - hdr = "" - row = "{{.ID}}\n" - } - } - format := hdr + "{{range . }}" + row + "{{end}}" - - tmpl := template.Must(template.New("report").Parse(format)) - 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")) - } - w.Flush() - return nil -} - -type historyreporter struct { - entities.ImageHistoryLayer -} - -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 { - 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 { - if len(h.ImageHistoryLayer.CreatedBy) > 45 { - return h.ImageHistoryLayer.CreatedBy[:45-3] + "..." - } - return h.ImageHistoryLayer.CreatedBy -} - -func (h historyreporter) ID() string { - if !opts.noTrunc && len(h.ImageHistoryLayer.ID) >= 12 { - return h.ImageHistoryLayer.ID[0:12] - } - return h.ImageHistoryLayer.ID -} diff --git a/cmd/podmanV2/images/image.go b/cmd/podmanV2/images/image.go deleted file mode 100644 index 7b469bc59..000000000 --- a/cmd/podmanV2/images/image.go +++ /dev/null @@ -1,25 +0,0 @@ -package images - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // Command: podman _image_ - imageCmd = &cobra.Command{ - Use: "image", - Short: "Manage images", - Long: "Manage images", - TraverseChildren: true, - RunE: registry.SubCommandExists, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imageCmd, - }) -} diff --git a/cmd/podmanV2/images/images.go b/cmd/podmanV2/images/images.go deleted file mode 100644 index 588369a7e..000000000 --- a/cmd/podmanV2/images/images.go +++ /dev/null @@ -1,30 +0,0 @@ -package images - -import ( - "strings" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - // podman _images_ Alias for podman image _list_ - imagesCmd = &cobra.Command{ - Use: strings.Replace(listCmd.Use, "list", "images", 1), - Args: listCmd.Args, - Short: listCmd.Short, - Long: listCmd.Long, - RunE: listCmd.RunE, - Example: strings.Replace(listCmd.Example, "podman image list", "podman images", -1), - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imagesCmd, - }) - - imageListFlagSet(imagesCmd.Flags()) -} diff --git a/cmd/podmanV2/images/import.go b/cmd/podmanV2/images/import.go deleted file mode 100644 index c86db34bf..000000000 --- a/cmd/podmanV2/images/import.go +++ /dev/null @@ -1,84 +0,0 @@ -package images - -import ( - "context" - "fmt" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/hashicorp/go-multierror" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - importDescription = `Create a container image from the contents of the specified tarball (.tar, .tar.gz, .tgz, .bzip, .tar.xz, .txz). - - Note remote tar balls can be specified, via web address. - Optionally tag the image. You can specify the instructions using the --change option.` - importCommand = &cobra.Command{ - Use: "import [flags] PATH [REFERENCE]", - Short: "Import a tarball to create a filesystem image", - Long: importDescription, - RunE: importCon, - Example: `podman import http://example.com/ctr.tar url-image - cat ctr.tar | podman -q import --message "importing the ctr.tar tarball" - image-imported - cat ctr.tar | podman import -`, - } -) - -var ( - importOpts entities.ImageImportOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: importCommand, - }) - - flags := importCommand.Flags() - flags.StringArrayVarP(&importOpts.Changes, "change", "c", []string{}, "Apply the following possible instructions to the created image (default []): CMD | ENTRYPOINT | ENV | EXPOSE | LABEL | STOPSIGNAL | USER | VOLUME | WORKDIR") - flags.StringVarP(&importOpts.Message, "message", "m", "", "Set commit message for imported image") - flags.BoolVarP(&importOpts.Quiet, "quiet", "q", false, "Suppress output") -} - -func importCon(cmd *cobra.Command, args []string) error { - var ( - source string - reference string - ) - switch len(args) { - case 0: - return errors.Errorf("need to give the path to the tarball, or must specify a tarball of '-' for stdin") - case 1: - source = args[0] - case 2: - source = args[0] - // TODO when save is merged, we need to process reference - // like it is done in there or we end up with docker.io prepends - // instead of the localhost ones - reference = args[1] - default: - return errors.Errorf("too many arguments. Usage TARBALL [REFERENCE]") - } - errFileName := parse.ValidateFileName(source) - errURL := parse.ValidURL(source) - if errURL == nil { - importOpts.SourceIsURL = true - } - if errFileName != nil && errURL != nil { - return multierror.Append(errFileName, errURL) - } - - importOpts.Source = source - importOpts.Reference = reference - - response, err := registry.ImageEngine().Import(context.Background(), importOpts) - if err != nil { - return err - } - fmt.Println(response.Id) - return nil -} diff --git a/cmd/podmanV2/images/inspect.go b/cmd/podmanV2/images/inspect.go deleted file mode 100644 index 2ee2d86ee..000000000 --- a/cmd/podmanV2/images/inspect.go +++ /dev/null @@ -1,108 +0,0 @@ -package images - -import ( - "context" - "encoding/json" - "fmt" - "os" - "strings" - "text/tabwriter" - "text/template" - - "github.com/containers/buildah/pkg/formats" - "github.com/containers/libpod/cmd/podmanV2/common" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - // Command: podman image _inspect_ - inspectCmd = &cobra.Command{ - Use: "inspect [flags] IMAGE", - Short: "Display the configuration of an image", - Long: `Displays the low-level information on an image identified by name or ID.`, - RunE: inspect, - Example: `podman image inspect alpine`, - } - inspectOpts *entities.InspectOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: inspectCmd, - Parent: imageCmd, - }) - inspectOpts = common.AddInspectFlagSet(inspectCmd) -} - -func inspect(cmd *cobra.Command, args []string) error { - latestContainer := inspectOpts.Latest - - if len(args) == 0 && !latestContainer { - return errors.Errorf("container or image name must be specified: podman inspect [options [...]] name") - } - - if len(args) > 0 && latestContainer { - return errors.Errorf("you cannot provide additional arguments with --latest") - } - - results, err := registry.ImageEngine().Inspect(context.Background(), args, *inspectOpts) - if err != nil { - return err - } - - if len(results.Images) > 0 { - if inspectOpts.Format == "" { - buf, err := json.MarshalIndent(results.Images, "", " ") - if err != nil { - return err - } - fmt.Println(string(buf)) - - for id, e := range results.Errors { - fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error()) - } - return nil - } - row := inspectFormat(inspectOpts.Format) - format := "{{range . }}" + row + "{{end}}" - tmpl, err := template.New("inspect").Parse(format) - if err != nil { - return err - } - - w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) - defer func() { _ = w.Flush() }() - err = tmpl.Execute(w, results.Images) - if err != nil { - return err - } - } - - for id, e := range results.Errors { - fmt.Fprintf(os.Stderr, "%s: %s\n", id, e.Error()) - } - return nil -} - -func inspectFormat(row string) string { - r := strings.NewReplacer("{{.Id}}", formats.IDString, - ".Src", ".Source", - ".Dst", ".Destination", - ".ImageID", ".Image", - ) - row = r.Replace(row) - - if !strings.HasSuffix(row, "\n") { - row += "\n" - } - return row -} - -func Inspect(cmd *cobra.Command, args []string, options *entities.InspectOptions) error { - inspectOpts = options - return inspect(cmd, args) -} diff --git a/cmd/podmanV2/images/list.go b/cmd/podmanV2/images/list.go deleted file mode 100644 index d594a4323..000000000 --- a/cmd/podmanV2/images/list.go +++ /dev/null @@ -1,273 +0,0 @@ -package images - -import ( - "errors" - "fmt" - "os" - "sort" - "strings" - "text/tabwriter" - "text/template" - "time" - "unicode" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/docker/go-units" - jsoniter "github.com/json-iterator/go" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -type listFlagType struct { - format string - history bool - noHeading bool - noTrunc bool - quiet bool - sort string - readOnly bool - digests bool -} - -var ( - // Command: podman image _list_ - listCmd = &cobra.Command{ - Use: "list [flag] [IMAGE]", - Aliases: []string{"ls"}, - Args: cobra.MaximumNArgs(1), - Short: "List images in local storage", - Long: "Lists images previously pulled to the system or created on the system.", - RunE: images, - Example: `podman image list --format json - podman image list --sort repository --format "table {{.ID}} {{.Repository}} {{.Tag}}" - podman image list --filter dangling=true`, - } - - // Options to pull data - listOptions = entities.ImageListOptions{} - - // Options for presenting data - listFlag = listFlagType{} - - sortFields = entities.NewStringSet( - "created", - "id", - "repository", - "size", - "tag") -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: listCmd, - Parent: imageCmd, - }) - imageListFlagSet(listCmd.Flags()) -} - -func imageListFlagSet(flags *pflag.FlagSet) { - flags.BoolVarP(&listOptions.All, "all", "a", false, "Show all images (default hides intermediate images)") - flags.StringSliceVarP(&listOptions.Filter, "filter", "f", []string{}, "Filter output based on conditions provided (default [])") - flags.StringVar(&listFlag.format, "format", "", "Change the output format to JSON or a Go template") - flags.BoolVar(&listFlag.digests, "digests", false, "Show digests") - flags.BoolVarP(&listFlag.noHeading, "noheading", "n", false, "Do not print column headings") - flags.BoolVar(&listFlag.noTrunc, "no-trunc", false, "Do not truncate output") - flags.BoolVar(&listFlag.noTrunc, "notruncate", false, "Do not truncate output") - flags.BoolVarP(&listFlag.quiet, "quiet", "q", false, "Display only image IDs") - flags.StringVar(&listFlag.sort, "sort", "created", "Sort by "+sortFields.String()) - flags.BoolVarP(&listFlag.history, "history", "", false, "Display the image name history") -} - -func images(cmd *cobra.Command, args []string) error { - if len(listOptions.Filter) > 0 && len(args) > 0 { - return errors.New("cannot specify an image and a filter(s)") - } - - if len(listOptions.Filter) < 1 && len(args) > 0 { - listOptions.Filter = append(listOptions.Filter, "reference="+args[0]) - } - - if cmd.Flag("sort").Changed && !sortFields.Contains(listFlag.sort) { - return fmt.Errorf("\"%s\" is not a valid field for sorting. Choose from: %s", - listFlag.sort, sortFields.String()) - } - - summaries, err := registry.ImageEngine().List(registry.GetContext(), listOptions) - if err != nil { - return err - } - - imageS := summaries - sort.Slice(imageS, sortFunc(listFlag.sort, imageS)) - - if cmd.Flag("format").Changed && listFlag.format == "json" { - return writeJSON(imageS) - } else { - return writeTemplate(imageS, err) - } -} - -func writeJSON(imageS []*entities.ImageSummary) error { - type image struct { - entities.ImageSummary - Created string - } - - imgs := make([]image, 0, len(imageS)) - for _, e := range imageS { - var h image - h.ImageSummary = *e - h.Created = time.Unix(e.Created, 0).Format(time.RFC3339) - h.RepoTags = nil - - imgs = append(imgs, h) - } - - json := jsoniter.ConfigCompatibleWithStandardLibrary - enc := json.NewEncoder(os.Stdout) - return enc.Encode(imgs) -} - -func writeTemplate(imageS []*entities.ImageSummary, err error) error { - var ( - hdr, row string - ) - imgs := make([]imageReporter, 0, len(imageS)) - for _, e := range imageS { - for _, tag := range e.RepoTags { - var h imageReporter - h.ImageSummary = *e - h.Repository, h.Tag = tokenRepoTag(tag) - imgs = append(imgs, h) - } - if e.IsReadOnly() { - listFlag.readOnly = true - } - } - if len(listFlag.format) < 1 { - hdr, row = imageListFormat(listFlag) - } else { - row = listFlag.format - if !strings.HasSuffix(row, "\n") { - row += "\n" - } - } - format := hdr + "{{range . }}" + row + "{{end}}" - tmpl := template.Must(template.New("list").Parse(format)) - w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) - defer w.Flush() - return tmpl.Execute(w, imgs) -} - -func tokenRepoTag(tag string) (string, string) { - tokens := strings.SplitN(tag, ":", 2) - switch len(tokens) { - case 0: - return tag, "" - case 1: - return tokens[0], "" - case 2: - return tokens[0], tokens[1] - default: - return "<N/A>", "" - } -} - -func sortFunc(key string, data []*entities.ImageSummary) func(i, j int) bool { - switch key { - case "id": - return func(i, j int) bool { - return data[i].ID < data[j].ID - } - case "repository": - return func(i, j int) bool { - return data[i].RepoTags[0] < data[j].RepoTags[0] - } - case "size": - return func(i, j int) bool { - return data[i].Size < data[j].Size - } - case "tag": - return func(i, j int) bool { - return data[i].RepoTags[0] < data[j].RepoTags[0] - } - default: - // case "created": - return func(i, j int) bool { - return data[i].Created >= data[j].Created - } - } -} - -func imageListFormat(flags listFlagType) (string, string) { - if flags.quiet { - return "", "{{.ID}}\n" - } - - // Defaults - hdr := "REPOSITORY\tTAG" - row := "{{.Repository}}\t{{if .Tag}}{{.Tag}}{{else}}<none>{{end}}" - - if flags.digests { - hdr += "\tDIGEST" - row += "\t{{.Digest}}" - } - - hdr += "\tIMAGE ID" - if flags.noTrunc { - row += "\tsha256:{{.ID}}" - } else { - row += "\t{{.ID}}" - } - - hdr += "\tCREATED\tSIZE" - row += "\t{{.Created}}\t{{.Size}}" - - if flags.history { - hdr += "\tHISTORY" - row += "\t{{if .History}}{{.History}}{{else}}<none>{{end}}" - } - - if flags.readOnly { - hdr += "\tReadOnly" - row += "\t{{.ReadOnly}}" - } - - if flags.noHeading { - hdr = "" - } else { - hdr += "\n" - } - - row += "\n" - return hdr, row -} - -type imageReporter struct { - Repository string `json:"repository,omitempty"` - Tag string `json:"tag,omitempty"` - entities.ImageSummary -} - -func (i imageReporter) ID() string { - if !listFlag.noTrunc && len(i.ImageSummary.ID) >= 12 { - return i.ImageSummary.ID[0:12] - } - return i.ImageSummary.ID -} - -func (i imageReporter) Created() string { - return units.HumanDuration(time.Since(time.Unix(i.ImageSummary.Created, 0))) + " ago" -} - -func (i imageReporter) Size() string { - s := units.HumanSizeWithPrecision(float64(i.ImageSummary.Size), 3) - j := strings.LastIndexFunc(s, unicode.IsNumber) - return s[:j+1] + " " + s[j+1:] -} - -func (i imageReporter) History() string { - return strings.Join(i.ImageSummary.History, ", ") -} diff --git a/cmd/podmanV2/images/load.go b/cmd/podmanV2/images/load.go deleted file mode 100644 index 004daa288..000000000 --- a/cmd/podmanV2/images/load.go +++ /dev/null @@ -1,94 +0,0 @@ -package images - -import ( - "context" - "fmt" - "io" - "io/ioutil" - "os" - - "github.com/containers/image/v5/docker/reference" - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/util" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "golang.org/x/crypto/ssh/terminal" -) - -var ( - loadDescription = "Loads an image from a locally stored archive (tar file) into container storage." - loadCommand = &cobra.Command{ - Use: "load [flags] [NAME[:TAG]]", - Short: "Load an image from container archive", - Long: loadDescription, - RunE: load, - Args: cobra.MaximumNArgs(1), - } -) - -var ( - loadOpts entities.ImageLoadOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: loadCommand, - }) - - flags := loadCommand.Flags() - flags.StringVarP(&loadOpts.Input, "input", "i", "", "Read from specified archive file (default: stdin)") - flags.BoolVarP(&loadOpts.Quiet, "quiet", "q", false, "Suppress the output") - flags.StringVar(&loadOpts.SignaturePolicy, "signature-policy", "", "Pathname of signature policy file") - if registry.IsRemote() { - _ = flags.MarkHidden("signature-policy") - } - -} - -func load(cmd *cobra.Command, args []string) error { - if len(args) > 0 { - ref, err := reference.Parse(args[0]) - if err != nil { - return err - } - if t, ok := ref.(reference.Tagged); ok { - loadOpts.Tag = t.Tag() - } else { - loadOpts.Tag = "latest" - } - if r, ok := ref.(reference.Named); ok { - fmt.Println(r.Name()) - loadOpts.Name = r.Name() - } - } - if len(loadOpts.Input) > 0 { - if err := parse.ValidateFileName(loadOpts.Input); err != nil { - return err - } - } else { - if terminal.IsTerminal(int(os.Stdin.Fd())) { - return errors.Errorf("cannot read from terminal. Use command-line redirection or the --input flag.") - } - outFile, err := ioutil.TempFile(util.Tmpdir(), "podman") - if err != nil { - return errors.Errorf("error creating file %v", err) - } - defer os.Remove(outFile.Name()) - defer outFile.Close() - - _, err = io.Copy(outFile, os.Stdin) - if err != nil { - return errors.Errorf("error copying file %v", err) - } - loadOpts.Input = outFile.Name() - } - response, err := registry.ImageEngine().Load(context.Background(), loadOpts) - if err != nil { - return err - } - fmt.Println("Loaded image: " + response.Name) - return nil -} diff --git a/cmd/podmanV2/images/prune.go b/cmd/podmanV2/images/prune.go deleted file mode 100644 index 6577c458e..000000000 --- a/cmd/podmanV2/images/prune.go +++ /dev/null @@ -1,86 +0,0 @@ -package images - -import ( - "bufio" - "fmt" - "os" - "strings" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" -) - -var ( - pruneDescription = `Removes all unnamed images from local storage. - - If an image is not being used by a container, it will be removed from the system.` - pruneCmd = &cobra.Command{ - Use: "prune", - Args: cobra.NoArgs, - Short: "Remove unused images", - Long: pruneDescription, - RunE: prune, - Example: `podman image prune`, - } - - pruneOpts = entities.ImagePruneOptions{} - force bool - filter = []string{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pruneCmd, - Parent: imageCmd, - }) - - flags := pruneCmd.Flags() - flags.BoolVarP(&pruneOpts.All, "all", "a", false, "Remove all unused images, not just dangling ones") - flags.BoolVarP(&force, "force", "f", false, "Do not prompt for confirmation") - flags.StringArrayVar(&filter, "filter", []string{}, "Provide filter values (e.g. 'label=<key>=<value>')") - -} - -func prune(cmd *cobra.Command, args []string) error { - if !force { - reader := bufio.NewReader(os.Stdin) - fmt.Printf(` -WARNING! This will remove all dangling images. -Are you sure you want to continue? [y/N] `) - answer, err := reader.ReadString('\n') - if err != nil { - return errors.Wrapf(err, "error reading input") - } - if strings.ToLower(answer)[0] != 'y' { - return nil - } - } - - // TODO Remove once filter refactor is finished and url.Values rules :) - for _, f := range filter { - t := strings.SplitN(f, "=", 2) - pruneOpts.Filters.Add(t[0], t[1]) - } - - results, err := registry.ImageEngine().Prune(registry.GetContext(), pruneOpts) - if err != nil { - return err - } - - for _, i := range results.Report.Id { - fmt.Println(i) - } - - for _, e := range results.Report.Err { - fmt.Fprint(os.Stderr, e.Error()+"\n") - } - - if results.Size > 0 { - fmt.Fprintf(os.Stdout, "Size: %d\n", results.Size) - } - - return nil -} diff --git a/cmd/podmanV2/images/pull.go b/cmd/podmanV2/images/pull.go deleted file mode 100644 index 74090dee4..000000000 --- a/cmd/podmanV2/images/pull.go +++ /dev/null @@ -1,118 +0,0 @@ -package images - -import ( - "fmt" - - buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/image/v5/types" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -// pullOptionsWrapper wraps entities.ImagePullOptions and prevents leaking -// CLI-only fields into the API types. -type pullOptionsWrapper struct { - entities.ImagePullOptions - TLSVerifyCLI bool // CLI only -} - -var ( - pullOptions = pullOptionsWrapper{} - pullDescription = `Pulls an image from a registry and stores it locally. - - An image can be pulled by tag or digest. If a tag is not specified, the image with the 'latest' tag is pulled.` - - // Command: podman pull - pullCmd = &cobra.Command{ - Use: "pull [flags] IMAGE", - Args: cobra.ExactArgs(1), - Short: "Pull an image from a registry", - Long: pullDescription, - RunE: imagePull, - Example: `podman pull imageName - podman pull fedora:latest`, - } - - // Command: podman image pull - // It's basically a clone of `pullCmd` with the exception of being a - // child of the images command. - imagesPullCmd = &cobra.Command{ - Use: pullCmd.Use, - Short: pullCmd.Short, - Long: pullCmd.Long, - RunE: pullCmd.RunE, - Example: `podman image pull imageName - podman image pull fedora:latest`, - } -) - -func init() { - // pull - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pullCmd, - }) - - flags := pullCmd.Flags() - pullFlags(flags) - - // images pull - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imagesPullCmd, - Parent: imageCmd, - }) - - imagesPullFlags := imagesPullCmd.Flags() - pullFlags(imagesPullFlags) -} - -// pullFlags set the flags for the pull command. -func pullFlags(flags *pflag.FlagSet) { - flags.BoolVar(&pullOptions.AllTags, "all-tags", false, "All tagged images in the repository will be pulled") - flags.StringVar(&pullOptions.Authfile, "authfile", buildahcli.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") - flags.StringVar(&pullOptions.CertDir, "cert-dir", "", "`Pathname` of a directory containing TLS certificates and keys") - flags.StringVar(&pullOptions.Credentials, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") - flags.StringVar(&pullOptions.OverrideArch, "override-arch", "", "Use `ARCH` instead of the architecture of the machine for choosing images") - flags.StringVar(&pullOptions.OverrideOS, "override-os", "", "Use `OS` instead of the running OS for choosing images") - flags.BoolVarP(&pullOptions.Quiet, "quiet", "q", false, "Suppress output information when pulling images") - flags.StringVar(&pullOptions.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") - flags.BoolVar(&pullOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - - if registry.IsRemote() { - _ = flags.MarkHidden("authfile") - _ = flags.MarkHidden("cert-dir") - _ = flags.MarkHidden("signature-policy") - _ = flags.MarkHidden("tls-verify") - } -} - -// imagePull is implement the command for pulling images. -func imagePull(cmd *cobra.Command, args []string) error { - pullOptsAPI := pullOptions.ImagePullOptions - // 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") { - pullOptsAPI.TLSVerify = types.NewOptionalBool(pullOptions.TLSVerifyCLI) - } - - // Let's do all the remaining Yoga in the API to prevent us from - // scattering logic across (too) many parts of the code. - pullReport, err := registry.ImageEngine().Pull(registry.GetContext(), args[0], pullOptsAPI) - if err != nil { - return err - } - - if len(pullReport.Images) > 1 { - fmt.Println("Pulled Images:") - } - for _, img := range pullReport.Images { - fmt.Println(img) - } - - return nil -} diff --git a/cmd/podmanV2/images/push.go b/cmd/podmanV2/images/push.go deleted file mode 100644 index 51a60664b..000000000 --- a/cmd/podmanV2/images/push.go +++ /dev/null @@ -1,120 +0,0 @@ -package images - -import ( - buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/image/v5/types" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -// pushOptionsWrapper wraps entities.ImagepushOptions and prevents leaking -// CLI-only fields into the API types. -type pushOptionsWrapper struct { - entities.ImagePushOptions - TLSVerifyCLI bool // CLI only -} - -var ( - pushOptions = pushOptionsWrapper{} - pushDescription = `Pushes a source image to a specified destination. - - The Image "DESTINATION" uses a "transport":"details" format. See podman-push(1) section "DESTINATION" for the expected format.` - - // Command: podman push - pushCmd = &cobra.Command{ - Use: "push [flags] SOURCE DESTINATION", - Short: "Push an image to a specified destination", - Long: pushDescription, - RunE: imagePush, - Example: `podman push imageID docker://registry.example.com/repository:tag - podman push imageID oci-archive:/path/to/layout:image:tag`, - } - - // Command: podman image push - // It's basically a clone of `pushCmd` with the exception of being a - // child of the images command. - imagePushCmd = &cobra.Command{ - Use: pushCmd.Use, - Short: pushCmd.Short, - Long: pushCmd.Long, - RunE: pushCmd.RunE, - Example: `podman image push imageID docker://registry.example.com/repository:tag - podman image push imageID oci-archive:/path/to/layout:image:tag`, - } -) - -func init() { - // push - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: pushCmd, - }) - - flags := pushCmd.Flags() - pushFlags(flags) - - // images push - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imagePushCmd, - Parent: imageCmd, - }) - - pushFlags(imagePushCmd.Flags()) -} - -// pushFlags set the flags for the push command. -func pushFlags(flags *pflag.FlagSet) { - flags.StringVar(&pushOptions.Authfile, "authfile", buildahcli.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") - flags.StringVar(&pushOptions.CertDir, "cert-dir", "", "Path to a directory containing TLS certificates and keys") - flags.BoolVar(&pushOptions.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(&pushOptions.Credentials, "creds", "", "`Credentials` (USERNAME:PASSWORD) to use for authenticating to a registry") - flags.StringVar(&pushOptions.DigestFile, "digestfile", "", "Write the digest of the pushed image to the specified file") - flags.StringVarP(&pushOptions.Format, "format", "f", "", "Manifest type (oci, v2s1, or v2s2) to use when pushing an image using the 'dir' transport (default is manifest type of source)") - flags.BoolVarP(&pushOptions.Quiet, "quiet", "q", false, "Suppress output information when pushing images") - flags.BoolVar(&pushOptions.RemoveSignatures, "remove-signatures", false, "Discard any pre-existing signatures in the image") - flags.StringVar(&pushOptions.SignaturePolicy, "signature-policy", "", "Path to a signature-policy file") - flags.StringVar(&pushOptions.SignBy, "sign-by", "", "Add a signature at the destination using the specified key") - flags.BoolVar(&pushOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - - if registry.IsRemote() { - _ = flags.MarkHidden("authfile") - _ = flags.MarkHidden("cert-dir") - _ = flags.MarkHidden("compress") - _ = flags.MarkHidden("quiet") - _ = flags.MarkHidden("signature-policy") - _ = flags.MarkHidden("tls-verify") - } -} - -// imagePush is implement the command for pushing images. -func imagePush(cmd *cobra.Command, args []string) error { - var source, destination string - switch len(args) { - case 1: - source = args[0] - case 2: - source = args[0] - destination = args[1] - case 0: - fallthrough - default: - return errors.New("push requires at least one image name, or optionally a second to specify a different destination") - } - - pushOptsAPI := pushOptions.ImagePushOptions - // 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") { - pushOptsAPI.TLSVerify = types.NewOptionalBool(pushOptions.TLSVerifyCLI) - } - - // Let's do all the remaining Yoga in the API to prevent us from scattering - // logic across (too) many parts of the code. - return registry.ImageEngine().Push(registry.GetContext(), source, destination, pushOptsAPI) -} diff --git a/cmd/podmanV2/images/rm.go b/cmd/podmanV2/images/rm.go deleted file mode 100644 index f93d6ed50..000000000 --- a/cmd/podmanV2/images/rm.go +++ /dev/null @@ -1,71 +0,0 @@ -package images - -import ( - "fmt" - "os" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -var ( - rmDescription = "Removes one or more previously pulled or locally created images." - rmCmd = &cobra.Command{ - Use: "rm [flags] IMAGE [IMAGE...]", - Short: "Removes one or more images from local storage", - Long: rmDescription, - RunE: rm, - Example: `podman image rm imageID - podman image rm --force alpine - podman image rm c4dfb1609ee2 93fd78260bd1 c0ed59d05ff7`, - } - - imageOpts = entities.ImageDeleteOptions{} -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: rmCmd, - Parent: imageCmd, - }) - - imageRemoveFlagSet(rmCmd.Flags()) -} - -func imageRemoveFlagSet(flags *pflag.FlagSet) { - flags.BoolVarP(&imageOpts.All, "all", "a", false, "Remove all images") - flags.BoolVarP(&imageOpts.Force, "force", "f", false, "Force Removal of the image") -} -func rm(cmd *cobra.Command, args []string) error { - - if len(args) < 1 && !imageOpts.All { - return errors.Errorf("image name or ID must be specified") - } - if len(args) > 0 && imageOpts.All { - return errors.Errorf("when using the --all switch, you may not pass any images names or IDs") - } - report, err := registry.ImageEngine().Delete(registry.GetContext(), args, imageOpts) - if err != nil { - switch { - case report != nil && report.ImageNotFound != nil: - fmt.Fprintln(os.Stderr, err.Error()) - registry.SetExitCode(2) - case report != nil && report.ImageInUse != nil: - fmt.Fprintln(os.Stderr, err.Error()) - default: - return err - } - } - - for _, u := range report.Untagged { - fmt.Println("Untagged: " + u) - } - for _, d := range report.Deleted { - fmt.Println("Deleted: " + d) - } - return nil -} diff --git a/cmd/podmanV2/images/rmi.go b/cmd/podmanV2/images/rmi.go deleted file mode 100644 index ae199b789..000000000 --- a/cmd/podmanV2/images/rmi.go +++ /dev/null @@ -1,28 +0,0 @@ -package images - -import ( - "strings" - - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - rmiCmd = &cobra.Command{ - Use: strings.Replace(rmCmd.Use, "rm ", "rmi ", 1), - Args: rmCmd.Args, - Short: rmCmd.Short, - Long: rmCmd.Long, - RunE: rmCmd.RunE, - Example: strings.Replace(rmCmd.Example, "podman image rm", "podman rmi", -1), - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: rmiCmd, - }) - imageRemoveFlagSet(rmiCmd.Flags()) -} diff --git a/cmd/podmanV2/images/save.go b/cmd/podmanV2/images/save.go deleted file mode 100644 index 29ee79392..000000000 --- a/cmd/podmanV2/images/save.go +++ /dev/null @@ -1,86 +0,0 @@ -package images - -import ( - "context" - "os" - "strings" - - "github.com/containers/libpod/libpod/define" - - "github.com/containers/libpod/cmd/podmanV2/parse" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/util" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "golang.org/x/crypto/ssh/terminal" -) - -var validFormats = []string{define.OCIManifestDir, define.OCIArchive, define.V2s2ManifestDir, define.V2s2Archive} - -var ( - saveDescription = `Save an image to docker-archive or oci-archive on the local machine. Default is docker-archive.` - - saveCommand = &cobra.Command{ - Use: "save [flags] IMAGE", - Short: "Save image to an archive", - Long: saveDescription, - RunE: save, - Args: func(cmd *cobra.Command, args []string) error { - if len(args) == 0 { - return errors.Errorf("need at least 1 argument") - } - format, err := cmd.Flags().GetString("format") - if err != nil { - return err - } - if !util.StringInSlice(format, validFormats) { - return errors.Errorf("format value must be one of %s", strings.Join(validFormats, " ")) - } - return nil - }, - Example: `podman save --quiet -o myimage.tar imageID - podman save --format docker-dir -o ubuntu-dir ubuntu - podman save > alpine-all.tar alpine:latest`, - } -) - -var ( - saveOpts entities.ImageSaveOptions -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: saveCommand, - }) - flags := saveCommand.Flags() - flags.BoolVar(&saveOpts.Compress, "compress", false, "Compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)") - 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") - -} - -func save(cmd *cobra.Command, args []string) error { - var ( - tags []string - ) - if cmd.Flag("compress").Changed && (saveOpts.Format != define.OCIManifestDir && saveOpts.Format != define.V2s2ManifestDir && saveOpts.Format == "") { - return errors.Errorf("--compress can only be set when --format is either 'oci-dir' or 'docker-dir'") - } - if len(saveOpts.Output) == 0 { - fi := os.Stdout - if terminal.IsTerminal(int(fi.Fd())) { - return errors.Errorf("refusing to save to terminal. Use -o flag or redirect") - } - saveOpts.Output = "/dev/stdout" - } - if err := parse.ValidateFileName(saveOpts.Output); err != nil { - return err - } - if len(args) > 1 { - tags = args[1:] - } - return registry.ImageEngine().Save(context.Background(), args[0], tags, saveOpts) -} diff --git a/cmd/podmanV2/images/search.go b/cmd/podmanV2/images/search.go deleted file mode 100644 index 17c72784c..000000000 --- a/cmd/podmanV2/images/search.go +++ /dev/null @@ -1,156 +0,0 @@ -package images - -import ( - "reflect" - "strings" - - buildahcli "github.com/containers/buildah/pkg/cli" - "github.com/containers/buildah/pkg/formats" - "github.com/containers/image/v5/types" - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/containers/libpod/pkg/util/camelcase" - "github.com/pkg/errors" - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -// searchOptionsWrapper wraps entities.ImagePullOptions and prevents leaking -// CLI-only fields into the API types. -type searchOptionsWrapper struct { - entities.ImageSearchOptions - // CLI only flags - TLSVerifyCLI bool // Used to convert to an optional bool later - Format string // For go templating -} - -var ( - searchOptions = searchOptionsWrapper{} - searchDescription = `Search registries for a given image. Can search all the default registries or a specific registry. - - Users can limit the number of results, and filter the output based on certain conditions.` - - // Command: podman search - searchCmd = &cobra.Command{ - Use: "search [flags] TERM", - Short: "Search registry for image", - Long: searchDescription, - RunE: imageSearch, - Args: cobra.ExactArgs(1), - Annotations: map[string]string{ - registry.ParentNSRequired: "", - }, - Example: `podman search --filter=is-official --limit 3 alpine - podman search registry.fedoraproject.org/ # only works with v2 registries - podman search --format "table {{.Index}} {{.Name}}" registry.fedoraproject.org/fedora`, - } - - // Command: podman image search - imageSearchCmd = &cobra.Command{ - Use: searchCmd.Use, - Short: searchCmd.Short, - Long: searchCmd.Long, - RunE: searchCmd.RunE, - Args: searchCmd.Args, - Example: `podman image search --filter=is-official --limit 3 alpine - podman image search registry.fedoraproject.org/ # only works with v2 registries - podman image search --format "table {{.Index}} {{.Name}}" registry.fedoraproject.org/fedora`, - } -) - -func init() { - // search - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: searchCmd, - }) - - flags := searchCmd.Flags() - searchFlags(flags) - - // images search - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: imageSearchCmd, - Parent: imageCmd, - }) - - imageSearchFlags := imageSearchCmd.Flags() - searchFlags(imageSearchFlags) -} - -// searchFlags set the flags for the pull command. -func searchFlags(flags *pflag.FlagSet) { - flags.StringSliceVarP(&searchOptions.Filters, "filter", "f", []string{}, "Filter output based on conditions provided (default [])") - flags.StringVar(&searchOptions.Format, "format", "", "Change the output format to a Go template") - flags.IntVar(&searchOptions.Limit, "limit", 0, "Limit the number of results") - flags.BoolVar(&searchOptions.NoTrunc, "no-trunc", false, "Do not truncate the output") - flags.StringVar(&searchOptions.Authfile, "authfile", buildahcli.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override") - flags.BoolVar(&searchOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries") - if registry.IsRemote() { - _ = flags.MarkHidden("authfile") - _ = flags.MarkHidden("tls-verify") - } -} - -// imageSearch implements the command for searching images. -func imageSearch(cmd *cobra.Command, args []string) error { - searchTerm := "" - switch len(args) { - case 1: - searchTerm = args[0] - default: - return errors.Errorf("search requires exactly one argument") - } - - sarchOptsAPI := searchOptions.ImageSearchOptions - // 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") { - sarchOptsAPI.TLSVerify = types.NewOptionalBool(pullOptions.TLSVerifyCLI) - } - - searchReport, err := registry.ImageEngine().Search(registry.GetContext(), searchTerm, sarchOptsAPI) - 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), " ")) - } - return values -} - -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) - } - return "table {{.Index}}\t{{.Name}}\t{{.Description}}\t{{.Stars}}\t{{.Official}}\t{{.Automated}}\t" -} - -func searchToGeneric(params []entities.ImageSearchReport) (genericParams []interface{}) { - for _, v := range params { - genericParams = append(genericParams, interface{}(v)) - } - return genericParams -} diff --git a/cmd/podmanV2/images/tag.go b/cmd/podmanV2/images/tag.go deleted file mode 100644 index bf3cf0de6..000000000 --- a/cmd/podmanV2/images/tag.go +++ /dev/null @@ -1,32 +0,0 @@ -package images - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - tagDescription = "Adds one or more additional names to locally-stored image." - tagCommand = &cobra.Command{ - Use: "tag [flags] IMAGE TARGET_NAME [TARGET_NAME...]", - Short: "Add an additional name to a local image", - Long: tagDescription, - RunE: tag, - Args: cobra.MinimumNArgs(2), - Example: `podman tag 0e3bbc2 fedora:latest - podman tag imageID:latest myNewImage:newTag - podman tag httpd myregistryhost:5000/fedora/httpd:v2`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: tagCommand, - }) -} - -func tag(cmd *cobra.Command, args []string) error { - return registry.ImageEngine().Tag(registry.GetContext(), args[0], args[1:], entities.ImageTagOptions{}) -} diff --git a/cmd/podmanV2/images/untag.go b/cmd/podmanV2/images/untag.go deleted file mode 100644 index 5eca1cb78..000000000 --- a/cmd/podmanV2/images/untag.go +++ /dev/null @@ -1,31 +0,0 @@ -package images - -import ( - "github.com/containers/libpod/cmd/podmanV2/registry" - "github.com/containers/libpod/pkg/domain/entities" - "github.com/spf13/cobra" -) - -var ( - untagCommand = &cobra.Command{ - Use: "untag [flags] IMAGE [NAME...]", - Short: "Remove a name from a local image", - Long: "Removes one or more names from a locally-stored image.", - RunE: untag, - Args: cobra.MinimumNArgs(1), - Example: `podman untag 0e3bbc2 - podman untag imageID:latest otherImageName:latest - podman untag httpd myregistryhost:5000/fedora/httpd:v2`, - } -) - -func init() { - registry.Commands = append(registry.Commands, registry.CliCommand{ - Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode}, - Command: untagCommand, - }) -} - -func untag(cmd *cobra.Command, args []string) error { - return registry.ImageEngine().Untag(registry.GetContext(), args[0], args[1:], entities.ImageUntagOptions{}) -} |