func (*suite) TestBootstrapConfig(c *gc.C) { defer testing.MakeFakeHomeNoEnvironments(c, "bladaam").Restore() attrs := dummySampleConfig().Merge(testing.Attrs{ "agent-version": "1.2.3", }) c.Assert(inMap(attrs, "secret"), jc.IsTrue) c.Assert(inMap(attrs, "ca-private-key"), jc.IsTrue) c.Assert(inMap(attrs, "admin-secret"), jc.IsTrue) cfg, err := config.New(config.NoDefaults, attrs) c.Assert(err, gc.IsNil) c.Assert(err, gc.IsNil) cfg1, err := environs.BootstrapConfig(cfg) c.Assert(err, gc.IsNil) expect := cfg.AllAttrs() expect["admin-secret"] = "" expect["ca-private-key"] = "" c.Assert(cfg1.AllAttrs(), gc.DeepEquals, expect) }
func (e *environ) Bootstrap(ctx environs.BootstrapContext, args environs.BootstrapParams) error { selectedTools, err := common.EnsureBootstrapTools(ctx, e, config.PreferredSeries(e.Config()), args.Constraints.Arch) if err != nil { return err } defer delay() if err := e.checkBroken("Bootstrap"); err != nil { return err } password := e.Config().AdminSecret() if password == "" { return fmt.Errorf("admin-secret is required for bootstrap") } if _, ok := e.Config().CACert(); !ok { return fmt.Errorf("no CA certificate in environment configuration") } logger.Infof("would pick tools from %s", selectedTools) cfg, err := environs.BootstrapConfig(e.Config()) if err != nil { return fmt.Errorf("cannot make bootstrap config: %v", err) } estate, err := e.state() if err != nil { return err } estate.mu.Lock() defer estate.mu.Unlock() if estate.bootstrapped { return fmt.Errorf("environment is already bootstrapped") } // Write the bootstrap file just like a normal provider. However // we need to release the mutex for the save state to work, so regain // it after the call. estate.mu.Unlock() if err := bootstrap.SaveState(e.Storage(), &bootstrap.BootstrapState{StateInstances: []instance.Id{"localhost"}}); err != nil { logger.Errorf("failed to save state instances: %v", err) estate.mu.Lock() // otherwise defered unlock will fail return err } estate.mu.Lock() // back at it if e.ecfg().stateServer() { // TODO(rog) factor out relevant code from cmd/jujud/bootstrap.go // so that we can call it here. info := stateInfo() st, err := state.Initialize(info, cfg, state.DefaultDialOpts(), estate.statePolicy) if err != nil { panic(err) } if err := st.SetEnvironConstraints(args.Constraints); err != nil { panic(err) } if err := st.SetAdminMongoPassword(utils.UserPasswordHash(password, utils.CompatSalt)); err != nil { panic(err) } _, err = st.AddUser("admin", password) if err != nil { panic(err) } estate.apiServer, err = apiserver.NewServer(st, "localhost:0", []byte(testing.ServerCert), []byte(testing.ServerKey), DataDir, LogDir) if err != nil { panic(err) } estate.apiState = st } estate.bootstrapped = true estate.ops <- OpBootstrap{Context: ctx, Env: e.name, Args: args} return nil }