From c22a80a071b6f9db457ca981f3a3f6229751f9a9 Mon Sep 17 00:00:00 2001 From: Solomon Hykes Date: Thu, 1 May 2014 18:13:55 -0700 Subject: [PATCH] Choose a single backend with `--backend` Note: for now there is only one backend available, `debug` --- backends/backends.go | 19 +++++++++++++++++++ backends/debug.go | 23 +++++++++++++---------- swarmd/swarmd.go | 37 +++++++++++++++++++++++++++---------- 3 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 backends/backends.go diff --git a/backends/backends.go b/backends/backends.go new file mode 100644 index 0000000000..04c66f3477 --- /dev/null +++ b/backends/backends.go @@ -0,0 +1,19 @@ +package backends + +import ( + "github.com/dotcloud/docker/engine" +) + +// New returns a new engine, with all backends +// registered but not activated. +// To activate a backend, call a job on the resulting +// engine, named after the desired backend. +// +// Example: `New().Job("debug").Run()` +func New() *engine.Engine { + back := engine.New() + back.Logging = false + // Register all backends here + Debug().Install(back) + return back +} diff --git a/backends/debug.go b/backends/debug.go index ad30844008..2cbf83e51c 100644 --- a/backends/debug.go +++ b/backends/debug.go @@ -14,16 +14,19 @@ type debug struct { } func (d *debug) Install(eng *engine.Engine) error { - eng.RegisterCatchall(func(job *engine.Job) engine.Status { - fmt.Printf("--> %s %s\n", job.Name, strings.Join(job.Args, " ")) - for k, v := range job.Env().Map() { - fmt.Printf(" %s=%s\n", k, v) - } - // This helps us detect the race condition if our time.Sleep - // missed it. (see comment in main) - if job.Name == "acceptconnections" { - panic("race condition in github.com/dotcloud/docker/api/server/ServeApi") - } + eng.Register("debug", func(job *engine.Job) engine.Status { + job.Eng.RegisterCatchall(func(job *engine.Job) engine.Status { + fmt.Printf("--> %s %s\n", job.Name, strings.Join(job.Args, " ")) + for k, v := range job.Env().Map() { + fmt.Printf(" %s=%s\n", k, v) + } + // This helps us detect the race condition if our time.Sleep + // missed it. (see comment in main) + if job.Name == "acceptconnections" { + panic("race condition in github.com/dotcloud/docker/api/server/ServeApi") + } + return engine.StatusOK + }) return engine.StatusOK }) return nil diff --git a/swarmd/swarmd.go b/swarmd/swarmd.go index 805413a194..c470050df7 100644 --- a/swarmd/swarmd.go +++ b/swarmd/swarmd.go @@ -2,13 +2,13 @@ package main import ( "fmt" + "github.com/codegangsta/cli" "github.com/docker/swarmd/backends" "github.com/dotcloud/docker/api/server" "github.com/dotcloud/docker/engine" "os" - "time" - "github.com/codegangsta/cli" "strings" + "time" ) func main() { @@ -17,6 +17,7 @@ func main() { app.Usage = "Control a heterogenous distributed system with the Docker API" app.Version = "0.0.1" app.Flags = []cli.Flag{ + cli.StringFlag{"backend", "debug", "load a backend"}, } app.Action = cmdDaemon app.Run(os.Args) @@ -26,20 +27,37 @@ func cmdDaemon(c *cli.Context) { if len(c.Args()) == 0 { Fatalf("Usage: %s ://
[://
]...\n", c.App.Name) } - eng := engine.New() - eng.Logging = false - if err := backends.Debug().Install(eng); err != nil { - Fatalf("backend install: %v", err) + + // Load backend + // FIXME: allow for multiple backends to be loaded. + // This could be done by instantiating 1 engine per backend, + // installing each backend in its respective engine, + // then registering a Catchall on the frontent engine which + // multiplexes across all backends (with routing / filtering + // logic along the way). + back := backends.New() + backendName := c.String("backend") + fmt.Printf("Loading backend '%s'\n", backendName) + if err := back.Job(backendName).Run(); err != nil { + Fatalf("%s: %v\n", backendName, err) } // Register the API entrypoint // (we register it as `argv[0]` so we can print usage messages straight from the job // stderr. - eng.Register(c.App.Name, server.ServeApi) + front := engine.New() + front.Logging = false + // FIXME: server should expose an engine.Installer + front.Register(c.App.Name, server.ServeApi) + front.RegisterCatchall(func(job *engine.Job) engine.Status { + fw := back.Job(job.Name, job.Args...) + fw.Run() + return engine.Status(fw.StatusCode()) + }) // Call the API entrypoint go func() { - serve := eng.Job(c.App.Name, c.Args()...) + serve := front.Job(c.App.Name, c.Args()...) serve.Stdout.Add(os.Stdout) serve.Stderr.Add(os.Stderr) if err := serve.Run(); err != nil { @@ -50,7 +68,7 @@ func cmdDaemon(c *cli.Context) { // As a workaround we sleep to give it time to register 'acceptconnections'. time.Sleep(1 * time.Second) // Notify that we're ready to receive connections - if err := eng.Job("acceptconnections").Run(); err != nil { + if err := front.Job("acceptconnections").Run(); err != nil { Fatalf("acceptconnections: %v", err) } // Inifinite loop @@ -61,7 +79,6 @@ func Fatalf(msg string, args ...interface{}) { if !strings.HasSuffix(msg, "\n") { msg = msg + "\n" } - panic(msg) fmt.Fprintf(os.Stderr, msg, args...) os.Exit(1) }