service.go 3.0 KB

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