This commit is contained in:
Solomon Hykes 2013-11-13 19:25:55 +00:00
parent 8e71391572
commit b00d5f0185
8 changed files with 66 additions and 68 deletions

View File

@ -30,10 +30,10 @@ func Register(name string, handler Handler) error {
// It acts as a store for *containers*, and allows manipulation of these
// containers by executing *jobs*.
type Engine struct {
root string
handlers map[string]Handler
hack Hack // data for temporary hackery (see hack.go)
id string
root string
handlers map[string]Handler
hack Hack // data for temporary hackery (see hack.go)
id string
}
func (eng *Engine) Root() string {
@ -50,7 +50,6 @@ func (eng *Engine) Register(name string, handler Handler) error {
return nil
}
// New initializes a new engine managing the directory specified at `root`.
// `root` is used to store containers and any other state private to the engine.
// Changing the contents of the root without executing a job will cause unspecified
@ -78,9 +77,9 @@ func New(root string) (*Engine, error) {
return nil, err
}
eng := &Engine{
root: root,
handlers: make(map[string]Handler),
id: utils.RandomString(),
root: root,
handlers: make(map[string]Handler),
id: utils.RandomString(),
}
// Copy existing global handlers
for k, v := range globalHandlers {
@ -97,12 +96,12 @@ func (eng *Engine) String() string {
// This function mimics `Command` from the standard os/exec package.
func (eng *Engine) Job(name string, args ...string) *Job {
job := &Job{
Eng: eng,
Name: name,
Args: args,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
Eng: eng,
Name: name,
Args: args,
Stdin: os.Stdin,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
handler, exists := eng.handlers[name]
if exists {

View File

@ -1,9 +1,7 @@
package engine
type Hack map[string]interface{}
func (eng *Engine) Hack_GetGlobalVar(key string) interface{} {
if eng.hack == nil {
return nil

View File

@ -3,14 +3,14 @@ package engine
import (
"bufio"
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"strconv"
"strings"
"fmt"
"sync"
"encoding/json"
"os"
)
// A job is the fundamental unit of work in the docker engine.
@ -27,16 +27,16 @@ import (
// This allows for richer error reporting.
//
type Job struct {
Eng *Engine
Name string
Args []string
env []string
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
handler func(*Job) string
status string
onExit []func()
Eng *Engine
Name string
Args []string
env []string
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
handler func(*Job) string
status string
onExit []func()
}
// Run executes the job and blocks until the job completes.
@ -106,30 +106,33 @@ func (job *Job) parseLines(src io.Reader, dst *[]string, limit int) {
func (job *Job) StdoutParseString(dst *string) {
lines := make([]string, 0, 1)
job.StdoutParseLines(&lines, 1)
job.onExit = append(job.onExit, func() { if len(lines) >= 1 { *dst = lines[0] }})
job.onExit = append(job.onExit, func() {
if len(lines) >= 1 {
*dst = lines[0]
}
})
}
func (job *Job) StderrParseString(dst *string) {
lines := make([]string, 0, 1)
job.StderrParseLines(&lines, 1)
job.onExit = append(job.onExit, func() { *dst = lines[0]; })
job.onExit = append(job.onExit, func() { *dst = lines[0] })
}
func (job *Job) StdoutPipe() io.ReadCloser {
r, w := io.Pipe()
job.Stdout = w
job.onExit = append(job.onExit, func(){ w.Close() })
job.onExit = append(job.onExit, func() { w.Close() })
return r
}
func (job *Job) StderrPipe() io.ReadCloser {
r, w := io.Pipe()
job.Stderr = w
job.onExit = append(job.onExit, func(){ w.Close() })
job.onExit = append(job.onExit, func() { w.Close() })
return r
}
func (job *Job) CallString() string {
return fmt.Sprintf("%s(%s)", job.Name, strings.Join(job.Args, ", "))
}
@ -242,7 +245,7 @@ func (job *Job) DecodeEnv(src io.Reader) error {
job.SetenvInt(k, int64(fval))
} else if sval, ok := v.(string); ok {
job.Setenv(k, sval)
} else if val, err := json.Marshal(v); err == nil {
} else if val, err := json.Marshal(v); err == nil {
job.Setenv(k, string(val))
} else {
job.Setenv(k, fmt.Sprintf("%v", v))

View File

@ -9,6 +9,7 @@ import (
"io"
"log"
"net"
"net/url"
"os"
"path/filepath"
"runtime"
@ -18,7 +19,6 @@ import (
"syscall"
"testing"
"time"
"net/url"
)
const (
@ -158,8 +158,8 @@ func spawnGlobalDaemon() {
go func() {
utils.Debugf("Spawning global daemon for integration tests")
listenURL := &url.URL{
Scheme: testDaemonProto,
Host: testDaemonAddr,
Scheme: testDaemonProto,
Host: testDaemonAddr,
}
job := eng.Job("serveapi", listenURL.String())
job.SetenvBool("Logging", os.Getenv("DEBUG") != "")

View File

@ -74,7 +74,6 @@ func jobInitApi(job *engine.Job) string {
return "0"
}
func (srv *Server) ListenAndServe(job *engine.Job) string {
protoAddrs := job.Args
chErrors := make(chan error, len(protoAddrs))
@ -1388,25 +1387,25 @@ func (srv *Server) ContainerStart(job *engine.Job) string {
return err.Error()
}
// Validate the HostConfig binds. Make sure that:
// 1) the source of a bind mount isn't /
// The bind mount "/:/foo" isn't allowed.
// 2) Check that the source exists
// The source to be bind mounted must exist.
for _, bind := range hostConfig.Binds {
splitBind := strings.Split(bind, ":")
source := splitBind[0]
// 1) the source of a bind mount isn't /
// The bind mount "/:/foo" isn't allowed.
// 2) Check that the source exists
// The source to be bind mounted must exist.
for _, bind := range hostConfig.Binds {
splitBind := strings.Split(bind, ":")
source := splitBind[0]
// refuse to bind mount "/" to the container
if source == "/" {
return fmt.Sprintf("Invalid bind mount '%s' : source can't be '/'", bind)
}
// refuse to bind mount "/" to the container
if source == "/" {
return fmt.Sprintf("Invalid bind mount '%s' : source can't be '/'", bind)
}
// ensure the source exists on the host
_, err := os.Stat(source)
if err != nil && os.IsNotExist(err) {
return fmt.Sprintf("Invalid bind mount '%s' : source doesn't exist", bind)
}
}
// ensure the source exists on the host
_, err := os.Stat(source)
if err != nil && os.IsNotExist(err) {
return fmt.Sprintf("Invalid bind mount '%s' : source doesn't exist", bind)
}
}
// Register any links from the host config before starting the container
// FIXME: we could just pass the container here, no need to lookup by name again.
if err := srv.RegisterLinks(name, &hostConfig); err != nil {

View File

@ -2,8 +2,8 @@ package docker
import (
"github.com/dotcloud/docker/utils"
"strings"
"io/ioutil"
"strings"
"testing"
"time"
)

View File

@ -266,23 +266,23 @@ func TestHumanSize(t *testing.T) {
}
func TestRAMInBytes(t *testing.T) {
assertRAMInBytes(t, "32", false, 32)
assertRAMInBytes(t, "32b", false, 32)
assertRAMInBytes(t, "32B", false, 32)
assertRAMInBytes(t, "32k", false, 32*1024)
assertRAMInBytes(t, "32K", false, 32*1024)
assertRAMInBytes(t, "32", false, 32)
assertRAMInBytes(t, "32b", false, 32)
assertRAMInBytes(t, "32B", false, 32)
assertRAMInBytes(t, "32k", false, 32*1024)
assertRAMInBytes(t, "32K", false, 32*1024)
assertRAMInBytes(t, "32kb", false, 32*1024)
assertRAMInBytes(t, "32Kb", false, 32*1024)
assertRAMInBytes(t, "32Mb", false, 32*1024*1024)
assertRAMInBytes(t, "32Gb", false, 32*1024*1024*1024)
assertRAMInBytes(t, "", true, -1)
assertRAMInBytes(t, "", true, -1)
assertRAMInBytes(t, "hello", true, -1)
assertRAMInBytes(t, "-32", true, -1)
assertRAMInBytes(t, " 32 ", true, -1)
assertRAMInBytes(t, "-32", true, -1)
assertRAMInBytes(t, " 32 ", true, -1)
assertRAMInBytes(t, "32 mb", true, -1)
assertRAMInBytes(t, "32m b", true, -1)
assertRAMInBytes(t, "32bm", true, -1)
assertRAMInBytes(t, "32bm", true, -1)
}
func assertRAMInBytes(t *testing.T, size string, expectError bool, expectedBytes int64) {

View File

@ -27,7 +27,7 @@ func mkRuntime(f utils.Fataler) *Runtime {
f.Fatal(err)
}
config := &DaemonConfig{
Root: root,
Root: root,
AutoRestart: false,
}
r, err := NewRuntimeFromDirectory(config)
@ -66,7 +66,6 @@ func mkServerFromEngine(eng *engine.Engine, t utils.Fataler) *Server {
return srv
}
func NewTestEngine(t utils.Fataler) *engine.Engine {
root, err := newTestDirectory(unitTestStoreBase)
if err != nil {