Ejemplo n.º 1
0
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,
	})
}
Ejemplo n.º 2
0
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,
	})
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
// 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())
}