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