Example #1
0
File: destroy.go Project: bac/juju
// DestroyController will attempt to destroy the controller. If the args
// specify the removal of blocks or the destruction of the models, this
// method will attempt to do so.
//
// If the controller has any non-Dead hosted models, then an error with
// the code params.CodeHasHostedModels will be transmitted, regardless of
// the value of the DestroyModels parameter. This is to inform the client
// that it should wait for hosted models to be completely cleaned up
// before proceeding.
func (s *ControllerAPI) DestroyController(args params.DestroyControllerArgs) error {
	hasPermission, err := s.authorizer.HasPermission(permission.SuperuserAccess, s.state.ControllerTag())
	if err != nil {
		return errors.Trace(err)
	}
	if !hasPermission {
		return errors.Trace(common.ErrPerm)
	}

	st := common.NewModelManagerBackend(s.state)
	controllerModel, err := st.ControllerModel()
	if err != nil {
		return errors.Trace(err)
	}
	systemTag := controllerModel.ModelTag()

	if err = s.ensureNotBlocked(args); err != nil {
		return errors.Trace(err)
	}

	// If we are destroying models, we need to tolerate living
	// models but set the controller to dying to prevent new
	// models sneaking in. If we are not destroying hosted models,
	// this will fail if any hosted models are found.
	if args.DestroyModels {
		return errors.Trace(common.DestroyModelIncludingHosted(st, systemTag))
	}
	if err := common.DestroyModel(st, systemTag); err != nil {
		return errors.Trace(err)
	}
	return nil
}
Example #2
0
func (s *destroyModelSuite) TestBlockDestroyDestroyHostedModel(c *gc.C) {
	otherSt := s.Factory.MakeModel(c, nil)
	defer otherSt.Close()
	info := s.APIInfo(c)
	info.ModelTag = otherSt.ModelTag()
	apiState, err := api.Open(info, api.DefaultDialOpts())

	block := commontesting.NewBlockHelper(apiState)
	defer block.Close()

	block.BlockDestroyModel(c, "TestBlockDestroyDestroyModel")
	err = common.DestroyModelIncludingHosted(s.State, s.State.ModelTag())
	s.AssertBlocked(c, err, "TestBlockDestroyDestroyModel")
}
Example #3
0
func (s *destroyTwoModelsSuite) TestDestroyControllerAndNonController(c *gc.C) {
	otherFactory := factory.NewFactory(s.otherState)
	otherFactory.MakeMachine(c, nil)
	m := otherFactory.MakeMachine(c, nil)
	otherFactory.MakeMachineNested(c, m.Id(), nil)

	err := common.DestroyModelIncludingHosted(s.State, s.State.ModelTag())
	c.Assert(err, jc.ErrorIsNil)

	runAllCleanups(c, s.State)
	runAllCleanups(c, s.otherState)
	assertAllMachinesDeadAndRemove(c, s.otherState)

	// Make sure we can continue to take the hosted model down while the
	// controller model is dying.
	c.Assert(s.otherState.ProcessDyingModel(), jc.ErrorIsNil)
}
Example #4
0
// DestroyController will attempt to destroy the controller. If the args
// specify the removal of blocks or the destruction of the models, this
// method will attempt to do so.
//
// If the controller has any non-Dead hosted models, then an error with
// the code params.CodeHasHostedModels will be transmitted, regardless of
// the value of the DestroyModels parameter. This is to inform the client
// that it should wait for hosted models to be completely cleaned up
// before proceeding.
func (s *ControllerAPI) DestroyController(args params.DestroyControllerArgs) error {
	controllerEnv, err := s.state.ControllerModel()
	if err != nil {
		return errors.Trace(err)
	}
	systemTag := controllerEnv.ModelTag()

	if err = s.ensureNotBlocked(args); err != nil {
		return errors.Trace(err)
	}

	// If we are destroying models, we need to tolerate living
	// models but set the controller to dying to prevent new
	// models sneaking in. If we are not destroying hosted models,
	// this will fail if any hosted models are found.
	if args.DestroyModels {
		return errors.Trace(common.DestroyModelIncludingHosted(s.state, systemTag))
	}
	if err := common.DestroyModel(s.state, systemTag); err != nil {
		return errors.Trace(err)
	}
	return nil
}