github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/worker/provisioner/lxc-broker.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package provisioner
     5  
     6  import (
     7  	"github.com/juju/loggo"
     8  
     9  	"launchpad.net/juju-core/agent"
    10  	"launchpad.net/juju-core/constraints"
    11  	"launchpad.net/juju-core/container"
    12  	"launchpad.net/juju-core/container/lxc"
    13  	"launchpad.net/juju-core/environs"
    14  	"launchpad.net/juju-core/environs/cloudinit"
    15  	"launchpad.net/juju-core/instance"
    16  	"launchpad.net/juju-core/state/api/params"
    17  	"launchpad.net/juju-core/tools"
    18  )
    19  
    20  var lxcLogger = loggo.GetLogger("juju.provisioner.lxc")
    21  
    22  var _ environs.InstanceBroker = (*lxcBroker)(nil)
    23  var _ tools.HasTools = (*lxcBroker)(nil)
    24  
    25  type APICalls interface {
    26  	ContainerConfig() (params.ContainerConfig, error)
    27  }
    28  
    29  func NewLxcBroker(api APICalls, tools *tools.Tools, agentConfig agent.Config) (environs.InstanceBroker, error) {
    30  	manager, err := lxc.NewContainerManager(container.ManagerConfig{container.ConfigName: "juju"})
    31  	if err != nil {
    32  		return nil, err
    33  	}
    34  	return &lxcBroker{
    35  		manager:     manager,
    36  		api:         api,
    37  		tools:       tools,
    38  		agentConfig: agentConfig,
    39  	}, nil
    40  }
    41  
    42  type lxcBroker struct {
    43  	manager     container.Manager
    44  	api         APICalls
    45  	tools       *tools.Tools
    46  	agentConfig agent.Config
    47  }
    48  
    49  func (broker *lxcBroker) Tools() tools.List {
    50  	return tools.List{broker.tools}
    51  }
    52  
    53  // StartInstance is specified in the Broker interface.
    54  func (broker *lxcBroker) StartInstance(cons constraints.Value, possibleTools tools.List,
    55  	machineConfig *cloudinit.MachineConfig) (instance.Instance, *instance.HardwareCharacteristics, error) {
    56  	// TODO: refactor common code out of the container brokers.
    57  	machineId := machineConfig.MachineId
    58  	lxcLogger.Infof("starting lxc container for machineId: %s", machineId)
    59  
    60  	// Default to using the host network until we can configure.
    61  	bridgeDevice := broker.agentConfig.Value(agent.LxcBridge)
    62  	if bridgeDevice == "" {
    63  		bridgeDevice = lxc.DefaultLxcBridge
    64  	}
    65  	network := container.BridgeNetworkConfig(bridgeDevice)
    66  
    67  	series := possibleTools.OneSeries()
    68  	machineConfig.MachineContainerType = instance.LXC
    69  	machineConfig.Tools = possibleTools[0]
    70  
    71  	config, err := broker.api.ContainerConfig()
    72  	if err != nil {
    73  		lxcLogger.Errorf("failed to get container config: %v", err)
    74  		return nil, nil, err
    75  	}
    76  	if err := environs.PopulateMachineConfig(
    77  		machineConfig,
    78  		config.ProviderType,
    79  		config.AuthorizedKeys,
    80  		config.SSLHostnameVerification,
    81  		config.Proxy,
    82  		config.AptProxy,
    83  	); err != nil {
    84  		lxcLogger.Errorf("failed to populate machine config: %v", err)
    85  		return nil, nil, err
    86  	}
    87  
    88  	inst, hardware, err := broker.manager.StartContainer(machineConfig, series, network)
    89  	if err != nil {
    90  		lxcLogger.Errorf("failed to start container: %v", err)
    91  		return nil, nil, err
    92  	}
    93  	lxcLogger.Infof("started lxc container for machineId: %s, %s, %s", machineId, inst.Id(), hardware.String())
    94  	return inst, hardware, nil
    95  }
    96  
    97  // StopInstances shuts down the given instances.
    98  func (broker *lxcBroker) StopInstances(instances []instance.Instance) error {
    99  	// TODO: potentially parallelise.
   100  	for _, instance := range instances {
   101  		lxcLogger.Infof("stopping lxc container for instance: %s", instance.Id())
   102  		if err := broker.manager.StopContainer(instance); err != nil {
   103  			lxcLogger.Errorf("container did not stop: %v", err)
   104  			return err
   105  		}
   106  	}
   107  	return nil
   108  }
   109  
   110  // AllInstances only returns running containers.
   111  func (broker *lxcBroker) AllInstances() (result []instance.Instance, err error) {
   112  	return broker.manager.ListContainers()
   113  }