github.com/stchris/docker@v1.4.2-0.20150106053530-1510a324dbd5/registry/service.go (about) 1 package registry 2 3 import ( 4 "github.com/docker/docker/engine" 5 ) 6 7 // Service exposes registry capabilities in the standard Engine 8 // interface. Once installed, it extends the engine with the 9 // following calls: 10 // 11 // 'auth': Authenticate against the public registry 12 // 'search': Search for images on the public registry 13 // 'pull': Download images from any registry (TODO) 14 // 'push': Upload images to any registry (TODO) 15 type Service struct { 16 insecureRegistries []string 17 } 18 19 // NewService returns a new instance of Service ready to be 20 // installed no an engine. 21 func NewService(insecureRegistries []string) *Service { 22 return &Service{ 23 insecureRegistries: insecureRegistries, 24 } 25 } 26 27 // Install installs registry capabilities to eng. 28 func (s *Service) Install(eng *engine.Engine) error { 29 eng.Register("auth", s.Auth) 30 eng.Register("search", s.Search) 31 return nil 32 } 33 34 // Auth contacts the public registry with the provided credentials, 35 // and returns OK if authentication was sucessful. 36 // It can be used to verify the validity of a client's credentials. 37 func (s *Service) Auth(job *engine.Job) engine.Status { 38 var authConfig = new(AuthConfig) 39 40 job.GetenvJson("authConfig", authConfig) 41 42 if addr := authConfig.ServerAddress; addr != "" && addr != IndexServerAddress() { 43 endpoint, err := NewEndpoint(addr, s.insecureRegistries) 44 if err != nil { 45 return job.Error(err) 46 } 47 if _, err := endpoint.Ping(); err != nil { 48 return job.Error(err) 49 } 50 authConfig.ServerAddress = endpoint.String() 51 } 52 53 status, err := Login(authConfig, HTTPRequestFactory(nil)) 54 if err != nil { 55 return job.Error(err) 56 } 57 job.Printf("%s\n", status) 58 59 return engine.StatusOK 60 } 61 62 // Search queries the public registry for images matching the specified 63 // search terms, and returns the results. 64 // 65 // Argument syntax: search TERM 66 // 67 // Option environment: 68 // 'authConfig': json-encoded credentials to authenticate against the registry. 69 // The search extends to images only accessible via the credentials. 70 // 71 // 'metaHeaders': extra HTTP headers to include in the request to the registry. 72 // The headers should be passed as a json-encoded dictionary. 73 // 74 // Output: 75 // Results are sent as a collection of structured messages (using engine.Table). 76 // Each result is sent as a separate message. 77 // Results are ordered by number of stars on the public registry. 78 func (s *Service) Search(job *engine.Job) engine.Status { 79 if n := len(job.Args); n != 1 { 80 return job.Errorf("Usage: %s TERM", job.Name) 81 } 82 var ( 83 term = job.Args[0] 84 metaHeaders = map[string][]string{} 85 authConfig = &AuthConfig{} 86 ) 87 job.GetenvJson("authConfig", authConfig) 88 job.GetenvJson("metaHeaders", metaHeaders) 89 90 hostname, term, err := ResolveRepositoryName(term) 91 if err != nil { 92 return job.Error(err) 93 } 94 95 endpoint, err := NewEndpoint(hostname, s.insecureRegistries) 96 if err != nil { 97 return job.Error(err) 98 } 99 r, err := NewSession(authConfig, HTTPRequestFactory(metaHeaders), endpoint, true) 100 if err != nil { 101 return job.Error(err) 102 } 103 results, err := r.SearchRepositories(term) 104 if err != nil { 105 return job.Error(err) 106 } 107 outs := engine.NewTable("star_count", 0) 108 for _, result := range results.Results { 109 out := &engine.Env{} 110 out.Import(result) 111 outs.Add(out) 112 } 113 outs.ReverseSort() 114 if _, err := outs.WriteListTo(job.Stdout); err != nil { 115 return job.Error(err) 116 } 117 return engine.StatusOK 118 }