mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
Node resources on client
This commit is contained in:
20
api/nodes.go
20
api/nodes.go
@@ -446,6 +446,7 @@ type Node struct {
|
||||
Attributes map[string]string
|
||||
Resources *Resources
|
||||
Reserved *Resources
|
||||
NodeResources *NodeResources
|
||||
Links map[string]string
|
||||
Meta map[string]string
|
||||
NodeClass string
|
||||
@@ -461,6 +462,25 @@ type Node struct {
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
type NodeResources struct {
|
||||
Cpu NodeCpuResources
|
||||
Memory NodeMemoryResources
|
||||
Disk NodeDiskResources
|
||||
Networks []*NetworkResource
|
||||
}
|
||||
|
||||
type NodeCpuResources struct {
|
||||
TotalShares uint64
|
||||
}
|
||||
|
||||
type NodeMemoryResources struct {
|
||||
MemoryMB uint64
|
||||
}
|
||||
|
||||
type NodeDiskResources struct {
|
||||
DiskMB uint64
|
||||
}
|
||||
|
||||
// DrainStrategy describes a Node's drain behavior.
|
||||
type DrainStrategy struct {
|
||||
// DrainSpec is the user declared drain specification
|
||||
|
||||
@@ -938,6 +938,9 @@ func (c *Client) setupNode() error {
|
||||
if node.Meta == nil {
|
||||
node.Meta = make(map[string]string)
|
||||
}
|
||||
if node.NodeResources == nil {
|
||||
node.NodeResources = &structs.NodeResources{}
|
||||
}
|
||||
if node.Resources == nil {
|
||||
node.Resources = &structs.Resources{}
|
||||
}
|
||||
@@ -1042,11 +1045,17 @@ func (c *Client) updateNodeFromFingerprint(response *cstructs.FingerprintRespons
|
||||
}
|
||||
}
|
||||
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
if response.Resources != nil && !resourcesAreEqual(c.config.Node.Resources, response.Resources) {
|
||||
nodeHasChanged = true
|
||||
c.config.Node.Resources.Merge(response.Resources)
|
||||
}
|
||||
|
||||
if response.NodeResources != nil && !c.config.Node.NodeResources.Equals(response.NodeResources) {
|
||||
nodeHasChanged = true
|
||||
c.config.Node.NodeResources.Merge(response.NodeResources)
|
||||
}
|
||||
|
||||
if nodeHasChanged {
|
||||
c.updateNodeLocked()
|
||||
}
|
||||
|
||||
@@ -24,9 +24,16 @@ func NewCPUFingerprint(logger *log.Logger) Fingerprint {
|
||||
func (f *CPUFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *cstructs.FingerprintResponse) error {
|
||||
cfg := req.Config
|
||||
setResourcesCPU := func(totalCompute int) {
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
resp.Resources = &structs.Resources{
|
||||
CPU: totalCompute,
|
||||
}
|
||||
|
||||
resp.NodeResources = &structs.NodeResources{
|
||||
Cpu: structs.NodeCpuResources{
|
||||
TotalShares: uint64(totalCompute),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if err := stats.Init(); err != nil {
|
||||
|
||||
@@ -45,9 +45,14 @@ func TestCPUFingerprint(t *testing.T) {
|
||||
t.Fatalf("Missing CPU Total Compute")
|
||||
}
|
||||
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
if response.Resources == nil || response.Resources.CPU == 0 {
|
||||
t.Fatalf("Expected to find CPU Resources")
|
||||
}
|
||||
|
||||
if response.NodeResources == nil || response.NodeResources.Cpu.TotalShares == 0 {
|
||||
t.Fatalf("Expected to find CPU Resources")
|
||||
}
|
||||
}
|
||||
|
||||
// TestCPUFingerprint_OverrideCompute asserts that setting cpu_total_compute in
|
||||
@@ -91,8 +96,12 @@ func TestCPUFingerprint_OverrideCompute(t *testing.T) {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
if response.Resources.CPU != cfg.CpuCompute {
|
||||
t.Fatalf("expected override cpu of %d but found %d", cfg.CpuCompute, response.Resources.CPU)
|
||||
}
|
||||
if response.NodeResources.Cpu.TotalShares != uint64(cfg.CpuCompute) {
|
||||
t.Fatalf("expected override cpu of %d but found %d", cfg.CpuCompute, response.NodeResources.Cpu.TotalShares)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,9 +43,17 @@ func (f *MemoryFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp *
|
||||
|
||||
if totalMemory > 0 {
|
||||
resp.AddAttribute("memory.totalbytes", fmt.Sprintf("%d", totalMemory))
|
||||
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
resp.Resources = &structs.Resources{
|
||||
MemoryMB: totalMemory / bytesInMB,
|
||||
}
|
||||
|
||||
resp.NodeResources = &structs.NodeResources{
|
||||
Memory: structs.NodeMemoryResources{
|
||||
MemoryMB: uint64(totalMemory / bytesInMB),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -29,9 +29,15 @@ func TestMemoryFingerprint(t *testing.T) {
|
||||
if response.Resources == nil {
|
||||
t.Fatalf("response resources should not be nil")
|
||||
}
|
||||
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
if response.Resources.MemoryMB == 0 {
|
||||
t.Fatalf("Expected node.Resources.MemoryMB to be non-zero")
|
||||
}
|
||||
|
||||
if response.NodeResources.Memory.MemoryMB == 0 {
|
||||
t.Fatalf("Expected node.Resources.MemoryMB to be non-zero")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMemoryFingerprint_Override(t *testing.T) {
|
||||
@@ -52,4 +58,5 @@ func TestMemoryFingerprint_Override(t *testing.T) {
|
||||
require := require.New(t)
|
||||
require.NotNil(response.Resources)
|
||||
require.Equal(response.Resources.MemoryMB, memoryMB)
|
||||
require.EqualValues(response.NodeResources.Memory.MemoryMB, memoryMB)
|
||||
}
|
||||
|
||||
@@ -95,9 +95,15 @@ func (f *NetworkFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp
|
||||
return err
|
||||
}
|
||||
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
resp.Resources = &structs.Resources{
|
||||
Networks: nwResources,
|
||||
}
|
||||
|
||||
resp.NodeResources = &structs.NodeResources{
|
||||
Networks: nwResources,
|
||||
}
|
||||
|
||||
for _, nwResource := range nwResources {
|
||||
f.logger.Printf("[DEBUG] fingerprint.network: Detected interface %v with IP: %v", intf.Name, nwResource.IP)
|
||||
}
|
||||
|
||||
@@ -47,9 +47,15 @@ func (f *StorageFingerprint) Fingerprint(req *cstructs.FingerprintRequest, resp
|
||||
resp.AddAttribute("unique.storage.bytesfree", strconv.FormatUint(free, 10))
|
||||
|
||||
// set the disk size for the response
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
resp.Resources = &structs.Resources{
|
||||
DiskMB: int(free / bytesPerMegabyte),
|
||||
}
|
||||
resp.NodeResources = &structs.NodeResources{
|
||||
Disk: structs.NodeDiskResources{
|
||||
DiskMB: uint64(free / bytesPerMegabyte),
|
||||
},
|
||||
}
|
||||
resp.Detected = true
|
||||
|
||||
return nil
|
||||
|
||||
@@ -37,10 +37,15 @@ func TestStorageFingerprint(t *testing.T) {
|
||||
t.Fatalf("unique.storage.bytesfree %d is larger than unique.storage.bytestotal %d", free, total)
|
||||
}
|
||||
|
||||
// COMPAT(0.10): Remove in 0.10
|
||||
if response.Resources == nil {
|
||||
t.Fatalf("Node Resources was nil")
|
||||
}
|
||||
if response.Resources.DiskMB == 0 {
|
||||
t.Errorf("Expected node.Resources.DiskMB to be non-zero")
|
||||
}
|
||||
|
||||
if response.NodeResources == nil || response.NodeResources.Disk.DiskMB == 0 {
|
||||
t.Errorf("Expected node.Resources.DiskMB to be non-zero")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,9 +354,10 @@ type FingerprintRequest struct {
|
||||
// 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
|
||||
Attributes map[string]string
|
||||
Links map[string]string
|
||||
Resources *structs.Resources
|
||||
NodeResources *structs.NodeResources
|
||||
|
||||
// Detected is a boolean indicating whether the fingerprinter detected
|
||||
// if the resource was available
|
||||
|
||||
@@ -1425,6 +1425,9 @@ type Node struct {
|
||||
// "docker.runtime=1.8.3"
|
||||
Attributes map[string]string
|
||||
|
||||
// NodeResources captures the available resources on the client.
|
||||
NodeResources *NodeResources
|
||||
|
||||
// Resources is the available resources on the client.
|
||||
// For example 'cpu=2' 'memory=2048'
|
||||
Resources *Resources
|
||||
@@ -1609,26 +1612,6 @@ type NodeListStub struct {
|
||||
ModifyIndex uint64
|
||||
}
|
||||
|
||||
// Networks defined for a task on the Resources struct.
|
||||
type Networks []*NetworkResource
|
||||
|
||||
// Port assignment and IP for the given label or empty values.
|
||||
func (ns Networks) Port(label string) (string, int) {
|
||||
for _, n := range ns {
|
||||
for _, p := range n.ReservedPorts {
|
||||
if p.Label == label {
|
||||
return n.IP, p.Value
|
||||
}
|
||||
}
|
||||
for _, p := range n.DynamicPorts {
|
||||
if p.Label == label {
|
||||
return n.IP, p.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", 0
|
||||
}
|
||||
|
||||
// Resources is used to define the resources available
|
||||
// on a client
|
||||
type Resources struct {
|
||||
@@ -1927,6 +1910,167 @@ func (n *NetworkResource) PortLabels() map[string]int {
|
||||
return labelValues
|
||||
}
|
||||
|
||||
// Networks defined for a task on the Resources struct.
|
||||
type Networks []*NetworkResource
|
||||
|
||||
// Port assignment and IP for the given label or empty values.
|
||||
func (ns Networks) Port(label string) (string, int) {
|
||||
for _, n := range ns {
|
||||
for _, p := range n.ReservedPorts {
|
||||
if p.Label == label {
|
||||
return n.IP, p.Value
|
||||
}
|
||||
}
|
||||
for _, p := range n.DynamicPorts {
|
||||
if p.Label == label {
|
||||
return n.IP, p.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
return "", 0
|
||||
}
|
||||
|
||||
type NodeResources struct {
|
||||
Cpu NodeCpuResources
|
||||
Memory NodeMemoryResources
|
||||
Disk NodeDiskResources
|
||||
Networks Networks
|
||||
}
|
||||
|
||||
func (n *NodeResources) Merge(o *NodeResources) {
|
||||
if o == nil {
|
||||
return
|
||||
}
|
||||
|
||||
n.Cpu.Merge(&o.Cpu)
|
||||
n.Memory.Merge(&o.Memory)
|
||||
n.Disk.Merge(&o.Disk)
|
||||
|
||||
if len(o.Networks) != 0 {
|
||||
n.Networks = o.Networks
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NodeResources) Equals(o *NodeResources) bool {
|
||||
if o == nil && n == nil {
|
||||
return true
|
||||
} else if o == nil {
|
||||
return false
|
||||
} else if n == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if !n.Cpu.Equals(&o.Cpu) {
|
||||
return false
|
||||
}
|
||||
if !n.Memory.Equals(&o.Memory) {
|
||||
return false
|
||||
}
|
||||
if !n.Disk.Equals(&o.Disk) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(n.Networks) != len(o.Networks) {
|
||||
return false
|
||||
}
|
||||
for i, n := range n.Networks {
|
||||
if !n.Equals(o.Networks[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type NodeCpuResources struct {
|
||||
TotalShares uint64
|
||||
}
|
||||
|
||||
func (n *NodeCpuResources) Merge(o *NodeCpuResources) {
|
||||
if o == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if o.TotalShares != 0 {
|
||||
n.TotalShares = o.TotalShares
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NodeCpuResources) Equals(o *NodeCpuResources) bool {
|
||||
if o == nil && n == nil {
|
||||
return true
|
||||
} else if o == nil {
|
||||
return false
|
||||
} else if n == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if n.TotalShares != o.TotalShares {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type NodeMemoryResources struct {
|
||||
MemoryMB uint64
|
||||
}
|
||||
|
||||
func (n *NodeMemoryResources) Merge(o *NodeMemoryResources) {
|
||||
if o == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if o.MemoryMB != 0 {
|
||||
n.MemoryMB = o.MemoryMB
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NodeMemoryResources) Equals(o *NodeMemoryResources) bool {
|
||||
if o == nil && n == nil {
|
||||
return true
|
||||
} else if o == nil {
|
||||
return false
|
||||
} else if n == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if n.MemoryMB != o.MemoryMB {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type NodeDiskResources struct {
|
||||
DiskMB uint64
|
||||
}
|
||||
|
||||
func (n *NodeDiskResources) Merge(o *NodeDiskResources) {
|
||||
if o == nil {
|
||||
return
|
||||
}
|
||||
if o.DiskMB != 0 {
|
||||
n.DiskMB = o.DiskMB
|
||||
}
|
||||
}
|
||||
|
||||
func (n *NodeDiskResources) Equals(o *NodeDiskResources) bool {
|
||||
if o == nil && n == nil {
|
||||
return true
|
||||
} else if o == nil {
|
||||
return false
|
||||
} else if n == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if n.DiskMB != o.DiskMB {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const (
|
||||
// JobTypeNomad is reserved for internal system tasks and is
|
||||
// always handled by the CoreScheduler.
|
||||
|
||||
Reference in New Issue
Block a user