-
Notifications
You must be signed in to change notification settings - Fork 3
/
service.go
118 lines (106 loc) · 3.29 KB
/
service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package registry
import (
"github.com/docker/docker/engine"
)
// Service exposes registry capabilities in the standard Engine
// interface. Once installed, it extends the engine with the
// following calls:
//
// 'auth': Authenticate against the public registry
// '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 {
insecureRegistries []string
}
// NewService returns a new instance of Service ready to be
// installed no an engine.
func NewService(insecureRegistries []string) *Service {
return &Service{
insecureRegistries: insecureRegistries,
}
}
// 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
}
// Auth contacts the public registry with the provided credentials,
// and returns OK if authentication was sucessful.
// It can be used to verify the validity of a client's credentials.
func (s *Service) Auth(job *engine.Job) engine.Status {
var authConfig = new(AuthConfig)
job.GetenvJson("authConfig", authConfig)
if addr := authConfig.ServerAddress; addr != "" && addr != IndexServerAddress() {
endpoint, err := NewEndpoint(addr, s.insecureRegistries)
if err != nil {
return job.Error(err)
}
if _, err := endpoint.Ping(); err != nil {
return job.Error(err)
}
authConfig.ServerAddress = endpoint.String()
}
status, err := Login(authConfig, HTTPRequestFactory(nil))
if err != nil {
return job.Error(err)
}
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)
hostname, term, err := ResolveRepositoryName(term)
if err != nil {
return job.Error(err)
}
endpoint, err := NewEndpoint(hostname, s.insecureRegistries)
if err != nil {
return job.Error(err)
}
r, err := NewSession(authConfig, HTTPRequestFactory(metaHeaders), endpoint, true)
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
}