This makes the engine more general purpose so that we can
use it and the job routing functionality for reexec'ing our binary
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
Conflicts:
integration/runtime_test.go
| ... | ... |
@@ -7,6 +7,7 @@ import ( |
| 7 | 7 |
"io/ioutil" |
| 8 | 8 |
"log" |
| 9 | 9 |
"os" |
| 10 |
+ "runtime" |
|
| 10 | 11 |
"strings" |
| 11 | 12 |
|
| 12 | 13 |
"github.com/dotcloud/docker/api" |
| ... | ... |
@@ -121,7 +122,10 @@ func main() {
|
| 121 | 121 |
} |
| 122 | 122 |
} |
| 123 | 123 |
|
| 124 |
- eng, err := engine.New(realRoot) |
|
| 124 |
+ if err := checkKernelAndArch(); err != nil {
|
|
| 125 |
+ log.Fatal(err) |
|
| 126 |
+ } |
|
| 127 |
+ eng, err := engine.New() |
|
| 125 | 128 |
if err != nil {
|
| 126 | 129 |
log.Fatal(err) |
| 127 | 130 |
} |
| ... | ... |
@@ -239,3 +243,27 @@ func main() {
|
| 239 | 239 |
func showVersion() {
|
| 240 | 240 |
fmt.Printf("Docker version %s, build %s\n", dockerversion.VERSION, dockerversion.GITCOMMIT)
|
| 241 | 241 |
} |
| 242 |
+ |
|
| 243 |
+func checkKernelAndArch() error {
|
|
| 244 |
+ // Check for unsupported architectures |
|
| 245 |
+ if runtime.GOARCH != "amd64" {
|
|
| 246 |
+ return fmt.Errorf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
|
|
| 247 |
+ } |
|
| 248 |
+ // Check for unsupported kernel versions |
|
| 249 |
+ // FIXME: it would be cleaner to not test for specific versions, but rather |
|
| 250 |
+ // test for specific functionalities. |
|
| 251 |
+ // Unfortunately we can't test for the feature "does not cause a kernel panic" |
|
| 252 |
+ // without actually causing a kernel panic, so we need this workaround until |
|
| 253 |
+ // the circumstances of pre-3.8 crashes are clearer. |
|
| 254 |
+ // For details see http://github.com/dotcloud/docker/issues/407 |
|
| 255 |
+ if k, err := utils.GetKernelVersion(); err != nil {
|
|
| 256 |
+ log.Printf("WARNING: %s\n", err)
|
|
| 257 |
+ } else {
|
|
| 258 |
+ if utils.CompareKernelVersion(k, &utils.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
|
|
| 259 |
+ if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" {
|
|
| 260 |
+ 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())
|
|
| 261 |
+ } |
|
| 262 |
+ } |
|
| 263 |
+ } |
|
| 264 |
+ return nil |
|
| 265 |
+} |
| ... | ... |
@@ -5,9 +5,7 @@ import ( |
| 5 | 5 |
"fmt" |
| 6 | 6 |
"github.com/dotcloud/docker/utils" |
| 7 | 7 |
"io" |
| 8 |
- "log" |
|
| 9 | 8 |
"os" |
| 10 |
- "runtime" |
|
| 11 | 9 |
"sort" |
| 12 | 10 |
"strings" |
| 13 | 11 |
) |
| ... | ... |
@@ -37,7 +35,6 @@ func unregister(name string) {
|
| 37 | 37 |
// It acts as a store for *containers*, and allows manipulation of these |
| 38 | 38 |
// containers by executing *jobs*. |
| 39 | 39 |
type Engine struct {
|
| 40 |
- root string |
|
| 41 | 40 |
handlers map[string]Handler |
| 42 | 41 |
hack Hack // data for temporary hackery (see hack.go) |
| 43 | 42 |
id string |
| ... | ... |
@@ -47,10 +44,6 @@ type Engine struct {
|
| 47 | 47 |
Logging bool |
| 48 | 48 |
} |
| 49 | 49 |
|
| 50 |
-func (eng *Engine) Root() string {
|
|
| 51 |
- return eng.root |
|
| 52 |
-} |
|
| 53 |
- |
|
| 54 | 50 |
func (eng *Engine) Register(name string, handler Handler) error {
|
| 55 | 51 |
_, exists := eng.handlers[name] |
| 56 | 52 |
if exists {
|
| ... | ... |
@@ -60,38 +53,9 @@ func (eng *Engine) Register(name string, handler Handler) error {
|
| 60 | 60 |
return nil |
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 |
-// New initializes a new engine managing the directory specified at `root`. |
|
| 64 |
-// `root` is used to store containers and any other state private to the engine. |
|
| 65 |
-// Changing the contents of the root without executing a job will cause unspecified |
|
| 66 |
-// behavior. |
|
| 67 |
-func New(root string) (*Engine, error) {
|
|
| 68 |
- // Check for unsupported architectures |
|
| 69 |
- if runtime.GOARCH != "amd64" {
|
|
| 70 |
- return nil, fmt.Errorf("The docker runtime currently only supports amd64 (not %s). This will change in the future. Aborting.", runtime.GOARCH)
|
|
| 71 |
- } |
|
| 72 |
- // Check for unsupported kernel versions |
|
| 73 |
- // FIXME: it would be cleaner to not test for specific versions, but rather |
|
| 74 |
- // test for specific functionalities. |
|
| 75 |
- // Unfortunately we can't test for the feature "does not cause a kernel panic" |
|
| 76 |
- // without actually causing a kernel panic, so we need this workaround until |
|
| 77 |
- // the circumstances of pre-3.8 crashes are clearer. |
|
| 78 |
- // For details see http://github.com/dotcloud/docker/issues/407 |
|
| 79 |
- if k, err := utils.GetKernelVersion(); err != nil {
|
|
| 80 |
- log.Printf("WARNING: %s\n", err)
|
|
| 81 |
- } else {
|
|
| 82 |
- if utils.CompareKernelVersion(k, &utils.KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0}) < 0 {
|
|
| 83 |
- if os.Getenv("DOCKER_NOWARN_KERNEL_VERSION") == "" {
|
|
| 84 |
- 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())
|
|
| 85 |
- } |
|
| 86 |
- } |
|
| 87 |
- } |
|
| 88 |
- |
|
| 89 |
- if err := os.MkdirAll(root, 0700); err != nil && !os.IsExist(err) {
|
|
| 90 |
- return nil, err |
|
| 91 |
- } |
|
| 92 |
- |
|
| 63 |
+// New initializes a new engine. |
|
| 64 |
+func New() (*Engine, error) {
|
|
| 93 | 65 |
eng := &Engine{
|
| 94 |
- root: root, |
|
| 95 | 66 |
handlers: make(map[string]Handler), |
| 96 | 67 |
id: utils.RandomString(), |
| 97 | 68 |
Stdout: os.Stdout, |
| ... | ... |
@@ -113,7 +77,7 @@ func New(root string) (*Engine, error) {
|
| 113 | 113 |
} |
| 114 | 114 |
|
| 115 | 115 |
func (eng *Engine) String() string {
|
| 116 |
- return fmt.Sprintf("%s|%s", eng.Root(), eng.id[:8])
|
|
| 116 |
+ return fmt.Sprintf("%s", eng.id[:8])
|
|
| 117 | 117 |
} |
| 118 | 118 |
|
| 119 | 119 |
// Commands returns a list of all currently registered commands, |
| ... | ... |
@@ -2,10 +2,6 @@ package engine |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"bytes" |
| 5 |
- "io/ioutil" |
|
| 6 |
- "os" |
|
| 7 |
- "path" |
|
| 8 |
- "path/filepath" |
|
| 9 | 5 |
"strings" |
| 10 | 6 |
"testing" |
| 11 | 7 |
) |
| ... | ... |
@@ -67,7 +63,6 @@ func TestJob(t *testing.T) {
|
| 67 | 67 |
|
| 68 | 68 |
func TestEngineCommands(t *testing.T) {
|
| 69 | 69 |
eng := newTestEngine(t) |
| 70 |
- defer os.RemoveAll(eng.Root()) |
|
| 71 | 70 |
handler := func(job *Job) Status { return StatusOK }
|
| 72 | 71 |
eng.Register("foo", handler)
|
| 73 | 72 |
eng.Register("bar", handler)
|
| ... | ... |
@@ -83,44 +78,9 @@ func TestEngineCommands(t *testing.T) {
|
| 83 | 83 |
} |
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 |
-func TestEngineRoot(t *testing.T) {
|
|
| 87 |
- tmp, err := ioutil.TempDir("", "docker-test-TestEngineCreateDir")
|
|
| 88 |
- if err != nil {
|
|
| 89 |
- t.Fatal(err) |
|
| 90 |
- } |
|
| 91 |
- defer os.RemoveAll(tmp) |
|
| 92 |
- // We expect Root to resolve to an absolute path. |
|
| 93 |
- // FIXME: this should not be necessary. |
|
| 94 |
- // Until the above FIXME is implemented, let's check for the |
|
| 95 |
- // current behavior. |
|
| 96 |
- tmp, err = filepath.EvalSymlinks(tmp) |
|
| 97 |
- if err != nil {
|
|
| 98 |
- t.Fatal(err) |
|
| 99 |
- } |
|
| 100 |
- tmp, err = filepath.Abs(tmp) |
|
| 101 |
- if err != nil {
|
|
| 102 |
- t.Fatal(err) |
|
| 103 |
- } |
|
| 104 |
- dir := path.Join(tmp, "dir") |
|
| 105 |
- eng, err := New(dir) |
|
| 106 |
- if err != nil {
|
|
| 107 |
- t.Fatal(err) |
|
| 108 |
- } |
|
| 109 |
- if st, err := os.Stat(dir); err != nil {
|
|
| 110 |
- t.Fatal(err) |
|
| 111 |
- } else if !st.IsDir() {
|
|
| 112 |
- t.Fatalf("engine.New() created something other than a directory at %s", dir)
|
|
| 113 |
- } |
|
| 114 |
- if r := eng.Root(); r != dir {
|
|
| 115 |
- t.Fatalf("Expected: %v\nReceived: %v", dir, r)
|
|
| 116 |
- } |
|
| 117 |
-} |
|
| 118 |
- |
|
| 119 | 86 |
func TestEngineString(t *testing.T) {
|
| 120 | 87 |
eng1 := newTestEngine(t) |
| 121 |
- defer os.RemoveAll(eng1.Root()) |
|
| 122 | 88 |
eng2 := newTestEngine(t) |
| 123 |
- defer os.RemoveAll(eng2.Root()) |
|
| 124 | 89 |
s1 := eng1.String() |
| 125 | 90 |
s2 := eng2.String() |
| 126 | 91 |
if eng1 == eng2 {
|
| ... | ... |
@@ -130,7 +90,6 @@ func TestEngineString(t *testing.T) {
|
| 130 | 130 |
|
| 131 | 131 |
func TestEngineLogf(t *testing.T) {
|
| 132 | 132 |
eng := newTestEngine(t) |
| 133 |
- defer os.RemoveAll(eng.Root()) |
|
| 134 | 133 |
input := "Test log line" |
| 135 | 134 |
if n, err := eng.Logf("%s\n", input); err != nil {
|
| 136 | 135 |
t.Fatal(err) |
| ... | ... |
@@ -141,7 +100,6 @@ func TestEngineLogf(t *testing.T) {
|
| 141 | 141 |
|
| 142 | 142 |
func TestParseJob(t *testing.T) {
|
| 143 | 143 |
eng := newTestEngine(t) |
| 144 |
- defer os.RemoveAll(eng.Root()) |
|
| 145 | 144 |
// Verify that the resulting job calls to the right place |
| 146 | 145 |
var called bool |
| 147 | 146 |
eng.Register("echo", func(job *Job) Status {
|
| ... | ... |
@@ -1,18 +1,13 @@ |
| 1 | 1 |
package engine |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "github.com/dotcloud/docker/utils" |
|
| 5 | 4 |
"testing" |
| 6 | 5 |
) |
| 7 | 6 |
|
| 8 | 7 |
var globalTestID string |
| 9 | 8 |
|
| 10 | 9 |
func newTestEngine(t *testing.T) *Engine {
|
| 11 |
- tmp, err := utils.TestDirectory("")
|
|
| 12 |
- if err != nil {
|
|
| 13 |
- t.Fatal(err) |
|
| 14 |
- } |
|
| 15 |
- eng, err := New(tmp) |
|
| 10 |
+ eng, err := New() |
|
| 16 | 11 |
if err != nil {
|
| 17 | 12 |
t.Fatal(err) |
| 18 | 13 |
} |
| ... | ... |
@@ -1,13 +1,11 @@ |
| 1 | 1 |
package engine |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "os" |
|
| 5 | 4 |
"testing" |
| 6 | 5 |
) |
| 7 | 6 |
|
| 8 | 7 |
func TestJobStatusOK(t *testing.T) {
|
| 9 | 8 |
eng := newTestEngine(t) |
| 10 |
- defer os.RemoveAll(eng.Root()) |
|
| 11 | 9 |
eng.Register("return_ok", func(job *Job) Status { return StatusOK })
|
| 12 | 10 |
err := eng.Job("return_ok").Run()
|
| 13 | 11 |
if err != nil {
|
| ... | ... |
@@ -17,7 +15,6 @@ func TestJobStatusOK(t *testing.T) {
|
| 17 | 17 |
|
| 18 | 18 |
func TestJobStatusErr(t *testing.T) {
|
| 19 | 19 |
eng := newTestEngine(t) |
| 20 |
- defer os.RemoveAll(eng.Root()) |
|
| 21 | 20 |
eng.Register("return_err", func(job *Job) Status { return StatusErr })
|
| 22 | 21 |
err := eng.Job("return_err").Run()
|
| 23 | 22 |
if err == nil {
|
| ... | ... |
@@ -27,7 +24,6 @@ func TestJobStatusErr(t *testing.T) {
|
| 27 | 27 |
|
| 28 | 28 |
func TestJobStatusNotFound(t *testing.T) {
|
| 29 | 29 |
eng := newTestEngine(t) |
| 30 |
- defer os.RemoveAll(eng.Root()) |
|
| 31 | 30 |
eng.Register("return_not_found", func(job *Job) Status { return StatusNotFound })
|
| 32 | 31 |
err := eng.Job("return_not_found").Run()
|
| 33 | 32 |
if err == nil {
|
| ... | ... |
@@ -37,7 +33,6 @@ func TestJobStatusNotFound(t *testing.T) {
|
| 37 | 37 |
|
| 38 | 38 |
func TestJobStdoutString(t *testing.T) {
|
| 39 | 39 |
eng := newTestEngine(t) |
| 40 |
- defer os.RemoveAll(eng.Root()) |
|
| 41 | 40 |
// FIXME: test multiple combinations of output and status |
| 42 | 41 |
eng.Register("say_something_in_stdout", func(job *Job) Status {
|
| 43 | 42 |
job.Printf("Hello world\n")
|
| ... | ... |
@@ -59,7 +54,6 @@ func TestJobStdoutString(t *testing.T) {
|
| 59 | 59 |
|
| 60 | 60 |
func TestJobStderrString(t *testing.T) {
|
| 61 | 61 |
eng := newTestEngine(t) |
| 62 |
- defer os.RemoveAll(eng.Root()) |
|
| 63 | 62 |
// FIXME: test multiple combinations of output and status |
| 64 | 63 |
eng.Register("say_something_in_stderr", func(job *Job) Status {
|
| 65 | 64 |
job.Errorf("Warning, something might happen\nHere it comes!\nOh no...\nSomething happened\n")
|
| ... | ... |
@@ -627,10 +627,9 @@ func TestRestore(t *testing.T) {
|
| 627 | 627 |
|
| 628 | 628 |
// Here are are simulating a docker restart - that is, reloading all containers |
| 629 | 629 |
// from scratch |
| 630 |
- eng = newTestEngine(t, false, eng.Root()) |
|
| 631 |
- daemon2 := mkDaemonFromEngine(eng, t) |
|
| 632 |
- if len(daemon2.List()) != 2 {
|
|
| 633 |
- t.Errorf("Expected 2 container, %v found", len(daemon2.List()))
|
|
| 630 |
+ eng = newTestEngine(t, false, runtime.Config().Root) |
|
| 631 |
+ if len(runtime2.List()) != 2 {
|
|
| 632 |
+ t.Errorf("Expected 2 container, %v found", len(runtime2.List()))
|
|
| 634 | 633 |
} |
| 635 | 634 |
runningCount := 0 |
| 636 | 635 |
for _, c := range daemon2.List() {
|
| ... | ... |
@@ -149,7 +149,7 @@ func TestRestartKillWait(t *testing.T) {
|
| 149 | 149 |
t.Fatal(err) |
| 150 | 150 |
} |
| 151 | 151 |
|
| 152 |
- eng = newTestEngine(t, false, eng.Root()) |
|
| 152 |
+ eng = newTestEngine(t, false, runtime.Config().Root) |
|
| 153 | 153 |
srv = mkServerFromEngine(eng, t) |
| 154 | 154 |
|
| 155 | 155 |
job = srv.Eng.Job("containers")
|