github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/apiserver/client/instanceconfig.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package client 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 "github.com/juju/utils/set" 11 12 "github.com/juju/juju/api" 13 "github.com/juju/juju/apiserver/common" 14 "github.com/juju/juju/apiserver/params" 15 "github.com/juju/juju/cloudconfig/instancecfg" 16 "github.com/juju/juju/controller/authentication" 17 "github.com/juju/juju/state" 18 "github.com/juju/juju/state/stateenvirons" 19 ) 20 21 // InstanceConfig returns information from the environment config that 22 // is needed for machine cloud-init (for non-controllers only). It 23 // is exposed for testing purposes. 24 // TODO(rog) fix environs/manual tests so they do not need to call this, or move this elsewhere. 25 func InstanceConfig(st *state.State, machineId, nonce, dataDir string) (*instancecfg.InstanceConfig, error) { 26 modelConfig, err := st.ModelConfig() 27 if err != nil { 28 return nil, errors.Annotate(err, "getting model config") 29 } 30 31 // Get the machine so we can get its series and arch. 32 // If the Arch is not set in hardware-characteristics, 33 // an error is returned. 34 machine, err := st.Machine(machineId) 35 if err != nil { 36 return nil, errors.Annotate(err, "getting machine") 37 } 38 hc, err := machine.HardwareCharacteristics() 39 if err != nil { 40 return nil, errors.Annotate(err, "getting machine hardware characteristics") 41 } 42 if hc.Arch == nil { 43 return nil, fmt.Errorf("arch is not set for %q", machine.Tag()) 44 } 45 46 // Find the appropriate tools information. 47 agentVersion, ok := modelConfig.AgentVersion() 48 if !ok { 49 return nil, errors.New("no agent version set in model configuration") 50 } 51 environment, err := st.Model() 52 if err != nil { 53 return nil, errors.Annotate(err, "getting state model") 54 } 55 urlGetter := common.NewToolsURLGetter(environment.UUID(), st) 56 configGetter := stateenvirons.EnvironConfigGetter{st} 57 toolsFinder := common.NewToolsFinder(configGetter, st, urlGetter) 58 findToolsResult, err := toolsFinder.FindTools(params.FindToolsParams{ 59 Number: agentVersion, 60 MajorVersion: -1, 61 MinorVersion: -1, 62 Series: machine.Series(), 63 Arch: *hc.Arch, 64 }) 65 if err != nil { 66 return nil, errors.Annotate(err, "finding tools") 67 } 68 if findToolsResult.Error != nil { 69 return nil, errors.Annotate(findToolsResult.Error, "finding tools") 70 } 71 toolsList := findToolsResult.List 72 73 // Get the API connection info; attempt all API addresses. 74 apiHostPorts, err := st.APIHostPorts() 75 if err != nil { 76 return nil, errors.Annotate(err, "getting API addresses") 77 } 78 apiAddrs := make(set.Strings) 79 for _, hostPorts := range apiHostPorts { 80 for _, hp := range hostPorts { 81 apiAddrs.Add(hp.NetAddr()) 82 } 83 } 84 apiInfo := &api.Info{ 85 Addrs: apiAddrs.SortedValues(), 86 CACert: st.CACert(), 87 ModelTag: st.ModelTag(), 88 } 89 90 auth := authentication.NewAuthenticator(st.MongoConnectionInfo(), apiInfo) 91 _, apiInfo, err = auth.SetupAuthentication(machine) 92 if err != nil { 93 return nil, errors.Annotate(err, "setting up machine authentication") 94 } 95 96 icfg, err := instancecfg.NewInstanceConfig(st.ControllerTag(), machineId, nonce, modelConfig.ImageStream(), 97 machine.Series(), apiInfo, 98 ) 99 if err != nil { 100 return nil, errors.Annotate(err, "initializing instance config") 101 } 102 if dataDir != "" { 103 icfg.DataDir = dataDir 104 } 105 if err := icfg.SetTools(toolsList); err != nil { 106 return nil, errors.Trace(err) 107 } 108 err = instancecfg.FinishInstanceConfig(icfg, modelConfig) 109 if err != nil { 110 return nil, errors.Annotate(err, "finishing instance config") 111 } 112 return icfg, nil 113 }