Files
docker-cli/components/engine/api/client/search.go
Aaron Lehmann 9ca2cca984 Introduce a client-side version of resolveAuthConfig
This is similar to the version in the registry package, but uses the
daemon's default index (as opposed to the default for the client's
platform) if using the "official index".

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
Upstream-commit: ff17cd0bf07fb8fbd811b3a1bf472d701405b1d1
Component: engine
2016-02-03 11:01:29 -08:00

92 lines
2.6 KiB
Go

package client
import (
"fmt"
"net/url"
"sort"
"strings"
"text/tabwriter"
Cli "github.com/docker/docker/cli"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/pkg/stringutils"
"github.com/docker/docker/registry"
"github.com/docker/engine-api/types"
registrytypes "github.com/docker/engine-api/types/registry"
)
// CmdSearch searches the Docker Hub for images.
//
// Usage: docker search [OPTIONS] TERM
func (cli *DockerCli) CmdSearch(args ...string) error {
cmd := Cli.Subcmd("search", []string{"TERM"}, Cli.DockerCommands["search"].Description, true)
noTrunc := cmd.Bool([]string{"-no-trunc"}, false, "Don't truncate output")
automated := cmd.Bool([]string{"-automated"}, false, "Only show automated builds")
stars := cmd.Uint([]string{"s", "-stars"}, 0, "Only displays with at least x stars")
cmd.Require(flag.Exact, 1)
cmd.ParseFlags(args, true)
name := cmd.Arg(0)
v := url.Values{}
v.Set("term", name)
indexInfo, err := registry.ParseSearchIndexInfo(name)
if err != nil {
return err
}
authConfig := cli.resolveAuthConfig(cli.configFile.AuthConfigs, indexInfo)
requestPrivilege := cli.registryAuthenticationPrivilegedFunc(indexInfo, "search")
encodedAuth, err := encodeAuthToBase64(authConfig)
if err != nil {
return err
}
options := types.ImageSearchOptions{
Term: name,
RegistryAuth: encodedAuth,
}
unorderedResults, err := cli.client.ImageSearch(options, requestPrivilege)
if err != nil {
return err
}
results := searchResultsByStars(unorderedResults)
sort.Sort(results)
w := tabwriter.NewWriter(cli.out, 10, 1, 3, ' ', 0)
fmt.Fprintf(w, "NAME\tDESCRIPTION\tSTARS\tOFFICIAL\tAUTOMATED\n")
for _, res := range results {
if (*automated && !res.IsAutomated) || (int(*stars) > res.StarCount) {
continue
}
desc := strings.Replace(res.Description, "\n", " ", -1)
desc = strings.Replace(desc, "\r", " ", -1)
if !*noTrunc && len(desc) > 45 {
desc = stringutils.Truncate(desc, 42) + "..."
}
fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount)
if res.IsOfficial {
fmt.Fprint(w, "[OK]")
}
fmt.Fprint(w, "\t")
if res.IsAutomated || res.IsTrusted {
fmt.Fprint(w, "[OK]")
}
fmt.Fprint(w, "\n")
}
w.Flush()
return nil
}
// SearchResultsByStars sorts search results in descending order by number of stars.
type searchResultsByStars []registrytypes.SearchResult
func (r searchResultsByStars) Len() int { return len(r) }
func (r searchResultsByStars) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
func (r searchResultsByStars) Less(i, j int) bool { return r[j].StarCount < r[i].StarCount }