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  }