Test driver network advertisement and checks

This commit is contained in:
Michael Schurter 2017-06-13 14:02:11 -07:00
parent b9bfb84b53
commit 67d154a274
18 changed files with 416 additions and 264 deletions

View File

@ -9,6 +9,7 @@ import (
"testing"
"github.com/hashicorp/nomad/client/driver"
cstructs "github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/nomad/structs"
)
@ -18,9 +19,10 @@ type mockConsulOp struct {
allocID string
task *structs.Task
exec driver.ScriptExecutor
net *cstructs.DriverNetwork
}
func newMockConsulOp(op, allocID string, task *structs.Task, exec driver.ScriptExecutor) mockConsulOp {
func newMockConsulOp(op, allocID string, task *structs.Task, exec driver.ScriptExecutor, net *cstructs.DriverNetwork) mockConsulOp {
if op != "add" && op != "remove" && op != "update" {
panic(fmt.Errorf("invalid consul op: %s", op))
}
@ -29,6 +31,7 @@ func newMockConsulOp(op, allocID string, task *structs.Task, exec driver.ScriptE
allocID: allocID,
task: task,
exec: exec,
net: net,
}
}
@ -56,15 +59,15 @@ func (m *mockConsulServiceClient) UpdateTask(allocID string, old, new *structs.T
m.mu.Lock()
defer m.mu.Unlock()
m.logger.Printf("[TEST] mock_consul: UpdateTask(%q, %v, %v, %T)", allocID, old, new, exec)
m.ops = append(m.ops, newMockConsulOp("update", allocID, new, exec))
m.ops = append(m.ops, newMockConsulOp("update", allocID, new, exec, nil))
return nil
}
func (m *mockConsulServiceClient) RegisterTask(allocID string, task *structs.Task, exec driver.ScriptExecutor) error {
func (m *mockConsulServiceClient) RegisterTask(allocID string, task *structs.Task, exec driver.ScriptExecutor, net *cstructs.DriverNetwork) error {
m.mu.Lock()
defer m.mu.Unlock()
m.logger.Printf("[TEST] mock_consul: RegisterTask(%q, %q, %T)", allocID, task.Name, exec)
m.ops = append(m.ops, newMockConsulOp("add", allocID, task, exec))
m.ops = append(m.ops, newMockConsulOp("add", allocID, task, exec, net))
return nil
}
@ -72,5 +75,5 @@ func (m *mockConsulServiceClient) RemoveTask(allocID string, task *structs.Task)
m.mu.Lock()
defer m.mu.Unlock()
m.logger.Printf("[TEST] mock_consul: RemoveTask(%q, %q)", allocID, task.Name)
m.ops = append(m.ops, newMockConsulOp("remove", allocID, task, nil))
m.ops = append(m.ops, newMockConsulOp("remove", allocID, task, nil, nil))
}

View File

@ -485,10 +485,17 @@ func (d *DockerDriver) Prestart(ctx *ExecContext, task *structs.Task) (*Prestart
if err != nil {
return nil, err
}
d.imageID = id
resp := NewPrestartResponse()
resp.CreatedResources.Add(dockerImageResKey, id)
d.imageID = id
// Return the PortMap if it's set
if len(driverConfig.PortMap) > 0 {
resp.Network = &cstructs.DriverNetwork{
PortMap: driverConfig.PortMap,
}
}
return resp, nil
}
@ -601,9 +608,9 @@ func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (*StartRespon
resp := &StartResponse{
Handle: h,
Network: &cstructs.DriverNetwork{
PortMap: d.driverConfig.PortMap,
IP: ip,
AutoUseIP: autoUse,
PortMap: d.driverConfig.PortMap,
IP: ip,
AutoAdvertise: autoUse,
},
}
return resp, nil

View File

@ -8,6 +8,7 @@ import (
"path/filepath"
"reflect"
"runtime/debug"
"sort"
"strconv"
"strings"
"testing"
@ -108,34 +109,39 @@ func dockerSetupWithClient(t *testing.T, task *structs.Task, client *docker.Clie
driver := NewDockerDriver(tctx.DriverCtx)
copyImage(t, tctx.ExecCtx.TaskDir, "busybox.tar")
resp, err := driver.Prestart(tctx.ExecCtx, task)
presp, err := driver.Prestart(tctx.ExecCtx, task)
if err != nil {
driver.Cleanup(tctx.ExecCtx, presp.CreatedResources)
tctx.AllocDir.Destroy()
t.Fatalf("error in prestart: %v", err)
}
// Update the exec ctx with the driver network env vars
tctx.ExecCtx.TaskEnv = tctx.EnvBuilder.SetDriverNetwork(presp.Network).Build()
// At runtime this is handled by TaskRunner
tctx.EnvBuilder.SetPortMap(resp.PortMap)
tctx.ExecCtx.TaskEnv = tctx.EnvBuilder.Build()
handle, err := driver.Start(tctx.ExecCtx, task)
sresp, err := driver.Start(tctx.ExecCtx, task)
if err != nil {
driver.Cleanup(tctx.ExecCtx, presp.CreatedResources)
tctx.AllocDir.Destroy()
t.Fatalf("Failed to start driver: %s\nStack\n%s", err, debug.Stack())
}
if handle == nil {
if sresp.Handle == nil {
driver.Cleanup(tctx.ExecCtx, presp.CreatedResources)
tctx.AllocDir.Destroy()
t.Fatalf("handle is nil\nStack\n%s", debug.Stack())
}
// At runtime this is handled by TaskRunner
tctx.EnvBuilder.SetDriverNetwork(sresp.Network)
tctx.ExecCtx.TaskEnv = tctx.EnvBuilder.Build()
cleanup := func() {
driver.Cleanup(tctx.ExecCtx, resp.CreatedResources)
handle.Kill()
driver.Cleanup(tctx.ExecCtx, presp.CreatedResources)
sresp.Handle.Kill()
tctx.AllocDir.Destroy()
}
return client, handle, cleanup
return client, sresp.Handle, cleanup
}
func newTestDockerClient(t *testing.T) *docker.Client {
@ -204,21 +210,21 @@ func TestDockerDriver_StartOpen_Wait(t *testing.T) {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
if resp.Handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
// Attempt to open
handle2, err := d.Open(ctx.ExecCtx, handle.ID())
resp2, err := d.Open(ctx.ExecCtx, resp.Handle.ID())
if err != nil {
t.Fatalf("err: %v", err)
}
if handle2 == nil {
if resp2 == nil {
t.Fatalf("missing handle")
}
}
@ -299,17 +305,14 @@ func TestDockerDriver_Start_LoadImage(t *testing.T) {
if err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -415,17 +418,14 @@ func TestDockerDriver_Start_Wait_AllocDir(t *testing.T) {
if err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -509,10 +509,12 @@ func TestDockerDriver_StartN(t *testing.T) {
if err != nil {
t.Fatalf("error in prestart #%d: %v", idx+1, err)
}
handles[idx], err = d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Errorf("Failed starting task #%d: %s", idx+1, err)
continue
}
handles[idx] = resp.Handle
}
t.Log("All tasks are started. Terminating...")
@ -569,10 +571,12 @@ func TestDockerDriver_StartNVersions(t *testing.T) {
if err != nil {
t.Fatalf("error in prestart #%d: %v", idx+1, err)
}
handles[idx], err = d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Errorf("Failed starting task #%d: %s", idx+1, err)
continue
}
handles[idx] = resp.Handle
}
t.Log("All tasks are started. Terminating...")
@ -917,6 +921,7 @@ func TestDockerDriver_PortsMapping(t *testing.T) {
"NOMAD_HOST_PORT_main": strconv.Itoa(docker_reserved),
}
sort.Strings(container.Config.Env)
for key, val := range expectedEnvironment {
search := fmt.Sprintf("%s=%s", key, val)
if !inSlice(search, container.Config.Env) {
@ -963,9 +968,9 @@ func TestDockerDriver_User(t *testing.T) {
// It should fail because the user "alice" does not exist on the given
// image.
handle, err := driver.Start(ctx.ExecCtx, task)
resp, err := driver.Start(ctx.ExecCtx, task)
if err == nil {
handle.Kill()
resp.Handle.Kill()
t.Fatalf("Should've failed")
}
@ -1164,14 +1169,14 @@ func TestDockerDriver_VolumesDisabled(t *testing.T) {
if err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := driver.Start(execCtx, task)
resp, err := driver.Start(execCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
defer handle.Kill()
defer resp.Handle.Kill()
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("unexpected err: %v", res)
}
@ -1215,14 +1220,14 @@ func TestDockerDriver_VolumesEnabled(t *testing.T) {
if err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := driver.Start(execCtx, task)
resp, err := driver.Start(execCtx, task)
if err != nil {
t.Fatalf("Failed to start docker driver: %v", err)
}
defer handle.Kill()
defer resp.Handle.Kill()
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("unexpected err: %v", res)
}

View File

@ -66,24 +66,21 @@ done
if err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
waitForExist(t, handle.(*DockerHandle).client, handle.(*DockerHandle))
waitForExist(t, resp.Handle.(*DockerHandle).client, resp.Handle.(*DockerHandle))
time.Sleep(1 * time.Second)
if err := handle.Signal(syscall.SIGUSR1); err != nil {
if err := resp.Handle.Signal(syscall.SIGUSR1); err != nil {
t.Fatalf("Signal returned an error: %v", err)
}
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if res.Successful() {
t.Fatalf("should err: %v", res)
}

View File

@ -57,6 +57,14 @@ type Factory func(*DriverContext) Driver
type PrestartResponse struct {
// CreatedResources by the driver.
CreatedResources *CreatedResources
// Network contains driver-specific network parameters such as the port
// map between the host and a container.
//
// Since the network configuration may not be fully populated by
// Prestart, it will only be used for creating an environment for
// Start. It will be overridden by the DriverNetwork returned by Start.
Network *cstructs.DriverNetwork
}
// NewPrestartResponse creates a new PrestartResponse with CreatedResources
@ -185,8 +193,8 @@ type StartResponse struct {
// of the task.
Handle DriverHandle
// DriverNetwork contains driver-specific network parameters such as
// the port map between the host and a container.
// Network contains driver-specific network parameters such as the port
// map between the host and a container.
//
// Network may be nil as not all drivers or configurations create
// networks.

View File

@ -211,6 +211,15 @@ func setupTaskEnv(t *testing.T, driver string) (*allocdir.TaskDir, map[string]st
"NOMAD_JOB_NAME": alloc.Job.Name,
"NOMAD_DC": "dc1",
"NOMAD_REGION": "global",
// Added in 0.6 via DriverNetworks
"NOMAD_HOST_IP_admin": "1.2.3.4",
"NOMAD_HOST_ADDR_admin": "1.2.3.4:8081",
"NOMAD_HOST_ADDR_two": "1.2.3.4:443",
"NOMAD_HOST_ADDR_web": "1.2.3.4:8086",
"NOMAD_HOST_IP_two": "1.2.3.4",
"NOMAD_HOST_ADDR_one": "1.2.3.4:80",
"NOMAD_HOST_IP_one": "1.2.3.4",
"NOMAD_HOST_IP_web": "1.2.3.4",
}
act := eb.Build().Map()

View File

@ -498,30 +498,32 @@ func buildPortEnv(envMap map[string]string, p structs.Port, ip string, driverNet
envMap["NOMAD_HOST_PORT_"+p.Label] = portStr
envMap["NOMAD_HOST_ADDR_"+p.Label] = net.JoinHostPort(ip, portStr)
// Driver IP, PORT, and ADDR; use host if nil
if driverNet == nil {
envMap["NOMAD_DRIVER_IP_"+p.Label] = ip
envMap["NOMAD_DRIVER_PORT_"+p.Label] = portStr
envMap["NOMAD_DRIVER_ADDR_"+p.Label] = net.JoinHostPort(ip, portStr)
} else {
// Driver IP, PORT, and ADDR if available
if driverNet != nil {
driverPortStr := strconv.Itoa(driverNet.PortMap[p.Label])
envMap["NOMAD_DRIVER_IP_"+p.Label] = driverNet.IP
envMap["NOMAD_DRIVER_PORT_"+p.Label] = driverPortStr
envMap["NOMAD_DRIVER_ADDR_"+p.Label] = net.JoinHostPort(driverNet.IP, driverPortStr)
}
// Auto IP, PORT, and ADDR
if driverNet.Use() {
// Use driver's
// Auto IP, PORT, and ADDR (driver if set; otherwise host)
if envMap["NOMAD_DRIVER_IP_"+p.Label] != "" {
// Driver IP set, use it
envMap[IpPrefix+p.Label] = envMap["NOMAD_DRIVER_IP_"+p.Label]
envMap[PortPrefix+p.Label] = envMap["NOMAD_DRIVER_PORT_"+p.Label]
envMap[AddrPrefix+p.Label] = envMap["NOMAD_DRIVER_ADDR_"+p.Label]
} else {
// Use host's
envMap[IpPrefix+p.Label] = envMap["NOMAD_HOST_IP_"+p.Label]
envMap[PortPrefix+p.Label] = envMap["NOMAD_HOST_PORT_"+p.Label]
envMap[AddrPrefix+p.Label] = envMap["NOMAD_HOST_ADDR_"+p.Label]
}
if envMap["NOMAD_DRIVER_PORT_"+p.Label] != "" {
// PortMap set, use it
envMap[PortPrefix+p.Label] = envMap["NOMAD_DRIVER_PORT_"+p.Label]
} else {
envMap[PortPrefix+p.Label] = envMap["NOMAD_HOST_PORT_"+p.Label]
}
// Address just joins the two (which doesn't make sense if IP is host
// and Port is driver, but it maintains pre-0.6 backward compat).
envMap[AddrPrefix+p.Label] = net.JoinHostPort(envMap[IpPrefix+p.Label], envMap[PortPrefix+p.Label])
}
// SetHostEnvvars adds the host environment variables to the tasks. The filter

View File

@ -69,16 +69,13 @@ func TestExecDriver_StartOpen_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Attempt to open
handle2, err := d.Open(ctx.ExecCtx, handle.ID())
handle2, err := d.Open(ctx.ExecCtx, resp.Handle.ID())
if err != nil {
t.Fatalf("err: %v", err)
}
@ -86,9 +83,10 @@ func TestExecDriver_StartOpen_Wait(t *testing.T) {
t.Fatalf("missing handle")
}
handle.Kill()
resp.Handle.Kill()
handle2.Kill()
}
func TestExecDriver_Start_Wait(t *testing.T) {
ctestutils.ExecCompatible(t)
task := &structs.Task{
@ -112,23 +110,20 @@ func TestExecDriver_Start_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Update should be a no-op
err = handle.Update(task)
err = resp.Handle.Update(task)
if err != nil {
t.Fatalf("err: %v", err)
}
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -166,17 +161,14 @@ func TestExecDriver_Start_Wait_AllocDir(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -220,17 +212,14 @@ func TestExecDriver_Start_Kill_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
go func() {
time.Sleep(100 * time.Millisecond)
err := handle.Kill()
err := resp.Handle.Kill()
if err != nil {
t.Fatalf("err: %v", err)
}
@ -238,7 +227,7 @@ func TestExecDriver_Start_Kill_Wait(t *testing.T) {
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if res.Successful() {
t.Fatal("should err")
}
@ -272,9 +261,9 @@ func TestExecDriverUser(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err == nil {
handle.Kill()
resp.Handle.Kill()
t.Fatalf("Should've failed")
}
msg := "user alice"
@ -308,13 +297,11 @@ func TestExecDriver_HandlerExec(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
handle := resp.Handle
// Exec a command that should work and dump the environment
out, code, err := handle.Exec(context.Background(), "/bin/sh", []string{"-c", "env | grep NOMAD"})

View File

@ -41,18 +41,15 @@ func TestExecDriver_KillUserPid_OnPluginReconnectFailure(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
id := &execId{}
if err := json.Unmarshal([]byte(handle.ID()), id); err != nil {
t.Fatalf("Failed to parse handle '%s': %v", handle.ID(), err)
if err := json.Unmarshal([]byte(resp.Handle.ID()), id); err != nil {
t.Fatalf("Failed to parse handle '%s': %v", resp.Handle.ID(), err)
}
pluginPid := id.PluginConfig.Pid
proc, err := os.FindProcess(pluginPid)
@ -64,7 +61,7 @@ func TestExecDriver_KillUserPid_OnPluginReconnectFailure(t *testing.T) {
}
// Attempt to open
handle2, err := d.Open(ctx.ExecCtx, handle.ID())
handle2, err := d.Open(ctx.ExecCtx, resp.Handle.ID())
if err == nil {
t.Fatalf("expected error")
}
@ -129,17 +126,14 @@ done
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
go func() {
time.Sleep(100 * time.Millisecond)
err := handle.Signal(syscall.SIGUSR1)
err := resp.Handle.Signal(syscall.SIGUSR1)
if err != nil {
t.Fatalf("err: %v", err)
}
@ -147,7 +141,7 @@ done
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if res.Successful() {
t.Fatal("should err")
}

View File

@ -97,16 +97,13 @@ func TestJavaDriver_StartOpen_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Attempt to open
handle2, err := d.Open(ctx.ExecCtx, handle.ID())
handle2, err := d.Open(ctx.ExecCtx, resp.Handle.ID())
if err != nil {
t.Fatalf("err: %v", err)
}
@ -118,7 +115,7 @@ func TestJavaDriver_StartOpen_Wait(t *testing.T) {
// There is a race condition between the handle waiting and killing. One
// will return an error.
handle.Kill()
resp.Handle.Kill()
handle2.Kill()
}
@ -152,17 +149,14 @@ func TestJavaDriver_Start_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -182,7 +176,7 @@ func TestJavaDriver_Start_Wait(t *testing.T) {
}
// need to kill long lived process
err = handle.Kill()
err = resp.Handle.Kill()
if err != nil {
t.Fatalf("Error: %s", err)
}
@ -218,17 +212,14 @@ func TestJavaDriver_Start_Kill_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
go func() {
time.Sleep(100 * time.Millisecond)
err := handle.Kill()
err := resp.Handle.Kill()
if err != nil {
t.Fatalf("err: %v", err)
}
@ -236,7 +227,7 @@ func TestJavaDriver_Start_Kill_Wait(t *testing.T) {
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if res.Successful() {
t.Fatal("should err")
}
@ -244,7 +235,7 @@ func TestJavaDriver_Start_Kill_Wait(t *testing.T) {
t.Fatalf("timeout")
// Need to kill long lived process
if err = handle.Kill(); err != nil {
if err = resp.Handle.Kill(); err != nil {
t.Fatalf("Error: %s", err)
}
}
@ -280,17 +271,14 @@ func TestJavaDriver_Signal(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
go func() {
time.Sleep(100 * time.Millisecond)
err := handle.Signal(syscall.SIGHUP)
err := resp.Handle.Signal(syscall.SIGHUP)
if err != nil {
t.Fatalf("err: %v", err)
}
@ -298,7 +286,7 @@ func TestJavaDriver_Signal(t *testing.T) {
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if res.Successful() {
t.Fatal("should err")
}
@ -306,7 +294,7 @@ func TestJavaDriver_Signal(t *testing.T) {
t.Fatalf("timeout")
// Need to kill long lived process
if err = handle.Kill(); err != nil {
if err = resp.Handle.Kill(); err != nil {
t.Fatalf("Error: %s", err)
}
}
@ -339,9 +327,9 @@ func TestJavaDriverUser(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err == nil {
handle.Kill()
resp.Handle.Kill()
t.Fatalf("Should've failed")
}
msg := "user alice"
@ -381,17 +369,14 @@ func TestJavaDriver_Start_Wait_Class(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -411,8 +396,7 @@ func TestJavaDriver_Start_Wait_Class(t *testing.T) {
}
// need to kill long lived process
err = handle.Kill()
if err != nil {
if err := resp.Handle.Kill(); err != nil {
t.Fatalf("Error: %s", err)
}
}

View File

@ -84,21 +84,18 @@ func TestQemuDriver_StartOpen_Wait(t *testing.T) {
t.Fatalf("Prestart faild: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Ensure that sending a Signal returns an error
if err := handle.Signal(syscall.SIGINT); err == nil {
if err := resp.Handle.Signal(syscall.SIGINT); err == nil {
t.Fatalf("Expect an error when signalling")
}
// Attempt to open
handle2, err := d.Open(ctx.ExecCtx, handle.ID())
handle2, err := d.Open(ctx.ExecCtx, resp.Handle.ID())
if err != nil {
t.Fatalf("err: %v", err)
}
@ -107,7 +104,7 @@ func TestQemuDriver_StartOpen_Wait(t *testing.T) {
}
// Clean up
if err := handle.Kill(); err != nil {
if err := resp.Handle.Kill(); err != nil {
fmt.Printf("\nError killing Qemu test: %s", err)
}
}
@ -150,9 +147,9 @@ func TestQemuDriverUser(t *testing.T) {
t.Fatalf("Prestart faild: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err == nil {
handle.Kill()
resp.Handle.Kill()
t.Fatalf("Should've failed")
}
msg := "unknown user alice"

View File

@ -81,16 +81,13 @@ func TestRawExecDriver_StartOpen_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Attempt to open
handle2, err := d.Open(ctx.ExecCtx, handle.ID())
handle2, err := d.Open(ctx.ExecCtx, resp.Handle.ID())
if err != nil {
t.Fatalf("err: %v", err)
}
@ -104,7 +101,7 @@ func TestRawExecDriver_StartOpen_Wait(t *testing.T) {
case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
t.Fatalf("timeout")
}
handle.Kill()
resp.Handle.Kill()
handle2.Kill()
}
@ -130,23 +127,20 @@ func TestRawExecDriver_Start_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Update should be a no-op
err = handle.Update(task)
err = resp.Handle.Update(task)
if err != nil {
t.Fatalf("err: %v", err)
}
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -156,7 +150,7 @@ func TestRawExecDriver_Start_Wait(t *testing.T) {
}
func TestRawExecDriver_Start_Wait_AllocDir(t *testing.T) {
exp := []byte{'w', 'i', 'n'}
exp := []byte("win")
file := "output.txt"
outPath := fmt.Sprintf(`${%s}/%s`, env.AllocDir, file)
task := &structs.Task{
@ -184,17 +178,14 @@ func TestRawExecDriver_Start_Wait_AllocDir(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -237,17 +228,14 @@ func TestRawExecDriver_Start_Kill_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
go func() {
time.Sleep(1 * time.Second)
err := handle.Kill()
err := resp.Handle.Kill()
// Can't rely on the ordering between wait and kill on travis...
if !testutil.IsTravis() && err != nil {
@ -257,7 +245,7 @@ func TestRawExecDriver_Start_Kill_Wait(t *testing.T) {
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if res.Successful() {
t.Fatal("should err")
}
@ -290,9 +278,9 @@ func TestRawExecDriverUser(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err == nil {
handle.Kill()
resp.Handle.Kill()
t.Fatalf("Should've failed")
}
msg := "unknown user alice"
@ -323,16 +311,13 @@ func TestRawExecDriver_HandlerExec(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Exec a command that should work
out, code, err := handle.Exec(context.TODO(), "/usr/bin/stat", []string{"/tmp"})
out, code, err := resp.Handle.Exec(context.TODO(), "/usr/bin/stat", []string{"/tmp"})
if err != nil {
t.Fatalf("error exec'ing stat: %v", err)
}
@ -344,7 +329,7 @@ func TestRawExecDriver_HandlerExec(t *testing.T) {
}
// Exec a command that should fail
out, code, err = handle.Exec(context.TODO(), "/usr/bin/stat", []string{"lkjhdsaflkjshowaisxmcvnlia"})
out, code, err = resp.Handle.Exec(context.TODO(), "/usr/bin/stat", []string{"lkjhdsaflkjshowaisxmcvnlia"})
if err != nil {
t.Fatalf("error exec'ing stat: %v", err)
}
@ -355,7 +340,7 @@ func TestRawExecDriver_HandlerExec(t *testing.T) {
t.Fatalf("expected output to contain %q but found: %q", expected, out)
}
if err := handle.Kill(); err != nil {
if err := resp.Handle.Kill(); err != nil {
t.Fatalf("error killing exec handle: %v", err)
}
}

View File

@ -52,17 +52,14 @@ done
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
go func() {
time.Sleep(100 * time.Millisecond)
err := handle.Signal(syscall.SIGUSR1)
err := resp.Handle.Signal(syscall.SIGUSR1)
if err != nil {
t.Fatalf("err: %v", err)
}
@ -70,7 +67,7 @@ done
// Task should terminate quickly
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if res.Successful() {
t.Fatal("should err")
}

View File

@ -103,23 +103,21 @@ func TestRktDriver_Start_DNS(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
// Attempt to open
handle2, err := d.Open(ctx.ExecCtx, handle.ID())
handle2, err := d.Open(ctx.ExecCtx, resp.Handle.ID())
if err != nil {
t.Fatalf("err: %v", err)
}
if handle2 == nil {
t.Fatalf("missing handle")
}
handle2.Kill()
}
func TestRktDriver_Start_Wait(t *testing.T) {
@ -154,28 +152,25 @@ func TestRktDriver_Start_Wait(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
// Update should be a no-op
err = handle.Update(task)
err = resp.Handle.Update(task)
if err != nil {
t.Fatalf("err: %v", err)
}
// Signal should be an error
if err = handle.Signal(syscall.SIGTERM); err == nil {
if err = resp.Handle.Signal(syscall.SIGTERM); err == nil {
t.Fatalf("err: %v", err)
}
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -215,23 +210,20 @@ func TestRktDriver_Start_Wait_Skip_Trust(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
// Update should be a no-op
err = handle.Update(task)
err = resp.Handle.Update(task)
if err != nil {
t.Fatalf("err: %v", err)
}
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -286,17 +278,14 @@ func TestRktDriver_Start_Wait_AllocDir(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
defer handle.Kill()
defer resp.Handle.Kill()
select {
case res := <-handle.WaitCh():
case res := <-resp.Handle.WaitCh():
if !res.Successful() {
t.Fatalf("err: %v", res)
}
@ -348,9 +337,9 @@ func TestRktDriverUser(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err == nil {
handle.Kill()
resp.Handle.Kill()
t.Fatalf("Should've failed")
}
msg := "unknown user alice"
@ -389,9 +378,9 @@ func TestRktTrustPrefix(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err == nil {
handle.Kill()
resp.Handle.Kill()
t.Fatalf("Should've failed")
}
msg := "Error running rkt trust"
@ -467,18 +456,15 @@ func TestRktDriver_PortsMapping(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
failCh := make(chan error, 1)
go func() {
time.Sleep(1 * time.Second)
if err := handle.Kill(); err != nil {
if err := resp.Handle.Kill(); err != nil {
failCh <- err
}
}()
@ -486,7 +472,7 @@ func TestRktDriver_PortsMapping(t *testing.T) {
select {
case err := <-failCh:
t.Fatalf("failed to kill handle: %v", err)
case <-handle.WaitCh():
case <-resp.Handle.WaitCh():
case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
t.Fatalf("timeout")
}
@ -523,19 +509,16 @@ func TestRktDriver_HandlerExec(t *testing.T) {
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("error in prestart: %v", err)
}
handle, err := d.Start(ctx.ExecCtx, task)
resp, err := d.Start(ctx.ExecCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Give the pod a second to start
time.Sleep(time.Second)
// Exec a command that should work
out, code, err := handle.Exec(context.TODO(), "/etcd", []string{"--version"})
out, code, err := resp.Handle.Exec(context.TODO(), "/etcd", []string{"--version"})
if err != nil {
t.Fatalf("error exec'ing etcd --version: %v", err)
}
@ -547,7 +530,7 @@ func TestRktDriver_HandlerExec(t *testing.T) {
}
// Exec a command that should fail
out, code, err = handle.Exec(context.TODO(), "/etcd", []string{"--kaljdshf"})
out, code, err = resp.Handle.Exec(context.TODO(), "/etcd", []string{"--kaljdshf"})
if err != nil {
t.Fatalf("error exec'ing bad command: %v", err)
}
@ -558,7 +541,7 @@ func TestRktDriver_HandlerExec(t *testing.T) {
t.Fatalf("expected output to contain %q but found: %q", expected, out)
}
if err := handle.Kill(); err != nil {
if err := resp.Handle.Kill(); err != nil {
t.Fatalf("error killing handle: %v", err)
}
}

View File

@ -135,15 +135,16 @@ type DriverNetwork struct {
// IP is the IP address for the task created by the driver.
IP string
// AutoUseIP indicates whether the driver thinks services that choose
// to auto-advertise-addresses should use this IP instead of the host's
AutoUseIP bool
// AutoAdvertise indicates whether the driver thinks services that
// choose to auto-advertise-addresses should use this IP instead of the
// host's. eg If a Docker network plugin is used
AutoAdvertise bool
}
// Use returns true if the driver suggests using the IP set. May be called on a
// nil Network in which case it returns false.
func (d *DriverNetwork) Use() bool {
return d != nil && d.AutoUseIP
// Advertise returns true if the driver suggests using the IP set. May be
// called on a nil Network in which case it returns false.
func (d *DriverNetwork) Advertise() bool {
return d != nil && d.AutoAdvertise
}
// Copy a Network struct. If it is nil, nil is returned.
@ -156,8 +157,8 @@ func (d *DriverNetwork) Copy() *DriverNetwork {
pm[k] = v
}
return &DriverNetwork{
PortMap: pm,
IP: d.IP,
AutoUseIP: d.AutoUseIP,
PortMap: pm,
IP: d.IP,
AutoAdvertise: d.AutoAdvertise,
}
}

View File

@ -1311,6 +1311,9 @@ func (r *TaskRunner) startTask() error {
r.createdResourcesLock.Lock()
r.createdResources.Merge(presp.CreatedResources)
r.createdResourcesLock.Unlock()
// Set any network configuration returned by the driver
r.envBuilder.SetDriverNetwork(presp.Network)
}
if err != nil {
@ -1333,7 +1336,7 @@ func (r *TaskRunner) startTask() error {
}
// Update environment with the network defined by the driver for the task
// Update environment with the network defined by the driver's Start method.
r.envBuilder.SetDriverNetwork(sresp.Network)
if err := r.registerServices(drv, sresp.Handle, sresp.Network); err != nil {

View File

@ -426,11 +426,11 @@ func (c *ServiceClient) serviceRegs(ops *operations, allocID string, service *st
id := makeTaskServiceID(allocID, task.Name, service)
addrMode := service.AddressMode
if addrMode == structs.AddressModeAuto {
if net == nil || !net.AutoUseIP {
if net.Advertise() {
addrMode = structs.AddressModeDriver
} else {
// No driver network or shouldn't default to driver's network
addrMode = structs.AddressModeHost
} else {
addrMode = structs.AddressModeDriver
}
}
ip, port := task.Resources.Networks.Port(service.PortLabel)

View File

@ -12,6 +12,7 @@ import (
"time"
"github.com/hashicorp/consul/api"
cstructs "github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/nomad/structs"
)
@ -169,6 +170,10 @@ func (c *fakeConsul) CheckRegister(check *api.AgentCheckRegistration) error {
c.mu.Lock()
defer c.mu.Unlock()
c.checks[check.ID] = check
// Be nice and make checks reachable-by-service
scheck := check.AgentServiceCheck
c.services[check.ServiceID].Checks = append(c.services[check.ServiceID].Checks, &scheck)
return nil
}
@ -210,7 +215,7 @@ func (c *fakeConsul) UpdateTTL(id string, output string, status string) error {
func TestConsul_ChangeTags(t *testing.T) {
ctx := setupFake()
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, nil); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, nil, nil); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
@ -290,7 +295,7 @@ func TestConsul_ChangePorts(t *testing.T) {
},
}
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx, nil); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
@ -375,7 +380,7 @@ func TestConsul_ChangePorts(t *testing.T) {
Path: "/",
Interval: time.Second,
Timeout: time.Second,
// Removed PortLabel
// Removed PortLabel; should default to service's (y)
},
}
if err := ctx.ServiceClient.UpdateTask("allocid", origTask, ctx.Task, ctx); err != nil {
@ -446,7 +451,7 @@ func TestConsul_ChangePorts(t *testing.T) {
func TestConsul_RegServices(t *testing.T) {
ctx := setupFake()
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, nil); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, nil, nil); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
@ -472,7 +477,7 @@ func TestConsul_RegServices(t *testing.T) {
// Make a change which will register a new service
ctx.Task.Services[0].Name = "taskname-service2"
ctx.Task.Services[0].Tags[0] = "tag3"
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, nil); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, nil, nil); err != nil {
t.Fatalf("unpexpected error registering task: %v", err)
}
@ -546,7 +551,7 @@ func TestConsul_ShutdownOK(t *testing.T) {
go ctx.ServiceClient.Run()
// Register a task and agent
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx, nil); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
@ -619,7 +624,7 @@ func TestConsul_ShutdownSlow(t *testing.T) {
go ctx.ServiceClient.Run()
// Register a task and agent
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx, nil); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
@ -690,7 +695,7 @@ func TestConsul_ShutdownBlocked(t *testing.T) {
go ctx.ServiceClient.Run()
// Register a task and agent
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx, nil); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
@ -747,7 +752,7 @@ func TestConsul_NoTLSSkipVerifySupport(t *testing.T) {
},
}
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, nil); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, nil, nil); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
@ -787,7 +792,7 @@ func TestConsul_CancelScript(t *testing.T) {
},
}
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx); err != nil {
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx, nil); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
@ -854,3 +859,188 @@ func TestConsul_CancelScript(t *testing.T) {
scriptHandle.cancel()
}
}
// TestConsul_DriverNetwork_AutoUse asserts that if a driver network has
// auto-use set then services should advertise it unless explicitly set to
// host. Checks should always use host.
func TestConsul_DriverNetwork_AutoUse(t *testing.T) {
ctx := setupFake()
ctx.Task.Services = []*structs.Service{
{
Name: "auto-advertise-x",
PortLabel: "x",
AddressMode: structs.AddressModeAuto,
Checks: []*structs.ServiceCheck{
{
Name: "default-check-x",
Type: "tcp",
Interval: time.Second,
Timeout: time.Second,
},
{
Name: "weird-y-check",
Type: "tcp",
Interval: time.Second,
Timeout: time.Second,
PortLabel: "y",
},
},
},
{
Name: "driver-advertise-y",
PortLabel: "y",
AddressMode: structs.AddressModeDriver,
Checks: []*structs.ServiceCheck{
{
Name: "default-check-y",
Type: "tcp",
Interval: time.Second,
Timeout: time.Second,
},
},
},
{
Name: "host-advertise-y",
PortLabel: "y",
AddressMode: structs.AddressModeHost,
},
}
net := &cstructs.DriverNetwork{
PortMap: map[string]int{
"x": 8888,
"y": 9999,
},
IP: "172.18.0.2",
AutoUseIP: true,
}
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx, net); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
if err := ctx.syncOnce(); err != nil {
t.Fatalf("unexpected error syncing task: %v", err)
}
if n := len(ctx.FakeConsul.services); n != 3 {
t.Fatalf("expected 2 services but found: %d", n)
}
for _, v := range ctx.FakeConsul.services {
switch v.Name {
case ctx.Task.Services[0].Name: // x
// Since DriverNetwork.AutoUseIP=true, driver ports should be used
if v.Port != net.PortMap["x"] {
t.Errorf("expected service %s's port to be %d but found %d",
v.Name, net.PortMap["x"], v.Port)
}
// Checks should always use host port though
if v.Checks[0].TCP != ":1234" { // xPort
t.Errorf("exepcted service %s check 1's port to be %d but found %q",
v.Name, xPort, v.Checks[0].TCP)
}
if v.Checks[1].TCP != ":1235" { // yPort
t.Errorf("exepcted service %s check 2's port to be %d but found %q",
v.Name, yPort, v.Checks[1].TCP)
}
case ctx.Task.Services[1].Name: // y
// Service should be container ip:port
if v.Address != net.IP {
t.Errorf("expected service %s's address to be %s but found %s",
v.Name, net.IP, v.Address)
}
if v.Port != net.PortMap["y"] {
t.Errorf("expected service %s's port to be %d but found %d",
v.Name, net.PortMap["x"], v.Port)
}
// Check should be host ip:port
if v.Checks[0].TCP != ":1235" { // yPort
t.Errorf("expected service %s check's port to be %d but found %s",
v.Name, yPort, v.Checks[0].TCP)
}
case ctx.Task.Services[2].Name: // y + host mode
if v.Port != yPort {
t.Errorf("expected service %s's port to be %d but found %s",
v.Name, yPort, v.Port)
}
default:
t.Errorf("unexpected service name: %q", v.Name)
}
}
}
// TestConsul_DriverNetwork_NoAutoUse asserts that if a driver network doesn't
// set auto-use only services which request the driver's network should
// advertise it.
func TestConsul_DriverNetwork_NoAutoUse(t *testing.T) {
ctx := setupFake()
ctx.Task.Services = []*structs.Service{
{
Name: "auto-advertise-x",
PortLabel: "x",
AddressMode: structs.AddressModeAuto,
},
{
Name: "driver-advertise-y",
PortLabel: "y",
AddressMode: structs.AddressModeDriver,
},
{
Name: "host-advertise-y",
PortLabel: "y",
AddressMode: structs.AddressModeHost,
},
}
net := &cstructs.DriverNetwork{
PortMap: map[string]int{
"x": 8888,
"y": 9999,
},
IP: "172.18.0.2",
AutoUseIP: false,
}
if err := ctx.ServiceClient.RegisterTask("allocid", ctx.Task, ctx, net); err != nil {
t.Fatalf("unexpected error registering task: %v", err)
}
if err := ctx.syncOnce(); err != nil {
t.Fatalf("unexpected error syncing task: %v", err)
}
if n := len(ctx.FakeConsul.services); n != 3 {
t.Fatalf("expected 2 services but found: %d", n)
}
for _, v := range ctx.FakeConsul.services {
switch v.Name {
case ctx.Task.Services[0].Name: // x + auto
// Since DriverNetwork.AutoUseIP=false, host ports should be used
if v.Port != xPort {
t.Errorf("expected service %s's port to be %d but found %d",
v.Name, xPort, v.Port)
}
case ctx.Task.Services[1].Name: // y + driver mode
// Service should be container ip:port
if v.Address != net.IP {
t.Errorf("expected service %s's address to be %s but found %s",
v.Name, net.IP, v.Address)
}
if v.Port != net.PortMap["y"] {
t.Errorf("expected service %s's port to be %d but found %d",
v.Name, net.PortMap["x"], v.Port)
}
case ctx.Task.Services[2].Name: // y + host mode
if v.Port != yPort {
t.Errorf("expected service %s's port to be %d but found %s",
v.Name, yPort, v.Port)
}
default:
t.Errorf("unexpected service name: %q", v.Name)
}
}
}