func (s *destroyEnvSuite) TestDestroyEnvironmentCommandConfirmation(c *gc.C) { var stdin, stdout bytes.Buffer ctx, err := cmd.DefaultContext() c.Assert(err, jc.ErrorIsNil) ctx.Stdout = &stdout ctx.Stdin = &stdin // Prepare the environment so we can destroy it. env, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) c.Assert(err, jc.ErrorIsNil) assertEnvironNotDestroyed(c, env, s.ConfigStore) // Ensure confirmation is requested if "-y" is not specified. stdin.WriteString("n") opc, errc := cmdtesting.RunCommand(ctx, newDestroyEnvironmentCommand(), "dummyenv") c.Check(<-errc, gc.ErrorMatches, "environment destruction aborted") c.Check(<-opc, gc.IsNil) c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*") assertEnvironNotDestroyed(c, env, s.ConfigStore) // EOF on stdin: equivalent to answering no. stdin.Reset() stdout.Reset() opc, errc = cmdtesting.RunCommand(ctx, newDestroyEnvironmentCommand(), "dummyenv") c.Check(<-opc, gc.IsNil) c.Check(<-errc, gc.ErrorMatches, "environment destruction aborted") assertEnvironNotDestroyed(c, env, s.ConfigStore) // "--yes" passed: no confirmation request. stdin.Reset() stdout.Reset() opc, errc = cmdtesting.RunCommand(ctx, newDestroyEnvironmentCommand(), "dummyenv", "--yes") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") c.Check(stdout.String(), gc.Equals, "") assertEnvironDestroyed(c, env, s.ConfigStore) // Any of casing of "y" and "yes" will confirm. for _, answer := range []string{"y", "Y", "yes", "YES"} { // Prepare the environment so we can destroy it. s.Reset(c) env, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) c.Assert(err, jc.ErrorIsNil) stdin.Reset() stdout.Reset() stdin.WriteString(answer) opc, errc = cmdtesting.RunCommand(ctx, newDestroyEnvironmentCommand(), "dummyenv") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*") assertEnvironDestroyed(c, env, s.ConfigStore) } }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandBroken(c *gc.C) { oldinfo, err := s.ConfigStore.ReadInfo("dummyenv") c.Assert(err, jc.ErrorIsNil) bootstrapConfig := oldinfo.BootstrapConfig() apiEndpoint := oldinfo.APIEndpoint() apiCredentials := oldinfo.APICredentials() err = oldinfo.Destroy() c.Assert(err, jc.ErrorIsNil) newinfo := s.ConfigStore.CreateInfo("dummyenv") bootstrapConfig["broken"] = "Destroy" newinfo.SetBootstrapConfig(bootstrapConfig) newinfo.SetAPIEndpoint(apiEndpoint) newinfo.SetAPICredentials(apiCredentials) err = newinfo.Write() c.Assert(err, jc.ErrorIsNil) // Prepare the environment so we can destroy it. _, err = environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) c.Assert(err, jc.ErrorIsNil) // destroy with broken environment opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummyenv", "--yes") op, ok := (<-opc).(dummy.OpDestroy) c.Assert(ok, jc.IsTrue) c.Assert(op.Error, gc.ErrorMatches, ".*dummy.Destroy is broken") c.Check(<-errc, gc.ErrorMatches, ".*dummy.Destroy is broken") c.Check(<-opc, gc.IsNil) }
// testingEnvConfig prepares an environment configuration using // the dummy provider. func testingEnvConfig(c *gc.C) *config.Config { cfg, err := config.New(config.NoDefaults, dummy.SampleConfig()) c.Assert(err, jc.ErrorIsNil) env, err := environs.Prepare(cfg, envcmd.BootstrapContext(testing.Context(c)), configstore.NewMem()) c.Assert(err, jc.ErrorIsNil) return env.Config() }
func nullContext() environs.BootstrapContext { ctx, _ := cmd.DefaultContext() ctx.Stdin = io.LimitReader(nil, 0) ctx.Stdout = ioutil.Discard ctx.Stderr = ioutil.Discard return envcmd.BootstrapContext(ctx) }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEFlag(c *gc.C) { // Prepare the environment so we can destroy it. _, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) c.Assert(err, jc.ErrorIsNil) // check that either environment or the flag is mandatory opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand()) c.Check(<-errc, gc.Equals, NoEnvironmentError) // We don't allow them to supply both entries at the same time opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "-e", "dummyenv", "dummyenv", "--yes") c.Check(<-errc, gc.Equals, DoubleEnvironmentError) // We treat --environment the same way opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "--environment", "dummyenv", "dummyenv", "--yes") c.Check(<-errc, gc.Equals, DoubleEnvironmentError) // destroy using the -e flag opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "-e", "dummyenv", "--yes") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") // Verify that the environment information has been removed. _, err = s.ConfigStore.ReadInfo("dummyenv") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func (s *BootstrapSuite) TestWaitSSHKilledWaitingForAddresses(c *gc.C) { ctx := coretesting.Context(c) interrupted := make(chan os.Signal, 1) interrupted <- os.Interrupt _, err := common.WaitSSH(envcmd.BootstrapContext(ctx), interrupted, ssh.DefaultClient, "/bin/true", neverAddresses{}, testSSHTimeout) c.Check(err, gc.ErrorMatches, "interrupted") c.Check(coretesting.Stderr(ctx), gc.Matches, "Waiting for address\n") }
func (s *BootstrapSuite) TestWaitSSHTimesOutWaitingForDial(c *gc.C) { ctx := coretesting.Context(c) // 0.x.y.z addresses are always invalid _, err := common.WaitSSH(envcmd.BootstrapContext(ctx), nil, ssh.DefaultClient, "/bin/true", &neverOpensPort{addr: "0.1.2.3"}, testSSHTimeout) c.Check(err, gc.ErrorMatches, `waited for `+testSSHTimeout.Timeout.String()+` without being able to connect: mock connection failure to 0.1.2.3`) c.Check(coretesting.Stderr(ctx), gc.Matches, "Waiting for address\n"+ "(Attempting to connect to 0.1.2.3:22\n)+") }
// resetJujuHome restores an new, clean Juju home environment without tools. func resetJujuHome(c *gc.C, envName string) environs.Environ { jenvDir := gitjujutesting.HomePath(".juju", "environments") err := os.RemoveAll(jenvDir) c.Assert(err, jc.ErrorIsNil) coretesting.WriteEnvironments(c, envConfig) dummy.Reset() store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) env, err := environs.PrepareFromName(envName, envcmd.BootstrapContext(cmdtesting.NullContext(c)), store) c.Assert(err, jc.ErrorIsNil) return env }
func (s *BootstrapSuite) TestWaitSSHKilledWaitingForDial(c *gc.C) { ctx := coretesting.Context(c) timeout := testSSHTimeout timeout.Timeout = 1 * time.Minute interrupted := make(chan os.Signal, 1) _, err := common.WaitSSH(envcmd.BootstrapContext(ctx), interrupted, ssh.DefaultClient, "", &interruptOnDial{name: "0.1.2.3", interrupted: interrupted}, timeout) c.Check(err, gc.ErrorMatches, "interrupted") // Exact timing is imprecise but it should have tried a few times before being killed c.Check(coretesting.Stderr(ctx), gc.Matches, "Waiting for address\n"+ "(Attempting to connect to 0.1.2.3:22\n)+") }
func (s *imageMetadataUpdateSuite) TestUpdateFromPublishedImages(c *gc.C) { saved := []cloudimagemetadata.Metadata{} expected := []cloudimagemetadata.Metadata{ cloudimagemetadata.Metadata{ cloudimagemetadata.MetadataAttributes{ RootStorageType: "ebs", VirtType: "pv", Arch: "amd64", Series: "trusty", Region: "nz-east-1", Source: "public", Stream: "released"}, "ami-36745463", }, cloudimagemetadata.Metadata{ cloudimagemetadata.MetadataAttributes{ RootStorageType: "ebs", VirtType: "pv", Arch: "amd64", Series: "precise", Region: "au-east-2", Source: "public", Stream: "released"}, "ami-26745463", }, } // testingEnvConfig prepares an environment configuration using // the dummy provider. s.state.environConfig = func() (*config.Config, error) { s.calls = append(s.calls, environConfig) cfg, err := config.New(config.NoDefaults, dummy.SampleConfig()) c.Assert(err, jc.ErrorIsNil) env, err := environs.Prepare(cfg, envcmd.BootstrapContext(testing.Context(c)), configstore.NewMem()) c.Assert(err, jc.ErrorIsNil) return env.Config(), err } s.state.saveMetadata = func(m cloudimagemetadata.Metadata) error { s.calls = append(s.calls, saveMetadata) saved = append(saved, m) return nil } err := s.api.UpdateFromPublishedImages() c.Assert(err, jc.ErrorIsNil) s.assertCalls(c, []string{environConfig, saveMetadata, saveMetadata}) c.Assert(saved, jc.SameContents, expected) }
func (s *BootstrapSuite) TestBootstrapJenvWarning(c *gc.C) { const envName = "devenv" s.patchVersionAndSeries(c, envName) store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) ctx := coretesting.Context(c) environs.PrepareFromName(envName, envcmd.BootstrapContext(ctx), store) logger := "jenv.warning.test" var testWriter loggo.TestWriter loggo.RegisterWriter(logger, &testWriter, loggo.WARNING) defer loggo.RemoveWriter(logger) _, errc := cmdtesting.RunCommand(ctx, newBootstrapCommand(), "-e", envName, "--auto-upgrade") c.Assert(<-errc, gc.IsNil) c.Assert(testWriter.Log(), jc.LogMatches, []string{"ignoring environments.yaml: using bootstrap config in .*"}) }
func (s *destroyEnvSuite) TestDestroyEnvironmentCommand(c *gc.C) { // Prepare the environment so we can destroy it. _, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) c.Assert(err, jc.ErrorIsNil) // check environment is mandatory opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand()) c.Check(<-errc, gc.Equals, NoEnvironmentError) // normal destroy opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummyenv", "--yes") c.Check(<-errc, gc.IsNil) c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv") // Verify that the environment information has been removed. _, err = s.ConfigStore.ReadInfo("dummyenv") c.Assert(err, jc.Satisfies, errors.IsNotFound) }
func environFromNameProductionFunc( ctx *cmd.Context, envName string, action string, ensureNotBootstrapped func(environs.Environ) error, ) (env environs.Environ, cleanup func(), err error) { store, err := configstore.Default() if err != nil { return nil, nil, err } envExisted := false if environInfo, err := store.ReadInfo(envName); err == nil { envExisted = true logger.Warningf( "ignoring environments.yaml: using bootstrap config in %s", environInfo.Location(), ) } else if !errors.IsNotFound(err) { return nil, nil, err } cleanup = func() { // Distinguish b/t removing the jenv file or tearing down the // environment. We want to remove the jenv file if preparation // was not successful. We want to tear down the environment // only in the case where the environment didn't already // exist. if env == nil { logger.Debugf("Destroying environment info.") destroyEnvInfo(ctx, envName, store, action) } else if !envExisted && ensureNotBootstrapped(env) != environs.ErrAlreadyBootstrapped { logger.Debugf("Destroying environment.") destroyPreparedEnviron(ctx, env, store, action) } } if env, err = environs.PrepareFromName(envName, envcmd.BootstrapContext(ctx), store); err != nil { return nil, cleanup, err } return env, cleanup, err }
// rebootstrap will bootstrap a new server in safe-mode (not killing any other agent) // if there is no current server available to restore to. func (c *restoreCommand) rebootstrap(ctx *cmd.Context) error { store, err := configstore.Default() if err != nil { return errors.Trace(err) } cfg, err := c.Config(store, nil) if err != nil { return errors.Trace(err) } // Turn on safe mode so that the newly bootstrapped instance // will not destroy all the instances it does not know about. cfg, err = cfg.Apply(map[string]interface{}{ "provisioner-safe-mode": true, }) if err != nil { return errors.Annotatef(err, "cannot enable provisioner-safe-mode") } env, err := environs.New(cfg) if err != nil { return errors.Trace(err) } instanceIds, err := env.StateServerInstances() if err != nil { return errors.Annotatef(err, "cannot determine state server instances") } if len(instanceIds) == 0 { return errors.Errorf("no instances found; perhaps the environment was not bootstrapped") } inst, err := env.Instances(instanceIds) if err == nil { return errors.Errorf("old bootstrap instance %q still seems to exist; will not replace", inst) } if err != environs.ErrNoInstances { return errors.Annotatef(err, "cannot detect whether old instance is still running") } cons := c.constraints args := bootstrap.BootstrapParams{Constraints: cons} if err := bootstrap.Bootstrap(envcmd.BootstrapContext(ctx), env, args); err != nil { return errors.Annotatef(err, "cannot bootstrap new instance") } return nil }
func (s *BootstrapSuite) TestWaitSSHRefreshAddresses(c *gc.C) { ctx := coretesting.Context(c) _, err := common.WaitSSH(envcmd.BootstrapContext(ctx), nil, ssh.DefaultClient, "", &addressesChange{addrs: [][]string{ nil, nil, {"0.1.2.3"}, {"0.1.2.3"}, nil, {"0.1.2.4"}, }}, testSSHTimeout) // Not necessarily the last one in the list, due to scheduling. c.Check(err, gc.ErrorMatches, `waited for `+testSSHTimeout.Timeout.String()+` without being able to connect: mock connection failure to 0.1.2.[34]`) stderr := coretesting.Stderr(ctx) c.Check(stderr, gc.Matches, "Waiting for address\n"+ "(.|\n)*(Attempting to connect to 0.1.2.3:22\n)+(.|\n)*") c.Check(stderr, gc.Matches, "Waiting for address\n"+ "(.|\n)*(Attempting to connect to 0.1.2.4:22\n)+(.|\n)*") }
func (s *BootstrapSuite) TestBootstrapJenvWarning(c *gc.C) { env := resetJujuHome(c, "devenv") defaultSeriesVersion := version.Current defaultSeriesVersion.Series = config.PreferredSeries(env.Config()) // Force a dev version by having a non zero build number. // This is because we have not uploaded any tools and auto // upload is only enabled for dev versions. defaultSeriesVersion.Build = 1234 s.PatchValue(&version.Current, defaultSeriesVersion) store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) ctx := coretesting.Context(c) environs.PrepareFromName("devenv", envcmd.BootstrapContext(ctx), store) logger := "jenv.warning.test" var testWriter loggo.TestWriter loggo.RegisterWriter(logger, &testWriter, loggo.WARNING) defer loggo.RemoveWriter(logger) _, errc := cmdtesting.RunCommand(ctx, envcmd.Wrap(new(BootstrapCommand)), "-e", "devenv") c.Assert(<-errc, gc.IsNil) c.Assert(testWriter.Log(), jc.LogMatches, []string{"ignoring environments.yaml: using bootstrap config in .*"}) }
func (s *imageMetadataUpdateSuite) TestUpdateFromPublishedImagesForProviderWithNoRegions(c *gc.C) { // This will save all available image metadata. saved := []cloudimagemetadata.Metadata{} // testingEnvConfig prepares an environment configuration using // the dummy provider since it doesn't implement simplestreams.HasRegion. s.state.environConfig = func() (*config.Config, error) { cfg, err := config.New(config.NoDefaults, dummy.SampleConfig()) c.Assert(err, jc.ErrorIsNil) env, err := environs.Prepare(cfg, envcmd.BootstrapContext(testing.Context(c)), configstore.NewMem()) c.Assert(err, jc.ErrorIsNil) return env.Config(), err } s.state.saveMetadata = func(m []cloudimagemetadata.Metadata) error { saved = append(saved, m...) return nil } err := s.api.UpdateFromPublishedImages() c.Assert(err, jc.ErrorIsNil) s.assertCalls(c, environConfig) c.Assert(saved, jc.SameContents, []cloudimagemetadata.Metadata{}) }
// BootstrapContext creates a simple bootstrap execution context. func BootstrapContext(c *gc.C) environs.BootstrapContext { return envcmd.BootstrapContext(coretesting.Context(c)) }
// Run connects to the environment specified on the command line and bootstraps // a juju in that environment if none already exists. If there is as yet no environments.yaml file, // the user is informed how to create one. func (c *BootstrapCommand) Run(ctx *cmd.Context) (resultErr error) { bootstrapFuncs := getBootstrapFuncs() if len(c.seriesOld) > 0 { fmt.Fprintln(ctx.Stderr, "Use of --series is obsolete. --upload-tools now expands to all supported series of the same operating system.") } if len(c.Series) > 0 { fmt.Fprintln(ctx.Stderr, "Use of --upload-series is obsolete. --upload-tools now expands to all supported series of the same operating system.") } envName := getEnvName(c) if envName == "" { return errors.Errorf("the name of the environment must be specified") } if err := checkProviderType(envName); errors.IsNotFound(err) { // This error will get handled later. } else if err != nil { return errors.Trace(err) } environ, cleanup, err := environFromName( ctx, envName, "Bootstrap", bootstrapFuncs.EnsureNotBootstrapped, ) // If we error out for any reason, clean up the environment. defer func() { if resultErr != nil && cleanup != nil { if c.KeepBrokenEnvironment { logger.Warningf("bootstrap failed but --keep-broken was specified so environment is not being destroyed.\n" + "When you are finished diagnosing the problem, remember to run juju destroy-environment --force\n" + "to clean up the environment.") } else { handleBootstrapError(ctx, resultErr, cleanup) } } }() // Handle any errors from environFromName(...). if err != nil { return errors.Annotatef(err, "there was an issue examining the environment") } // Check to see if this environment is already bootstrapped. If it // is, we inform the user and exit early. If an error is returned // but it is not that the environment is already bootstrapped, // then we're in an unknown state. if err := bootstrapFuncs.EnsureNotBootstrapped(environ); nil != err { if environs.ErrAlreadyBootstrapped == err { logger.Warningf("This juju environment is already bootstrapped. If you want to start a new Juju\nenvironment, first run juju destroy-environment to clean up, or switch to an\nalternative environment.") return err } return errors.Annotatef(err, "cannot determine if environment is already bootstrapped.") } // Block interruption during bootstrap. Providers may also // register for interrupt notification so they can exit early. interrupted := make(chan os.Signal, 1) defer close(interrupted) ctx.InterruptNotify(interrupted) defer ctx.StopInterruptNotify(interrupted) go func() { for _ = range interrupted { ctx.Infof("Interrupt signalled: waiting for bootstrap to exit") } }() // If --metadata-source is specified, override the default tools metadata source so // SyncTools can use it, and also upload any image metadata. var metadataDir string if c.MetadataSource != "" { metadataDir = ctx.AbsPath(c.MetadataSource) } // TODO (wallyworld): 2013-09-20 bug 1227931 // We can set a custom tools data source instead of doing an // unnecessary upload. if environ.Config().Type() == provider.Local { c.UploadTools = true } err = bootstrapFuncs.Bootstrap(envcmd.BootstrapContext(ctx), environ, bootstrap.BootstrapParams{ Constraints: c.Constraints, Placement: c.Placement, UploadTools: c.UploadTools, AgentVersion: c.AgentVersion, MetadataDir: metadataDir, }) if err != nil { return errors.Annotate(err, "failed to bootstrap environment") } err = c.SetBootstrapEndpointAddress(environ) if err != nil { return errors.Annotate(err, "saving bootstrap endpoint address") } // To avoid race conditions when running scripted bootstraps, wait // for the state server's machine agent to be ready to accept commands // before exiting this bootstrap command. return c.waitForAgentInitialisation(ctx) }
// startEnvironment prepare the environment so we can destroy it. func (s *destroyEnvSuite) startEnvironment(c *gc.C, desiredEnvName string) { _, err := environs.PrepareFromName(desiredEnvName, envcmd.BootstrapContext(cmdtesting.NullContext(c)), s.ConfigStore) c.Assert(err, jc.ErrorIsNil) }
func (s *JujuConnSuite) setUpConn(c *gc.C) { if s.RootDir != "" { panic("JujuConnSuite.setUpConn without teardown") } s.RootDir = c.MkDir() s.oldHome = utils.Home() home := filepath.Join(s.RootDir, "/home/ubuntu") err := os.MkdirAll(home, 0777) c.Assert(err, jc.ErrorIsNil) utils.SetHome(home) s.oldJujuHome = osenv.SetJujuHome(filepath.Join(home, ".juju")) err = os.Mkdir(osenv.JujuHome(), 0777) c.Assert(err, jc.ErrorIsNil) err = os.MkdirAll(s.DataDir(), 0777) c.Assert(err, jc.ErrorIsNil) s.PatchEnvironment(osenv.JujuEnvEnvKey, "") // TODO(rog) remove these files and add them only when // the tests specifically need them (in cmd/juju for example) s.writeSampleConfig(c, osenv.JujuHomePath("environments.yaml")) err = ioutil.WriteFile(osenv.JujuHomePath("dummyenv-cert.pem"), []byte(testing.CACert), 0666) c.Assert(err, jc.ErrorIsNil) err = ioutil.WriteFile(osenv.JujuHomePath("dummyenv-private-key.pem"), []byte(testing.CAKey), 0600) c.Assert(err, jc.ErrorIsNil) store, err := configstore.Default() c.Assert(err, jc.ErrorIsNil) s.ConfigStore = store ctx := testing.Context(c) environ, err := environs.PrepareFromName("dummyenv", envcmd.BootstrapContext(ctx), s.ConfigStore) c.Assert(err, jc.ErrorIsNil) // sanity check we've got the correct environment. c.Assert(environ.Config().Name(), gc.Equals, "dummyenv") s.PatchValue(&dummy.DataDir, s.DataDir()) s.LogDir = c.MkDir() s.PatchValue(&dummy.LogDir, s.LogDir) versions := PreferredDefaultVersions(environ.Config(), version.Binary{Number: version.Current.Number, Series: "precise", Arch: "amd64"}) versions = append(versions, version.Current) // Upload tools for both preferred and fake default series s.DefaultToolsStorageDir = c.MkDir() s.PatchValue(&tools.DefaultBaseURL, s.DefaultToolsStorageDir) stor, err := filestorage.NewFileStorageWriter(s.DefaultToolsStorageDir) c.Assert(err, jc.ErrorIsNil) // Upload tools to both release and devel streams since config will dictate that we // end up looking in both places. envtesting.AssertUploadFakeToolsVersions(c, stor, "released", "released", versions...) envtesting.AssertUploadFakeToolsVersions(c, stor, "devel", "devel", versions...) s.DefaultToolsStorage = stor err = bootstrap.Bootstrap(envcmd.BootstrapContext(ctx), environ, bootstrap.BootstrapParams{}) c.Assert(err, jc.ErrorIsNil) s.BackingState = environ.(GetStater).GetStateInAPIServer() s.State, err = newState(environ, s.BackingState.MongoConnectionInfo()) c.Assert(err, jc.ErrorIsNil) s.APIState, err = juju.NewAPIState(s.AdminUserTag(c), environ, api.DialOpts{}) c.Assert(err, jc.ErrorIsNil) err = s.State.SetAPIHostPorts(s.APIState.APIHostPorts()) c.Assert(err, jc.ErrorIsNil) // Make sure the config store has the api endpoint address set info, err := s.ConfigStore.ReadInfo("dummyenv") c.Assert(err, jc.ErrorIsNil) endpoint := info.APIEndpoint() endpoint.Addresses = []string{s.APIState.APIHostPorts()[0][0].String()} info.SetAPIEndpoint(endpoint) err = info.Write() c.Assert(err, jc.ErrorIsNil) // Make sure the jenv file has the local host ports. c.Logf("jenv host ports: %#v", s.APIState.APIHostPorts()) s.Environ = environ // Insert expected values... servingInfo := state.StateServingInfo{ PrivateKey: testing.ServerKey, Cert: testing.ServerCert, CAPrivateKey: testing.CAKey, SharedSecret: "really, really secret", APIPort: 4321, StatePort: 1234, } s.State.SetStateServingInfo(servingInfo) }
func (s *EnvironmentCommandSuite) TestBootstrapContext(c *gc.C) { ctx := envcmd.BootstrapContext(&cmd.Context{}) c.Assert(ctx.ShouldVerifyCredentials(), jc.IsTrue) }
func (s *BootstrapSuite) TestWaitSSHTimesOutWaitingForAddresses(c *gc.C) { ctx := coretesting.Context(c) _, err := common.WaitSSH(envcmd.BootstrapContext(ctx), nil, ssh.DefaultClient, "/bin/true", neverAddresses{}, testSSHTimeout) c.Check(err, gc.ErrorMatches, `waited for `+testSSHTimeout.Timeout.String()+` without getting any addresses`) c.Check(coretesting.Stderr(ctx), gc.Matches, "Waiting for address\n") }
func (s *BootstrapSuite) TestWaitSSHStopsOnBadError(c *gc.C) { ctx := coretesting.Context(c) _, err := common.WaitSSH(envcmd.BootstrapContext(ctx), nil, ssh.DefaultClient, "/bin/true", brokenAddresses{}, testSSHTimeout) c.Check(err, gc.ErrorMatches, "getting addresses: Addresses will never work") c.Check(coretesting.Stderr(ctx), gc.Equals, "Waiting for address\n") }