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

     1  package driver
     2  
     3  import (
     4  	"fmt"
     5  	systemd "github.com/coreos/go-systemd/dbus"
     6  	"github.com/coreos/go-systemd/util"
     7  	"github.com/hashicorp/nomad/client/config"
     8  	"github.com/hashicorp/nomad/client/driver/executor"
     9  	cstructs "github.com/hashicorp/nomad/client/driver/structs"
    10  	"github.com/hashicorp/nomad/client/fingerprint"
    11  	"github.com/hashicorp/nomad/nomad/structs"
    12  	"github.com/mitchellh/mapstructure"
    13  	"log"
    14  )
    15  
    16  type SystemdDriverConfig struct {
    17  	Command string `mapstructure:"command"`
    18  }
    19  
    20  type SystemdDriver struct {
    21  	DriverContext
    22  	fingerprint.StaticFingerprinter
    23  }
    24  
    25  type systemdHandle struct {
    26  	logger   *log.Logger
    27  	Conn     *systemd.Conn
    28  	waitCh   chan *cstructs.WaitResult
    29  	doneCh   chan struct{}
    30  	executor *executor.SystemdExecutor
    31  }
    32  
    33  func NewSystemdDriver(ctx *DriverContext) Driver {
    34  	return &SystemdDriver{DriverContext: *ctx}
    35  }
    36  
    37  func (d *SystemdDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) {
    38  	if !util.IsRunningSystemd() {
    39  		return false, nil
    40  	}
    41  	conn, err := systemd.New()
    42  	if err != nil {
    43  		return false, err
    44  	}
    45  	defer conn.Close()
    46  	v, err := conn.GetManagerProperty("Version")
    47  	if err != nil {
    48  		return false, err
    49  	}
    50  	node.Attributes["driver.systemd.version"] = v
    51  	node.Attributes["driver.systemd"] = "1"
    52  	d.logger.Printf("[DEBUG] systemd version : %s\n", v)
    53  	return true, nil
    54  }
    55  
    56  func (d *SystemdDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) {
    57  	var config SystemdDriverConfig
    58  	if err := mapstructure.WeakDecode(task.Config, &config); err != nil {
    59  		d.logger.Printf("[ERROR] Failed to decode systemd driver config. Error: %s\n", err)
    60  		return nil, err
    61  	}
    62  	h := &systemdHandle{
    63  		logger:   d.logger,
    64  		doneCh:   make(chan struct{}),
    65  		waitCh:   make(chan *cstructs.WaitResult, 1),
    66  		executor: executor.NewSystemdExecutor(ctx.AllocID, config.Command, d.logger),
    67  	}
    68  
    69  	if err := h.executor.Limit(task.Resources); err != nil {
    70  		d.logger.Printf("[WARN] Failed to set resource constraints %s", err)
    71  		return nil, err
    72  	}
    73  
    74  	if err := h.executor.Start(); err != nil {
    75  		d.logger.Printf("[WARN] Failed to start systemd executor %s", err)
    76  		return nil, err
    77  	}
    78  	go h.run()
    79  	return h, nil
    80  }
    81  
    82  func (h *systemdHandle) run() {
    83  	waitResult := h.executor.Wait()
    84  	close(h.doneCh)
    85  	h.waitCh <- waitResult
    86  	close(h.waitCh)
    87  }
    88  
    89  func (d *SystemdDriver) Open(ctx *ExecContext, _ string) (DriverHandle, error) {
    90  	h := &systemdHandle{
    91  		logger:   d.logger,
    92  		doneCh:   make(chan struct{}),
    93  		waitCh:   make(chan *cstructs.WaitResult, 1),
    94  		executor: executor.NewSystemdExecutor(ctx.AllocID, "", d.logger),
    95  	}
    96  	return h, nil
    97  }
    98  
    99  func (h *systemdHandle) ID() string {
   100  	return fmt.Sprintf("systemd:%s", 1)
   101  }
   102  
   103  func (h *systemdHandle) WaitCh() chan *cstructs.WaitResult {
   104  	return h.waitCh
   105  }
   106  
   107  func (h *systemdHandle) Kill() error {
   108  	return h.executor.Shutdown()
   109  }
   110  
   111  func (h *systemdHandle) Update(task *structs.Task) error {
   112  	h.logger.Printf("[WARN] Update is not supported by lxc driver")
   113  	return nil
   114  }