docs/scheduler/node/node.go

84 lines
1.9 KiB
Go

package node
import (
"errors"
"strings"
"github.com/docker/swarm/cluster"
)
// Node is an abstract type used by the scheduler.
type Node struct {
ID string
IP string
Addr string
Name string
Labels map[string]string
Containers []*cluster.Container
Images []*cluster.Image
UsedMemory int64
UsedCpus int64
TotalMemory int64
TotalCpus int64
IsHealthy bool
}
// NewNode creates a node from an engine.
func NewNode(e *cluster.Engine) *Node {
return &Node{
ID: e.ID,
IP: e.IP,
Addr: e.Addr,
Name: e.Name,
Labels: e.Labels,
Containers: e.Containers(),
Images: e.Images(),
UsedMemory: e.UsedMemory(),
UsedCpus: e.UsedCpus(),
TotalMemory: e.TotalMemory(),
TotalCpus: e.TotalCpus(),
IsHealthy: e.IsHealthy(),
}
}
// Container returns the container with IDOrName in the engine.
func (n *Node) Container(IDOrName string) *cluster.Container {
// Abort immediately if the name is empty.
if len(IDOrName) == 0 {
return nil
}
for _, container := range n.Containers {
// Match ID prefix.
if strings.HasPrefix(container.Id, IDOrName) {
return container
}
// Match name, /name or engine/name.
for _, name := range container.Names {
if name == IDOrName || name == "/"+IDOrName || container.Engine.ID+name == IDOrName || container.Engine.Name+name == IDOrName {
return container
}
}
}
return nil
}
// AddContainer injects a container into the internal state.
func (n *Node) AddContainer(container *cluster.Container) error {
if container.Config != nil {
memory := container.Config.Memory
cpus := container.Config.CpuShares
if n.TotalMemory-memory < 0 || n.TotalCpus-cpus < 0 {
return errors.New("not enough resources")
}
n.UsedMemory = n.UsedMemory + memory
n.UsedCpus = n.UsedCpus + cpus
}
n.Containers = append(n.Containers, container)
return nil
}