func (*configSuite) TestStoreConfigTLS(c *gc.C) { var config localTLSStorageConfig m, err := localstorage.StoreConfig(&config) c.Assert(err, gc.IsNil) c.Assert(m, gc.DeepEquals, map[string]string{ localstorage.StorageDir: "", localstorage.StorageAddr: "", }) config.storageDir = "a" config.storageAddr = "b" config.caCertPEM = "heyhey" config.caKeyPEM = "hoho" config.hostnames = []string{"easy", "as", "1.2.3"} config.authkey = "password" m, err = localstorage.StoreConfig(&config) c.Assert(err, gc.IsNil) c.Assert(m, gc.DeepEquals, map[string]string{ localstorage.StorageDir: config.storageDir, localstorage.StorageAddr: config.storageAddr, localstorage.StorageCACert: string(config.caCertPEM), localstorage.StorageCAKey: string(config.caKeyPEM), localstorage.StorageHostnames: mustMarshalYAML(c, config.hostnames), localstorage.StorageAuthKey: config.authkey, }) }
func (*configSuite) TestStoreConfig(c *gc.C) { var config localStorageConfig m, err := localstorage.StoreConfig(&config) c.Assert(err, gc.IsNil) c.Assert(m, gc.DeepEquals, map[string]string{ localstorage.StorageDir: "", localstorage.StorageAddr: "", }) config.storageDir = "a" config.storageAddr = "b" m, err = localstorage.StoreConfig(&config) c.Assert(err, gc.IsNil) c.Assert(m, gc.DeepEquals, map[string]string{ localstorage.StorageDir: config.storageDir, localstorage.StorageAddr: config.storageAddr, }) }
func (e *manualEnviron) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) (arch, series string, _ environs.BootstrapFinalizer, _ error) { // Set "use-sshstorage" to false, so agents know not to use sshstorage. cfg, err := e.Config().Apply(map[string]interface{}{"use-sshstorage": false}) if err != nil { return "", "", nil, err } if err := e.SetConfig(cfg); err != nil { return "", "", nil, err } agentEnv, err := localstorage.StoreConfig(e) if err != nil { return "", "", nil, err } envConfig := e.envConfig() // TODO(axw) consider how we can use placement to override bootstrap-host. host := envConfig.bootstrapHost() provisioned, err := manualCheckProvisioned(host) if err != nil { return "", "", nil, errors.Annotate(err, "failed to check provisioned status") } if provisioned { return "", "", nil, manual.ErrProvisioned } hc, series, err := manualDetectSeriesAndHardwareCharacteristics(host) if err != nil { return "", "", nil, err } finalize := func(ctx environs.BootstrapContext, icfg *instancecfg.InstanceConfig) error { icfg.InstanceId = BootstrapInstanceId icfg.HardwareCharacteristics = &hc if err := instancecfg.FinishInstanceConfig(icfg, e.Config()); err != nil { return err } for k, v := range agentEnv { icfg.AgentEnvironment[k] = v } return common.ConfigureMachine(ctx, ssh.DefaultClient, host, icfg) } return *hc.Arch, series, finalize, nil }
// NewManualBootstrapEnviron wraps a LocalStorageEnviron with another which // overrides the Bootstrap method; when Bootstrap is invoked, the specified // host will be manually bootstrapped. // // InitUbuntuUser is expected to have been executed successfully against // the host being bootstrapped. func Bootstrap(args BootstrapArgs) (err error) { if args.Host == "" { return errors.New("host argument is empty") } if args.Environ == nil { return errors.New("environ argument is nil") } if args.DataDir == "" { return errors.New("data-dir argument is empty") } if args.Series == "" { return errors.New("series argument is empty") } if args.HardwareCharacteristics == nil { return errors.New("hardware characteristics argument is empty") } if len(args.PossibleTools) == 0 { return errors.New("possible tools is empty") } provisioned, err := checkProvisioned(args.Host) if err != nil { return fmt.Errorf("failed to check provisioned status: %v", err) } if provisioned { return ErrProvisioned } // Filter tools based on detected series/arch. logger.Infof("Filtering possible tools: %v", args.PossibleTools) possibleTools, err := args.PossibleTools.Match(tools.Filter{ Arch: *args.HardwareCharacteristics.Arch, Series: args.Series, }) if err != nil { return err } // Store the state file. If provisioning fails, we'll remove the file. logger.Infof("Saving bootstrap state file to bootstrap storage") bootstrapStorage := args.Environ.Storage() err = bootstrap.SaveState( bootstrapStorage, &bootstrap.BootstrapState{ StateInstances: []instance.Id{BootstrapInstanceId}, }, ) if err != nil { return err } defer func() { if err != nil { logger.Errorf("bootstrapping failed, removing state file: %v", err) bootstrapStorage.Remove(bootstrap.StateFile) } }() // If the tools are on the machine already, get a file:// scheme tools URL. tools := *possibleTools[0] storageDir := args.Environ.StorageDir() toolsStorageName := envtools.StorageName(tools.Version) if url, _ := bootstrapStorage.URL(toolsStorageName); url == tools.URL { tools.URL = fmt.Sprintf("file://%s/%s", storageDir, toolsStorageName) } // Add the local storage configuration. agentEnv, err := localstorage.StoreConfig(args.Environ) if err != nil { return err } privateKey, err := common.GenerateSystemSSHKey(args.Environ) if err != nil { return err } // Finally, provision the machine agent. mcfg := environs.NewBootstrapMachineConfig(privateKey) mcfg.InstanceId = BootstrapInstanceId mcfg.HardwareCharacteristics = args.HardwareCharacteristics if args.DataDir != "" { mcfg.DataDir = args.DataDir } mcfg.Tools = &tools err = environs.FinishMachineConfig(mcfg, args.Environ.Config(), constraints.Value{}) if err != nil { return err } for k, v := range agentEnv { mcfg.AgentEnvironment[k] = v } return provisionMachineAgent(args.Host, mcfg, args.Context.GetStderr()) }