launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/statecmd/machineconfig.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package statecmd 5 6 import ( 7 errgo "launchpad.net/errgo/errors" 8 "launchpad.net/juju-core/constraints" 9 "launchpad.net/juju-core/environs" 10 "launchpad.net/juju-core/environs/cloudinit" 11 envtools "launchpad.net/juju-core/environs/tools" 12 "launchpad.net/juju-core/errors" 13 "launchpad.net/juju-core/state" 14 "launchpad.net/juju-core/tools" 15 ) 16 17 var mask = errgo.Mask 18 19 func findInstanceTools(env environs.Environ, series, arch string) (*tools.Tools, error) { 20 agentVersion, ok := env.Config().AgentVersion() 21 if !ok { 22 return nil, errgo.Newf("no agent version set in environment configuration") 23 } 24 possibleTools, err := envtools.FindInstanceTools(env, agentVersion, series, &arch) 25 if err != nil { 26 return nil, mask(err, errors.IsNotFoundError) 27 } 28 return possibleTools[0], nil 29 } 30 31 // MachineConfig returns information from the environment config that is 32 // needed for machine cloud-init (for non-state servers only). 33 // 34 // The code is here so that it can be shared between the API server 35 // (for ProvisioningScript) and the CLI (for manual provisioning) for maintaining 36 // compatibiility with juju-1.16 (where the API MachineConfig did not exist). 37 // When we drop 1.16 compatibility, this code should be moved into apiserver. 38 // 39 // MachineConfig returns an errors.NotFoundError if no tools 40 // are found for the machine. 41 func MachineConfig(st *state.State, machineId, nonce, dataDir string) (*cloudinit.MachineConfig, error) { 42 environConfig, err := st.EnvironConfig() 43 if err != nil { 44 return nil, mask(err) 45 } 46 // Get the machine so we can get its series and arch. 47 // If the Arch is not set in hardware-characteristics, 48 // an error is returned. 49 machine, err := st.Machine(machineId) 50 if err != nil { 51 return nil, mask(err) 52 } 53 hc, err := machine.HardwareCharacteristics() 54 if err != nil { 55 return nil, mask(err) 56 } 57 if hc.Arch == nil { 58 return nil, errgo.Newf("arch is not set for %q", machine.Tag()) 59 } 60 61 // Find the appropriate tools information. 62 env, err := environs.New(environConfig) 63 if err != nil { 64 return nil, mask(err) 65 } 66 tools, err := findInstanceTools(env, machine.Series(), *hc.Arch) 67 if err != nil { 68 return nil, mask(err, errors.IsNotFoundError) 69 } 70 71 // Find the secrets and API endpoints. 72 auth, err := environs.NewEnvironAuthenticator(env) 73 if err != nil { 74 return nil, mask(err) 75 } 76 stateInfo, apiInfo, err := auth.SetupAuthentication(machine) 77 if err != nil { 78 return nil, mask(err) 79 } 80 81 mcfg := environs.NewMachineConfig(machineId, nonce, stateInfo, apiInfo) 82 if dataDir != "" { 83 mcfg.DataDir = dataDir 84 } 85 mcfg.Tools = tools 86 err = environs.FinishMachineConfig(mcfg, environConfig, constraints.Value{}) 87 if err != nil { 88 return nil, mask(err) 89 } 90 return mcfg, nil 91 }