diff --git a/client/consul.go b/client/consul.go index c9fe4e107..043a17bdb 100644 --- a/client/consul.go +++ b/client/consul.go @@ -1,14 +1,14 @@ package client import ( - "github.com/hashicorp/nomad/command/agent/consul" + "github.com/hashicorp/nomad/client/driver" "github.com/hashicorp/nomad/nomad/structs" ) // ConsulServiceAPI is the interface the Nomad Client uses to register and // remove services and checks from Consul. type ConsulServiceAPI interface { - RegisterTask(allocID string, task *structs.Task, exec consul.ScriptExecutor) error + RegisterTask(allocID string, task *structs.Task, exec driver.ScriptExecutor) error RemoveTask(allocID string, task *structs.Task) - UpdateTask(allocID string, existing, newTask *structs.Task, exec consul.ScriptExecutor) error + UpdateTask(allocID string, existing, newTask *structs.Task, exec driver.ScriptExecutor) error } diff --git a/client/driver/driver.go b/client/driver/driver.go index a89db8167..74c898031 100644 --- a/client/driver/driver.go +++ b/client/driver/driver.go @@ -1,6 +1,7 @@ package driver import ( + "context" "errors" "fmt" "log" @@ -256,6 +257,12 @@ type DriverHandle interface { Signal(s os.Signal) error } +// ScriptExecutor is a DriverHandle that supports Exec()ing commands in the +// driver's context. +type ScriptExecutor interface { + Exec(ctx context.Context, cmd string, args []string) ([]byte, int, error) +} + // ExecContext is a task's execution context type ExecContext struct { // TaskDir contains information about the task directory structure. diff --git a/client/task_runner.go b/client/task_runner.go index 209336d70..e4e4c15e8 100644 --- a/client/task_runner.go +++ b/client/task_runner.go @@ -21,7 +21,6 @@ import ( "github.com/hashicorp/nomad/client/driver" "github.com/hashicorp/nomad/client/getter" "github.com/hashicorp/nomad/client/vaultclient" - "github.com/hashicorp/nomad/command/agent/consul" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/client/driver/env" @@ -298,7 +297,7 @@ func (r *TaskRunner) RestoreState() error { interpolateServices(r.getTaskEnv(), r.task) // Ensure the service is registered - scriptExec, _ := handle.(consul.ScriptExecutor) + scriptExec, _ := handle.(driver.ScriptExecutor) if err := r.consul.RegisterTask(r.alloc.ID, r.task, scriptExec); err != nil { //FIXME What to do if this fails? r.logger.Printf("[WARN] client: failed to register services and checks for task %q alloc %q: %v", @@ -1243,7 +1242,7 @@ func (r *TaskRunner) startTask() error { // RegisterTask properly handles scriptExec being nil, so it just // ignore the ok value. - scriptExec, _ := handle.(consul.ScriptExecutor) + scriptExec, _ := handle.(driver.ScriptExecutor) if err := r.consul.RegisterTask(r.alloc.ID, r.task, scriptExec); err != nil { //FIXME handle errors?! //FIXME could break into prepare & submit steps as only preperation can error... @@ -1399,7 +1398,7 @@ func (r *TaskRunner) handleUpdate(update *structs.Allocation) error { // Not all drivers support Exec (eg QEMU), but RegisterTask // handles nil ScriptExecutors - scriptExec, _ := r.handle.(consul.ScriptExecutor) + scriptExec, _ := r.handle.(driver.ScriptExecutor) // Since the handle exists, the task is running, so we need to // update it in Consul (if the handle doesn't exist diff --git a/command/agent/consul/client.go b/command/agent/consul/client.go index 6a5bbe49b..449184e2d 100644 --- a/command/agent/consul/client.go +++ b/command/agent/consul/client.go @@ -1,7 +1,6 @@ package consul import ( - "context" "fmt" "log" "net" @@ -12,6 +11,7 @@ import ( "time" "github.com/hashicorp/consul/api" + "github.com/hashicorp/nomad/client/driver" "github.com/hashicorp/nomad/nomad/structs" ) @@ -51,12 +51,6 @@ const ( ServiceTagSerf = "serf" ) -// ScriptExecutor is the interface the ServiceClient uses to execute script -// checks inside a container. -type ScriptExecutor interface { - Exec(ctx context.Context, cmd string, args []string) ([]byte, int, error) -} - // CatalogAPI is the consul/api.Catalog API used by Nomad. type CatalogAPI interface { Datacenters() ([]string, error) @@ -386,7 +380,7 @@ func (c *ServiceClient) RegisterAgent(role string, services []*structs.Service) // makeCheckReg adds a check reg to operations. func (c *ServiceClient) makeCheckReg(ops *operations, check *structs.ServiceCheck, - service *api.AgentServiceRegistration, exec ScriptExecutor, parseAddr addrParser) error { + service *api.AgentServiceRegistration, exec driver.ScriptExecutor, parseAddr addrParser) error { checkID := createCheckID(service.ID, check) if check.Type == structs.ServiceCheckScript { @@ -412,7 +406,7 @@ func (c *ServiceClient) makeCheckReg(ops *operations, check *structs.ServiceChec // serviceRegs creates service registrations, check registrations, and script // checks from a service. func (c *ServiceClient) serviceRegs(ops *operations, allocID string, service *structs.Service, - exec ScriptExecutor, task *structs.Task) error { + exec driver.ScriptExecutor, task *structs.Task) error { id := makeTaskServiceID(allocID, task.Name, service) host, port := task.FindHostAndPortFor(service.PortLabel) @@ -441,7 +435,7 @@ func (c *ServiceClient) serviceRegs(ops *operations, allocID string, service *st // exec is nil and a script check exists an error is returned. // // Actual communication with Consul is done asynchrously (see Run). -func (c *ServiceClient) RegisterTask(allocID string, task *structs.Task, exec ScriptExecutor) error { +func (c *ServiceClient) RegisterTask(allocID string, task *structs.Task, exec driver.ScriptExecutor) error { ops := &operations{} for _, service := range task.Services { if err := c.serviceRegs(ops, allocID, service, exec, task); err != nil { @@ -454,7 +448,7 @@ func (c *ServiceClient) RegisterTask(allocID string, task *structs.Task, exec Sc // UpdateTask in Consul. Does not alter the service if only checks have // changed. -func (c *ServiceClient) UpdateTask(allocID string, existing, newTask *structs.Task, exec ScriptExecutor) error { +func (c *ServiceClient) UpdateTask(allocID string, existing, newTask *structs.Task, exec driver.ScriptExecutor) error { ops := &operations{} existingIDs := make(map[string]*structs.Service, len(existing.Services)) diff --git a/command/agent/consul/script.go b/command/agent/consul/script.go index 96c52e741..608de8db1 100644 --- a/command/agent/consul/script.go +++ b/command/agent/consul/script.go @@ -6,6 +6,7 @@ import ( "time" "github.com/hashicorp/consul/api" + "github.com/hashicorp/nomad/client/driver" "github.com/hashicorp/nomad/nomad/structs" ) @@ -29,7 +30,7 @@ func (s *scriptHandle) wait() <-chan struct{} { type scriptCheck struct { id string check *structs.ServiceCheck - exec ScriptExecutor + exec driver.ScriptExecutor agent heartbeater running bool @@ -40,7 +41,9 @@ type scriptCheck struct { shutdownCh <-chan struct{} } -func newScriptCheck(id string, check *structs.ServiceCheck, exec ScriptExecutor, agent heartbeater, logger *log.Logger, shutdownCh <-chan struct{}) *scriptCheck { +func newScriptCheck(id string, check *structs.ServiceCheck, exec driver.ScriptExecutor, agent heartbeater, + logger *log.Logger, shutdownCh <-chan struct{}) *scriptCheck { + return &scriptCheck{ id: id, check: check,