Merge pull request #225 from hashicorp/b-docker-port

Change docker default port to support windows and boot2docker
This commit is contained in:
Chris Bednarski
2015-10-08 23:50:11 -07:00
3 changed files with 60 additions and 19 deletions

View File

@@ -37,11 +37,36 @@ func NewDockerDriver(ctx *DriverContext) Driver {
return &DockerDriver{*ctx}
}
// dockerClient creates *docker.Client. In test / dev mode we can use ENV vars
// to connect to the docker daemon. In production mode we will read
// docker.endpoint from the config file.
func (d *DockerDriver) dockerClient() (*docker.Client, error) {
// In dev mode, read DOCKER_* environment variables DOCKER_HOST,
// DOCKER_TLS_VERIFY, and DOCKER_CERT_PATH. This allows you to run tests and
// demo against boot2docker or a VM on OSX and Windows. This falls back on
// the default unix socket on linux if tests are run on linux.
//
// Also note that we need to turn on DevMode in the test configs.
if d.config.DevMode {
return docker.NewClientFromEnv()
}
// In prod mode we'll read the docker.endpoint configuration and fall back
// on the host-specific default. We do not read from the environment.
defaultEndpoint, err := docker.DefaultDockerHost()
if err != nil {
return nil, fmt.Errorf("Unable to determine default docker endpoint: %s", err)
}
dockerEndpoint := d.config.ReadDefault("docker.endpoint", defaultEndpoint)
return docker.NewClient(dockerEndpoint)
}
func (d *DockerDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
// Initialize docker API client
dockerEndpoint := d.config.ReadDefault("docker.endpoint", "unix:///var/run/docker.sock")
client, err := docker.NewClient(dockerEndpoint)
client, err := d.dockerClient()
if err != nil {
d.logger.Printf("[DEBUG] driver.docker: could not connect to docker daemon: %v", err)
return false, nil
}
@@ -56,6 +81,7 @@ func (d *DockerDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool
env, err := client.Version()
if err != nil {
d.logger.Printf("[DEBUG] driver.docker: could not read version from daemon: %v", err)
// Check the "no such file" error if the unix file is missing
if strings.Contains(err.Error(), "no such file") {
return false, nil
@@ -212,10 +238,9 @@ func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle
}
// Initialize docker API client
dockerEndpoint := d.config.ReadDefault("docker.endpoint", "unix:///var/run/docker.sock")
client, err := docker.NewClient(dockerEndpoint)
client, err := d.dockerClient()
if err != nil {
return nil, fmt.Errorf("Failed to connect to docker.endpoint (%s): %s", dockerEndpoint, err)
return nil, fmt.Errorf("Failed to connect to docker daemon: %s", err)
}
repo, tag := docker.ParseRepositoryTag(image)
@@ -309,10 +334,9 @@ func (d *DockerDriver) Open(ctx *ExecContext, handleID string) (DriverHandle, er
d.logger.Printf("[INFO] driver.docker: re-attaching to docker process: %s", handleID)
// Initialize docker API client
dockerEndpoint := d.config.ReadDefault("docker.endpoint", "unix:///var/run/docker.sock")
client, err := docker.NewClient(dockerEndpoint)
client, err := d.dockerClient()
if err != nil {
return nil, fmt.Errorf("Failed to connect to docker.endpoint (%s): %s", dockerEndpoint, err)
return nil, fmt.Errorf("Failed to connect to docker daemon: %s", err)
}
// Look for a running container with this ID
@@ -401,6 +425,7 @@ func (h *dockerHandle) Kill() error {
err = h.client.RemoveImage(h.imageID)
if err != nil {
containers, err := h.client.ListContainers(docker.ListContainersOptions{
// The image might be in use by a stopped container, so check everything
All: true,
Filters: map[string][]string{
"image": []string{h.imageID},

View File

@@ -9,6 +9,12 @@ import (
"github.com/hashicorp/nomad/nomad/structs"
)
func testDockerDriverContext(task string) *DriverContext {
cfg := testConfig()
cfg.DevMode = true
return NewDriverContext(task, cfg, cfg.Node, testLogger())
}
// dockerLocated looks to see whether docker is available on this system before
// we try to run tests. We'll keep it simple and just check for the CLI.
func dockerLocated() bool {
@@ -33,7 +39,7 @@ func TestDockerDriver_Handle(t *testing.T) {
// The fingerprinter test should always pass, even if Docker is not installed.
func TestDockerDriver_Fingerprint(t *testing.T) {
d := NewDockerDriver(testDriverContext(""))
d := NewDockerDriver(testDockerDriverContext(""))
node := &structs.Node{
Attributes: make(map[string]string),
}
@@ -56,14 +62,14 @@ func TestDockerDriver_StartOpen_Wait(t *testing.T) {
}
task := &structs.Task{
Name: "python-demo",
Name: "redis-demo",
Config: map[string]string{
"image": "redis",
},
Resources: basicResources,
}
driverCtx := testDriverContext(task.Name)
driverCtx := testDockerDriverContext(task.Name)
ctx := testDriverExecContext(task, driverCtx)
defer ctx.AllocDir.Destroy()
d := NewDockerDriver(driverCtx)
@@ -93,7 +99,7 @@ func TestDockerDriver_Start_Wait(t *testing.T) {
}
task := &structs.Task{
Name: "python-demo",
Name: "redis-demo",
Config: map[string]string{
"image": "redis",
"command": "redis-server -v",
@@ -104,7 +110,7 @@ func TestDockerDriver_Start_Wait(t *testing.T) {
},
}
driverCtx := testDriverContext(task.Name)
driverCtx := testDockerDriverContext(task.Name)
ctx := testDriverExecContext(task, driverCtx)
defer ctx.AllocDir.Destroy()
d := NewDockerDriver(driverCtx)
@@ -140,7 +146,7 @@ func TestDockerDriver_Start_Kill_Wait(t *testing.T) {
}
task := &structs.Task{
Name: "python-demo",
Name: "redis-demo",
Config: map[string]string{
"image": "redis",
"command": "sleep 10",
@@ -148,7 +154,7 @@ func TestDockerDriver_Start_Kill_Wait(t *testing.T) {
Resources: basicResources,
}
driverCtx := testDriverContext(task.Name)
driverCtx := testDockerDriverContext(task.Name)
ctx := testDriverExecContext(task, driverCtx)
defer ctx.AllocDir.Destroy()
d := NewDockerDriver(driverCtx)
@@ -222,7 +228,7 @@ func TestDocker_StartN(t *testing.T) {
// Let's spin up a bunch of things
var err error
for idx, task := range taskList {
driverCtx := testDriverContext(task.Name)
driverCtx := testDockerDriverContext(task.Name)
ctx := testDriverExecContext(task, driverCtx)
defer ctx.AllocDir.Destroy()
d := NewDockerDriver(driverCtx)
@@ -271,7 +277,7 @@ func TestDocker_StartNVersions(t *testing.T) {
// Let's spin up a bunch of things
var err error
for idx, task := range taskList {
driverCtx := testDriverContext(task.Name)
driverCtx := testDockerDriverContext(task.Name)
ctx := testDriverExecContext(task, driverCtx)
defer ctx.AllocDir.Destroy()
d := NewDockerDriver(driverCtx)
@@ -309,7 +315,7 @@ func TestDockerHostNet(t *testing.T) {
CPU: 512,
},
}
driverCtx := testDriverContext(task.Name)
driverCtx := testDockerDriverContext(task.Name)
ctx := testDriverExecContext(task, driverCtx)
defer ctx.AllocDir.Destroy()
d := NewDockerDriver(driverCtx)

View File

@@ -111,11 +111,21 @@ The `docker` driver has the following configuration options:
* `docker.endpoint` - Defaults to `unix:///var/run/docker.sock`. You will need
to customize this if you use a non-standard socket (http or another location).
* `docker.cleanup.container` Defaults to `true`. Changing this to `false` will
prevent Nomad from removing containers from stopped tasks.
* `docker.cleanup.image` Defaults to `true`. Changing this to `false` will
prevent Nomad from removing images from stopped tasks.
Note: When testing or using the `-dev` flag you can use `DOCKER_HOST`,
`DOCKER_TLS_VERIFY`, and `DOCKER_CERT_PATH` to customize Nomad's behavior. In
production Nomad will always read `docker.endpoint`.
## Client Attributes
The `docker` driver will set the following client attributes:
* `driver.Docker` - This will be set to "1", indicating the
* `driver.docker` - This will be set to "1", indicating the
driver is available.
## Resource Isolation