summaryrefslogtreecommitdiff
path: root/cmd/podman/images/search.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/podman/images/search.go')
-rw-r--r--cmd/podman/images/search.go93
1 files changed, 58 insertions, 35 deletions
diff --git a/cmd/podman/images/search.go b/cmd/podman/images/search.go
index b1a1442a6..c2ef7d767 100644
--- a/cmd/podman/images/search.go
+++ b/cmd/podman/images/search.go
@@ -1,18 +1,20 @@
package images
import (
+ "fmt"
"os"
"text/tabwriter"
"text/template"
"github.com/containers/common/pkg/auth"
+ "github.com/containers/common/pkg/completion"
"github.com/containers/common/pkg/report"
"github.com/containers/image/v5/types"
+ "github.com/containers/podman/v2/cmd/podman/parse"
"github.com/containers/podman/v2/cmd/podman/registry"
"github.com/containers/podman/v2/pkg/domain/entities"
"github.com/pkg/errors"
"github.com/spf13/cobra"
- "github.com/spf13/pflag"
)
// searchOptionsWrapper wraps entities.ImagePullOptions and prevents leaking
@@ -32,11 +34,12 @@ var (
// Command: podman search
searchCmd = &cobra.Command{
- Use: "search [options] TERM",
- Short: "Search registry for image",
- Long: searchDescription,
- RunE: imageSearch,
- Args: cobra.ExactArgs(1),
+ Use: "search [options] TERM",
+ Short: "Search registry for image",
+ Long: searchDescription,
+ RunE: imageSearch,
+ Args: cobra.ExactArgs(1),
+ ValidArgsFunction: completion.AutocompleteNone,
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`,
@@ -44,12 +47,13 @@ var (
// Command: podman image search
imageSearchCmd = &cobra.Command{
- Use: searchCmd.Use,
- Short: searchCmd.Short,
- Long: searchCmd.Long,
- RunE: searchCmd.RunE,
- Args: searchCmd.Args,
- Annotations: searchCmd.Annotations,
+ Use: searchCmd.Use,
+ Short: searchCmd.Short,
+ Long: searchCmd.Long,
+ RunE: searchCmd.RunE,
+ Args: searchCmd.Args,
+ Annotations: searchCmd.Annotations,
+ ValidArgsFunction: searchCmd.ValidArgsFunction,
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`,
@@ -62,9 +66,7 @@ func init() {
Mode: []entities.EngineMode{entities.ABIMode, entities.TunnelMode},
Command: searchCmd,
})
-
- flags := searchCmd.Flags()
- searchFlags(flags)
+ searchFlags(searchCmd)
// images search
registry.Commands = append(registry.Commands, registry.CliCommand{
@@ -72,18 +74,32 @@ func init() {
Command: imageSearchCmd,
Parent: imageCmd,
})
-
- imageSearchFlags := imageSearchCmd.Flags()
- searchFlags(imageSearchFlags)
+ searchFlags(imageSearchCmd)
}
// 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")
+func searchFlags(cmd *cobra.Command) {
+ flags := cmd.Flags()
+
+ filterFlagName := "filter"
+ flags.StringSliceVarP(&searchOptions.Filters, filterFlagName, "f", []string{}, "Filter output based on conditions provided (default [])")
+ //TODO add custom filter function
+ _ = cmd.RegisterFlagCompletionFunc(filterFlagName, completion.AutocompleteNone)
+
+ formatFlagName := "format"
+ flags.StringVar(&searchOptions.Format, formatFlagName, "", "Change the output format to JSON or a Go template")
+ _ = cmd.RegisterFlagCompletionFunc(formatFlagName, completion.AutocompleteNone)
+
+ limitFlagName := "limit"
+ flags.IntVar(&searchOptions.Limit, limitFlagName, 0, "Limit the number of results")
+ _ = cmd.RegisterFlagCompletionFunc(limitFlagName, completion.AutocompleteNone)
+
flags.BoolVar(&searchOptions.NoTrunc, "no-trunc", false, "Do not truncate the output")
- flags.StringVar(&searchOptions.Authfile, "authfile", auth.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
+
+ authfileFlagName := "authfile"
+ flags.StringVar(&searchOptions.Authfile, authfileFlagName, auth.GetDefaultAuthFile(), "Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override")
+ _ = cmd.RegisterFlagCompletionFunc(authfileFlagName, completion.AutocompleteDefault)
+
flags.BoolVar(&searchOptions.TLSVerifyCLI, "tls-verify", true, "Require HTTPS and verify certificates when contacting registries")
flags.BoolVar(&searchOptions.ListTags, "list-tags", false, "List the tags of the input registry")
}
@@ -98,10 +114,6 @@ func imageSearch(cmd *cobra.Command, args []string) error {
return errors.Errorf("search requires exactly one argument")
}
- if searchOptions.Limit > 100 {
- return errors.Errorf("Limit %d is outside the range of [1, 100]", searchOptions.Limit)
- }
-
if searchOptions.ListTags && len(searchOptions.Filters) != 0 {
return errors.Errorf("filters are not applicable to list tags result")
}
@@ -116,7 +128,7 @@ func imageSearch(cmd *cobra.Command, args []string) error {
if searchOptions.Authfile != "" {
if _, err := os.Stat(searchOptions.Authfile); err != nil {
- return errors.Wrapf(err, "error getting authfile %s", searchOptions.Authfile)
+ return err
}
}
@@ -130,26 +142,37 @@ func imageSearch(cmd *cobra.Command, args []string) error {
}
hdrs := report.Headers(entities.ImageSearchReport{}, nil)
- row := "{{.Index}}\t{{.Name}}\t{{.Description}}\t{{.Stars}}\t{{.Official}}\t{{.Automated}}\n"
- if searchOptions.ListTags {
+ renderHeaders := true
+ var row string
+ switch {
+ case searchOptions.ListTags:
if len(searchOptions.Filters) != 0 {
return errors.Errorf("filters are not applicable to list tags result")
}
row = "{{.Name}}\t{{.Tag}}\n"
- }
- if cmd.Flags().Changed("format") {
+ case report.IsJSON(searchOptions.Format):
+ prettyJSON, err := json.MarshalIndent(searchReport, "", " ")
+ if err != nil {
+ return err
+ }
+ fmt.Println(string(prettyJSON))
+ return nil
+ case cmd.Flags().Changed("format"):
+ renderHeaders = parse.HasTable(searchOptions.Format)
row = report.NormalizeFormat(searchOptions.Format)
+ default:
+ row = "{{.Index}}\t{{.Name}}\t{{.Description}}\t{{.Stars}}\t{{.Official}}\t{{.Automated}}\n"
}
- row = "{{range .}}" + row + "{{end}}"
+ format := parse.EnforceRange(row)
- tmpl, err := template.New("search").Parse(row)
+ tmpl, err := template.New("search").Parse(format)
if err != nil {
return err
}
w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0)
defer w.Flush()
- if !cmd.Flags().Changed("format") {
+ if renderHeaders {
if err := tmpl.Execute(w, hdrs); err != nil {
return errors.Wrapf(err, "failed to write search column headers")
}