Example #1
0
func opClientResolved(c *gc.C, st *api.State, _ *state.State) (func(), error) {
	err := st.Client().Resolved("wordpress/1", false)
	// There are several scenarios in which this test is called, one is
	// that the user is not authorized.  In that case we want to exit now,
	// letting the error percolate out so the caller knows that the
	// permission error was correctly generated.
	if err != nil && params.IsCodeUnauthorized(err) {
		return func() {}, err
	}
	// Otherwise, the user was authorized, but we expect an error anyway
	// because the unit is not in an error state when we tried to resolve
	// the error.  Therefore, since it is complaining it means that the
	// call to Resolved worked, so we're happy.
	c.Assert(err, gc.NotNil)
	c.Assert(err.Error(), gc.Equals, `unit "wordpress/1" is not in an error state`)
	return func() {}, nil
}
Example #2
0
// openAPIState opens the API using the given information, and
// returns the opened state and the api entity with
// the given tag. The given changeConfig function is
// called if the password changes to set the password.
func openAPIState(agentConfig agent.Config, a Agent) (_ *api.State, _ *apiagent.Entity, resultErr error) {
	// We let the API dial fail immediately because the
	// runner's loop outside the caller of openAPIState will
	// keep on retrying. If we block for ages here,
	// then the worker that's calling this cannot
	// be interrupted.
	info := agentConfig.APIInfo()
	st, err := apiOpen(info, api.DialOpts{})
	usedOldPassword := false
	if params.IsCodeUnauthorized(err) {
		// We've perhaps used the wrong password, so
		// try again with the fallback password.
		info := *info
		info.Password = agentConfig.OldPassword()
		usedOldPassword = true
		st, err = apiOpen(&info, api.DialOpts{})
	}
	if err != nil {
		if params.IsCodeNotProvisioned(err) {
			return nil, nil, worker.ErrTerminateAgent
		}
		if params.IsCodeUnauthorized(err) {
			return nil, nil, worker.ErrTerminateAgent
		}
		return nil, nil, err
	}
	defer func() {
		if resultErr != nil {
			st.Close()
		}
	}()
	entity, err := st.Agent().Entity(a.Tag())
	if err == nil && entity.Life() == params.Dead {
		return nil, nil, worker.ErrTerminateAgent
	}
	if err != nil {
		if params.IsCodeUnauthorized(err) {
			return nil, nil, worker.ErrTerminateAgent
		}
		return nil, nil, err
	}
	if usedOldPassword {
		// We succeeded in connecting with the fallback
		// password, so we need to create a new password
		// for the future.

		newPassword, err := utils.RandomPassword()
		if err != nil {
			return nil, nil, err
		}
		// Change the configuration *before* setting the entity
		// password, so that we avoid the possibility that
		// we might successfully change the entity's
		// password but fail to write the configuration,
		// thus locking us out completely.
		if err := a.ChangeConfig(func(c agent.ConfigSetter) {
			c.SetPassword(newPassword)
			c.SetOldPassword(info.Password)
		}); err != nil {
			return nil, nil, err
		}
		if err := entity.SetPassword(newPassword); err != nil {
			return nil, nil, err
		}
	}

	return st, entity, nil
}