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 }