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  }