func (s *configureSuite) getCloudConfig(c *gc.C, stateServer bool, vers version.Binary) *cloudinit.Config { var mcfg *envcloudinit.MachineConfig var err error if stateServer { mcfg, err = environs.NewBootstrapMachineConfig(constraints.Value{}, vers.Series) c.Assert(err, gc.IsNil) mcfg.InstanceId = "instance-id" mcfg.Jobs = []params.MachineJob{params.JobManageEnviron, params.JobHostUnits} } else { mcfg, err = environs.NewMachineConfig("0", "ya", imagemetadata.ReleasedStream, vers.Series, nil, nil, nil) c.Assert(err, gc.IsNil) mcfg.Jobs = []params.MachineJob{params.JobHostUnits} } mcfg.Tools = &tools.Tools{ Version: vers, URL: "http://testing.invalid/tools.tar.gz", } environConfig := testConfig(c, stateServer, vers) err = environs.FinishMachineConfig(mcfg, environConfig) c.Assert(err, gc.IsNil) cloudcfg := cloudinit.New() udata, err := envcloudinit.NewUserdataConfig(mcfg, cloudcfg) c.Assert(err, gc.IsNil) err = udata.Configure() c.Assert(err, gc.IsNil) return cloudcfg }
// MachineConfig returns information from the environment config that is // needed for machine cloud-init (for non-state servers only). // It is exposed for testing purposes. // TODO(rog) fix environs/manual tests so they do not need to // call this, or move this elsewhere. func MachineConfig(st *state.State, machineId, nonce, dataDir string) (*cloudinit.MachineConfig, error) { environConfig, err := st.EnvironConfig() if err != nil { return nil, err } // Get the machine so we can get its series and arch. // If the Arch is not set in hardware-characteristics, // an error is returned. machine, err := st.Machine(machineId) if err != nil { return nil, err } hc, err := machine.HardwareCharacteristics() if err != nil { return nil, err } if hc.Arch == nil { return nil, fmt.Errorf("arch is not set for %q", machine.Tag()) } // Find the appropriate tools information. env, err := environs.New(environConfig) if err != nil { return nil, err } tools, err := findInstanceTools(env, machine.Series(), *hc.Arch) if err != nil { return nil, err } // Find the API endpoints. apiInfo, err := environs.APIInfo(env) if err != nil { return nil, err } auth := authentication.NewAuthenticator(st.MongoConnectionInfo(), apiInfo) mongoInfo, apiInfo, err := auth.SetupAuthentication(machine) if err != nil { return nil, err } // Find requested networks. networks, err := machine.RequestedNetworks() if err != nil { return nil, err } mcfg := environs.NewMachineConfig(machineId, nonce, networks, mongoInfo, apiInfo) if dataDir != "" { mcfg.DataDir = dataDir } mcfg.Tools = tools err = environs.FinishMachineConfig(mcfg, environConfig, constraints.Value{}) if err != nil { return nil, err } return mcfg, nil }
func (task *provisionerTask) constructMachineConfig( machine *apiprovisioner.Machine, auth authentication.AuthenticationProvider, pInfo *params.ProvisioningInfo, ) (*cloudinit.MachineConfig, error) { stateInfo, apiInfo, err := auth.SetupAuthentication(machine) if err != nil { return nil, errors.Annotate(err, "failed to setup authentication") } // Generated a nonce for the new instance, with the format: "machine-#:UUID". // The first part is a badge, specifying the tag of the machine the provisioner // is running on, while the second part is a random UUID. uuid, err := utils.NewUUID() if err != nil { return nil, errors.Annotate(err, "failed to generate a nonce for machine "+machine.Id()) } nonce := fmt.Sprintf("%s:%s", task.machineTag, uuid) return environs.NewMachineConfig( machine.Id(), nonce, task.imageStream, pInfo.Series, nil, stateInfo, apiInfo, ) }
// StartInstanceWithParams is a test helper function that starts an instance // with the given parameters, and a plausible but invalid configuration, and // returns the result of Environ.StartInstance. The provided params's // MachineConfig and Tools field values will be ignored. func StartInstanceWithParams( env environs.Environ, machineId string, params environs.StartInstanceParams, networks []string, ) ( instance.Instance, *instance.HardwareCharacteristics, []network.Info, error, ) { series := config.PreferredSeries(env.Config()) agentVersion, ok := env.Config().AgentVersion() if !ok { return nil, nil, nil, fmt.Errorf("missing agent version in environment config") } possibleTools, err := tools.FindInstanceTools( env, agentVersion, series, params.Constraints.Arch, ) if err != nil { return nil, nil, nil, err } machineNonce := "fake_nonce" stateInfo := FakeStateInfo(machineId) apiInfo := FakeAPIInfo(machineId) machineConfig := environs.NewMachineConfig( machineId, machineNonce, networks, stateInfo, apiInfo) params.Tools = possibleTools params.MachineConfig = machineConfig return env.StartInstance(params) }
func (*cloudinitSuite) createMachineConfig(c *gc.C, environConfig *config.Config) *cloudinit.MachineConfig { machineId := "42" machineNonce := "fake-nonce" stateInfo := jujutesting.FakeStateInfo(machineId) apiInfo := jujutesting.FakeAPIInfo(machineId) machineConfig := environs.NewMachineConfig(machineId, machineNonce, nil, stateInfo, apiInfo) machineConfig.Tools = &tools.Tools{ Version: version.MustParseBinary("2.3.4-foo-bar"), URL: "http://tools.testing.invalid/2.3.4-foo-bar.tgz", } err := environs.FinishMachineConfig(machineConfig, environConfig, constraints.Value{}) c.Assert(err, gc.IsNil) return machineConfig }
func (s *kvmBrokerSuite) startInstance(c *gc.C, machineId string) instance.Instance { machineNonce := "fake-nonce" stateInfo := jujutesting.FakeStateInfo(machineId) apiInfo := jujutesting.FakeAPIInfo(machineId) machineConfig := environs.NewMachineConfig(machineId, machineNonce, nil, stateInfo, apiInfo) cons := constraints.Value{} possibleTools := s.broker.(coretools.HasTools).Tools("precise") kvm, _, _, err := s.broker.StartInstance(environs.StartInstanceParams{ Constraints: cons, Tools: possibleTools, MachineConfig: machineConfig, }) c.Assert(err, gc.IsNil) return kvm }
func (*cloudinitSuite) createMachineConfig(c *gc.C, environConfig *config.Config) *cloudinit.MachineConfig { machineId := "42" machineNonce := "fake-nonce" stateInfo := jujutesting.FakeStateInfo(machineId) apiInfo := jujutesting.FakeAPIInfo(machineId) machineConfig, err := environs.NewMachineConfig(machineId, machineNonce, imagemetadata.ReleasedStream, "quantal", nil, stateInfo, apiInfo) c.Assert(err, gc.IsNil) machineConfig.Tools = &tools.Tools{ Version: version.MustParseBinary("2.3.4-quantal-amd64"), URL: "http://tools.testing.invalid/2.3.4-quantal-amd64.tgz", } err = environs.FinishMachineConfig(machineConfig, environConfig) c.Assert(err, gc.IsNil) return machineConfig }
func MockMachineConfig(machineId string) (*cloudinit.MachineConfig, error) { stateInfo := jujutesting.FakeStateInfo(machineId) apiInfo := jujutesting.FakeAPIInfo(machineId) machineConfig, err := environs.NewMachineConfig(machineId, "fake-nonce", imagemetadata.ReleasedStream, "quantal", nil, stateInfo, apiInfo) if err != nil { return nil, err } machineConfig.Tools = &tools.Tools{ Version: version.MustParseBinary("2.3.4-quantal-amd64"), URL: "http://tools.testing.invalid/2.3.4-quantal-amd64.tgz", } return machineConfig, nil }
func CreateContainer(c *gc.C, manager container.Manager, machineId string) instance.Instance { stateInfo := jujutesting.FakeStateInfo(machineId) apiInfo := jujutesting.FakeAPIInfo(machineId) machineConfig := environs.NewMachineConfig(machineId, "fake-nonce", nil, stateInfo, apiInfo) machineConfig.Tools = &tools.Tools{ Version: version.MustParseBinary("2.3.4-foo-bar"), URL: "http://tools.testing.invalid/2.3.4-foo-bar.tgz", } series := "series" network := container.BridgeNetworkConfig("nic42") inst, hardware, err := manager.CreateContainer(machineConfig, series, network) c.Assert(err, gc.IsNil) c.Assert(hardware, gc.NotNil) c.Assert(hardware.String(), gc.Not(gc.Equals), "") return inst }
// StartInstanceWithParams is a test helper function that starts an instance // with the given parameters, and a plausible but invalid configuration, and // returns the result of Environ.StartInstance. The provided params's // MachineConfig and Tools field values will be ignored. func StartInstanceWithParams( env environs.Environ, machineId string, params environs.StartInstanceParams, networks []string, ) ( instance.Instance, *instance.HardwareCharacteristics, []network.Info, error, ) { series := config.PreferredSeries(env.Config()) agentVersion, ok := env.Config().AgentVersion() if !ok { return nil, nil, nil, fmt.Errorf("missing agent version in environment config") } filter := coretools.Filter{ Number: agentVersion, Series: series, } if params.Constraints.Arch != nil { filter.Arch = *params.Constraints.Arch } possibleTools, err := tools.FindTools( env, -1, -1, filter, tools.DoNotAllowRetry, ) if err != nil { return nil, nil, nil, err } machineNonce := "fake_nonce" stateInfo := FakeStateInfo(machineId) apiInfo := FakeAPIInfo(machineId) machineConfig, err := environs.NewMachineConfig( machineId, machineNonce, imagemetadata.ReleasedStream, series, networks, stateInfo, apiInfo, ) if err != nil { return nil, nil, nil, err } params.Tools = possibleTools params.MachineConfig = machineConfig return env.StartInstance(params) }
// Check that we get a consistent error when asking for an instance without // a valid machine config. func (t *LiveTests) TestStartInstanceWithEmptyNonceFails(c *gc.C) { machineId := "4" stateInfo := testing.FakeStateInfo(machineId) apiInfo := testing.FakeAPIInfo(machineId) machineConfig := environs.NewMachineConfig(machineId, "", nil, stateInfo, apiInfo) t.PrepareOnce(c) possibleTools := envtesting.AssertUploadFakeToolsVersions(c, t.Env.Storage(), version.MustParseBinary("5.4.5-precise-amd64")) inst, _, _, err := t.Env.StartInstance(environs.StartInstanceParams{ Tools: possibleTools, MachineConfig: machineConfig, }) if inst != nil { err := t.Env.StopInstances(inst.Id()) c.Check(err, gc.IsNil) } c.Assert(inst, gc.IsNil) c.Assert(err, gc.ErrorMatches, ".*missing machine nonce") }
func (s *kvmBrokerSuite) startInstance(c *gc.C, machineId string) instance.Instance { machineNonce := "fake-nonce" stateInfo := jujutesting.FakeStateInfo(machineId) apiInfo := jujutesting.FakeAPIInfo(machineId) machineConfig, err := environs.NewMachineConfig(machineId, machineNonce, "released", "quantal", nil, stateInfo, apiInfo) c.Assert(err, gc.IsNil) cons := constraints.Value{} possibleTools := coretools.List{&coretools.Tools{ Version: version.MustParseBinary("2.3.4-quantal-amd64"), URL: "http://tools.testing.invalid/2.3.4-quantal-amd64.tgz", }} kvm, _, _, err := s.broker.StartInstance(environs.StartInstanceParams{ Constraints: cons, Tools: possibleTools, MachineConfig: machineConfig, }) c.Assert(err, gc.IsNil) return kvm }
func (task *provisionerTask) provisioningInfo(machine *apiprovisioner.Machine) (*provisioningInfo, error) { stateInfo, apiInfo, err := task.auth.SetupAuthentication(machine) if err != nil { logger.Errorf("failed to setup authentication: %v", err) return nil, err } // Generated a nonce for the new instance, with the format: "machine-#:UUID". // The first part is a badge, specifying the tag of the machine the provisioner // is running on, while the second part is a random UUID. uuid, err := utils.NewUUID() if err != nil { return nil, err } // ProvisioningInfo is new in 1.20; wait for the API server to be upgraded // so we don't spew errors on upgrade. var pInfo *params.ProvisioningInfo for { if pInfo, err = machine.ProvisioningInfo(); err == nil { break } if params.IsCodeNotImplemented(err) { logger.Infof("waiting for state server to be upgraded") select { case <-task.tomb.Dying(): return nil, tomb.ErrDying case <-time.After(15 * time.Second): continue } } return nil, err } nonce := fmt.Sprintf("%s:%s", task.machineTag, uuid.String()) machineConfig := environs.NewMachineConfig(machine.Id(), nonce, pInfo.Networks, stateInfo, apiInfo) return &provisioningInfo{ Constraints: pInfo.Constraints, Series: pInfo.Series, Placement: pInfo.Placement, MachineConfig: machineConfig, }, nil }
func (s *configureSuite) getCloudConfig(c *gc.C, stateServer bool, vers version.Binary) *cloudinit.Config { var mcfg *envcloudinit.MachineConfig if stateServer { mcfg = environs.NewBootstrapMachineConfig("private-key") mcfg.InstanceId = "instance-id" mcfg.Jobs = []params.MachineJob{params.JobManageEnviron, params.JobHostUnits} } else { mcfg = environs.NewMachineConfig("0", "ya", nil, nil, nil) mcfg.Jobs = []params.MachineJob{params.JobHostUnits} } mcfg.Tools = &tools.Tools{ Version: vers, URL: "file:///var/lib/juju/storage/" + envtools.StorageName(vers), } environConfig := testConfig(c, stateServer, vers) err := environs.FinishMachineConfig(mcfg, environConfig, constraints.Value{}) c.Assert(err, gc.IsNil) cloudcfg := cloudinit.New() err = envcloudinit.Configure(mcfg, cloudcfg) c.Assert(err, gc.IsNil) return cloudcfg }
func createContainer(c *gc.C, manager container.Manager, machineId string) instance.Instance { machineNonce := "fake-nonce" stateInfo := jujutesting.FakeStateInfo(machineId) apiInfo := jujutesting.FakeAPIInfo(machineId) machineConfig := environs.NewMachineConfig(machineId, machineNonce, nil, stateInfo, apiInfo) network := container.BridgeNetworkConfig("virbr0") machineConfig.Tools = &tools.Tools{ Version: version.MustParseBinary("2.3.4-foo-bar"), URL: "http://tools.testing.invalid/2.3.4-foo-bar.tgz", } environConfig := dummyConfig(c) err := environs.FinishMachineConfig(machineConfig, environConfig, constraints.Value{}) c.Assert(err, gc.IsNil) inst, hardware, err := manager.CreateContainer(machineConfig, "precise", network) c.Assert(err, gc.IsNil) c.Assert(hardware, gc.NotNil) expected := fmt.Sprintf("arch=%s cpu-cores=1 mem=512M root-disk=8192M", version.Current.Arch) c.Assert(hardware.String(), gc.Equals, expected) return inst }
// MachineConfig returns information from the environment config that // is needed for machine cloud-init (for non-state servers only). It // is exposed for testing purposes. // TODO(rog) fix environs/manual tests so they do not need to call this, or move this elsewhere. func MachineConfig(st *state.State, machineId, nonce, dataDir string) (*cloudinit.MachineConfig, error) { environConfig, err := st.EnvironConfig() if err != nil { return nil, err } // Get the machine so we can get its series and arch. // If the Arch is not set in hardware-characteristics, // an error is returned. machine, err := st.Machine(machineId) if err != nil { return nil, err } hc, err := machine.HardwareCharacteristics() if err != nil { return nil, err } if hc.Arch == nil { return nil, fmt.Errorf("arch is not set for %q", machine.Tag()) } // Find the appropriate tools information. agentVersion, ok := environConfig.AgentVersion() if !ok { return nil, errors.New("no agent version set in environment configuration") } environment, err := st.Environment() if err != nil { return nil, err } urlGetter := common.NewToolsURLGetter(environment.UUID(), st) toolsFinder := common.NewToolsFinder(st, st, urlGetter) findToolsResult, err := toolsFinder.FindTools(params.FindToolsParams{ Number: agentVersion, MajorVersion: -1, MinorVersion: -1, Series: machine.Series(), Arch: *hc.Arch, }) if err != nil { return nil, err } if findToolsResult.Error != nil { return nil, findToolsResult.Error } tools := findToolsResult.List[0] // Find the API endpoints. env, err := environs.New(environConfig) if err != nil { return nil, err } apiInfo, err := environs.APIInfo(env) if err != nil { return nil, err } auth := authentication.NewAuthenticator(st.MongoConnectionInfo(), apiInfo) mongoInfo, apiInfo, err := auth.SetupAuthentication(machine) if err != nil { return nil, err } // Find requested networks. networks, err := machine.RequestedNetworks() if err != nil { return nil, err } mcfg, err := environs.NewMachineConfig(machineId, nonce, env.Config().ImageStream(), machine.Series(), networks, mongoInfo, apiInfo) if err != nil { return nil, err } if dataDir != "" { mcfg.DataDir = dataDir } mcfg.Tools = tools err = environs.FinishMachineConfig(mcfg, environConfig) if err != nil { return nil, err } return mcfg, nil }