Remove builtins

Signed-off-by: Antonio Murdaca <me@runcom.ninja>
This commit is contained in:
Antonio Murdaca 2015-04-16 21:48:04 +02:00
parent 5e40de9286
commit a0bf80fe03
12 changed files with 122 additions and 160 deletions

View File

@ -3,6 +3,7 @@ package server
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"runtime"
"time" "time"
"encoding/base64" "encoding/base64"
@ -21,6 +22,7 @@ import (
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/docker/docker/api" "github.com/docker/docker/api"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/autogen/dockerversion"
"github.com/docker/docker/daemon" "github.com/docker/docker/daemon"
"github.com/docker/docker/daemon/networkdriver/bridge" "github.com/docker/docker/daemon/networkdriver/bridge"
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
@ -28,6 +30,7 @@ import (
"github.com/docker/docker/pkg/jsonmessage" "github.com/docker/docker/pkg/jsonmessage"
"github.com/docker/docker/pkg/parsers" "github.com/docker/docker/pkg/parsers"
"github.com/docker/docker/pkg/parsers/filters" "github.com/docker/docker/pkg/parsers/filters"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/stdcopy" "github.com/docker/docker/pkg/stdcopy"
"github.com/docker/docker/pkg/streamformatter" "github.com/docker/docker/pkg/streamformatter"
@ -41,6 +44,19 @@ var (
activationLock = make(chan struct{}) activationLock = make(chan struct{})
) )
type ServerConfig struct {
Logging bool
EnableCors bool
CorsHeaders string
Version string
SocketGroup string
Tls bool
TlsVerify bool
TlsCa string
TlsCert string
TlsKey string
}
type HttpServer struct { type HttpServer struct {
srv *http.Server srv *http.Server
l net.Listener l net.Listener
@ -187,8 +203,20 @@ func postAuth(eng *engine.Engine, version version.Version, w http.ResponseWriter
func getVersion(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func getVersion(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
eng.ServeHTTP(w, r)
return nil v := &types.Version{
Version: dockerversion.VERSION,
ApiVersion: api.APIVERSION,
GitCommit: dockerversion.GITCOMMIT,
GoVersion: runtime.Version(),
Os: runtime.GOOS,
Arch: runtime.GOARCH,
}
if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
v.KernelVersion = kernelVersion.String()
}
return writeJSON(w, http.StatusOK, v)
} }
func postContainersKill(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error { func postContainersKill(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
@ -1588,28 +1616,22 @@ type Server interface {
// ServeApi loops through all of the protocols sent in to docker and spawns // ServeApi loops through all of the protocols sent in to docker and spawns
// off a go routine to setup a serving http.Server for each. // off a go routine to setup a serving http.Server for each.
func ServeApi(job *engine.Job) error { func ServeApi(protoAddrs []string, conf *ServerConfig, eng *engine.Engine) error {
if len(job.Args) == 0 { var chErrors = make(chan error, len(protoAddrs))
return fmt.Errorf("usage: %s PROTO://ADDR [PROTO://ADDR ...]", job.Name)
}
var (
protoAddrs = job.Args
chErrors = make(chan error, len(protoAddrs))
)
for _, protoAddr := range protoAddrs { for _, protoAddr := range protoAddrs {
protoAddrParts := strings.SplitN(protoAddr, "://", 2) protoAddrParts := strings.SplitN(protoAddr, "://", 2)
if len(protoAddrParts) != 2 { if len(protoAddrParts) != 2 {
return fmt.Errorf("usage: %s PROTO://ADDR [PROTO://ADDR ...]", job.Name) return fmt.Errorf("bad format, expected PROTO://ADDR")
} }
go func() { go func() {
logrus.Infof("Listening for HTTP on %s (%s)", protoAddrParts[0], protoAddrParts[1]) logrus.Infof("Listening for HTTP on %s (%s)", protoAddrParts[0], protoAddrParts[1])
srv, err := NewServer(protoAddrParts[0], protoAddrParts[1], job) srv, err := NewServer(protoAddrParts[0], protoAddrParts[1], conf, eng)
if err != nil { if err != nil {
chErrors <- err chErrors <- err
return return
} }
job.Eng.OnShutdown(func() { eng.OnShutdown(func() {
if err := srv.Close(); err != nil { if err := srv.Close(); err != nil {
logrus.Error(err) logrus.Error(err)
} }

View File

@ -13,16 +13,16 @@ import (
) )
// NewServer sets up the required Server and does protocol specific checking. // NewServer sets up the required Server and does protocol specific checking.
func NewServer(proto, addr string, job *engine.Job) (Server, error) { func NewServer(proto, addr string, conf *ServerConfig, eng *engine.Engine) (Server, error) {
var ( var (
err error err error
l net.Listener l net.Listener
r = createRouter( r = createRouter(
job.Eng, eng,
job.GetenvBool("Logging"), conf.Logging,
job.GetenvBool("EnableCors"), conf.EnableCors,
job.Getenv("CorsHeaders"), conf.CorsHeaders,
job.Getenv("Version"), conf.Version,
) )
) )
switch proto { switch proto {
@ -52,17 +52,17 @@ func NewServer(proto, addr string, job *engine.Job) (Server, error) {
} }
return nil, nil return nil, nil
case "tcp": case "tcp":
if !job.GetenvBool("TlsVerify") { if !conf.TlsVerify {
logrus.Warn("/!\\ DON'T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\") logrus.Warn("/!\\ DON'T BIND ON ANY IP ADDRESS WITHOUT setting -tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
} }
if l, err = NewTcpSocket(addr, tlsConfigFromJob(job)); err != nil { if l, err = NewTcpSocket(addr, tlsConfigFromServerConfig(conf)); err != nil {
return nil, err return nil, err
} }
if err := allocateDaemonPort(addr); err != nil { if err := allocateDaemonPort(addr); err != nil {
return nil, err return nil, err
} }
case "unix": case "unix":
if l, err = NewUnixSocket(addr, job.Getenv("SocketGroup")); err != nil { if l, err = NewUnixSocket(addr, conf.SocketGroup); err != nil {
return nil, err return nil, err
} }
default: default:
@ -77,8 +77,7 @@ func NewServer(proto, addr string, job *engine.Job) (Server, error) {
}, nil }, nil
} }
// Called through eng.Job("acceptconnections") func AcceptConnections() {
func AcceptConnections(job *engine.Job) error {
// Tell the init daemon we are accepting requests // Tell the init daemon we are accepting requests
go systemd.SdNotify("READY=1") go systemd.SdNotify("READY=1")
// close the lock so the listeners start accepting connections // close the lock so the listeners start accepting connections
@ -87,5 +86,4 @@ func AcceptConnections(job *engine.Job) error {
default: default:
close(activationLock) close(activationLock)
} }
return nil
} }

View File

@ -34,35 +34,6 @@ func TesthttpError(t *testing.T) {
} }
} }
func TestGetVersion(t *testing.T) {
eng := engine.New()
var called bool
eng.Register("version", func(job *engine.Job) error {
called = true
v := &engine.Env{}
v.SetJson("Version", "42.1")
v.Set("ApiVersion", "1.1.1.1.1")
v.Set("GoVersion", "2.42")
v.Set("Os", "Linux")
v.Set("Arch", "x86_64")
if _, err := v.WriteTo(job.Stdout); err != nil {
return err
}
return nil
})
r := serveRequest("GET", "/version", nil, eng, t)
if !called {
t.Fatalf("handler was not called")
}
v := readEnv(r.Body, t)
if v.Get("Version") != "42.1" {
t.Fatalf("%#v\n", v)
}
if r.HeaderMap.Get("Content-Type") != "application/json" {
t.Fatalf("%#v\n", r)
}
}
func TestGetInfo(t *testing.T) { func TestGetInfo(t *testing.T) {
eng := engine.New() eng := engine.New()
var called bool var called bool

View File

@ -39,13 +39,11 @@ func NewServer(proto, addr string, job *engine.Job) (Server, error) {
} }
} }
// Called through eng.Job("acceptconnections") func AcceptConnections() {
func AcceptConnections(job *engine.Job) error {
// close the lock so the listeners start accepting connections // close the lock so the listeners start accepting connections
select { select {
case <-activationLock: case <-activationLock:
default: default:
close(activationLock) close(activationLock)
} }
return nil
} }

View File

@ -8,7 +8,6 @@ import (
"net" "net"
"os" "os"
"github.com/docker/docker/engine"
"github.com/docker/docker/pkg/listenbuffer" "github.com/docker/docker/pkg/listenbuffer"
) )
@ -19,16 +18,16 @@ type tlsConfig struct {
Verify bool Verify bool
} }
func tlsConfigFromJob(job *engine.Job) *tlsConfig { func tlsConfigFromServerConfig(conf *ServerConfig) *tlsConfig {
verify := job.GetenvBool("TlsVerify") verify := conf.TlsVerify
if !job.GetenvBool("Tls") && !verify { if !conf.Tls && !conf.TlsVerify {
return nil return nil
} }
return &tlsConfig{ return &tlsConfig{
Verify: verify, Verify: verify,
Certificate: job.Getenv("TlsCert"), Certificate: conf.TlsCert,
Key: job.Getenv("TlsKey"), Key: conf.TlsKey,
CA: job.Getenv("TlsCa"), CA: conf.TlsCa,
} }
} }

View File

@ -1,5 +1,7 @@
package types package types
import "github.com/docker/docker/pkg/version"
// ContainerCreateResponse contains the information returned to a client on the // ContainerCreateResponse contains the information returned to a client on the
// creation of a new container. // creation of a new container.
type ContainerCreateResponse struct { type ContainerCreateResponse struct {
@ -110,3 +112,13 @@ type ContainerProcessList struct {
Processes [][]string Processes [][]string
Titles []string Titles []string
} }
type Version struct {
Version string
ApiVersion version.Version
GitCommit string
GoVersion string
Os string
Arch string
KernelVersion string `json:",omitempty"`
}

View File

@ -1,48 +0,0 @@
package builtins
import (
"runtime"
"github.com/docker/docker/api"
apiserver "github.com/docker/docker/api/server"
"github.com/docker/docker/autogen/dockerversion"
"github.com/docker/docker/engine"
"github.com/docker/docker/pkg/parsers/kernel"
)
func Register(eng *engine.Engine) error {
if err := remote(eng); err != nil {
return err
}
if err := eng.Register("version", dockerVersion); err != nil {
return err
}
return nil
}
// remote: a RESTful api for cross-docker communication
func remote(eng *engine.Engine) error {
if err := eng.Register("serveapi", apiserver.ServeApi); err != nil {
return err
}
return eng.Register("acceptconnections", apiserver.AcceptConnections)
}
// builtins jobs independent of any subsystem
func dockerVersion(job *engine.Job) error {
v := &engine.Env{}
v.SetJson("Version", dockerversion.VERSION)
v.SetJson("ApiVersion", api.APIVERSION)
v.SetJson("GitCommit", dockerversion.GITCOMMIT)
v.Set("GoVersion", runtime.Version())
v.Set("Os", runtime.GOOS)
v.Set("Arch", runtime.GOARCH)
if kernelVersion, err := kernel.GetKernelVersion(); err == nil {
v.Set("KernelVersion", kernelVersion.String())
}
if _, err := v.WriteTo(job.Stdout); err != nil {
return err
}
return nil
}

View File

@ -10,9 +10,9 @@ import (
"strings" "strings"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
apiserver "github.com/docker/docker/api/server"
"github.com/docker/docker/autogen/dockerversion" "github.com/docker/docker/autogen/dockerversion"
"github.com/docker/docker/builder" "github.com/docker/docker/builder"
"github.com/docker/docker/builtins"
"github.com/docker/docker/daemon" "github.com/docker/docker/daemon"
_ "github.com/docker/docker/daemon/execdriver/lxc" _ "github.com/docker/docker/daemon/execdriver/lxc"
_ "github.com/docker/docker/daemon/execdriver/native" _ "github.com/docker/docker/daemon/execdriver/native"
@ -93,11 +93,6 @@ func mainDaemon() {
} }
daemonCfg.TrustKeyPath = *flTrustKey daemonCfg.TrustKeyPath = *flTrustKey
// Load builtins
if err := builtins.Register(eng); err != nil {
logrus.Fatal(err)
}
registryService := registry.NewService(registryCfg) registryService := registry.NewService(registryCfg)
// load the daemon in the background so we can immediately start // load the daemon in the background so we can immediately start
// the http api so that connections don't fail while the daemon // the http api so that connections don't fail while the daemon
@ -127,33 +122,30 @@ func mainDaemon() {
// after the daemon is done setting up we can tell the api to start // after the daemon is done setting up we can tell the api to start
// accepting connections // accepting connections
if err := eng.Job("acceptconnections").Run(); err != nil { apiserver.AcceptConnections()
daemonInitWait <- err
return
}
daemonInitWait <- nil daemonInitWait <- nil
}() }()
// Serve api serverConfig := &apiserver.ServerConfig{
job := eng.Job("serveapi", flHosts...) Logging: true,
job.SetenvBool("Logging", true) EnableCors: daemonCfg.EnableCors,
job.SetenvBool("EnableCors", daemonCfg.EnableCors) CorsHeaders: daemonCfg.CorsHeaders,
job.Setenv("CorsHeaders", daemonCfg.CorsHeaders) Version: dockerversion.VERSION,
job.Setenv("Version", dockerversion.VERSION) SocketGroup: daemonCfg.SocketGroup,
job.Setenv("SocketGroup", daemonCfg.SocketGroup) Tls: *flTls,
TlsVerify: *flTlsVerify,
TlsCa: *flCa,
TlsCert: *flCert,
TlsKey: *flKey,
}
job.SetenvBool("Tls", *flTls) // The serve API routine never exits unless an error occurs
job.SetenvBool("TlsVerify", *flTlsVerify)
job.Setenv("TlsCa", *flCa)
job.Setenv("TlsCert", *flCert)
job.Setenv("TlsKey", *flKey)
// The serve API job never exits unless an error occurs
// We need to start it as a goroutine and wait on it so // We need to start it as a goroutine and wait on it so
// daemon doesn't exit // daemon doesn't exit
serveAPIWait := make(chan error) serveAPIWait := make(chan error)
go func() { go func() {
if err := job.Run(); err != nil { if err := apiserver.ServeApi(flHosts, serverConfig, eng); err != nil {
logrus.Errorf("ServeAPI error: %v", err) logrus.Errorf("ServeAPI error: %v", err)
serveAPIWait <- err serveAPIWait <- err
return return

View File

@ -0,0 +1,24 @@
package main
import (
"encoding/json"
"testing"
"github.com/docker/docker/api/types"
"github.com/docker/docker/autogen/dockerversion"
)
func TestGetVersion(t *testing.T) {
_, body, err := sockRequest("GET", "/version", nil)
if err != nil {
t.Fatal(err)
}
var v types.Version
if err := json.Unmarshal(body, &v); err != nil {
t.Fatal(err)
}
if v.Version != dockerversion.VERSION {
t.Fatal("Version mismatch")
}
}

View File

@ -3363,7 +3363,7 @@ func TestRunRestartMaxRetries(t *testing.T) {
t.Fatal(string(out), err) t.Fatal(string(out), err)
} }
id := strings.TrimSpace(string(out)) id := strings.TrimSpace(string(out))
if err := waitInspect(id, "{{ .State.Restarting }} {{ .State.Running }}", "false false", 5); err != nil { if err := waitInspect(id, "{{ .State.Restarting }} {{ .State.Running }}", "false false", 10); err != nil {
t.Fatal(err) t.Fatal(err)
} }
count, err := inspectField(id, "RestartCount") count, err := inspectField(id, "RestartCount")

View File

@ -17,6 +17,7 @@ import (
"time" "time"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
apiserver "github.com/docker/docker/api/server"
"github.com/docker/docker/daemon" "github.com/docker/docker/daemon"
"github.com/docker/docker/daemon/execdriver" "github.com/docker/docker/daemon/execdriver"
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
@ -157,9 +158,9 @@ func spawnGlobalDaemon() {
Scheme: testDaemonProto, Scheme: testDaemonProto,
Host: testDaemonAddr, Host: testDaemonAddr,
} }
job := eng.Job("serveapi", listenURL.String())
job.SetenvBool("Logging", true) serverConfig := &apiserver.ServerConfig{Logging: true}
if err := job.Run(); err != nil { if err := apiserver.ServeApi([]string{listenURL.String()}, serverConfig, eng); err != nil {
logrus.Fatalf("Unable to spawn the test daemon: %s", err) logrus.Fatalf("Unable to spawn the test daemon: %s", err)
} }
}() }()
@ -168,9 +169,7 @@ func spawnGlobalDaemon() {
// FIXME: use inmem transports instead of tcp // FIXME: use inmem transports instead of tcp
time.Sleep(time.Second) time.Sleep(time.Second)
if err := eng.Job("acceptconnections").Run(); err != nil { apiserver.AcceptConnections()
logrus.Fatalf("Unable to accept connections for test api: %s", err)
}
} }
func spawnLegitHttpsDaemon() { func spawnLegitHttpsDaemon() {
@ -207,14 +206,15 @@ func spawnHttpsDaemon(addr, cacert, cert, key string) *engine.Engine {
Scheme: testDaemonHttpsProto, Scheme: testDaemonHttpsProto,
Host: addr, Host: addr,
} }
job := eng.Job("serveapi", listenURL.String()) serverConfig := &apiserver.ServerConfig{
job.SetenvBool("Logging", true) Logging: true,
job.SetenvBool("Tls", true) Tls: true,
job.SetenvBool("TlsVerify", true) TlsVerify: true,
job.Setenv("TlsCa", cacert) TlsCa: cacert,
job.Setenv("TlsCert", cert) TlsCert: cert,
job.Setenv("TlsKey", key) TlsKey: key,
if err := job.Run(); err != nil { }
if err := apiserver.ServeApi([]string{listenURL.String()}, serverConfig, eng); err != nil {
logrus.Fatalf("Unable to spawn the test daemon: %s", err) logrus.Fatalf("Unable to spawn the test daemon: %s", err)
} }
}() }()
@ -222,9 +222,8 @@ func spawnHttpsDaemon(addr, cacert, cert, key string) *engine.Engine {
// Give some time to ListenAndServer to actually start // Give some time to ListenAndServer to actually start
time.Sleep(time.Second) time.Sleep(time.Second)
if err := eng.Job("acceptconnections").Run(); err != nil { apiserver.AcceptConnections()
logrus.Fatalf("Unable to accept connections for test api: %s", err)
}
return eng return eng
} }

View File

@ -17,7 +17,6 @@ import (
"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar" "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/builtins"
"github.com/docker/docker/daemon" "github.com/docker/docker/daemon"
"github.com/docker/docker/daemon/networkdriver/bridge" "github.com/docker/docker/daemon/networkdriver/bridge"
"github.com/docker/docker/engine" "github.com/docker/docker/engine"
@ -170,10 +169,6 @@ func newTestEngine(t Fataler, autorestart bool, root string) *engine.Engine {
eng := engine.New() eng := engine.New()
eng.Logging = false eng.Logging = false
// Load default plugins
if err := builtins.Register(eng); err != nil {
t.Fatal(err)
}
// (This is manually copied and modified from main() until we have a more generic plugin system) // (This is manually copied and modified from main() until we have a more generic plugin system)
cfg := &daemon.Config{ cfg := &daemon.Config{