github.com/ranjib/nomad@v0.1.1-0.20160225204057-97751b02f70b/client/driver/lxc.go (about) 1 package driver 2 3 import ( 4 "fmt" 5 "github.com/hashicorp/nomad/client/config" 6 cstructs "github.com/hashicorp/nomad/client/driver/structs" 7 "github.com/hashicorp/nomad/client/fingerprint" 8 "github.com/hashicorp/nomad/nomad/structs" 9 "github.com/mitchellh/mapstructure" 10 lxc "gopkg.in/lxc/go-lxc.v2" 11 "log" 12 ) 13 14 type LXCDriver struct { 15 DriverContext 16 fingerprint.StaticFingerprinter 17 } 18 19 type lxcHandle struct { 20 logger *log.Logger 21 Name string 22 waitCh chan *cstructs.WaitResult 23 doneCh chan struct{} 24 executor *LXCExecutor 25 } 26 27 func NewLXCDriver(ctx *DriverContext) Driver { 28 return &LXCDriver{DriverContext: *ctx} 29 } 30 31 func (d *LXCDriver) Fingerprint(cfg *config.Config, node *structs.Node) (bool, error) { 32 node.Attributes["driver.lxc.version"] = lxc.Version() 33 node.Attributes["driver.lxc"] = "1" 34 d.logger.Printf("[DEBUG] lxc.version: %s", node.Attributes["driver.lxc.version"]) 35 return true, nil 36 } 37 38 func (d *LXCDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) { 39 var config LXCExecutorConfig 40 if err := mapstructure.WeakDecode(task.Config, &config); err != nil { 41 return nil, err 42 } 43 executor, e := NewLXCExecutor(&config, d.logger) 44 d.logger.Printf("[DEBUG] Using lxc name: %s", config.Name) 45 //envVars := TaskEnvironmentVariables(ctx, task) 46 if e != nil { 47 d.logger.Printf("[ERROR] failed to create container: %s", e) 48 return nil, e 49 } 50 d.logger.Printf("[DEBUG] Successfully created container: %s", config.Name) 51 h := &lxcHandle{ 52 Name: config.Name, 53 logger: d.logger, 54 doneCh: make(chan struct{}), 55 waitCh: make(chan *cstructs.WaitResult, 1), 56 executor: executor, 57 } 58 59 if err := h.executor.Limit(task.Resources); err != nil { 60 d.logger.Printf("[WARN] Failed to set resource constraints %s", err) 61 return nil, err 62 } 63 64 if err := h.executor.Start(); err != nil { 65 d.logger.Printf("[WARN] Failed to start container %s", err) 66 return nil, err 67 } 68 go h.run() 69 return h, nil 70 } 71 72 func (h *lxcHandle) run() { 73 waitResult := h.executor.Wait() 74 close(h.doneCh) 75 h.waitCh <- waitResult 76 close(h.waitCh) 77 } 78 79 func (d *LXCDriver) Open(ctx *ExecContext, name string) (DriverHandle, error) { 80 lxcpath := lxc.DefaultConfigPath() 81 c, err := lxc.NewContainer(name, lxcpath) 82 if err != nil { 83 d.logger.Printf("[WARN] Failed to initialize container %s", err) 84 return nil, err 85 } 86 h := &lxcHandle{ 87 Name: name, 88 logger: d.logger, 89 doneCh: make(chan struct{}), 90 waitCh: make(chan *cstructs.WaitResult, 1), 91 executor: &LXCExecutor{ 92 container: c, 93 logger: d.logger, 94 }, 95 } 96 return h, nil 97 } 98 99 func (h *lxcHandle) ID() string { 100 return fmt.Sprintf("LXC:%s", h.Name) 101 } 102 103 func (h *lxcHandle) WaitCh() chan *cstructs.WaitResult { 104 return h.waitCh 105 } 106 107 func (h *lxcHandle) Kill() error { 108 return h.executor.Shutdown() 109 } 110 111 func (h *lxcHandle) Update(task *structs.Task) error { 112 h.logger.Printf("[WARN] Update is not supported by lxc driver") 113 return nil 114 }