github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/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 "fmt" 8 9 "github.com/juju/loggo" 10 11 "github.com/juju/juju/agent" 12 "github.com/juju/juju/container" 13 "github.com/juju/juju/container/lxc" 14 "github.com/juju/juju/environs" 15 "github.com/juju/juju/environs/network" 16 "github.com/juju/juju/instance" 17 "github.com/juju/juju/state/api/params" 18 "github.com/juju/juju/tools" 19 ) 20 21 var lxcLogger = loggo.GetLogger("juju.provisioner.lxc") 22 23 var _ environs.InstanceBroker = (*lxcBroker)(nil) 24 var _ tools.HasTools = (*lxcBroker)(nil) 25 26 type APICalls interface { 27 ContainerConfig() (params.ContainerConfig, error) 28 } 29 30 func NewLxcBroker(api APICalls, tools *tools.Tools, agentConfig agent.Config, managerConfig container.ManagerConfig) (environs.InstanceBroker, error) { 31 manager, err := lxc.NewContainerManager(managerConfig) 32 if err != nil { 33 return nil, err 34 } 35 return &lxcBroker{ 36 manager: manager, 37 api: api, 38 tools: tools, 39 agentConfig: agentConfig, 40 }, nil 41 } 42 43 type lxcBroker struct { 44 manager container.Manager 45 api APICalls 46 tools *tools.Tools 47 agentConfig agent.Config 48 } 49 50 func (broker *lxcBroker) Tools(series string) tools.List { 51 // TODO: thumper 2014-04-08 bug 1304151 52 // should use the api get get tools for the series. 53 seriesTools := *broker.tools 54 seriesTools.Version.Series = series 55 return tools.List{&seriesTools} 56 } 57 58 // StartInstance is specified in the Broker interface. 59 func (broker *lxcBroker) StartInstance(args environs.StartInstanceParams) (instance.Instance, *instance.HardwareCharacteristics, []network.Info, error) { 60 if args.MachineConfig.HasNetworks() { 61 return nil, nil, nil, fmt.Errorf("starting lxc containers with networks is not supported yet.") 62 } 63 // TODO: refactor common code out of the container brokers. 64 machineId := args.MachineConfig.MachineId 65 lxcLogger.Infof("starting lxc container for machineId: %s", machineId) 66 67 // Default to using the host network until we can configure. 68 bridgeDevice := broker.agentConfig.Value(agent.LxcBridge) 69 if bridgeDevice == "" { 70 bridgeDevice = lxc.DefaultLxcBridge 71 } 72 network := container.BridgeNetworkConfig(bridgeDevice) 73 74 series := args.Tools.OneSeries() 75 args.MachineConfig.MachineContainerType = instance.LXC 76 args.MachineConfig.Tools = args.Tools[0] 77 78 config, err := broker.api.ContainerConfig() 79 if err != nil { 80 lxcLogger.Errorf("failed to get container config: %v", err) 81 return nil, nil, nil, err 82 } 83 if err := environs.PopulateMachineConfig( 84 args.MachineConfig, 85 config.ProviderType, 86 config.AuthorizedKeys, 87 config.SSLHostnameVerification, 88 config.Proxy, 89 config.AptProxy, 90 ); err != nil { 91 lxcLogger.Errorf("failed to populate machine config: %v", err) 92 return nil, nil, nil, err 93 } 94 95 inst, hardware, err := broker.manager.CreateContainer(args.MachineConfig, series, network) 96 if err != nil { 97 lxcLogger.Errorf("failed to start container: %v", err) 98 return nil, nil, nil, err 99 } 100 lxcLogger.Infof("started lxc container for machineId: %s, %s, %s", machineId, inst.Id(), hardware.String()) 101 return inst, hardware, nil, nil 102 } 103 104 // StopInstances shuts down the given instances. 105 func (broker *lxcBroker) StopInstances(ids ...instance.Id) error { 106 // TODO: potentially parallelise. 107 for _, id := range ids { 108 lxcLogger.Infof("stopping lxc container for instance: %s", id) 109 if err := broker.manager.DestroyContainer(id); err != nil { 110 lxcLogger.Errorf("container did not stop: %v", err) 111 return err 112 } 113 } 114 return nil 115 } 116 117 // AllInstances only returns running containers. 118 func (broker *lxcBroker) AllInstances() (result []instance.Instance, err error) { 119 return broker.manager.ListContainers() 120 }