github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/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 "errors" 8 9 "github.com/juju/loggo" 10 11 "github.com/juju/juju/agent" 12 "github.com/juju/juju/apiserver/params" 13 "github.com/juju/juju/container" 14 "github.com/juju/juju/container/lxc" 15 "github.com/juju/juju/environs" 16 "github.com/juju/juju/instance" 17 ) 18 19 var lxcLogger = loggo.GetLogger("juju.provisioner.lxc") 20 21 var _ environs.InstanceBroker = (*lxcBroker)(nil) 22 23 type APICalls interface { 24 ContainerConfig() (params.ContainerConfig, error) 25 } 26 27 // Override for testing. 28 var NewLxcBroker = newLxcBroker 29 30 func newLxcBroker( 31 api APICalls, agentConfig agent.Config, managerConfig container.ManagerConfig, 32 imageURLGetter container.ImageURLGetter, 33 ) (environs.InstanceBroker, error) { 34 manager, err := lxc.NewContainerManager(managerConfig, imageURLGetter) 35 if err != nil { 36 return nil, err 37 } 38 return &lxcBroker{ 39 manager: manager, 40 api: api, 41 agentConfig: agentConfig, 42 }, nil 43 } 44 45 type lxcBroker struct { 46 manager container.Manager 47 api APICalls 48 agentConfig agent.Config 49 } 50 51 // StartInstance is specified in the Broker interface. 52 func (broker *lxcBroker) StartInstance(args environs.StartInstanceParams) (*environs.StartInstanceResult, error) { 53 if args.MachineConfig.HasNetworks() { 54 return nil, errors.New("starting lxc containers with networks is not supported yet") 55 } 56 // TODO: refactor common code out of the container brokers. 57 machineId := args.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, args.NetworkInfo) 66 67 series := args.Tools.OneSeries() 68 args.MachineConfig.MachineContainerType = instance.LXC 69 args.MachineConfig.Tools = args.Tools[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, err 75 } 76 if err := environs.PopulateMachineConfig( 77 args.MachineConfig, 78 config.ProviderType, 79 config.AuthorizedKeys, 80 config.SSLHostnameVerification, 81 config.Proxy, 82 config.AptProxy, 83 config.AptMirror, 84 config.PreferIPv6, 85 config.EnableOSRefreshUpdate, 86 config.EnableOSUpgrade, 87 ); err != nil { 88 lxcLogger.Errorf("failed to populate machine config: %v", err) 89 return nil, err 90 } 91 92 inst, hardware, err := broker.manager.CreateContainer(args.MachineConfig, series, network) 93 if err != nil { 94 lxcLogger.Errorf("failed to start container: %v", err) 95 return nil, err 96 } 97 lxcLogger.Infof("started lxc container for machineId: %s, %s, %s", machineId, inst.Id(), hardware.String()) 98 return &environs.StartInstanceResult{ 99 Instance: inst, 100 Hardware: hardware, 101 }, 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 }