diff --git a/docs/service.go b/docs/service.go index 530a7f7a..1c7a93de 100644 --- a/docs/service.go +++ b/docs/service.go @@ -9,7 +9,7 @@ import ( // following calls: // // 'auth': Authenticate against the public registry -// 'search': Search for images on the public registry (TODO) +// 'search': Search for images on the public registry // 'pull': Download images from any registry (TODO) // 'push': Upload images to any registry (TODO) type Service struct { @@ -24,6 +24,7 @@ func NewService() *Service { // Install installs registry capabilities to eng. func (s *Service) Install(eng *engine.Engine) error { eng.Register("auth", s.Auth) + eng.Register("search", s.Search) return nil } @@ -52,3 +53,52 @@ func (s *Service) Auth(job *engine.Job) engine.Status { job.Printf("%s\n", status) return engine.StatusOK } + +// Search queries the public registry for images matching the specified +// search terms, and returns the results. +// +// Argument syntax: search TERM +// +// Option environment: +// 'authConfig': json-encoded credentials to authenticate against the registry. +// The search extends to images only accessible via the credentials. +// +// 'metaHeaders': extra HTTP headers to include in the request to the registry. +// The headers should be passed as a json-encoded dictionary. +// +// Output: +// Results are sent as a collection of structured messages (using engine.Table). +// Each result is sent as a separate message. +// Results are ordered by number of stars on the public registry. +func (s *Service) Search(job *engine.Job) engine.Status { + if n := len(job.Args); n != 1 { + return job.Errorf("Usage: %s TERM", job.Name) + } + var ( + term = job.Args[0] + metaHeaders = map[string][]string{} + authConfig = &AuthConfig{} + ) + job.GetenvJson("authConfig", authConfig) + job.GetenvJson("metaHeaders", metaHeaders) + + r, err := NewRegistry(authConfig, HTTPRequestFactory(metaHeaders), IndexServerAddress()) + if err != nil { + return job.Error(err) + } + results, err := r.SearchRepositories(term) + if err != nil { + return job.Error(err) + } + outs := engine.NewTable("star_count", 0) + for _, result := range results.Results { + out := &engine.Env{} + out.Import(result) + outs.Add(out) + } + outs.ReverseSort() + if _, err := outs.WriteListTo(job.Stdout); err != nil { + return job.Error(err) + } + return engine.StatusOK +}