github.com/ranjib/nomad@v0.1.1-0.20160225204057-97751b02f70b/client/fingerprint/cgroup.go (about)

     1  package fingerprint
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"time"
     7  
     8  	client "github.com/hashicorp/nomad/client/config"
     9  	"github.com/hashicorp/nomad/nomad/structs"
    10  )
    11  
    12  const (
    13  	cgroupAvailable   = "available"
    14  	cgroupUnavailable = "unavailable"
    15  	interval          = 15
    16  )
    17  
    18  type CGroupFingerprint struct {
    19  	logger             *log.Logger
    20  	lastState          string
    21  	mountPointDetector MountPointDetector
    22  }
    23  
    24  // An interface to isolate calls to the cgroup library
    25  // This facilitates testing where we can implement
    26  // fake mount points to test various code paths
    27  type MountPointDetector interface {
    28  	MountPoint() (string, error)
    29  }
    30  
    31  // Implements the interface detector which calls the cgroups library directly
    32  type DefaultMountPointDetector struct {
    33  }
    34  
    35  // Call out to the default cgroup library
    36  func (b *DefaultMountPointDetector) MountPoint() (string, error) {
    37  	return FindCgroupMountpointDir()
    38  }
    39  
    40  // NewCGroupFingerprint returns a new cgroup fingerprinter
    41  func NewCGroupFingerprint(logger *log.Logger) Fingerprint {
    42  	f := &CGroupFingerprint{
    43  		logger:             logger,
    44  		lastState:          cgroupUnavailable,
    45  		mountPointDetector: &DefaultMountPointDetector{},
    46  	}
    47  	return f
    48  }
    49  
    50  // Fingerprint tries to find a valid cgroup moint point
    51  func (f *CGroupFingerprint) Fingerprint(cfg *client.Config, node *structs.Node) (bool, error) {
    52  	mount, err := f.mountPointDetector.MountPoint()
    53  	if err != nil {
    54  		f.clearCGroupAttributes(node)
    55  		return false, fmt.Errorf("Failed to discover cgroup mount point: %s", err)
    56  	}
    57  
    58  	// Check if a cgroup mount point was found
    59  	if mount == "" {
    60  		// Clear any attributes from the previous fingerprint.
    61  		f.clearCGroupAttributes(node)
    62  
    63  		if f.lastState == cgroupAvailable {
    64  			f.logger.Printf("[INFO] fingerprint.cgroups: cgroups are unavailable")
    65  		}
    66  		f.lastState = cgroupUnavailable
    67  		return true, nil
    68  	}
    69  
    70  	node.Attributes["unique.cgroup.mountpoint"] = mount
    71  
    72  	if f.lastState == cgroupUnavailable {
    73  		f.logger.Printf("[INFO] fingerprint.cgroups: cgroups are available")
    74  	}
    75  	f.lastState = cgroupAvailable
    76  	return true, nil
    77  }
    78  
    79  // clearCGroupAttributes clears any node attributes related to cgroups that might
    80  // have been set in a previous fingerprint run.
    81  func (f *CGroupFingerprint) clearCGroupAttributes(n *structs.Node) {
    82  	delete(n.Attributes, "unique.cgroup.mountpoint")
    83  }
    84  
    85  // Periodic determines the interval at which the periodic fingerprinter will run.
    86  func (f *CGroupFingerprint) Periodic() (bool, time.Duration) {
    87  	return true, interval * time.Second
    88  }