Browse code

Implemented command

shin- authored on 2013/05/07 19:49:08
Showing 3 changed files
... ...
@@ -56,6 +56,7 @@ func (srv *Server) Help() string {
56 56
 		{"rm", "Remove a container"},
57 57
 		{"rmi", "Remove an image"},
58 58
 		{"run", "Run a command in a new container"},
59
+		{"search", "Search for an image in the docker index"}
59 60
 		{"start", "Start a stopped container"},
60 61
 		{"stop", "Stop a running container"},
61 62
 		{"tag", "Tag an image into a repository"},
... ...
@@ -1001,6 +1002,34 @@ func (srv *Server) CmdAttach(stdin io.ReadCloser, stdout rcli.DockerConn, args .
1001 1001
 	return <-container.Attach(stdin, nil, stdout, stdout)
1002 1002
 }
1003 1003
 
1004
+func (srv *Server) CmdSearch(stdin io.ReadCloser, stdout rcli.DockerConn, args ...string) error {
1005
+	cmd := rcli.Subcmd(stdout, "search", "NAME", "Search the docker index for images")
1006
+	if err := cmd.Parse(args); err != nil {
1007
+		return nil
1008
+	}
1009
+	if cmd.NArg() != 1 {
1010
+		cmd.Usage()
1011
+		return nil
1012
+	}
1013
+	term := cmd.Arg(0)
1014
+	results, err := srv.runtime.graph.SearchRepositories(stdout, term)
1015
+	if err != nil {
1016
+		return err
1017
+	}
1018
+	fmt.Fprintf(stdout, "Found %d results matching your query (\"%s\")\n", results.NumResults, results.Query)
1019
+	w := tabwriter.NewWriter(stdout, 20, 1, 3, ' ', 0)
1020
+	fmt.Fprintf(w, "NAME\tDESCRIPTION\n")
1021
+	for _, repo := range results.Results {
1022
+		description := repo["description"]
1023
+		if len(description) > 45 {
1024
+			description = Trunc(description, 42) + "..."
1025
+		}
1026
+		fmt.Fprintf(w, "%s\t%s\n", repo["name"], description)
1027
+	}
1028
+	w.Flush()
1029
+	return nil
1030
+}
1031
+
1004 1032
 // Ports type - Used to parse multiple -p flags
1005 1033
 type ports []int
1006 1034
 
... ...
@@ -9,6 +9,7 @@ import (
9 9
 	"io"
10 10
 	"io/ioutil"
11 11
 	"net/http"
12
+	"net/url"
12 13
 	"path"
13 14
 	"strings"
14 15
 )
... ...
@@ -638,3 +639,33 @@ func (graph *Graph) Checksums(output io.Writer, repo Repository) ([]map[string]s
638 638
 	}
639 639
 	return result, nil
640 640
 }
641
+
642
+type SearchResults struct {
643
+	Query      string              `json:"query"`
644
+	NumResults int                 `json:"num_results"`
645
+	Results    []map[string]string `json:"results"`
646
+}
647
+
648
+func (graph *Graph) SearchRepositories(stdout io.Writer, term string) (*SearchResults, error) {
649
+	client := graph.getHttpClient()
650
+	u := INDEX_ENDPOINT + "/search?q=" + url.QueryEscape(term)
651
+	req, err := http.NewRequest("GET", u, nil)
652
+	if err != nil {
653
+		return nil, err
654
+	}
655
+	res, err := client.Do(req)
656
+	if err != nil {
657
+		return nil, err
658
+	}
659
+	defer res.Body.Close()
660
+	if res.StatusCode != 200 {
661
+		return nil, fmt.Errorf("Unexepected status code %d", res.StatusCode)
662
+	}
663
+	rawData, err := ioutil.ReadAll(res.Body)
664
+	if err != nil {
665
+		return nil, err
666
+	}
667
+	result := new(SearchResults)
668
+	err = json.Unmarshal(rawData, result)
669
+	return result, err
670
+}
... ...
@@ -404,7 +404,6 @@ func CopyEscapable(dst io.Writer, src io.ReadCloser) (written int64, err error)
404 404
 	return written, err
405 405
 }
406 406
 
407
-
408 407
 func HashData(src io.Reader) (string, error) {
409 408
 	h := sha256.New()
410 409
 	if _, err := io.Copy(h, src); err != nil {