Ejemplo n.º 1
0
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandBroken(c *gc.C) {
	oldinfo, err := s.ConfigStore.ReadInfo("dummyenv")
	c.Assert(err, gc.IsNil)
	bootstrapConfig := oldinfo.BootstrapConfig()
	apiEndpoint := oldinfo.APIEndpoint()
	apiCredentials := oldinfo.APICredentials()
	err = oldinfo.Destroy()
	c.Assert(err, gc.IsNil)
	newinfo := s.ConfigStore.CreateInfo("dummyenv")

	bootstrapConfig["broken"] = "Destroy"
	newinfo.SetBootstrapConfig(bootstrapConfig)
	newinfo.SetAPIEndpoint(apiEndpoint)
	newinfo.SetAPICredentials(apiCredentials)
	err = newinfo.Write()
	c.Assert(err, gc.IsNil)

	// Prepare the environment so we can destroy it.
	_, err = environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore)
	c.Assert(err, gc.IsNil)

	// destroy with broken environment
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "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.Equals, op.Error)
	c.Check(<-opc, gc.IsNil)
}
Ejemplo n.º 2
0
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEFlag(c *gc.C) {
	// Prepare the environment so we can destroy it.
	_, err := environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore)
	c.Assert(err, gc.IsNil)

	// check that either environment or the flag is mandatory
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand))
	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), new(DestroyEnvironmentCommand), "-e", "dummyenv", "dummyenv", "--yes")
	c.Check(<-errc, gc.Equals, DoubleEnvironmentError)
	// We treat --environment the same way
	opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "--environment", "dummyenv", "dummyenv", "--yes")
	c.Check(<-errc, gc.Equals, DoubleEnvironmentError)

	// destroy using the -e flag
	opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "-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)
}
Ejemplo n.º 3
0
func (s *destroyEnvSuite) checkDestroyEnvironment(c *gc.C, blocked, force bool) {
	//Setup environment
	envName := "dummyenv"
	s.startEnvironment(c, envName)
	if blocked {
		s.BlockDestroyEnvironment(c, "checkDestroyEnvironment")
	}
	opc := make(chan dummy.Operation)
	errc := make(chan error)
	if force {
		opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), envName, "--yes", "--force")
	} else {
		opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), envName, "--yes")
	}
	if force || !blocked {
		c.Check(<-errc, gc.IsNil)
		c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, envName)
		// Verify that the environment information has been removed.
		_, err := s.ConfigStore.ReadInfo(envName)
		c.Assert(err, jc.Satisfies, errors.IsNotFound)
	} else {
		c.Check(<-errc, gc.Not(gc.IsNil))
		c.Check((<-opc), gc.IsNil)
		// Verify that the environment information has not been removed.
		_, err := s.ConfigStore.ReadInfo(envName)
		c.Assert(err, jc.ErrorIsNil)
	}
}
Ejemplo n.º 4
0
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandConfirmation(c *gc.C) {
	var stdin, stdout bytes.Buffer
	ctx, err := cmd.DefaultContext()
	c.Assert(err, gc.IsNil)
	ctx.Stdout = &stdout
	ctx.Stdin = &stdin

	// Prepare the environment so we can destroy it.
	env, err := environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore)
	c.Assert(err, gc.IsNil)

	assertEnvironNotDestroyed(c, env, s.ConfigStore)

	// Ensure confirmation is requested if "-y" is not specified.
	stdin.WriteString("n")
	opc, errc := cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "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, new(DestroyEnvironmentCommand), "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, new(DestroyEnvironmentCommand), "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", cmdtesting.NullContext(c), s.ConfigStore)
		c.Assert(err, gc.IsNil)

		stdin.Reset()
		stdout.Reset()
		stdin.WriteString(answer)
		opc, errc = cmdtesting.RunCommand(ctx, new(DestroyEnvironmentCommand), "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)
	}
}
Ejemplo n.º 5
0
func (s *BootstrapSuite) TestBootstrapDestroy(c *gc.C) {
	resetJujuXDGDataHome(c)
	s.patchVersion(c)

	opc, errc := cmdtesting.RunCommand(
		cmdtesting.NullContext(c), s.newBootstrapCommand(),
		"devcontroller", "dummy-cloud/region-1",
		"--config", "broken=Bootstrap Destroy",
		"--auto-upgrade",
	)
	err := <-errc
	c.Assert(err, gc.ErrorMatches, "failed to bootstrap model: dummy.Bootstrap is broken")
	var opDestroy *dummy.OpDestroy
	for opDestroy == nil {
		select {
		case op := <-opc:
			switch op := op.(type) {
			case dummy.OpDestroy:
				opDestroy = &op
			}
		default:
			c.Error("expected call to env.Destroy")
			return
		}
	}
	c.Assert(opDestroy.Error, gc.ErrorMatches, "dummy.Destroy is broken")
}
Ejemplo n.º 6
0
func (s *BootstrapSuite) TestAutoUploadOnlyForDev(c *gc.C) {
	s.setupAutoUploadTest(c, "1.8.3", "precise")
	_, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)))
	err := <-errc
	c.Assert(err, gc.ErrorMatches,
		"failed to bootstrap environment: Juju cannot bootstrap because no tools are available for your environment(.|\n)*")
}
Ejemplo n.º 7
0
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandTwiceOnNonStateServer(c *gc.C) {
	s.setupHostedEnviron(c, "dummy-non-state-server")
	oldInfo, err := s.ConfigStore.ReadInfo("dummy-non-state-server")
	c.Assert(err, jc.ErrorIsNil)

	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummy-non-state-server", "--yes")
	c.Check(<-errc, gc.IsNil)
	c.Check(<-opc, gc.IsNil)

	_, err = s.ConfigStore.ReadInfo("dummy-non-state-server")
	c.Assert(err, jc.Satisfies, errors.IsNotFound)

	// Simluate another client calling destroy on the same environment. This
	// client will have a local cache of the environ info, so write it back out.
	info := s.ConfigStore.CreateInfo("dummy-non-state-server")
	info.SetAPIEndpoint(oldInfo.APIEndpoint())
	info.SetAPICredentials(oldInfo.APICredentials())
	err = info.Write()
	c.Assert(err, jc.ErrorIsNil)

	// Call destroy again.
	context, err := coretesting.RunCommand(c, newDestroyEnvironmentCommand(), "dummy-non-state-server", "--yes")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(coretesting.Stderr(context), gc.Equals, "environment not found, removing config file\n")

	// Check that the client's cached info has been removed.
	_, err = s.ConfigStore.ReadInfo("dummy-non-state-server")
	c.Assert(err, jc.Satisfies, errors.IsNotFound)
}
Ejemplo n.º 8
0
func (s *BootstrapSuite) TestBootstrapKeepBroken(c *gc.C) {
	resetJujuHome(c, "devenv")
	s.patchVersion(c)

	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newBootstrapCommand(), "-e", "brokenenv", "--keep-broken", "--auto-upgrade")
	err := <-errc
	c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: dummy.Bootstrap is broken")
	done := false
	for !done {
		select {
		case op, ok := <-opc:
			if !ok {
				done = true
				break
			}
			switch op.(type) {
			case dummy.OpDestroy:
				c.Error("unexpected call to env.Destroy")
				break
			}
		default:
			break
		}
	}
}
Ejemplo n.º 9
0
func (s *BootstrapSuite) TestBootstrapKeepBroken(c *gc.C) {
	resetJujuXDGDataHome(c)
	s.patchVersion(c)

	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), s.newBootstrapCommand(),
		"--keep-broken",
		"devcontroller", "dummy-cloud/region-1",
		"--config", "broken=Bootstrap Destroy",
		"--auto-upgrade",
	)
	err := <-errc
	c.Assert(err, gc.ErrorMatches, "failed to bootstrap model: dummy.Bootstrap is broken")
	done := false
	for !done {
		select {
		case op, ok := <-opc:
			if !ok {
				done = true
				break
			}
			switch op.(type) {
			case dummy.OpDestroy:
				c.Error("unexpected call to env.Destroy")
				break
			}
		default:
			break
		}
	}
}
Ejemplo n.º 10
0
func (s *BootstrapSuite) TestBootstrapKeepBroken(c *gc.C) {
	resetJujuHome(c, "devenv")
	devVersion := version.Current
	// 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.
	devVersion.Build = 1234
	s.PatchValue(&version.Current, devVersion)
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), "-e", "brokenenv", "--keep-broken")
	err := <-errc
	c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: dummy.Bootstrap is broken")
	done := false
	for !done {
		select {
		case op, ok := <-opc:
			if !ok {
				done = true
				break
			}
			switch op.(type) {
			case dummy.OpDestroy:
				c.Error("unexpected call to env.Destroy")
				break
			}
		default:
			break
		}
	}
}
Ejemplo n.º 11
0
func (s *BootstrapSuite) TestBootstrapDestroy(c *gc.C) {
	resetJujuHome(c, "devenv")
	devVersion := version.Current
	// 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.
	devVersion.Build = 1234
	s.PatchValue(&version.Current, devVersion)
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), "-e", "brokenenv")
	err := <-errc
	c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: dummy.Bootstrap is broken")
	var opDestroy *dummy.OpDestroy
	for opDestroy == nil {
		select {
		case op := <-opc:
			switch op := op.(type) {
			case dummy.OpDestroy:
				opDestroy = &op
			}
		default:
			c.Error("expected call to env.Destroy")
			return
		}
	}
	c.Assert(opDestroy.Error, gc.ErrorMatches, "dummy.Destroy is broken")
}
Ejemplo n.º 12
0
func (s *controllerSuite) TestWaitForAgentAPIReadyWaitsForSpaceDiscovery(c *gc.C) {
	s.mockBlockClient.discoveringSpacesError = 2
	cmd := &modelcmd.ModelCommandBase{}
	cmd.SetClientStore(jujuclienttesting.NewMemStore())
	err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(s.mockBlockClient.discoveringSpacesError, gc.Equals, 0)
}
Ejemplo n.º 13
0
func (s *destroyEnvSuite) TestDestroyEnvironmentCommand(c *gc.C) {
	// Prepare the environment so we can destroy it.
	_, err := environs.PrepareFromName("dummyenv", cmdtesting.NullContext(c), s.ConfigStore)
	c.Assert(err, gc.IsNil)

	// check environment is mandatory
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand))
	c.Check(<-errc, gc.Equals, NoEnvironmentError)

	// normal destroy
	opc, errc = cmdtesting.RunCommand(cmdtesting.NullContext(c), new(DestroyEnvironmentCommand), "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)
}
Ejemplo n.º 14
0
func (s *controllerSuite) TestWaitForAgentAPIReadyRetriesWithOpenEOFErr(c *gc.C) {
	s.mockBlockClient.numRetries = 0
	s.mockBlockClient.retryCount = 0
	s.mockBlockClient.loginError = io.EOF
	err := WaitForAgentInitialisation(cmdtesting.NullContext(c), nil, "controller")
	c.Check(err, jc.ErrorIsNil)

	c.Check(s.mockBlockClient.retryCount, gc.Equals, 1)
}
Ejemplo n.º 15
0
func (s *controllerSuite) TestWaitForAgentAPIReadyStopsRetriesWithOpenErr(c *gc.C) {
	s.mockBlockClient.numRetries = 0
	s.mockBlockClient.retryCount = 0
	s.mockBlockClient.loginError = errors.NewUnauthorized(nil, "")
	err := WaitForAgentInitialisation(cmdtesting.NullContext(c), nil, "controller")
	c.Check(err, jc.Satisfies, errors.IsUnauthorized)

	c.Check(s.mockBlockClient.retryCount, gc.Equals, 0)
}
Ejemplo n.º 16
0
func (s *BootstrapSuite) TestAutoUploadOnlyForDev(c *gc.C) {
	s.setupAutoUploadTest(c, "1.8.3", "precise")
	_, errc := cmdtesting.RunCommand(
		cmdtesting.NullContext(c), s.newBootstrapCommand(),
		"devcontroller", "dummy-cloud/region-1",
	)
	err := <-errc
	c.Assert(err, gc.ErrorMatches,
		"failed to bootstrap model: Juju cannot bootstrap because no tools are available for your model(.|\n)*")
}
Ejemplo n.º 17
0
func (s *destroyEnvSuite) TestForceDestroyEnvironmentCommandOnNonStateServerNoConfimFails(c *gc.C) {
	s.setupHostedEnviron(c, "dummy-non-state-server")
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummy-non-state-server", "--force")
	c.Check(<-errc, gc.ErrorMatches, "cannot force destroy environment without bootstrap information")
	c.Check(<-opc, gc.IsNil)

	serverInfo, err := s.ConfigStore.ReadInfo("dummy-non-state-server")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(serverInfo, gc.Not(gc.IsNil))
}
Ejemplo n.º 18
0
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandNonStateServer(c *gc.C) {
	s.setupHostedEnviron(c, "dummy-non-state-server")
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummy-non-state-server", "--yes")
	c.Check(<-errc, gc.IsNil)
	// Check that there are no operations on the provider, we do not want to call
	// Destroy on it.
	c.Check(<-opc, gc.IsNil)

	_, err := s.ConfigStore.ReadInfo("dummy-non-state-server")
	c.Assert(err, jc.Satisfies, errors.IsNotFound)
}
Ejemplo n.º 19
0
func (s *controllerSuite) TestWaitForAgentAPIReadyRetriesWithOpenEOFErr(c *gc.C) {
	s.mockBlockClient.numRetries = 0
	s.mockBlockClient.retryCount = 0
	s.mockBlockClient.loginError = io.EOF
	cmd := &modelcmd.ModelCommandBase{}
	cmd.SetClientStore(jujuclienttesting.NewMemStore())
	err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default")
	c.Check(err, jc.ErrorIsNil)

	c.Check(s.mockBlockClient.retryCount, gc.Equals, 1)
}
Ejemplo n.º 20
0
func (s *controllerSuite) TestWaitForAgentAPIReadyStopsRetriesWithOpenErr(c *gc.C) {
	s.mockBlockClient.numRetries = 0
	s.mockBlockClient.retryCount = 0
	s.mockBlockClient.loginError = errors.NewUnauthorized(nil, "")
	cmd := &modelcmd.ModelCommandBase{}
	cmd.SetClientStore(jujuclienttesting.NewMemStore())
	err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default")
	c.Check(err, jc.Satisfies, errors.IsUnauthorized)

	c.Check(s.mockBlockClient.retryCount, gc.Equals, 0)
}
Ejemplo n.º 21
0
// 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
}
Ejemplo n.º 22
0
func (s *BootstrapSuite) TestAutoUploadAfterFailedSync(c *gc.C) {
	s.PatchValue(&version.Current.Series, config.LatestLtsSeries())
	s.setupAutoUploadTest(c, "1.7.3", "quantal")
	// Run command and check for that upload has been run for tools matching
	// the current juju version.
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), "-e", "devenv")
	c.Assert(<-errc, gc.IsNil)
	c.Check((<-opc).(dummy.OpBootstrap).Env, gc.Equals, "devenv")
	icfg := (<-opc).(dummy.OpFinalizeBootstrap).InstanceConfig
	c.Assert(icfg, gc.NotNil)
	c.Assert(icfg.Tools.Version.String(), gc.Equals, "1.7.3.1-raring-"+arch.HostArch())
}
Ejemplo n.º 23
0
// resetJujuHome restores an new, clean Juju home environment without tools.
func resetJujuHome(c *gc.C) environs.Environ {
	jenvDir := gitjujutesting.HomePath(".juju", "environments")
	err := os.RemoveAll(jenvDir)
	c.Assert(err, gc.IsNil)
	coretesting.WriteEnvironments(c, envConfig)
	dummy.Reset()
	store, err := configstore.Default()
	c.Assert(err, gc.IsNil)
	env, err := environs.PrepareFromName("peckham", cmdtesting.NullContext(c), store)
	c.Assert(err, gc.IsNil)
	envtesting.RemoveAllTools(c, env)
	return env
}
Ejemplo n.º 24
0
func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEmptyJenv(c *gc.C) {
	oldinfo, err := s.ConfigStore.ReadInfo("dummyenv")
	info := s.ConfigStore.CreateInfo("dummy-no-bootstrap")
	info.SetAPICredentials(oldinfo.APICredentials())
	info.SetAPIEndpoint(oldinfo.APIEndpoint())
	err = info.Write()
	c.Assert(err, jc.ErrorIsNil)

	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newDestroyEnvironmentCommand(), "dummy-no-bootstrap", "--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)
}
Ejemplo n.º 25
0
func (s *BootstrapSuite) TestAutoUploadAfterFailedSync(c *gc.C) {
	s.PatchValue(&series.HostSeries, func() string { return series.LatestLts() })
	s.setupAutoUploadTest(c, "1.7.3", "quantal")
	// Run command and check for that upload has been run for tools matching
	// the current juju version.
	opc, errc := cmdtesting.RunCommand(
		cmdtesting.NullContext(c), s.newBootstrapCommand(),
		"devcontroller", "dummy-cloud/region-1",
		"--config", "default-series=raring",
		"--auto-upgrade",
	)
	c.Assert(<-errc, gc.IsNil)
	c.Check((<-opc).(dummy.OpBootstrap).Env, gc.Equals, "admin")
	icfg := (<-opc).(dummy.OpFinalizeBootstrap).InstanceConfig
	c.Assert(icfg, gc.NotNil)
	c.Assert(icfg.AgentVersion().String(), gc.Equals, "1.7.3.1-raring-"+arch.HostArch())
}
Ejemplo n.º 26
0
func (s *BootstrapSuite) TestBootstrapDestroy(c *gc.C) {
	resetJujuHome(c, "devenv")
	s.patchVersion(c)

	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), newBootstrapCommand(), "-e", "brokenenv", "--auto-upgrade")
	err := <-errc
	c.Assert(err, gc.ErrorMatches, "failed to bootstrap environment: dummy.Bootstrap is broken")
	var opDestroy *dummy.OpDestroy
	for opDestroy == nil {
		select {
		case op := <-opc:
			switch op := op.(type) {
			case dummy.OpDestroy:
				opDestroy = &op
			}
		default:
			c.Error("expected call to env.Destroy")
			return
		}
	}
	c.Assert(opDestroy.Error, gc.ErrorMatches, "dummy.Destroy is broken")
}
Ejemplo n.º 27
0
func (s *controllerSuite) TestWaitForAgentAPIReadyRetries(c *gc.C) {
	s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond)
	s.PatchValue(&bootstrapReadyPollCount, 5)
	defaultSeriesVersion := version.Current
	// 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)
	for _, t := range []struct {
		numRetries int
		err        error
	}{
		{0, nil}, // agent ready immediately
		{2, nil}, // agent ready after 2 polls
		{6, &rpc.RequestError{
			Message: params.CodeUpgradeInProgress,
			Code:    params.CodeUpgradeInProgress,
		}}, // agent ready after 6 polls but that's too long
		{-1, errOther}, // another error is returned
	} {
		s.mockBlockClient.numRetries = t.numRetries
		s.mockBlockClient.retryCount = 0
		cmd := &modelcmd.ModelCommandBase{}
		cmd.SetClientStore(jujuclienttesting.NewMemStore())
		err := WaitForAgentInitialisation(cmdtesting.NullContext(c), cmd, "controller", "default")
		c.Check(errors.Cause(err), gc.DeepEquals, t.err)
		expectedRetries := t.numRetries
		if t.numRetries <= 0 {
			expectedRetries = 1
		}
		// Only retry maximum of bootstrapReadyPollCount times.
		if expectedRetries > 5 {
			expectedRetries = 5
		}
		c.Check(s.mockBlockClient.retryCount, gc.Equals, expectedRetries)
	}
}
Ejemplo n.º 28
0
func (test bootstrapTest) run(c *gc.C) {
	// Create home with dummy provider and remove all
	// of its envtools.
	env := resetJujuHome(c)

	if test.version != "" {
		useVersion := strings.Replace(test.version, "%LTS%", config.LatestLtsSeries(), 1)
		origVersion := version.Current
		version.Current = version.MustParseBinary(useVersion)
		defer func() { version.Current = origVersion }()
	}

	if test.hostArch != "" {
		origVersion := arch.HostArch
		arch.HostArch = func() string {
			return test.hostArch
		}
		defer func() { arch.HostArch = origVersion }()
	}

	if test.upload == "" {
		usefulVersion := version.Current
		usefulVersion.Series = config.PreferredSeries(env.Config())
		envtesting.AssertUploadFakeToolsVersions(c, env.Storage(), usefulVersion)
	}

	// Run command and check for uploads.
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), test.args...)
	// Check for remaining operations/errors.
	if test.err != "" {
		err := <-errc
		stripped := strings.Replace(err.Error(), "\n", "", -1)
		c.Check(stripped, gc.Matches, test.err)
		return
	}
	if !c.Check(<-errc, gc.IsNil) {
		return
	}

	opPutBootstrapVerifyFile := (<-opc).(dummy.OpPutFile)
	c.Check(opPutBootstrapVerifyFile.Env, gc.Equals, "peckham")
	c.Check(opPutBootstrapVerifyFile.FileName, gc.Equals, environs.VerificationFilename)

	opBootstrap := (<-opc).(dummy.OpBootstrap)
	c.Check(opBootstrap.Env, gc.Equals, "peckham")
	c.Check(opBootstrap.Args.Constraints, gc.DeepEquals, test.constraints)
	c.Check(opBootstrap.Args.Placement, gc.Equals, test.placement)
	c.Check(opBootstrap.Args.KeepBroken, gc.Equals, test.keepBroken)

	opFinalizeBootstrap := (<-opc).(dummy.OpFinalizeBootstrap)
	c.Check(opFinalizeBootstrap.Env, gc.Equals, "peckham")
	c.Check(opFinalizeBootstrap.MachineConfig.Tools, gc.NotNil)
	if test.upload != "" {
		c.Check(opFinalizeBootstrap.MachineConfig.Tools.Version.String(), gc.Equals, test.upload)
	}

	store, err := configstore.Default()
	c.Assert(err, gc.IsNil)
	// Check a CA cert/key was generated by reloading the environment.
	env, err = environs.NewFromName("peckham", store)
	c.Assert(err, gc.IsNil)
	_, hasCert := env.Config().CACert()
	c.Check(hasCert, gc.Equals, true)
	_, hasKey := env.Config().CAPrivateKey()
	c.Check(hasKey, gc.Equals, true)
	info, err := store.ReadInfo("peckham")
	c.Assert(err, gc.IsNil)
	c.Assert(info, gc.NotNil)
	c.Assert(info.APIEndpoint().Addresses, gc.DeepEquals, []string{"localhost:17070"})
}
Ejemplo n.º 29
0
func (s *BootstrapSuite) run(c *gc.C, test bootstrapTest) (restore gitjujutesting.Restorer) {
	// Create home with dummy provider and remove all
	// of its envtools.
	env := resetJujuHome(c, "peckham")

	// Although we're testing PrepareEndpointsForCaching interactions
	// separately in the juju package, here we just ensure it gets
	// called with the right arguments.
	prepareCalled := false
	addrConnectedTo := "localhost:17070"
	restore = gitjujutesting.PatchValue(
		&prepareEndpointsForCaching,
		func(info configstore.EnvironInfo, hps [][]network.HostPort, addr network.HostPort) (_, _ []string, _ bool) {
			prepareCalled = true
			addrs, hosts, changed := juju.PrepareEndpointsForCaching(info, hps, addr)
			// Because we're bootstrapping the addresses will always
			// change, as there's no .jenv file saved yet.
			c.Assert(changed, jc.IsTrue)
			return addrs, hosts, changed
		},
	)

	if test.version != "" {
		useVersion := strings.Replace(test.version, "%LTS%", config.LatestLtsSeries(), 1)
		origVersion := version.Current
		version.Current = version.MustParseBinary(useVersion)
		restore = restore.Add(func() {
			version.Current = origVersion
		})
	}

	if test.hostArch != "" {
		origArch := arch.HostArch
		arch.HostArch = func() string {
			return test.hostArch
		}
		restore = restore.Add(func() {
			arch.HostArch = origArch
		})
	}

	// Run command and check for uploads.
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), envcmd.Wrap(new(BootstrapCommand)), test.args...)
	// Check for remaining operations/errors.
	if test.err != "" {
		err := <-errc
		c.Assert(err, gc.NotNil)
		stripped := strings.Replace(err.Error(), "\n", "", -1)
		c.Check(stripped, gc.Matches, test.err)
		return restore
	}
	if !c.Check(<-errc, gc.IsNil) {
		return restore
	}

	opBootstrap := (<-opc).(dummy.OpBootstrap)
	c.Check(opBootstrap.Env, gc.Equals, "peckham")
	c.Check(opBootstrap.Args.Constraints, gc.DeepEquals, test.constraints)
	c.Check(opBootstrap.Args.Placement, gc.Equals, test.placement)

	opFinalizeBootstrap := (<-opc).(dummy.OpFinalizeBootstrap)
	c.Check(opFinalizeBootstrap.Env, gc.Equals, "peckham")
	c.Check(opFinalizeBootstrap.InstanceConfig.Tools, gc.NotNil)
	if test.upload != "" {
		c.Check(opFinalizeBootstrap.InstanceConfig.Tools.Version.String(), gc.Equals, test.upload)
	}

	store, err := configstore.Default()
	c.Assert(err, jc.ErrorIsNil)
	// Check a CA cert/key was generated by reloading the environment.
	env, err = environs.NewFromName("peckham", store)
	c.Assert(err, jc.ErrorIsNil)
	_, hasCert := env.Config().CACert()
	c.Check(hasCert, jc.IsTrue)
	_, hasKey := env.Config().CAPrivateKey()
	c.Check(hasKey, jc.IsTrue)
	info, err := store.ReadInfo("peckham")
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(info, gc.NotNil)
	c.Assert(prepareCalled, jc.IsTrue)
	c.Assert(info.APIEndpoint().Addresses, gc.DeepEquals, []string{addrConnectedTo})
	return restore
}
Ejemplo n.º 30
0
func (s *BootstrapSuite) run(c *gc.C, test bootstrapTest) testing.Restorer {
	// Create home with dummy provider and remove all
	// of its envtools.
	resetJujuXDGDataHome(c)
	dummy.Reset(c)

	var restore testing.Restorer = func() {
		s.store = jujuclienttesting.NewMemStore()
	}
	if test.version != "" {
		useVersion := strings.Replace(test.version, "%LTS%", series.LatestLts(), 1)
		v := version.MustParseBinary(useVersion)
		restore = restore.Add(testing.PatchValue(&jujuversion.Current, v.Number))
		restore = restore.Add(testing.PatchValue(&arch.HostArch, func() string { return v.Arch }))
		restore = restore.Add(testing.PatchValue(&series.HostSeries, func() string { return v.Series }))
	}

	if test.hostArch != "" {
		restore = restore.Add(testing.PatchValue(&arch.HostArch, func() string { return test.hostArch }))
	}

	controllerName := "peckham-controller"
	cloudName := "dummy"

	// Run command and check for uploads.
	args := append([]string{
		controllerName, cloudName,
		"--config", "default-series=raring",
	}, test.args...)
	opc, errc := cmdtesting.RunCommand(cmdtesting.NullContext(c), s.newBootstrapCommand(), args...)
	// Check for remaining operations/errors.
	if test.err != "" {
		err := <-errc
		c.Assert(err, gc.NotNil)
		stripped := strings.Replace(err.Error(), "\n", "", -1)
		c.Check(stripped, gc.Matches, test.err)
		return restore
	}
	if !c.Check(<-errc, gc.IsNil) {
		return restore
	}

	opBootstrap := (<-opc).(dummy.OpBootstrap)
	c.Check(opBootstrap.Env, gc.Equals, "admin")
	c.Check(opBootstrap.Args.ModelConstraints, gc.DeepEquals, test.constraints)
	if test.bootstrapConstraints == (constraints.Value{}) {
		test.bootstrapConstraints = test.constraints
	}
	c.Check(opBootstrap.Args.BootstrapConstraints, gc.DeepEquals, test.bootstrapConstraints)
	c.Check(opBootstrap.Args.Placement, gc.Equals, test.placement)

	opFinalizeBootstrap := (<-opc).(dummy.OpFinalizeBootstrap)
	c.Check(opFinalizeBootstrap.Env, gc.Equals, "admin")
	c.Check(opFinalizeBootstrap.InstanceConfig.ToolsList(), gc.Not(gc.HasLen), 0)
	if test.upload != "" {
		c.Check(opFinalizeBootstrap.InstanceConfig.AgentVersion().String(), gc.Equals, test.upload)
	}

	expectedBootstrappedControllerName := bootstrappedControllerName(controllerName)

	// Check controllers.yaml controller details.
	addrConnectedTo := []string{"localhost:17070"}

	controller, err := s.store.ControllerByName(expectedBootstrappedControllerName)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(controller.CACert, gc.Not(gc.Equals), "")
	c.Assert(controller.UnresolvedAPIEndpoints, gc.DeepEquals, addrConnectedTo)
	c.Assert(controller.APIEndpoints, gc.DeepEquals, addrConnectedTo)
	c.Assert(utils.IsValidUUIDString(controller.ControllerUUID), jc.IsTrue)

	// Controller model should be called "admin".
	controllerModel, err := s.store.ModelByName(expectedBootstrappedControllerName, "admin@local", "admin")
	c.Assert(controllerModel.ModelUUID, gc.Equals, controller.ControllerUUID)
	c.Assert(err, jc.ErrorIsNil)

	// Bootstrap config should have been saved, and should only contain
	// the type, name, and any user-supplied configuration.
	bootstrapConfig, err := s.store.BootstrapConfigForController(expectedBootstrappedControllerName)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(bootstrapConfig.Cloud, gc.Equals, "dummy")
	c.Assert(bootstrapConfig.Credential, gc.Equals, "")
	c.Assert(bootstrapConfig.Config, jc.DeepEquals, map[string]interface{}{
		"name":           "admin",
		"type":           "dummy",
		"default-series": "raring",
	})

	return restore
}