mirror of https://github.com/docker/docs.git
Merge pull request #5347 from crosbymichael/engine-root
Remove root dir from engine
This commit is contained in:
commit
baf6cf9056
|
@ -6,11 +6,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker/api"
|
"github.com/dotcloud/docker/api"
|
||||||
"github.com/dotcloud/docker/engine"
|
"github.com/dotcloud/docker/engine"
|
||||||
"github.com/dotcloud/docker/utils"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -59,8 +57,7 @@ func TesthttpError(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetVersion(t *testing.T) {
|
func TestGetVersion(t *testing.T) {
|
||||||
eng := tmpEngine(t)
|
eng := engine.New()
|
||||||
defer rmEngine(eng)
|
|
||||||
var called bool
|
var called bool
|
||||||
eng.Register("version", func(job *engine.Job) engine.Status {
|
eng.Register("version", func(job *engine.Job) engine.Status {
|
||||||
called = true
|
called = true
|
||||||
|
@ -89,8 +86,7 @@ func TestGetVersion(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetInfo(t *testing.T) {
|
func TestGetInfo(t *testing.T) {
|
||||||
eng := tmpEngine(t)
|
eng := engine.New()
|
||||||
defer rmEngine(eng)
|
|
||||||
var called bool
|
var called bool
|
||||||
eng.Register("info", func(job *engine.Job) engine.Status {
|
eng.Register("info", func(job *engine.Job) engine.Status {
|
||||||
called = true
|
called = true
|
||||||
|
@ -130,22 +126,6 @@ func serveRequest(method, target string, body io.Reader, eng *engine.Engine, t *
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func tmpEngine(t *testing.T) *engine.Engine {
|
|
||||||
tmp, err := utils.TestDirectory("")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
eng, err := engine.New(tmp)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
return eng
|
|
||||||
}
|
|
||||||
|
|
||||||
func rmEngine(eng *engine.Engine) {
|
|
||||||
os.RemoveAll(eng.Root())
|
|
||||||
}
|
|
||||||
|
|
||||||
func readEnv(src io.Reader, t *testing.T) *engine.Env {
|
func readEnv(src io.Reader, t *testing.T) *engine.Env {
|
||||||
out := engine.NewOutput()
|
out := engine.NewOutput()
|
||||||
v, err := out.AddEnv()
|
v, err := out.AddEnv()
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/dotcloud/docker/api"
|
"github.com/dotcloud/docker/api"
|
||||||
|
@ -120,11 +121,11 @@ func main() {
|
||||||
log.Fatalf("Unable to get the full path to root (%s): %s", root, err)
|
log.Fatalf("Unable to get the full path to root (%s): %s", root, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := checkKernelAndArch(); err != nil {
|
||||||
eng, err := engine.New(realRoot)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eng := engine.New()
|
||||||
// Load builtins
|
// Load builtins
|
||||||
builtins.Register(eng)
|
builtins.Register(eng)
|
||||||
// load the daemon in the background so we can immediately start
|
// load the daemon in the background so we can immediately start
|
||||||
|
@ -239,3 +240,27 @@ func main() {
|
||||||
func showVersion() {
|
func showVersion() {
|
||||||
fmt.Printf("Docker version %s, build %s\n", dockerversion.VERSION, dockerversion.GITCOMMIT)
|
fmt.Printf("Docker version %s, build %s\n", dockerversion.VERSION, dockerversion.GITCOMMIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkKernelAndArch() error {
|
||||||
|
// Check for unsupported architectures
|
||||||
|
if runtime.GOARCH != "amd64" {
|
||||||
|
return fmt.Errorf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
|
||||||
|
}
|
||||||
|
// Check for unsupported kernel versions
|
||||||
|
// FIXME: it would be cleaner to not test for specific versions, but rather
|
||||||
|
// test for specific functionalities.
|
||||||
|
// Unfortunately we can't test for the feature "does not cause a kernel panic"
|
||||||
|
// without actually causing a kernel panic, so we need this workaround until
|
||||||
|
// the circumstances of pre-3.8 crashes are clearer.
|
||||||
|
// For details see http://github.com/dotcloud/docker/issues/407
|
||||||
|
if k, err := utils.GetKernelVersion(); err != nil {
|
||||||
|
log.Printf("WARNING: %s\n", err)
|
||||||
|
} else {
|
||||||
|
if utils.CompareKernelVersion(k, &utils.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
|
||||||
|
if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" {
|
||||||
|
log.Printf("WARNING: You are running linux kernel version %s, which might be unstable running docker. Please upgrade your kernel to 3.8.0.", k.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -5,9 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dotcloud/docker/utils"
|
"github.com/dotcloud/docker/utils"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -37,7 +35,6 @@ func unregister(name string) {
|
||||||
// It acts as a store for *containers*, and allows manipulation of these
|
// It acts as a store for *containers*, and allows manipulation of these
|
||||||
// containers by executing *jobs*.
|
// containers by executing *jobs*.
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
root string
|
|
||||||
handlers map[string]Handler
|
handlers map[string]Handler
|
||||||
hack Hack // data for temporary hackery (see hack.go)
|
hack Hack // data for temporary hackery (see hack.go)
|
||||||
id string
|
id string
|
||||||
|
@ -47,10 +44,6 @@ type Engine struct {
|
||||||
Logging bool
|
Logging bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (eng *Engine) Root() string {
|
|
||||||
return eng.root
|
|
||||||
}
|
|
||||||
|
|
||||||
func (eng *Engine) Register(name string, handler Handler) error {
|
func (eng *Engine) Register(name string, handler Handler) error {
|
||||||
_, exists := eng.handlers[name]
|
_, exists := eng.handlers[name]
|
||||||
if exists {
|
if exists {
|
||||||
|
@ -60,38 +53,9 @@ func (eng *Engine) Register(name string, handler Handler) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// New initializes a new engine managing the directory specified at `root`.
|
// New initializes a new engine.
|
||||||
// `root` is used to store containers and any other state private to the engine.
|
func New() *Engine {
|
||||||
// Changing the contents of the root without executing a job will cause unspecified
|
|
||||||
// behavior.
|
|
||||||
func New(root string) (*Engine, error) {
|
|
||||||
// Check for unsupported architectures
|
|
||||||
if runtime.GOARCH != "amd64" {
|
|
||||||
return nil, fmt.Errorf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
|
|
||||||
}
|
|
||||||
// Check for unsupported kernel versions
|
|
||||||
// FIXME: it would be cleaner to not test for specific versions, but rather
|
|
||||||
// test for specific functionalities.
|
|
||||||
// Unfortunately we can't test for the feature "does not cause a kernel panic"
|
|
||||||
// without actually causing a kernel panic, so we need this workaround until
|
|
||||||
// the circumstances of pre-3.8 crashes are clearer.
|
|
||||||
// For details see http://github.com/dotcloud/docker/issues/407
|
|
||||||
if k, err := utils.GetKernelVersion(); err != nil {
|
|
||||||
log.Printf("WARNING: %s\n", err)
|
|
||||||
} else {
|
|
||||||
if utils.CompareKernelVersion(k, &utils.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
|
|
||||||
if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" {
|
|
||||||
log.Printf("WARNING: You are running linux kernel version %s, which might be unstable running docker. Please upgrade your kernel to 3.8.0.", k.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := os.MkdirAll(root, 0700); err != nil && !os.IsExist(err) {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
eng := &Engine{
|
eng := &Engine{
|
||||||
root: root,
|
|
||||||
handlers: make(map[string]Handler),
|
handlers: make(map[string]Handler),
|
||||||
id: utils.RandomString(),
|
id: utils.RandomString(),
|
||||||
Stdout: os.Stdout,
|
Stdout: os.Stdout,
|
||||||
|
@ -109,11 +73,11 @@ func New(root string) (*Engine, error) {
|
||||||
for k, v := range globalHandlers {
|
for k, v := range globalHandlers {
|
||||||
eng.handlers[k] = v
|
eng.handlers[k] = v
|
||||||
}
|
}
|
||||||
return eng, nil
|
return eng
|
||||||
}
|
}
|
||||||
|
|
||||||
func (eng *Engine) String() string {
|
func (eng *Engine) String() string {
|
||||||
return fmt.Sprintf("%s|%s", eng.Root(), eng.id[:8])
|
return fmt.Sprintf("%s", eng.id[:8])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commands returns a list of all currently registered commands,
|
// Commands returns a list of all currently registered commands,
|
||||||
|
|
|
@ -2,10 +2,6 @@ package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -21,7 +17,7 @@ func TestRegister(t *testing.T) {
|
||||||
// Register is global so let's cleanup to avoid conflicts
|
// Register is global so let's cleanup to avoid conflicts
|
||||||
defer unregister("dummy1")
|
defer unregister("dummy1")
|
||||||
|
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
|
|
||||||
//Should fail because global handlers are copied
|
//Should fail because global handlers are copied
|
||||||
//at the engine creation
|
//at the engine creation
|
||||||
|
@ -40,7 +36,7 @@ func TestRegister(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJob(t *testing.T) {
|
func TestJob(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
job1 := eng.Job("dummy1", "--level=awesome")
|
job1 := eng.Job("dummy1", "--level=awesome")
|
||||||
|
|
||||||
if job1.handler != nil {
|
if job1.handler != nil {
|
||||||
|
@ -66,8 +62,7 @@ func TestJob(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEngineCommands(t *testing.T) {
|
func TestEngineCommands(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
defer os.RemoveAll(eng.Root())
|
|
||||||
handler := func(job *Job) Status { return StatusOK }
|
handler := func(job *Job) Status { return StatusOK }
|
||||||
eng.Register("foo", handler)
|
eng.Register("foo", handler)
|
||||||
eng.Register("bar", handler)
|
eng.Register("bar", handler)
|
||||||
|
@ -83,44 +78,9 @@ func TestEngineCommands(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEngineRoot(t *testing.T) {
|
|
||||||
tmp, err := ioutil.TempDir("", "docker-test-TestEngineCreateDir")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(tmp)
|
|
||||||
// We expect Root to resolve to an absolute path.
|
|
||||||
// FIXME: this should not be necessary.
|
|
||||||
// Until the above FIXME is implemented, let's check for the
|
|
||||||
// current behavior.
|
|
||||||
tmp, err = filepath.EvalSymlinks(tmp)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
tmp, err = filepath.Abs(tmp)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
dir := path.Join(tmp, "dir")
|
|
||||||
eng, err := New(dir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if st, err := os.Stat(dir); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
} else if !st.IsDir() {
|
|
||||||
t.Fatalf("engine.New() created something other than a directory at %s", dir)
|
|
||||||
}
|
|
||||||
if r := eng.Root(); r != dir {
|
|
||||||
t.Fatalf("Expected: %v\nReceived: %v", dir, r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEngineString(t *testing.T) {
|
func TestEngineString(t *testing.T) {
|
||||||
eng1 := newTestEngine(t)
|
eng1 := New()
|
||||||
defer os.RemoveAll(eng1.Root())
|
eng2 := New()
|
||||||
eng2 := newTestEngine(t)
|
|
||||||
defer os.RemoveAll(eng2.Root())
|
|
||||||
s1 := eng1.String()
|
s1 := eng1.String()
|
||||||
s2 := eng2.String()
|
s2 := eng2.String()
|
||||||
if eng1 == eng2 {
|
if eng1 == eng2 {
|
||||||
|
@ -129,8 +89,7 @@ func TestEngineString(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEngineLogf(t *testing.T) {
|
func TestEngineLogf(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
defer os.RemoveAll(eng.Root())
|
|
||||||
input := "Test log line"
|
input := "Test log line"
|
||||||
if n, err := eng.Logf("%s\n", input); err != nil {
|
if n, err := eng.Logf("%s\n", input); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -140,8 +99,7 @@ func TestEngineLogf(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseJob(t *testing.T) {
|
func TestParseJob(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
defer os.RemoveAll(eng.Root())
|
|
||||||
// Verify that the resulting job calls to the right place
|
// Verify that the resulting job calls to the right place
|
||||||
var called bool
|
var called bool
|
||||||
eng.Register("echo", func(job *Job) Status {
|
eng.Register("echo", func(job *Job) Status {
|
||||||
|
|
|
@ -1,24 +1,11 @@
|
||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/dotcloud/docker/utils"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var globalTestID string
|
var globalTestID string
|
||||||
|
|
||||||
func newTestEngine(t *testing.T) *Engine {
|
|
||||||
tmp, err := utils.TestDirectory("")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
eng, err := New(tmp)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
return eng
|
|
||||||
}
|
|
||||||
|
|
||||||
func mkJob(t *testing.T, name string, args ...string) *Job {
|
func mkJob(t *testing.T, name string, args ...string) *Job {
|
||||||
return newTestEngine(t).Job(name, args...)
|
return New().Job(name, args...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package engine
|
package engine
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestJobStatusOK(t *testing.T) {
|
func TestJobStatusOK(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
defer os.RemoveAll(eng.Root())
|
|
||||||
eng.Register("return_ok", func(job *Job) Status { return StatusOK })
|
eng.Register("return_ok", func(job *Job) Status { return StatusOK })
|
||||||
err := eng.Job("return_ok").Run()
|
err := eng.Job("return_ok").Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,8 +14,7 @@ func TestJobStatusOK(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJobStatusErr(t *testing.T) {
|
func TestJobStatusErr(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
defer os.RemoveAll(eng.Root())
|
|
||||||
eng.Register("return_err", func(job *Job) Status { return StatusErr })
|
eng.Register("return_err", func(job *Job) Status { return StatusErr })
|
||||||
err := eng.Job("return_err").Run()
|
err := eng.Job("return_err").Run()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -26,8 +23,7 @@ func TestJobStatusErr(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJobStatusNotFound(t *testing.T) {
|
func TestJobStatusNotFound(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
defer os.RemoveAll(eng.Root())
|
|
||||||
eng.Register("return_not_found", func(job *Job) Status { return StatusNotFound })
|
eng.Register("return_not_found", func(job *Job) Status { return StatusNotFound })
|
||||||
err := eng.Job("return_not_found").Run()
|
err := eng.Job("return_not_found").Run()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -36,8 +32,7 @@ func TestJobStatusNotFound(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJobStdoutString(t *testing.T) {
|
func TestJobStdoutString(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
defer os.RemoveAll(eng.Root())
|
|
||||||
// FIXME: test multiple combinations of output and status
|
// FIXME: test multiple combinations of output and status
|
||||||
eng.Register("say_something_in_stdout", func(job *Job) Status {
|
eng.Register("say_something_in_stdout", func(job *Job) Status {
|
||||||
job.Printf("Hello world\n")
|
job.Printf("Hello world\n")
|
||||||
|
@ -58,8 +53,7 @@ func TestJobStdoutString(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJobStderrString(t *testing.T) {
|
func TestJobStderrString(t *testing.T) {
|
||||||
eng := newTestEngine(t)
|
eng := New()
|
||||||
defer os.RemoveAll(eng.Root())
|
|
||||||
// FIXME: test multiple combinations of output and status
|
// FIXME: test multiple combinations of output and status
|
||||||
eng.Register("say_something_in_stderr", func(job *Job) Status {
|
eng.Register("say_something_in_stderr", func(job *Job) Status {
|
||||||
job.Errorf("Warning, something might happen\nHere it comes!\nOh no...\nSomething happened\n")
|
job.Errorf("Warning, something might happen\nHere it comes!\nOh no...\nSomething happened\n")
|
||||||
|
|
|
@ -627,7 +627,7 @@ func TestRestore(t *testing.T) {
|
||||||
|
|
||||||
// Here are are simulating a docker restart - that is, reloading all containers
|
// Here are are simulating a docker restart - that is, reloading all containers
|
||||||
// from scratch
|
// from scratch
|
||||||
eng = newTestEngine(t, false, eng.Root())
|
eng = newTestEngine(t, false, daemon1.Config().Root)
|
||||||
daemon2 := mkDaemonFromEngine(eng, t)
|
daemon2 := mkDaemonFromEngine(eng, t)
|
||||||
if len(daemon2.List()) != 2 {
|
if len(daemon2.List()) != 2 {
|
||||||
t.Errorf("Expected 2 container, %v found", len(daemon2.List()))
|
t.Errorf("Expected 2 container, %v found", len(daemon2.List()))
|
||||||
|
|
|
@ -149,7 +149,7 @@ func TestRestartKillWait(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
eng = newTestEngine(t, false, eng.Root())
|
eng = newTestEngine(t, false, runtime.Config().Root)
|
||||||
srv = mkServerFromEngine(eng, t)
|
srv = mkServerFromEngine(eng, t)
|
||||||
|
|
||||||
job = srv.Eng.Job("containers")
|
job = srv.Eng.Job("containers")
|
||||||
|
|
|
@ -181,10 +181,9 @@ func newTestEngine(t utils.Fataler, autorestart bool, root string) *engine.Engin
|
||||||
root = dir
|
root = dir
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eng, err := engine.New(root)
|
os.MkdirAll(root, 0700)
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
eng := engine.New()
|
||||||
}
|
|
||||||
// Load default plugins
|
// Load default plugins
|
||||||
builtins.Register(eng)
|
builtins.Register(eng)
|
||||||
// (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)
|
||||||
|
|
Loading…
Reference in New Issue