mirror of
https://github.com/kemko/nomad.git
synced 2026-01-10 12:25:42 +03:00
Merge pull request #391 from hashicorp/f-periodic-fingerprint
Add support for periodic fingerprints and make consul periodic
This commit is contained in:
@@ -443,11 +443,33 @@ func (c *Client) fingerprint() error {
|
||||
if applies {
|
||||
applied = append(applied, name)
|
||||
}
|
||||
p, period := f.Periodic()
|
||||
if p {
|
||||
// TODO: If more periodic fingerprinters are added, then
|
||||
// fingerprintPeriodic should be used to handle all the periodic
|
||||
// fingerprinters by using a priority queue.
|
||||
go c.fingerprintPeriodic(name, f, period)
|
||||
}
|
||||
}
|
||||
c.logger.Printf("[DEBUG] client: applied fingerprints %v", applied)
|
||||
return nil
|
||||
}
|
||||
|
||||
// fingerprintPeriodic runs a fingerprinter at the specified duration.
|
||||
func (c *Client) fingerprintPeriodic(name string, f fingerprint.Fingerprint, d time.Duration) {
|
||||
c.logger.Printf("[DEBUG] client: periodically fingerprinting %v at duration %v", name, d)
|
||||
for {
|
||||
select {
|
||||
case <-time.After(d):
|
||||
if _, err := f.Fingerprint(c.config, c.config.Node); err != nil {
|
||||
c.logger.Printf("[DEBUG] client: periodic fingerprinting for %v failed: %v", name, err)
|
||||
}
|
||||
case <-c.shutdownCh:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setupDrivers is used to find the available drivers
|
||||
func (c *Client) setupDrivers() error {
|
||||
var avail []string
|
||||
|
||||
@@ -13,11 +13,13 @@ import (
|
||||
"github.com/hashicorp/nomad/client/allocdir"
|
||||
"github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/client/driver/args"
|
||||
"github.com/hashicorp/nomad/client/fingerprint"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
type DockerDriver struct {
|
||||
DriverContext
|
||||
fingerprint.StaticFingerprinter
|
||||
}
|
||||
|
||||
type dockerPID struct {
|
||||
@@ -37,7 +39,7 @@ type dockerHandle struct {
|
||||
}
|
||||
|
||||
func NewDockerDriver(ctx *DriverContext) Driver {
|
||||
return &DockerDriver{*ctx}
|
||||
return &DockerDriver{DriverContext: *ctx}
|
||||
}
|
||||
|
||||
// dockerClient creates *docker.Client. In test / dev mode we can use ENV vars
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/hashicorp/nomad/client/allocdir"
|
||||
"github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/client/driver/executor"
|
||||
"github.com/hashicorp/nomad/client/fingerprint"
|
||||
"github.com/hashicorp/nomad/client/getter"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
// features.
|
||||
type ExecDriver struct {
|
||||
DriverContext
|
||||
fingerprint.StaticFingerprinter
|
||||
}
|
||||
|
||||
// execHandle is returned from Start/Open as a handle to the PID
|
||||
@@ -29,7 +31,7 @@ type execHandle struct {
|
||||
|
||||
// NewExecDriver is used to create a new exec driver
|
||||
func NewExecDriver(ctx *DriverContext) Driver {
|
||||
return &ExecDriver{*ctx}
|
||||
return &ExecDriver{DriverContext: *ctx}
|
||||
}
|
||||
|
||||
func (d *ExecDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/hashicorp/nomad/client/allocdir"
|
||||
"github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/client/driver/executor"
|
||||
"github.com/hashicorp/nomad/client/fingerprint"
|
||||
"github.com/hashicorp/nomad/client/getter"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
@@ -21,6 +22,7 @@ import (
|
||||
// It literally just fork/execs tasks with the java command.
|
||||
type JavaDriver struct {
|
||||
DriverContext
|
||||
fingerprint.StaticFingerprinter
|
||||
}
|
||||
|
||||
// javaHandle is returned from Start/Open as a handle to the PID
|
||||
@@ -32,7 +34,7 @@ type javaHandle struct {
|
||||
|
||||
// NewJavaDriver is used to create a new exec driver
|
||||
func NewJavaDriver(ctx *DriverContext) Driver {
|
||||
return &JavaDriver{*ctx}
|
||||
return &JavaDriver{DriverContext: *ctx}
|
||||
}
|
||||
|
||||
func (d *JavaDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
|
||||
"github.com/hashicorp/nomad/client/allocdir"
|
||||
"github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/client/fingerprint"
|
||||
"github.com/hashicorp/nomad/client/getter"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
@@ -29,6 +30,7 @@ var (
|
||||
// planned in the future
|
||||
type QemuDriver struct {
|
||||
DriverContext
|
||||
fingerprint.StaticFingerprinter
|
||||
}
|
||||
|
||||
// qemuHandle is returned from Start/Open as a handle to the PID
|
||||
@@ -48,7 +50,7 @@ type qemuPID struct {
|
||||
|
||||
// NewQemuDriver is used to create a new exec driver
|
||||
func NewQemuDriver(ctx *DriverContext) Driver {
|
||||
return &QemuDriver{*ctx}
|
||||
return &QemuDriver{DriverContext: *ctx}
|
||||
}
|
||||
|
||||
func (d *QemuDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/hashicorp/nomad/client/allocdir"
|
||||
"github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/client/driver/args"
|
||||
"github.com/hashicorp/nomad/client/fingerprint"
|
||||
"github.com/hashicorp/nomad/client/getter"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
@@ -31,6 +32,7 @@ const (
|
||||
// and this should only be used when explicitly needed.
|
||||
type RawExecDriver struct {
|
||||
DriverContext
|
||||
fingerprint.StaticFingerprinter
|
||||
}
|
||||
|
||||
// rawExecHandle is returned from Start/Open as a handle to the PID
|
||||
@@ -42,7 +44,7 @@ type rawExecHandle struct {
|
||||
|
||||
// NewRawExecDriver is used to create a new raw exec driver
|
||||
func NewRawExecDriver(ctx *DriverContext) Driver {
|
||||
return &RawExecDriver{*ctx}
|
||||
return &RawExecDriver{DriverContext: *ctx}
|
||||
}
|
||||
|
||||
func (d *RawExecDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/hashicorp/nomad/client/allocdir"
|
||||
"github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/client/driver/args"
|
||||
"github.com/hashicorp/nomad/client/fingerprint"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
@@ -30,6 +31,7 @@ var (
|
||||
// planned in the future
|
||||
type RktDriver struct {
|
||||
DriverContext
|
||||
fingerprint.StaticFingerprinter
|
||||
}
|
||||
|
||||
// rktHandle is returned from Start/Open as a handle to the PID
|
||||
@@ -50,7 +52,7 @@ type rktPID struct {
|
||||
|
||||
// NewRktDriver is used to create a new exec driver
|
||||
func NewRktDriver(ctx *DriverContext) Driver {
|
||||
return &RktDriver{*ctx}
|
||||
return &RktDriver{DriverContext: *ctx}
|
||||
}
|
||||
|
||||
func (d *RktDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
// ArchFingerprint is used to fingerprint the architecture
|
||||
type ArchFingerprint struct {
|
||||
StaticFingerprinter
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ func (f *ConsulFingerprint) Fingerprint(config *client.Config, node *structs.Nod
|
||||
// If we can't hit this URL consul is probably not running on this machine.
|
||||
info, err := consulClient.Agent().Self()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("Failed to query consul for agent status: %s", err)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
node.Attributes["consul.server"] = strconv.FormatBool(info["Config"]["Server"].(bool))
|
||||
@@ -63,3 +63,7 @@ func (f *ConsulFingerprint) Fingerprint(config *client.Config, node *structs.Nod
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (f *ConsulFingerprint) Periodic() (bool, time.Duration) {
|
||||
return true, 15 * time.Second
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
// CPUFingerprint is used to fingerprint the CPU
|
||||
type CPUFingerprint struct {
|
||||
StaticFingerprinter
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ var ec2InstanceSpeedMap = map[string]int{
|
||||
|
||||
// EnvAWSFingerprint is used to fingerprint AWS metadata
|
||||
type EnvAWSFingerprint struct {
|
||||
StaticFingerprinter
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ func lastToken(s string) string {
|
||||
|
||||
// EnvGCEFingerprint is used to fingerprint GCE metadata
|
||||
type EnvGCEFingerprint struct {
|
||||
StaticFingerprinter
|
||||
client *http.Client
|
||||
logger *log.Logger
|
||||
metadataURL string
|
||||
|
||||
@@ -3,35 +3,41 @@ package fingerprint
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/client/config"
|
||||
"github.com/hashicorp/nomad/nomad/structs"
|
||||
)
|
||||
|
||||
// EmptyDuration is to be used by fingerprinters that are not periodic.
|
||||
const EmptyDuration = time.Duration(0)
|
||||
|
||||
// BuiltinFingerprints is a slice containing the key names of all regestered
|
||||
// fingerprints available, to provided an ordered iteration
|
||||
var BuiltinFingerprints = []string{
|
||||
"arch",
|
||||
"consul",
|
||||
"cpu",
|
||||
"host",
|
||||
"memory",
|
||||
"storage",
|
||||
"network",
|
||||
"env_aws",
|
||||
"env_gce",
|
||||
"host",
|
||||
"memory",
|
||||
"network",
|
||||
"storage",
|
||||
}
|
||||
|
||||
// builtinFingerprintMap contains the built in registered fingerprints
|
||||
// which are available, corresponding to a key found in BuiltinFingerprints
|
||||
var builtinFingerprintMap = map[string]Factory{
|
||||
"arch": NewArchFingerprint,
|
||||
"consul": NewConsulFingerprint,
|
||||
"cpu": NewCPUFingerprint,
|
||||
"host": NewHostFingerprint,
|
||||
"memory": NewMemoryFingerprint,
|
||||
"storage": NewStorageFingerprint,
|
||||
"network": NewNetworkFingerprinter,
|
||||
"env_aws": NewEnvAWSFingerprint,
|
||||
"env_gce": NewEnvGCEFingerprint,
|
||||
"host": NewHostFingerprint,
|
||||
"memory": NewMemoryFingerprint,
|
||||
"network": NewNetworkFingerprinter,
|
||||
"storage": NewStorageFingerprint,
|
||||
}
|
||||
|
||||
// NewFingerprint is used to instantiate and return a new fingerprint
|
||||
@@ -59,4 +65,17 @@ type Fingerprint interface {
|
||||
// Fingerprint is used to update properties of the Node,
|
||||
// and returns if the fingerprint was applicable and a potential error.
|
||||
Fingerprint(*config.Config, *structs.Node) (bool, 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
|
||||
// should be periodic, and if true, a duration.
|
||||
Periodic() (bool, time.Duration)
|
||||
}
|
||||
|
||||
// StaticFingerprinter can be embeded in a struct that has a Fingerprint method
|
||||
// to make it non-periodic.
|
||||
type StaticFingerprinter struct{}
|
||||
|
||||
func (s *StaticFingerprinter) Periodic() (bool, time.Duration) {
|
||||
return false, EmptyDuration
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
// HostFingerprint is used to fingerprint the host
|
||||
type HostFingerprint struct {
|
||||
StaticFingerprinter
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
// MemoryFingerprint is used to fingerprint the available memory on the node
|
||||
type MemoryFingerprint struct {
|
||||
StaticFingerprinter
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
// NetworkFingerprint is used to fingerprint the Network capabilities of a node
|
||||
type NetworkFingerprint struct {
|
||||
StaticFingerprinter
|
||||
logger *log.Logger
|
||||
interfaceDetector NetworkInterfaceDetector
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
// NetworkFingerprint is used to fingerprint the Network capabilities of a node
|
||||
type NetworkFingerprint struct {
|
||||
StaticFingerprinter
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
// StorageFingerprint is used to measure the amount of storage free for
|
||||
// applications that the Nomad agent will run on this machine.
|
||||
type StorageFingerprint struct {
|
||||
StaticFingerprinter
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user