Prechádzať zdrojové kódy

Merge pull request #5575 from vieux/pr-5428

Victor Vieux 11 rokov pred
rodič
commit
51933bd5e1
5 zmenil súbory, kde vykonal 164 pridanie a 105 odobranie
  1. 16 8
      builtins/builtins.go
  2. 3 1
      docker/docker.go
  3. 39 0
      registry/registry.go
  4. 104 0
      registry/service.go
  5. 2 96
      server/server.go

+ 16 - 8
builtins/builtins.go

@@ -4,17 +4,23 @@ import (
 	api "github.com/dotcloud/docker/api/server"
 	"github.com/dotcloud/docker/daemon/networkdriver/bridge"
 	"github.com/dotcloud/docker/engine"
+	"github.com/dotcloud/docker/registry"
 	"github.com/dotcloud/docker/server"
 )
 
-func Register(eng *engine.Engine) {
-	daemon(eng)
-	remote(eng)
+func Register(eng *engine.Engine) error {
+	if err := daemon(eng); err != nil {
+		return err
+	}
+	if err := remote(eng); err != nil {
+		return err
+	}
+	return registry.NewService().Install(eng)
 }
 
 // remote: a RESTful api for cross-docker communication
-func remote(eng *engine.Engine) {
-	eng.Register("serveapi", api.ServeApi)
+func remote(eng *engine.Engine) error {
+	return eng.Register("serveapi", api.ServeApi)
 }
 
 // daemon: a default execution and storage backend for Docker on Linux,
@@ -32,7 +38,9 @@ func remote(eng *engine.Engine) {
 //
 // These components should be broken off into plugins of their own.
 //
-func daemon(eng *engine.Engine) {
-	eng.Register("initserver", server.InitServer)
-	eng.Register("init_networkdriver", bridge.InitDriver)
+func daemon(eng *engine.Engine) error {
+	if err := eng.Register("initserver", server.InitServer); err != nil {
+		return err
+	}
+	return eng.Register("init_networkdriver", bridge.InitDriver)
 }

+ 3 - 1
docker/docker.go

@@ -132,7 +132,9 @@ func main() {
 
 		eng := engine.New()
 		// Load builtins
-		builtins.Register(eng)
+		if err := builtins.Register(eng); err != nil {
+			log.Fatal(err)
+		}
 		// load the daemon in the background so we can immediately start
 		// the http api so that connections don't fail while the daemon
 		// is booting

+ 39 - 0
registry/registry.go

@@ -13,10 +13,12 @@ import (
 	"net/http/cookiejar"
 	"net/url"
 	"regexp"
+	"runtime"
 	"strconv"
 	"strings"
 	"time"
 
+	"github.com/dotcloud/docker/dockerversion"
 	"github.com/dotcloud/docker/utils"
 )
 
@@ -757,3 +759,40 @@ func NewRegistry(authConfig *AuthConfig, factory *utils.HTTPRequestFactory, inde
 	r.reqFactory = factory
 	return r, nil
 }
+
+func HTTPRequestFactory(metaHeaders map[string][]string) *utils.HTTPRequestFactory {
+	// FIXME: this replicates the 'info' job.
+	httpVersion := make([]utils.VersionInfo, 0, 4)
+	httpVersion = append(httpVersion, &simpleVersionInfo{"docker", dockerversion.VERSION})
+	httpVersion = append(httpVersion, &simpleVersionInfo{"go", runtime.Version()})
+	httpVersion = append(httpVersion, &simpleVersionInfo{"git-commit", dockerversion.GITCOMMIT})
+	if kernelVersion, err := utils.GetKernelVersion(); err == nil {
+		httpVersion = append(httpVersion, &simpleVersionInfo{"kernel", kernelVersion.String()})
+	}
+	httpVersion = append(httpVersion, &simpleVersionInfo{"os", runtime.GOOS})
+	httpVersion = append(httpVersion, &simpleVersionInfo{"arch", runtime.GOARCH})
+	ud := utils.NewHTTPUserAgentDecorator(httpVersion...)
+	md := &utils.HTTPMetaHeadersDecorator{
+		Headers: metaHeaders,
+	}
+	factory := utils.NewHTTPRequestFactory(ud, md)
+	return factory
+}
+
+// simpleVersionInfo is a simple implementation of
+// the interface VersionInfo, which is used
+// to provide version information for some product,
+// component, etc. It stores the product name and the version
+// in string and returns them on calls to Name() and Version().
+type simpleVersionInfo struct {
+	name    string
+	version string
+}
+
+func (v *simpleVersionInfo) Name() string {
+	return v.name
+}
+
+func (v *simpleVersionInfo) Version() string {
+	return v.version
+}

+ 104 - 0
registry/service.go

@@ -0,0 +1,104 @@
+package registry
+
+import (
+	"github.com/dotcloud/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 {
+}
+
+// NewService returns a new instance of Service ready to be
+// installed no an engine.
+func NewService() *Service {
+	return &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
+}
+
+// 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 (
+		err        error
+		authConfig = &AuthConfig{}
+	)
+
+	job.GetenvJson("authConfig", authConfig)
+	// TODO: this is only done here because auth and registry need to be merged into one pkg
+	if addr := authConfig.ServerAddress; addr != "" && addr != IndexServerAddress() {
+		addr, err = ExpandAndVerifyRegistryUrl(addr)
+		if err != nil {
+			return job.Error(err)
+		}
+		authConfig.ServerAddress = addr
+	}
+	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)
+
+	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
+}

+ 2 - 96
server/server.go

@@ -126,7 +126,6 @@ func InitServer(job *engine.Job) engine.Status {
 		"insert":           srv.ImageInsert,
 		"attach":           srv.ContainerAttach,
 		"logs":             srv.ContainerLogs,
-		"search":           srv.ImagesSearch,
 		"changes":          srv.ContainerChanges,
 		"top":              srv.ContainerTop,
 		"version":          srv.DockerVersion,
@@ -139,7 +138,6 @@ func InitServer(job *engine.Job) engine.Status {
 		"events":           srv.Events,
 		"push":             srv.ImagePush,
 		"containers":       srv.Containers,
-		"auth":             srv.Auth,
 	} {
 		if err := job.Eng.Register(name, handler); err != nil {
 			return job.Error(err)
@@ -148,24 +146,6 @@ func InitServer(job *engine.Job) engine.Status {
 	return engine.StatusOK
 }
 
-// simpleVersionInfo is a simple implementation of
-// the interface VersionInfo, which is used
-// to provide version information for some product,
-// component, etc. It stores the product name and the version
-// in string and returns them on calls to Name() and Version().
-type simpleVersionInfo struct {
-	name    string
-	version string
-}
-
-func (v *simpleVersionInfo) Name() string {
-	return v.name
-}
-
-func (v *simpleVersionInfo) Version() string {
-	return v.version
-}
-
 // ContainerKill send signal to the container
 // If no signal is given (sig 0), then Kill with SIGKILL and wait
 // for the container to exit.
@@ -215,29 +195,6 @@ func (srv *Server) ContainerKill(job *engine.Job) engine.Status {
 	return engine.StatusOK
 }
 
-func (srv *Server) Auth(job *engine.Job) engine.Status {
-	var (
-		err        error
-		authConfig = &registry.AuthConfig{}
-	)
-
-	job.GetenvJson("authConfig", authConfig)
-	// TODO: this is only done here because auth and registry need to be merged into one pkg
-	if addr := authConfig.ServerAddress; addr != "" && addr != registry.IndexServerAddress() {
-		addr, err = registry.ExpandAndVerifyRegistryUrl(addr)
-		if err != nil {
-			return job.Error(err)
-		}
-		authConfig.ServerAddress = addr
-	}
-	status, err := registry.Login(authConfig, srv.HTTPRequestFactory(nil))
-	if err != nil {
-		return job.Error(err)
-	}
-	job.Printf("%s\n", status)
-	return engine.StatusOK
-}
-
 func (srv *Server) Events(job *engine.Job) engine.Status {
 	if len(job.Args) != 1 {
 		return job.Errorf("Usage: %s FROM", job.Name)
@@ -642,39 +599,6 @@ func (srv *Server) recursiveLoad(address, tmpImageDir string) error {
 	return nil
 }
 
-func (srv *Server) ImagesSearch(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  = &registry.AuthConfig{}
-	)
-	job.GetenvJson("authConfig", authConfig)
-	job.GetenvJson("metaHeaders", metaHeaders)
-
-	r, err := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), registry.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
-}
-
 // FIXME: 'insert' is deprecated and should be removed in a future version.
 func (srv *Server) ImageInsert(job *engine.Job) engine.Status {
 	fmt.Fprintf(job.Stderr, "Warning: '%s' is deprecated and will be removed in a future version. Please use 'build' and 'ADD' instead.\n", job.Name)
@@ -1457,7 +1381,7 @@ func (srv *Server) ImagePull(job *engine.Job) engine.Status {
 		return job.Error(err)
 	}
 
-	r, err := registry.NewRegistry(&authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint)
+	r, err := registry.NewRegistry(&authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint)
 	if err != nil {
 		return job.Error(err)
 	}
@@ -1680,7 +1604,7 @@ func (srv *Server) ImagePush(job *engine.Job) engine.Status {
 	}
 
 	img, err := srv.daemon.Graph().Get(localName)
-	r, err2 := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint)
+	r, err2 := registry.NewRegistry(authConfig, registry.HTTPRequestFactory(metaHeaders), endpoint)
 	if err2 != nil {
 		return job.Error(err2)
 	}
@@ -2558,24 +2482,6 @@ func NewServer(eng *engine.Engine, config *daemonconfig.Config) (*Server, error)
 	return srv, nil
 }
 
-func (srv *Server) HTTPRequestFactory(metaHeaders map[string][]string) *utils.HTTPRequestFactory {
-	httpVersion := make([]utils.VersionInfo, 0, 4)
-	httpVersion = append(httpVersion, &simpleVersionInfo{"docker", dockerversion.VERSION})
-	httpVersion = append(httpVersion, &simpleVersionInfo{"go", goruntime.Version()})
-	httpVersion = append(httpVersion, &simpleVersionInfo{"git-commit", dockerversion.GITCOMMIT})
-	if kernelVersion, err := utils.GetKernelVersion(); err == nil {
-		httpVersion = append(httpVersion, &simpleVersionInfo{"kernel", kernelVersion.String()})
-	}
-	httpVersion = append(httpVersion, &simpleVersionInfo{"os", goruntime.GOOS})
-	httpVersion = append(httpVersion, &simpleVersionInfo{"arch", goruntime.GOARCH})
-	ud := utils.NewHTTPUserAgentDecorator(httpVersion...)
-	md := &utils.HTTPMetaHeadersDecorator{
-		Headers: metaHeaders,
-	}
-	factory := utils.NewHTTPRequestFactory(ud, md)
-	return factory
-}
-
 func (srv *Server) LogEvent(action, id, from string) *utils.JSONMessage {
 	now := time.Now().UTC().Unix()
 	jm := utils.JSONMessage{Status: action, ID: id, From: from, Time: now}