diff --git a/client/allocdir/alloc_dir_test.go b/client/allocdir/alloc_dir_test.go index 811b29f08..ac9bad946 100644 --- a/client/allocdir/alloc_dir_test.go +++ b/client/allocdir/alloc_dir_test.go @@ -9,12 +9,12 @@ import ( "log" "os" "path/filepath" + "runtime" "strings" "syscall" "testing" cstructs "github.com/hashicorp/nomad/client/structs" - "github.com/hashicorp/nomad/client/testutil" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" "github.com/stretchr/testify/require" @@ -83,8 +83,21 @@ func TestAllocDir_BuildAlloc(t *testing.T) { } } +// HACK: This function is copy/pasted from client.testutil to prevent a test +// import cycle, due to testutil transitively importing allocdir. This +// should be fixed after DriverManager is implemented. +func MountCompatible(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("Windows does not support mount") + } + + if syscall.Geteuid() != 0 { + t.Skip("Must be root to run test") + } +} + func TestAllocDir_MountSharedAlloc(t *testing.T) { - testutil.MountCompatible(t) + MountCompatible(t) tmp, err := ioutil.TempDir("", "AllocDir") if err != nil { t.Fatalf("Couldn't create temp dir: %v", err) diff --git a/client/client.go b/client/client.go index 1f570a3c6..ce2e87573 100644 --- a/client/client.go +++ b/client/client.go @@ -27,6 +27,7 @@ import ( "github.com/hashicorp/nomad/client/config" consulApi "github.com/hashicorp/nomad/client/consul" "github.com/hashicorp/nomad/client/devicemanager" + "github.com/hashicorp/nomad/client/fingerprint" "github.com/hashicorp/nomad/client/servers" "github.com/hashicorp/nomad/client/state" "github.com/hashicorp/nomad/client/stats" @@ -1084,7 +1085,7 @@ func (c *Client) setupNode() error { // updateNodeFromFingerprint updates the node with the result of // fingerprinting the node from the diff that was created -func (c *Client) updateNodeFromFingerprint(response *cstructs.FingerprintResponse) *structs.Node { +func (c *Client) updateNodeFromFingerprint(response *fingerprint.FingerprintResponse) *structs.Node { c.configLock.Lock() defer c.configLock.Unlock() diff --git a/client/client_test.go b/client/client_test.go index 6d02990b7..3dadc3ce6 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -12,7 +12,7 @@ import ( memdb "github.com/hashicorp/go-memdb" "github.com/hashicorp/nomad/client/config" consulApi "github.com/hashicorp/nomad/client/consul" - cstructs "github.com/hashicorp/nomad/client/structs" + "github.com/hashicorp/nomad/client/fingerprint" "github.com/hashicorp/nomad/command/agent/consul" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/helper/uuid" @@ -1007,13 +1007,13 @@ func TestClient_UpdateNodeFromDevicesAccumulates(t *testing.T) { client, cleanup := TestClient(t, func(c *config.Config) {}) defer cleanup() - client.updateNodeFromFingerprint(&cstructs.FingerprintResponse{ + client.updateNodeFromFingerprint(&fingerprint.FingerprintResponse{ NodeResources: &structs.NodeResources{ Cpu: structs.NodeCpuResources{CpuShares: 123}, }, }) - client.updateNodeFromFingerprint(&cstructs.FingerprintResponse{ + client.updateNodeFromFingerprint(&fingerprint.FingerprintResponse{ NodeResources: &structs.NodeResources{ Memory: structs.NodeMemoryResources{MemoryMB: 1024}, }, @@ -1047,7 +1047,7 @@ func TestClient_UpdateNodeFromDevicesAccumulates(t *testing.T) { // overrides of values - client.updateNodeFromFingerprint(&cstructs.FingerprintResponse{ + client.updateNodeFromFingerprint(&fingerprint.FingerprintResponse{ NodeResources: &structs.NodeResources{ Memory: structs.NodeMemoryResources{MemoryMB: 2048}, }, diff --git a/client/fingerprint/arch.go b/client/fingerprint/arch.go index 7f2083f5a..5d309a1c0 100644 --- a/client/fingerprint/arch.go +++ b/client/fingerprint/arch.go @@ -4,7 +4,6 @@ import ( "runtime" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" ) // ArchFingerprint is used to fingerprint the architecture @@ -19,7 +18,7 @@ func NewArchFingerprint(logger log.Logger) Fingerprint { return f } -func (f *ArchFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *ArchFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { resp.AddAttribute("cpu.arch", runtime.GOARCH) resp.Detected = true return nil diff --git a/client/fingerprint/arch_test.go b/client/fingerprint/arch_test.go index 3d23b7a84..c5faa2fff 100644 --- a/client/fingerprint/arch_test.go +++ b/client/fingerprint/arch_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" ) @@ -15,8 +14,8 @@ func TestArchFingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) diff --git a/client/fingerprint/cgroup.go b/client/fingerprint/cgroup.go index e399e7d08..b6f171782 100644 --- a/client/fingerprint/cgroup.go +++ b/client/fingerprint/cgroup.go @@ -4,7 +4,6 @@ import ( "time" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" ) const ( @@ -46,7 +45,7 @@ func NewCGroupFingerprint(logger log.Logger) Fingerprint { // clearCGroupAttributes clears any node attributes related to cgroups that might // have been set in a previous fingerprint run. -func (f *CGroupFingerprint) clearCGroupAttributes(r *cstructs.FingerprintResponse) { +func (f *CGroupFingerprint) clearCGroupAttributes(r *FingerprintResponse) { r.RemoveAttribute("unique.cgroup.mountpoint") } diff --git a/client/fingerprint/cgroup_default.go b/client/fingerprint/cgroup_default.go index 948fcb97f..8ee17d1a1 100644 --- a/client/fingerprint/cgroup_default.go +++ b/client/fingerprint/cgroup_default.go @@ -2,14 +2,12 @@ package fingerprint -import cstructs "github.com/hashicorp/nomad/client/structs" - // FindCgroupMountpointDir is used to find the cgroup mount point on a Linux // system. Here it is a no-op implemtation func FindCgroupMountpointDir() (string, error) { return "", nil } -func (f *CGroupFingerprint) Fingerprint(*cstructs.FingerprintRequest, *cstructs.FingerprintResponse) error { +func (f *CGroupFingerprint) Fingerprint(*FingerprintRequest, *FingerprintResponse) error { return nil } diff --git a/client/fingerprint/cgroup_linux.go b/client/fingerprint/cgroup_linux.go index 467904ebd..c72d16b47 100644 --- a/client/fingerprint/cgroup_linux.go +++ b/client/fingerprint/cgroup_linux.go @@ -5,7 +5,6 @@ package fingerprint import ( "fmt" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/opencontainers/runc/libcontainer/cgroups" ) @@ -31,7 +30,7 @@ func FindCgroupMountpointDir() (string, error) { } // Fingerprint tries to find a valid cgroup mount point -func (f *CGroupFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *CGroupFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { mount, err := f.mountPointDetector.MountPoint() if err != nil { f.clearCGroupAttributes(resp) diff --git a/client/fingerprint/cgroup_test.go b/client/fingerprint/cgroup_test.go index 5016cd855..8aa5b7455 100644 --- a/client/fingerprint/cgroup_test.go +++ b/client/fingerprint/cgroup_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" ) @@ -52,8 +51,8 @@ func TestCGroupFingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err == nil { t.Fatalf("expected an error") @@ -75,8 +74,8 @@ func TestCGroupFingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("unexpected error, %s", err) @@ -97,8 +96,8 @@ func TestCGroupFingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("unexpected error, %s", err) @@ -118,8 +117,8 @@ func TestCGroupFingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("unexpected error, %s", err) diff --git a/client/fingerprint/consul.go b/client/fingerprint/consul.go index 66e86a86e..8717f2f84 100644 --- a/client/fingerprint/consul.go +++ b/client/fingerprint/consul.go @@ -7,7 +7,6 @@ import ( consul "github.com/hashicorp/consul/api" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" ) const ( @@ -27,7 +26,7 @@ func NewConsulFingerprint(logger log.Logger) Fingerprint { return &ConsulFingerprint{logger: logger.Named("consul"), lastState: consulUnavailable} } -func (f *ConsulFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *ConsulFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { // Only create the client once to avoid creating too many connections to // Consul. if f.client == nil { @@ -103,7 +102,7 @@ func (f *ConsulFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp * // clearConsulAttributes removes consul attributes and links from the passed // Node. -func (f *ConsulFingerprint) clearConsulAttributes(r *cstructs.FingerprintResponse) { +func (f *ConsulFingerprint) clearConsulAttributes(r *FingerprintResponse) { r.RemoveAttribute("consul.server") r.RemoveAttribute("consul.version") r.RemoveAttribute("consul.revision") diff --git a/client/fingerprint/consul_test.go b/client/fingerprint/consul_test.go index c260fd493..79dee85fa 100644 --- a/client/fingerprint/consul_test.go +++ b/client/fingerprint/consul_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" "github.com/stretchr/testify/assert" @@ -29,8 +28,8 @@ func TestConsulFingerprint(t *testing.T) { conf := config.DefaultConfig() conf.ConsulConfig.Addr = strings.TrimPrefix(ts.URL, "http://") - request := &cstructs.FingerprintRequest{Config: conf, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: conf, Node: node} + var response FingerprintResponse err := fp.Fingerprint(request, &response) if err != nil { t.Fatalf("Failed to fingerprint: %s", err) @@ -185,8 +184,8 @@ func TestConsulFingerprint_UnexpectedResponse(t *testing.T) { conf := config.DefaultConfig() conf.ConsulConfig.Addr = strings.TrimPrefix(ts.URL, "http://") - request := &cstructs.FingerprintRequest{Config: conf, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: conf, Node: node} + var response FingerprintResponse err := fp.Fingerprint(request, &response) assert.Nil(err) diff --git a/client/fingerprint/cpu.go b/client/fingerprint/cpu.go index 68f01589f..54a05451f 100644 --- a/client/fingerprint/cpu.go +++ b/client/fingerprint/cpu.go @@ -4,7 +4,6 @@ import ( "fmt" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/stats" "github.com/hashicorp/nomad/nomad/structs" ) @@ -21,7 +20,7 @@ func NewCPUFingerprint(logger log.Logger) Fingerprint { return f } -func (f *CPUFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *CPUFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { cfg := req.Config setResourcesCPU := func(totalCompute int) { // COMPAT(0.10): Remove in 0.10 diff --git a/client/fingerprint/cpu_test.go b/client/fingerprint/cpu_test.go index 81862d08f..7546f9e74 100644 --- a/client/fingerprint/cpu_test.go +++ b/client/fingerprint/cpu_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" ) @@ -15,8 +14,8 @@ func TestCPUFingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -66,8 +65,8 @@ func TestCPUFingerprint_OverrideCompute(t *testing.T) { var originalCPU int { - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -89,8 +88,8 @@ func TestCPUFingerprint_OverrideCompute(t *testing.T) { cfg.CpuCompute = originalCPU + 123 // Make sure the Fingerprinter applies the override to the node resources - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) diff --git a/client/fingerprint/env_aws.go b/client/fingerprint/env_aws.go index 6b1749303..ba7d2cbf8 100644 --- a/client/fingerprint/env_aws.go +++ b/client/fingerprint/env_aws.go @@ -11,7 +11,6 @@ import ( "time" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/nomad/nomad/structs" @@ -64,7 +63,7 @@ func NewEnvAWSFingerprint(logger log.Logger) Fingerprint { return f } -func (f *EnvAWSFingerprint) Fingerprint(request *cstructs.FingerprintRequest, response *cstructs.FingerprintResponse) error { +func (f *EnvAWSFingerprint) Fingerprint(request *FingerprintRequest, response *FingerprintResponse) error { cfg := request.Config // Check if we should tighten the timeout diff --git a/client/fingerprint/env_aws_test.go b/client/fingerprint/env_aws_test.go index 3f16a3e3d..16bb464f0 100644 --- a/client/fingerprint/env_aws_test.go +++ b/client/fingerprint/env_aws_test.go @@ -9,7 +9,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" ) @@ -21,8 +20,8 @@ func TestEnvAWSFingerprint_nonAws(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -55,8 +54,8 @@ func TestEnvAWSFingerprint_aws(t *testing.T) { defer ts.Close() os.Setenv("AWS_ENV_URL", ts.URL+"/latest/meta-data/") - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -173,8 +172,8 @@ func TestNetworkFingerprint_AWS(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -223,8 +222,8 @@ func TestNetworkFingerprint_AWS_network(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -266,8 +265,8 @@ func TestNetworkFingerprint_AWS_network(t *testing.T) { NetworkSpeed: 10, } - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -303,8 +302,8 @@ func TestNetworkFingerprint_notAWS(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) diff --git a/client/fingerprint/env_gce.go b/client/fingerprint/env_gce.go index c3ca35638..4d0f7f13d 100644 --- a/client/fingerprint/env_gce.go +++ b/client/fingerprint/env_gce.go @@ -13,7 +13,6 @@ import ( "time" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/nomad/helper/useragent" @@ -137,7 +136,7 @@ func checkError(err error, logger log.Logger, desc string) error { return err } -func (f *EnvGCEFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *EnvGCEFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { cfg := req.Config // Check if we should tighten the timeout diff --git a/client/fingerprint/env_gce_test.go b/client/fingerprint/env_gce_test.go index 82a596787..03f1f60f9 100644 --- a/client/fingerprint/env_gce_test.go +++ b/client/fingerprint/env_gce_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" ) @@ -22,8 +21,8 @@ func TestGCEFingerprint_nonGCE(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -93,8 +92,8 @@ func testFingerprint_GCE(t *testing.T, withExternalIp bool) { os.Setenv("GCE_ENV_URL", ts.URL+"/computeMetadata/v1/instance/") f := NewEnvGCEFingerprint(testlog.HCLogger(t)) - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) diff --git a/client/fingerprint/fingerprint.go b/client/fingerprint/fingerprint.go index 1a5f6f41c..f7d0e2279 100644 --- a/client/fingerprint/fingerprint.go +++ b/client/fingerprint/fingerprint.go @@ -107,7 +107,7 @@ type HealthCheck interface { type Fingerprint interface { // Fingerprint is used to update properties of the Node, // and returns a diff of updated node attributes and a potential error. - Fingerprint(*cstructs.FingerprintRequest, *cstructs.FingerprintResponse) error + Fingerprint(*FingerprintRequest, *FingerprintResponse) error // Periodic is a mechanism for the fingerprinter to indicate that it should // be run periodically. The return value is a boolean indicating if it diff --git a/client/fingerprint/fingerprint_test.go b/client/fingerprint/fingerprint_test.go index ca14bd9b7..186a52f13 100644 --- a/client/fingerprint/fingerprint_test.go +++ b/client/fingerprint/fingerprint_test.go @@ -6,13 +6,12 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/nomad/structs" ) -func assertFingerprintOK(t *testing.T, fp Fingerprint, node *structs.Node) *cstructs.FingerprintResponse { - request := &cstructs.FingerprintRequest{Config: new(config.Config), Node: node} - var response cstructs.FingerprintResponse +func assertFingerprintOK(t *testing.T, fp Fingerprint, node *structs.Node) *FingerprintResponse { + request := &FingerprintRequest{Config: new(config.Config), Node: node} + var response FingerprintResponse err := fp.Fingerprint(request, &response) if err != nil { t.Fatalf("Failed to fingerprint: %s", err) diff --git a/client/fingerprint/host.go b/client/fingerprint/host.go index d0e69163f..32b82043a 100644 --- a/client/fingerprint/host.go +++ b/client/fingerprint/host.go @@ -4,7 +4,6 @@ import ( "runtime" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/shirou/gopsutil/host" ) @@ -20,7 +19,7 @@ func NewHostFingerprint(logger log.Logger) Fingerprint { return f } -func (f *HostFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *HostFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { hostInfo, err := host.Info() if err != nil { f.logger.Warn("error retrieving host information", "error", err) diff --git a/client/fingerprint/host_test.go b/client/fingerprint/host_test.go index 2fe3a635f..02f7b5d0e 100644 --- a/client/fingerprint/host_test.go +++ b/client/fingerprint/host_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" ) @@ -15,8 +14,8 @@ func TestHostFingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) diff --git a/client/fingerprint/memory.go b/client/fingerprint/memory.go index f31ded76b..ad28ed2ec 100644 --- a/client/fingerprint/memory.go +++ b/client/fingerprint/memory.go @@ -4,7 +4,6 @@ import ( "fmt" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/nomad/structs" "github.com/shirou/gopsutil/mem" ) @@ -25,7 +24,7 @@ func NewMemoryFingerprint(logger log.Logger) Fingerprint { return f } -func (f *MemoryFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *MemoryFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { var totalMemory int cfg := req.Config if cfg.MemoryMB != 0 { diff --git a/client/fingerprint/memory_test.go b/client/fingerprint/memory_test.go index b1e0c14ac..6624b9225 100644 --- a/client/fingerprint/memory_test.go +++ b/client/fingerprint/memory_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" @@ -17,8 +16,8 @@ func TestMemoryFingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -47,8 +46,8 @@ func TestMemoryFingerprint_Override(t *testing.T) { } memoryMB := 15000 - request := &cstructs.FingerprintRequest{Config: &config.Config{MemoryMB: memoryMB}, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: &config.Config{MemoryMB: memoryMB}, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) diff --git a/client/fingerprint/network.go b/client/fingerprint/network.go index f42b31c37..2d706a1e9 100644 --- a/client/fingerprint/network.go +++ b/client/fingerprint/network.go @@ -6,7 +6,6 @@ import ( log "github.com/hashicorp/go-hclog" sockaddr "github.com/hashicorp/go-sockaddr" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/nomad/structs" ) @@ -61,7 +60,7 @@ func NewNetworkFingerprint(logger log.Logger) Fingerprint { return f } -func (f *NetworkFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *NetworkFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { cfg := req.Config // Find the named interface diff --git a/client/fingerprint/network_test.go b/client/fingerprint/network_test.go index 5d69710a0..5b55b87a6 100644 --- a/client/fingerprint/network_test.go +++ b/client/fingerprint/network_test.go @@ -7,7 +7,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" ) @@ -191,8 +190,8 @@ func TestNetworkFingerprint_basic(t *testing.T) { } cfg := &config.Config{NetworkSpeed: 101} - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -242,8 +241,8 @@ func TestNetworkFingerprint_default_device_absent(t *testing.T) { } cfg := &config.Config{NetworkSpeed: 100, NetworkInterface: "eth0"} - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err == nil { t.Fatalf("err: %v", err) @@ -265,8 +264,8 @@ func TestNetworkFingerPrint_default_device(t *testing.T) { } cfg := &config.Config{NetworkSpeed: 100, NetworkInterface: "lo"} - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -316,8 +315,8 @@ func TestNetworkFingerPrint_LinkLocal_Allowed(t *testing.T) { } cfg := &config.Config{NetworkSpeed: 100, NetworkInterface: "eth3"} - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -363,8 +362,8 @@ func TestNetworkFingerPrint_LinkLocal_Allowed_MixedIntf(t *testing.T) { } cfg := &config.Config{NetworkSpeed: 100, NetworkInterface: "eth4"} - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -423,8 +422,8 @@ func TestNetworkFingerPrint_LinkLocal_Disallowed(t *testing.T) { }, } - request := &cstructs.FingerprintRequest{Config: cfg, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: cfg, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) diff --git a/client/fingerprint/nomad.go b/client/fingerprint/nomad.go index 59d4c5b39..bee62758e 100644 --- a/client/fingerprint/nomad.go +++ b/client/fingerprint/nomad.go @@ -2,7 +2,6 @@ package fingerprint import ( log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" ) // NomadFingerprint is used to fingerprint the Nomad version @@ -17,7 +16,7 @@ func NewNomadFingerprint(logger log.Logger) Fingerprint { return f } -func (f *NomadFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *NomadFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { resp.AddAttribute("nomad.advertise.address", req.Node.HTTPAddr) resp.AddAttribute("nomad.version", req.Config.Version.VersionNumber()) resp.AddAttribute("nomad.revision", req.Config.Version.Revision) diff --git a/client/fingerprint/nomad_test.go b/client/fingerprint/nomad_test.go index a57b322ef..c2dba204f 100644 --- a/client/fingerprint/nomad_test.go +++ b/client/fingerprint/nomad_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/version" @@ -27,8 +26,8 @@ func TestNomadFingerprint(t *testing.T) { HTTPAddr: h, } - request := &cstructs.FingerprintRequest{Config: c, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: c, Node: node} + var response FingerprintResponse err := f.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) diff --git a/client/fingerprint/signal.go b/client/fingerprint/signal.go index 1d328d1a2..c6d795b9d 100644 --- a/client/fingerprint/signal.go +++ b/client/fingerprint/signal.go @@ -5,7 +5,6 @@ import ( "github.com/hashicorp/consul-template/signals" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" ) // SignalFingerprint is used to fingerprint the available signals @@ -20,7 +19,7 @@ func NewSignalFingerprint(logger log.Logger) Fingerprint { return f } -func (f *SignalFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *SignalFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { // Build the list of available signals sigs := make([]string, 0, len(signals.SignalLookup)) for signal := range signals.SignalLookup { diff --git a/client/fingerprint/storage.go b/client/fingerprint/storage.go index 501b85a52..8b8b992fc 100644 --- a/client/fingerprint/storage.go +++ b/client/fingerprint/storage.go @@ -6,7 +6,6 @@ import ( "strconv" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/nomad/structs" ) @@ -24,7 +23,7 @@ func NewStorageFingerprint(logger log.Logger) Fingerprint { return fp } -func (f *StorageFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *StorageFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { cfg := req.Config // Guard against unset AllocDir diff --git a/client/fingerprint/structs.go b/client/fingerprint/structs.go new file mode 100644 index 000000000..42ee1f940 --- /dev/null +++ b/client/fingerprint/structs.go @@ -0,0 +1,69 @@ +package fingerprint + +import ( + "github.com/hashicorp/nomad/client/config" + "github.com/hashicorp/nomad/nomad/structs" +) + +// FingerprintRequest is a request which a fingerprinter accepts to fingerprint +// the node +type FingerprintRequest struct { + Config *config.Config + Node *structs.Node +} + +// FingerprintResponse is the response which a fingerprinter annotates with the +// results of the fingerprint method +type FingerprintResponse struct { + Attributes map[string]string + Links map[string]string + Resources *structs.Resources // COMPAT(0.10): Remove in 0.10 + NodeResources *structs.NodeResources + + // Detected is a boolean indicating whether the fingerprinter detected + // if the resource was available + Detected bool +} + +// AddAttribute adds the name and value for a node attribute to the fingerprint +// response +func (f *FingerprintResponse) AddAttribute(name, value string) { + // initialize Attributes if it has not been already + if f.Attributes == nil { + f.Attributes = make(map[string]string, 0) + } + + f.Attributes[name] = value +} + +// RemoveAttribute sets the given attribute to empty, which will later remove +// it entirely from the node +func (f *FingerprintResponse) RemoveAttribute(name string) { + // initialize Attributes if it has not been already + if f.Attributes == nil { + f.Attributes = make(map[string]string, 0) + } + + f.Attributes[name] = "" +} + +// AddLink adds a link entry to the fingerprint response +func (f *FingerprintResponse) AddLink(name, value string) { + // initialize Links if it has not been already + if f.Links == nil { + f.Links = make(map[string]string, 0) + } + + f.Links[name] = value +} + +// RemoveLink removes a link entry from the fingerprint response. This will +// later remove it entirely from the node +func (f *FingerprintResponse) RemoveLink(name string) { + // initialize Links if it has not been already + if f.Links == nil { + f.Links = make(map[string]string, 0) + } + + f.Links[name] = "" +} diff --git a/client/fingerprint/vault.go b/client/fingerprint/vault.go index 8ad2c3cab..3ef933d9e 100644 --- a/client/fingerprint/vault.go +++ b/client/fingerprint/vault.go @@ -7,7 +7,6 @@ import ( "time" log "github.com/hashicorp/go-hclog" - cstructs "github.com/hashicorp/nomad/client/structs" vapi "github.com/hashicorp/vault/api" ) @@ -28,7 +27,7 @@ func NewVaultFingerprint(logger log.Logger) Fingerprint { return &VaultFingerprint{logger: logger.Named("vault"), lastState: vaultUnavailable} } -func (f *VaultFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error { +func (f *VaultFingerprint) Fingerprint(req *FingerprintRequest, resp *FingerprintResponse) error { config := req.Config if config.VaultConfig == nil || !config.VaultConfig.IsEnabled() { @@ -82,7 +81,7 @@ func (f *VaultFingerprint) Periodic() (bool, time.Duration) { return true, 15 * time.Second } -func (f *VaultFingerprint) clearVaultAttributes(r *cstructs.FingerprintResponse) { +func (f *VaultFingerprint) clearVaultAttributes(r *FingerprintResponse) { r.RemoveAttribute("vault.accessible") r.RemoveAttribute("vault.version") r.RemoveAttribute("vault.cluster_id") diff --git a/client/fingerprint/vault_test.go b/client/fingerprint/vault_test.go index f25d7b76a..2056dda4d 100644 --- a/client/fingerprint/vault_test.go +++ b/client/fingerprint/vault_test.go @@ -4,7 +4,6 @@ import ( "testing" "github.com/hashicorp/nomad/client/config" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/helper/testlog" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" @@ -22,8 +21,8 @@ func TestVaultFingerprint(t *testing.T) { conf := config.DefaultConfig() conf.VaultConfig = tv.Config - request := &cstructs.FingerprintRequest{Config: conf, Node: node} - var response cstructs.FingerprintResponse + request := &FingerprintRequest{Config: conf, Node: node} + var response FingerprintResponse err := fp.Fingerprint(request, &response) if err != nil { t.Fatalf("Failed to fingerprint: %s", err) diff --git a/client/fingerprint_manager.go b/client/fingerprint_manager.go index 2adedede3..4b856d9da 100644 --- a/client/fingerprint_manager.go +++ b/client/fingerprint_manager.go @@ -9,7 +9,6 @@ import ( log "github.com/hashicorp/go-hclog" "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/client/fingerprint" - cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/plugins/base" "github.com/hashicorp/nomad/plugins/drivers" @@ -38,7 +37,7 @@ type FingerprintManager struct { // updateNodeAttributes is a callback to the client to update the state of its // associated node - updateNodeAttributes func(*cstructs.FingerprintResponse) *structs.Node + updateNodeAttributes func(*fingerprint.FingerprintResponse) *structs.Node // updateNodeFromDriver is a callback to the client to update the state of a // specific driver for the node @@ -53,7 +52,7 @@ func NewFingerprintManager( getConfig func() *config.Config, node *structs.Node, shutdownCh chan struct{}, - updateNodeAttributes func(*cstructs.FingerprintResponse) *structs.Node, + updateNodeAttributes func(*fingerprint.FingerprintResponse) *structs.Node, updateNodeFromDriver func(string, *structs.DriverInfo) *structs.Node, logger log.Logger) *FingerprintManager { @@ -250,10 +249,10 @@ func (fm *FingerprintManager) runFingerprint(f fingerprint.Fingerprint, period t // is meant to be run continuously, a process is launched to perform this // fingerprint on an ongoing basis in the background. func (fm *FingerprintManager) fingerprint(name string, f fingerprint.Fingerprint) (bool, error) { - var response cstructs.FingerprintResponse + var response fingerprint.FingerprintResponse fm.nodeLock.Lock() - request := &cstructs.FingerprintRequest{Config: fm.getConfig(), Node: fm.node} + request := &fingerprint.FingerprintRequest{Config: fm.getConfig(), Node: fm.node} err := f.Fingerprint(request, &response) fm.nodeLock.Unlock() diff --git a/client/structs/structs.go b/client/structs/structs.go index 043437041..8f6da2d79 100644 --- a/client/structs/structs.go +++ b/client/structs/structs.go @@ -9,7 +9,6 @@ import ( "strconv" "time" - "github.com/hashicorp/nomad/client/config" "github.com/hashicorp/nomad/client/stats" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/plugins/device" @@ -348,69 +347,6 @@ func (d *DriverNetwork) Hash() []byte { return h.Sum(nil) } -// FingerprintRequest is a request which a fingerprinter accepts to fingerprint -// the node -type FingerprintRequest struct { - Config *config.Config - Node *structs.Node -} - -// FingerprintResponse is the response which a fingerprinter annotates with the -// results of the fingerprint method -type FingerprintResponse struct { - Attributes map[string]string - Links map[string]string - Resources *structs.Resources // COMPAT(0.10): Remove in 0.10 - NodeResources *structs.NodeResources - - // Detected is a boolean indicating whether the fingerprinter detected - // if the resource was available - Detected bool -} - -// AddAttribute adds the name and value for a node attribute to the fingerprint -// response -func (f *FingerprintResponse) AddAttribute(name, value string) { - // initialize Attributes if it has not been already - if f.Attributes == nil { - f.Attributes = make(map[string]string, 0) - } - - f.Attributes[name] = value -} - -// RemoveAttribute sets the given attribute to empty, which will later remove -// it entirely from the node -func (f *FingerprintResponse) RemoveAttribute(name string) { - // initialize Attributes if it has not been already - if f.Attributes == nil { - f.Attributes = make(map[string]string, 0) - } - - f.Attributes[name] = "" -} - -// AddLink adds a link entry to the fingerprint response -func (f *FingerprintResponse) AddLink(name, value string) { - // initialize Links if it has not been already - if f.Links == nil { - f.Links = make(map[string]string, 0) - } - - f.Links[name] = value -} - -// RemoveLink removes a link entry from the fingerprint response. This will -// later remove it entirely from the node -func (f *FingerprintResponse) RemoveLink(name string) { - // initialize Links if it has not been already - if f.Links == nil { - f.Links = make(map[string]string, 0) - } - - f.Links[name] = "" -} - // HealthCheckRequest is the request type for a type that fulfils the Health // Check interface type HealthCheckRequest struct{} diff --git a/drivers/docker/driver_test.go b/drivers/docker/driver_test.go index bc8f60d32..697e078ae 100644 --- a/drivers/docker/driver_test.go +++ b/drivers/docker/driver_test.go @@ -16,6 +16,8 @@ import ( "testing" "time" + dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" + docker "github.com/fsouza/go-dockerclient" "github.com/hashicorp/consul/lib/freeport" hclog "github.com/hashicorp/go-hclog" @@ -112,7 +114,7 @@ func dockerTask(t *testing.T) (*drivers.TaskConfig, *TaskConfig, []int) { // // If there is a problem during setup this function will abort or skip the test // and indicate the reason. -func dockerSetup(t *testing.T, task *drivers.TaskConfig) (*docker.Client, *drivers.DriverHarness, *taskHandle, func()) { +func dockerSetup(t *testing.T, task *drivers.TaskConfig) (*docker.Client, *dtestutil.DriverHarness, *taskHandle, func()) { client := newTestDockerClient(t) driver := dockerDriverHarness(t, nil) cleanup := driver.MkAllocDir(task, true) @@ -134,9 +136,9 @@ func dockerSetup(t *testing.T, task *drivers.TaskConfig) (*docker.Client, *drive // dockerDriverHarness wires up everything needed to launch a task with a docker driver. // A driver plugin interface and cleanup function is returned -func dockerDriverHarness(t *testing.T, cfg map[string]interface{}) *drivers.DriverHarness { +func dockerDriverHarness(t *testing.T, cfg map[string]interface{}) *dtestutil.DriverHarness { logger := testlog.HCLogger(t) - harness := drivers.NewDriverHarness(t, NewDockerDriver(logger)) + harness := dtestutil.NewDriverHarness(t, NewDockerDriver(logger)) if cfg == nil { cfg = map[string]interface{}{ "gc": map[string]interface{}{ @@ -160,7 +162,7 @@ func dockerDriverHarness(t *testing.T, cfg map[string]interface{}) *drivers.Driv require.NoError(t, err) instance, err := plugLoader.Dispense(pluginName, base.PluginTypeDriver, nil, logger) require.NoError(t, err) - driver, ok := instance.Plugin().(*drivers.DriverHarness) + driver, ok := instance.Plugin().(*dtestutil.DriverHarness) if !ok { t.Fatal("plugin instance is not a driver... wat?") } @@ -196,8 +198,8 @@ func TestDockerDriver_Fingerprint(t *testing.T) { Attributes: make(map[string]string), } - request := &cstructs.FingerprintRequest{Config: &config.Config{}, Node: node} - var response cstructs.FingerprintResponse + request := &fingerprint.FingerprintRequest{Config: &config.Config{}, Node: node} + var response fingerprint.FingerprintResponse err := d.Fingerprint(request, &response) if err != nil { t.Fatalf("err: %v", err) @@ -249,8 +251,8 @@ func TestDockerDriver_Fingerprint_Bridge(t *testing.T) { conf.Node = mock.Node() dd := NewDockerDriver(NewDriverContext("", "", "", "", conf, conf.Node, testlog.Logger(t), nil)) - request := &cstructs.FingerprintRequest{Config: conf, Node: conf.Node} - var response cstructs.FingerprintResponse + request := &fingerprint.FingerprintRequest{Config: conf, Node: conf.Node} + var response fingerprint.FingerprintResponse err = dd.Fingerprint(request, &response) if err != nil { @@ -1525,7 +1527,7 @@ func TestDockerDriver_Stats(t *testing.T) { } } -func setupDockerVolumes(t *testing.T, cfg map[string]interface{}, hostpath string) (*drivers.TaskConfig, *drivers.DriverHarness, *TaskConfig, string, func()) { +func setupDockerVolumes(t *testing.T, cfg map[string]interface{}, hostpath string) (*drivers.TaskConfig, *dtestutil.DriverHarness, *TaskConfig, string, func()) { if !testutil.DockerIsConnected(t) { t.Skip("Docker not connected") } diff --git a/drivers/exec/driver_test.go b/drivers/exec/driver_test.go index f09eef52b..ea4b58d28 100644 --- a/drivers/exec/driver_test.go +++ b/drivers/exec/driver_test.go @@ -13,6 +13,8 @@ import ( "testing" "time" + dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" + "github.com/hashicorp/hcl2/hcl" ctestutils "github.com/hashicorp/nomad/client/testutil" "github.com/hashicorp/nomad/helper/testlog" @@ -41,7 +43,7 @@ func TestExecDriver_Fingerprint_NonLinux(t *testing.T) { } d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) fingerCh, err := harness.Fingerprint(context.Background()) require.NoError(err) @@ -60,7 +62,7 @@ func TestExecDriver_Fingerprint(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) fingerCh, err := harness.Fingerprint(context.Background()) require.NoError(err) @@ -79,7 +81,7 @@ func TestExecDriver_StartWait(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "test", @@ -111,7 +113,7 @@ func TestExecDriver_StartWaitStop(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "test", @@ -173,7 +175,7 @@ func TestExecDriver_StartWaitRecover(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "test", @@ -242,7 +244,7 @@ func TestExecDriver_Stats(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "test", @@ -275,7 +277,7 @@ func TestExecDriver_Start_Wait_AllocDir(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "sleep", @@ -323,7 +325,7 @@ func TestExecDriver_User(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "sleep", @@ -356,7 +358,7 @@ func TestExecDriver_HandlerExec(t *testing.T) { ctestutils.ExecCompatible(t) d := NewExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), Name: "sleep", diff --git a/drivers/java/driver_test.go b/drivers/java/driver_test.go index e9882febc..62c0aec0b 100644 --- a/drivers/java/driver_test.go +++ b/drivers/java/driver_test.go @@ -8,6 +8,8 @@ import ( "sync" "testing" + dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" + "context" "time" @@ -39,7 +41,7 @@ func TestJavaDriver_Fingerprint(t *testing.T) { } d := NewDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) fpCh, err := harness.Fingerprint(context.Background()) require.NoError(t, err) @@ -62,7 +64,7 @@ func TestJavaDriver_Jar_Start_Wait(t *testing.T) { require := require.New(t) d := NewDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := basicTask(t, "demo-app", map[string]interface{}{ "jar_path": "demoapp.jar", @@ -101,7 +103,7 @@ func TestJavaDriver_Jar_Stop_Wait(t *testing.T) { require := require.New(t) d := NewDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := basicTask(t, "demo-app", map[string]interface{}{ "jar_path": "demoapp.jar", @@ -165,7 +167,7 @@ func TestJavaDriver_Class_Start_Wait(t *testing.T) { require := require.New(t) d := NewDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := basicTask(t, "demo-app", map[string]interface{}{ "class": "Hello", diff --git a/drivers/qemu/driver_test.go b/drivers/qemu/driver_test.go index 828f9315f..545fa43e8 100644 --- a/drivers/qemu/driver_test.go +++ b/drivers/qemu/driver_test.go @@ -11,6 +11,8 @@ import ( "fmt" "time" + dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" + "github.com/hashicorp/hcl2/hcl" ctestutil "github.com/hashicorp/nomad/client/testutil" "github.com/hashicorp/nomad/helper/testlog" @@ -36,7 +38,7 @@ func TestQemuDriver_Start_Wait_Stop(t *testing.T) { require := require.New(t) d := NewQemuDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -94,7 +96,7 @@ func TestQemuDriver_GetMonitorPathOldQemu(t *testing.T) { require := require.New(t) d := NewQemuDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -145,7 +147,7 @@ func TestQemuDriver_GetMonitorPathNewQemu(t *testing.T) { require := require.New(t) d := NewQemuDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -234,7 +236,7 @@ func TestQemuDriver_User(t *testing.T) { require := require.New(t) d := NewQemuDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -287,7 +289,7 @@ func TestQemuDriver_Stats(t *testing.T) { require := require.New(t) d := NewQemuDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -357,7 +359,7 @@ func TestQemuDriver_Fingerprint(t *testing.T) { } d := NewQemuDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) fingerCh, err := harness.Fingerprint(context.Background()) require.NoError(err) diff --git a/drivers/rawexec/driver_test.go b/drivers/rawexec/driver_test.go index 8e9cc6d29..18629b908 100644 --- a/drivers/rawexec/driver_test.go +++ b/drivers/rawexec/driver_test.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/nomad/helper/uuid" basePlug "github.com/hashicorp/nomad/plugins/base" "github.com/hashicorp/nomad/plugins/drivers" + dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" "github.com/hashicorp/nomad/plugins/shared" "github.com/hashicorp/nomad/plugins/shared/hclspec" pstructs "github.com/hashicorp/nomad/plugins/shared/structs" @@ -37,7 +38,7 @@ func TestRawExecDriver_SetConfig(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) defer harness.Kill() // Disable raw exec. @@ -69,7 +70,7 @@ func TestRawExecDriver_Fingerprint(t *testing.T) { return func(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)).(*Driver) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) defer harness.Kill() var data []byte @@ -126,7 +127,7 @@ func TestRawExecDriver_StartWait(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) defer harness.Kill() task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -159,7 +160,7 @@ func TestRawExecDriver_StartWaitStop(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) defer harness.Kill() // Disable cgroups so test works without root @@ -228,7 +229,7 @@ func TestRawExecDriver_StartWaitRecoverWaitStop(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) defer harness.Kill() // Disable cgroups so test works without root @@ -311,7 +312,7 @@ func TestRawExecDriver_Start_Wait_AllocDir(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) defer harness.Kill() task := &drivers.TaskConfig{ @@ -365,7 +366,7 @@ func TestRawExecDriver_Start_Kill_Wait_Cgroup(t *testing.T) { pidFile := "pid" d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) defer harness.Kill() task := &drivers.TaskConfig{ @@ -454,7 +455,7 @@ func TestRawExecDriver_Exec(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) defer harness.Kill() task := &drivers.TaskConfig{ diff --git a/drivers/rawexec/driver_unix_test.go b/drivers/rawexec/driver_unix_test.go index b23e021d3..3682a6753 100644 --- a/drivers/rawexec/driver_unix_test.go +++ b/drivers/rawexec/driver_unix_test.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/nomad/helper/testtask" "github.com/hashicorp/nomad/helper/uuid" "github.com/hashicorp/nomad/plugins/drivers" + dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" "github.com/hashicorp/nomad/testutil" "github.com/stretchr/testify/require" ) @@ -29,7 +30,7 @@ func TestRawExecDriver_User(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -61,7 +62,7 @@ func TestRawExecDriver_Signal(t *testing.T) { require := require.New(t) d := NewRawExecDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), diff --git a/drivers/rkt/driver_test.go b/drivers/rkt/driver_test.go index a306c5749..e5ca1445d 100644 --- a/drivers/rkt/driver_test.go +++ b/drivers/rkt/driver_test.go @@ -13,6 +13,8 @@ import ( "testing" "time" + dtestutil "github.com/hashicorp/nomad/plugins/drivers/testutils" + "github.com/hashicorp/hcl2/hcl" ctestutil "github.com/hashicorp/nomad/client/testutil" "github.com/hashicorp/nomad/helper/testlog" @@ -53,7 +55,7 @@ func TestRktDriver_SetConfig(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) // Enable Volumes config := &Config{ @@ -83,7 +85,7 @@ func TestRktDriver_Start_Wait_Stop_DNS(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -176,7 +178,7 @@ func TestRktDriver_Start_Wait_Stop(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -231,7 +233,7 @@ func TestRktDriver_Start_Wait_Skip_Trust(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -286,7 +288,7 @@ func TestRktDriver_InvalidTrustPrefix(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -337,7 +339,7 @@ func TestRktDriver_StartWaitRecoverWaitStop(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -430,7 +432,7 @@ func TestRktDriver_Start_Wait_Volume(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) // enable volumes config := &Config{VolumesEnabled: true} @@ -508,7 +510,7 @@ func TestRktDriver_PortMapping(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -561,7 +563,7 @@ func TestRktDriver_UserGroup(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -621,7 +623,7 @@ func TestRktDriver_Exec(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), @@ -691,7 +693,7 @@ func TestRktDriver_Stats(t *testing.T) { require := require.New(t) d := NewRktDriver(testlog.HCLogger(t)) - harness := drivers.NewDriverHarness(t, d) + harness := dtestutil.NewDriverHarness(t, d) task := &drivers.TaskConfig{ ID: uuid.Generate(), diff --git a/plugins/drivers/plugin.go b/plugins/drivers/plugin.go index 67165cb8a..524123cba 100644 --- a/plugins/drivers/plugin.go +++ b/plugins/drivers/plugin.go @@ -46,3 +46,16 @@ func (p *PluginDriver) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker doneCtx: ctx, }, nil } + +// Serve is used to serve a driverplugin +func Serve(d DriverPlugin, logger hclog.Logger) { + plugin.Serve(&plugin.ServeConfig{ + HandshakeConfig: base.Handshake, + Plugins: map[string]plugin.Plugin{ + base.PluginTypeBase: &base.PluginBase{Impl: d}, + base.PluginTypeDriver: &PluginDriver{impl: d, logger: logger}, + }, + GRPCServer: plugin.DefaultGRPCServer, + Logger: logger, + }) +} diff --git a/plugins/drivers/testing_test.go b/plugins/drivers/testing_test.go deleted file mode 100644 index faa83c616..000000000 --- a/plugins/drivers/testing_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package drivers - -import ( - "testing" - - cstructs "github.com/hashicorp/nomad/client/structs" - "github.com/stretchr/testify/require" -) - -var _ DriverPlugin = (*MockDriver)(nil) - -// Very simple test to ensure the test harness works as expected -func TestDriverHarness(t *testing.T) { - handle := &TaskHandle{Config: &TaskConfig{Name: "mock"}} - d := &MockDriver{ - StartTaskF: func(task *TaskConfig) (*TaskHandle, *cstructs.DriverNetwork, error) { - return handle, nil, nil - }, - } - harness := NewDriverHarness(t, d) - defer harness.Kill() - actual, _, err := harness.StartTask(&TaskConfig{}) - require.NoError(t, err) - require.Equal(t, handle.Config.Name, actual.Config.Name) -} diff --git a/plugins/drivers/testing.go b/plugins/drivers/testutils/testing.go similarity index 73% rename from plugins/drivers/testing.go rename to plugins/drivers/testutils/testing.go index eb49ab9e9..39dafa2e9 100644 --- a/plugins/drivers/testing.go +++ b/plugins/drivers/testutils/testing.go @@ -1,4 +1,4 @@ -package drivers +package testutils import ( "context" @@ -20,6 +20,7 @@ import ( "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/plugins/base" + "github.com/hashicorp/nomad/plugins/drivers" "github.com/hashicorp/nomad/plugins/drivers/utils" "github.com/hashicorp/nomad/plugins/shared/hclspec" "github.com/mitchellh/go-testing-interface" @@ -27,28 +28,28 @@ import ( ) type DriverHarness struct { - DriverPlugin + drivers.DriverPlugin client *plugin.GRPCClient server *plugin.GRPCServer t testing.T lm logmon.LogMon logger hclog.Logger - impl DriverPlugin + impl drivers.DriverPlugin } -func (d *DriverHarness) Impl() DriverPlugin { +func (d *DriverHarness) Impl() drivers.DriverPlugin { return d.impl } -func NewDriverHarness(t testing.T, d DriverPlugin) *DriverHarness { +func NewDriverHarness(t testing.T, d drivers.DriverPlugin) *DriverHarness { logger := testlog.HCLogger(t).Named("driver_harness") + + pd := drivers.NewDriverPlugin(d, logger).(*drivers.PluginDriver) + client, server := plugin.TestPluginGRPCConn(t, map[string]plugin.Plugin{ - base.PluginTypeDriver: &PluginDriver{ - impl: d, - logger: logger.Named("driver_plugin"), - }, - base.PluginTypeBase: &base.PluginBase{Impl: d}, - "logmon": logmon.NewPlugin(logmon.NewLogMon(logger.Named("logmon"))), + base.PluginTypeDriver: pd, + base.PluginTypeBase: &base.PluginBase{Impl: d}, + "logmon": logmon.NewPlugin(logmon.NewLogMon(logger.Named("logmon"))), }, ) @@ -57,7 +58,7 @@ func NewDriverHarness(t testing.T, d DriverPlugin) *DriverHarness { t.Fatalf("err dispensing plugin: %v", err) } - dClient := raw.(DriverPlugin) + dClient := raw.(drivers.DriverPlugin) h := &DriverHarness{ client: client, server: server, @@ -86,7 +87,7 @@ func (h *DriverHarness) Kill() { // to the LogDir of the task // A cleanup func is returned and should be defered so as to not leak dirs // between tests. -func (h *DriverHarness) MkAllocDir(t *TaskConfig, enableLogs bool) func() { +func (h *DriverHarness) MkAllocDir(t *drivers.TaskConfig, enableLogs bool) func() { dir, err := ioutil.TempDir("", "nomad_driver_harness-") require.NoError(h.t, err) t.AllocDir = dir @@ -165,13 +166,13 @@ func (h *DriverHarness) MkAllocDir(t *TaskConfig, enableLogs bool) func() { // state or the timeout is reached func (h *DriverHarness) WaitUntilStarted(taskID string, timeout time.Duration) error { deadline := time.Now().Add(timeout) - var lastState TaskState + var lastState drivers.TaskState for { status, err := h.InspectTask(taskID) if err != nil { return err } - if status.State == TaskStateRunning { + if status.State == drivers.TaskStateRunning { return nil } lastState = status.State @@ -188,30 +189,30 @@ func (h *DriverHarness) WaitUntilStarted(taskID string, timeout time.Duration) e type MockDriver struct { base.MockPlugin TaskConfigSchemaF func() (*hclspec.Spec, error) - FingerprintF func(context.Context) (<-chan *Fingerprint, error) - CapabilitiesF func() (*Capabilities, error) - RecoverTaskF func(*TaskHandle) error - StartTaskF func(*TaskConfig) (*TaskHandle, *cstructs.DriverNetwork, error) - WaitTaskF func(context.Context, string) (<-chan *ExitResult, error) + FingerprintF func(context.Context) (<-chan *drivers.Fingerprint, error) + CapabilitiesF func() (*drivers.Capabilities, error) + RecoverTaskF func(*drivers.TaskHandle) error + StartTaskF func(*drivers.TaskConfig) (*drivers.TaskHandle, *cstructs.DriverNetwork, error) + WaitTaskF func(context.Context, string) (<-chan *drivers.ExitResult, error) StopTaskF func(string, time.Duration, string) error DestroyTaskF func(string, bool) error - InspectTaskF func(string) (*TaskStatus, error) + InspectTaskF func(string) (*drivers.TaskStatus, error) TaskStatsF func(string) (*cstructs.TaskResourceUsage, error) - TaskEventsF func(context.Context) (<-chan *TaskEvent, error) + TaskEventsF func(context.Context) (<-chan *drivers.TaskEvent, error) SignalTaskF func(string, string) error - ExecTaskF func(string, []string, time.Duration) (*ExecTaskResult, error) + ExecTaskF func(string, []string, time.Duration) (*drivers.ExecTaskResult, error) } func (d *MockDriver) TaskConfigSchema() (*hclspec.Spec, error) { return d.TaskConfigSchemaF() } -func (d *MockDriver) Fingerprint(ctx context.Context) (<-chan *Fingerprint, error) { +func (d *MockDriver) Fingerprint(ctx context.Context) (<-chan *drivers.Fingerprint, error) { return d.FingerprintF(ctx) } -func (d *MockDriver) Capabilities() (*Capabilities, error) { return d.CapabilitiesF() } -func (d *MockDriver) RecoverTask(h *TaskHandle) error { return d.RecoverTaskF(h) } -func (d *MockDriver) StartTask(c *TaskConfig) (*TaskHandle, *cstructs.DriverNetwork, error) { +func (d *MockDriver) Capabilities() (*drivers.Capabilities, error) { return d.CapabilitiesF() } +func (d *MockDriver) RecoverTask(h *drivers.TaskHandle) error { return d.RecoverTaskF(h) } +func (d *MockDriver) StartTask(c *drivers.TaskConfig) (*drivers.TaskHandle, *cstructs.DriverNetwork, error) { return d.StartTaskF(c) } -func (d *MockDriver) WaitTask(ctx context.Context, id string) (<-chan *ExitResult, error) { +func (d *MockDriver) WaitTask(ctx context.Context, id string) (<-chan *drivers.ExitResult, error) { return d.WaitTaskF(ctx, id) } func (d *MockDriver) StopTask(taskID string, timeout time.Duration, signal string) error { @@ -220,16 +221,18 @@ func (d *MockDriver) StopTask(taskID string, timeout time.Duration, signal strin func (d *MockDriver) DestroyTask(taskID string, force bool) error { return d.DestroyTaskF(taskID, force) } -func (d *MockDriver) InspectTask(taskID string) (*TaskStatus, error) { return d.InspectTaskF(taskID) } +func (d *MockDriver) InspectTask(taskID string) (*drivers.TaskStatus, error) { + return d.InspectTaskF(taskID) +} func (d *MockDriver) TaskStats(taskID string) (*cstructs.TaskResourceUsage, error) { return d.TaskStats(taskID) } -func (d *MockDriver) TaskEvents(ctx context.Context) (<-chan *TaskEvent, error) { +func (d *MockDriver) TaskEvents(ctx context.Context) (<-chan *drivers.TaskEvent, error) { return d.TaskEventsF(ctx) } func (d *MockDriver) SignalTask(taskID string, signal string) error { return d.SignalTask(taskID, signal) } -func (d *MockDriver) ExecTask(taskID string, cmd []string, timeout time.Duration) (*ExecTaskResult, error) { +func (d *MockDriver) ExecTask(taskID string, cmd []string, timeout time.Duration) (*drivers.ExecTaskResult, error) { return d.ExecTaskF(taskID, cmd, timeout) } diff --git a/plugins/drivers/plugin_test.go b/plugins/drivers/testutils/testing_test.go similarity index 74% rename from plugins/drivers/plugin_test.go rename to plugins/drivers/testutils/testing_test.go index 026d86f66..a940bbf61 100644 --- a/plugins/drivers/plugin_test.go +++ b/plugins/drivers/testutils/testing_test.go @@ -1,4 +1,4 @@ -package drivers +package testutils import ( "bytes" @@ -9,11 +9,29 @@ import ( cstructs "github.com/hashicorp/nomad/client/structs" "github.com/hashicorp/nomad/nomad/structs" + "github.com/hashicorp/nomad/plugins/drivers" pstructs "github.com/hashicorp/nomad/plugins/shared/structs" "github.com/stretchr/testify/require" "github.com/ugorji/go/codec" ) +var _ drivers.DriverPlugin = (*MockDriver)(nil) + +// Very simple test to ensure the test harness works as expected +func TestDriverHarness(t *testing.T) { + handle := &drivers.TaskHandle{Config: &drivers.TaskConfig{Name: "mock"}} + d := &MockDriver{ + StartTaskF: func(task *drivers.TaskConfig) (*drivers.TaskHandle, *cstructs.DriverNetwork, error) { + return handle, nil, nil + }, + } + harness := NewDriverHarness(t, d) + defer harness.Kill() + actual, _, err := harness.StartTask(&drivers.TaskConfig{}) + require.NoError(t, err) + require.Equal(t, handle.Config.Name, actual.Config.Name) +} + type testDriverState struct { Pid int Log string @@ -23,23 +41,23 @@ func TestBaseDriver_Fingerprint(t *testing.T) { t.Parallel() require := require.New(t) - fingerprints := []*Fingerprint{ + fingerprints := []*drivers.Fingerprint{ { Attributes: map[string]*pstructs.Attribute{"foo": pstructs.NewStringAttribute("bar")}, - Health: HealthStateUnhealthy, + Health: drivers.HealthStateUnhealthy, HealthDescription: "starting up", }, { Attributes: map[string]*pstructs.Attribute{"foo": pstructs.NewStringAttribute("bar")}, - Health: HealthStateHealthy, + Health: drivers.HealthStateHealthy, HealthDescription: "running", }, } var complete bool impl := &MockDriver{ - FingerprintF: func(ctx context.Context) (<-chan *Fingerprint, error) { - ch := make(chan *Fingerprint) + FingerprintF: func(ctx context.Context) (<-chan *drivers.Fingerprint, error) { + ch := make(chan *drivers.Fingerprint) go func() { defer close(ch) ch <- fingerprints[0] @@ -92,7 +110,7 @@ func TestBaseDriver_RecoverTask(t *testing.T) { // mock the RecoverTask driver call impl := &MockDriver{ - RecoverTaskF: func(h *TaskHandle) error { + RecoverTaskF: func(h *drivers.TaskHandle) error { var actual testDriverState require.NoError(h.GetDriverState(&actual)) require.Equal(state, actual) @@ -103,7 +121,7 @@ func TestBaseDriver_RecoverTask(t *testing.T) { harness := NewDriverHarness(t, impl) defer harness.Kill() - handle := &TaskHandle{ + handle := &drivers.TaskHandle{ DriverState: buf.Bytes(), } err := harness.RecoverTask(handle) @@ -114,16 +132,16 @@ func TestBaseDriver_StartTask(t *testing.T) { t.Parallel() require := require.New(t) - cfg := &TaskConfig{ + cfg := &drivers.TaskConfig{ ID: "foo", } state := &testDriverState{Pid: 1, Log: "log"} - var handle *TaskHandle + var handle *drivers.TaskHandle impl := &MockDriver{ - StartTaskF: func(c *TaskConfig) (*TaskHandle, *cstructs.DriverNetwork, error) { - handle = NewTaskHandle("test") + StartTaskF: func(c *drivers.TaskConfig) (*drivers.TaskHandle, *cstructs.DriverNetwork, error) { + handle = drivers.NewTaskHandle("test") handle.Config = c - handle.State = TaskStateRunning + handle.State = drivers.TaskStateRunning handle.SetDriverState(state) return handle, nil, nil }, @@ -146,13 +164,13 @@ func TestBaseDriver_WaitTask(t *testing.T) { t.Parallel() require := require.New(t) - result := &ExitResult{ExitCode: 1, Signal: 9} + result := &drivers.ExitResult{ExitCode: 1, Signal: 9} signalTask := make(chan struct{}) impl := &MockDriver{ - WaitTaskF: func(_ context.Context, id string) (<-chan *ExitResult, error) { - ch := make(chan *ExitResult) + WaitTaskF: func(_ context.Context, id string) (<-chan *drivers.ExitResult, error) { + ch := make(chan *drivers.ExitResult) go func() { <-signalTask ch <- result @@ -185,7 +203,7 @@ func TestBaseDriver_TaskEvents(t *testing.T) { require := require.New(t) now := time.Now().UTC().Truncate(time.Millisecond) - events := []*TaskEvent{ + events := []*drivers.TaskEvent{ { TaskID: "abc", Timestamp: now, @@ -213,8 +231,8 @@ func TestBaseDriver_TaskEvents(t *testing.T) { } impl := &MockDriver{ - TaskEventsF: func(ctx context.Context) (<-chan *TaskEvent, error) { - ch := make(chan *TaskEvent) + TaskEventsF: func(ctx context.Context) (<-chan *drivers.TaskEvent, error) { + ch := make(chan *drivers.TaskEvent) go func() { defer close(ch) for _, event := range events { diff --git a/plugins/serve.go b/plugins/serve.go index 7927e14f8..f317f52c8 100644 --- a/plugins/serve.go +++ b/plugins/serve.go @@ -5,6 +5,7 @@ import ( log "github.com/hashicorp/go-hclog" "github.com/hashicorp/nomad/plugins/device" + "github.com/hashicorp/nomad/plugins/drivers" ) // PluginFactory returns a new plugin instance @@ -21,6 +22,8 @@ func Serve(f PluginFactory) { switch p := plugin.(type) { case device.DevicePlugin: device.Serve(p, logger) + case drivers.DriverPlugin: + drivers.Serve(p, logger) default: fmt.Println("Unsupported plugin type") } diff --git a/plugins/shared/loader/loader.go b/plugins/shared/loader/loader.go index 760ef5d6f..d2175af07 100644 --- a/plugins/shared/loader/loader.go +++ b/plugins/shared/loader/loader.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/nomad/plugins" "github.com/hashicorp/nomad/plugins/base" "github.com/hashicorp/nomad/plugins/device" + "github.com/hashicorp/nomad/plugins/drivers" "github.com/hashicorp/nomad/plugins/shared/hclspec" ) @@ -218,6 +219,8 @@ func getPluginMap(pluginType string) map[string]plugin.Plugin { switch pluginType { case base.PluginTypeDevice: pmap[base.PluginTypeDevice] = &device.PluginDevice{} + case base.PluginTypeDriver: + pmap[base.PluginTypeDriver] = &drivers.PluginDriver{} } return pmap