Example #1
0
// Somewhere in the 1.20 cycle the system-identity was added to the
// state serving info collection in the database, however no migration
// step was added to take the identity file from disk and put it into the
// new value in the database.
func ensureSystemSSHKeyRedux(context Context) error {
	// If there is a system-identity in the database already, we don't need to
	// do anything.
	stateInfo, err := context.State().StateServingInfo()
	if err != nil {
		logger.Errorf("failed to read state serving info: %v", err)
		return errors.Trace(err)
	}
	if stateInfo.SystemIdentity != "" {
		logger.Infof("state serving info has a system identity already, all good")
		// We are good. One exists already.
		// Make sure that the agent thinks that it is the same.
		return updateSystemIdentityInAgentConfig(context, stateInfo.SystemIdentity)
	}

	privateKey, publicKey, err := readOrMakeSystemIdentity(context)
	if err != nil {
		logger.Errorf("failed to read or make system identity: %v", err)
		return errors.Trace(err)
	}

	if err := state.SetSystemIdentity(context.State(), privateKey); err != nil {
		if errors.Cause(err) == txn.ErrAborted {
			logger.Errorf("someone else has set system identity already")
			// Another state server upgrading concurrently has updated
			// the system identity so it is no longer empty. So discard
			// anything that was created, reread the system info and write
			// out the file.  We also assume that the other upgrade has
			// updated the authorized keys already.
			stateInfo, err := context.State().StateServingInfo()
			if err != nil {
				logger.Errorf("failed to read state serving info: %v", err)
				return errors.Trace(err)
			}
			if stateInfo.SystemIdentity == "" {
				logger.Errorf("but the transaction said it would be there...")
				return errors.New("system identity is not set")
			}
			if err := writeSystemIdentity(context, stateInfo.SystemIdentity); err != nil {
				logger.Errorf("failed to write the system identity file: %v", err)
				return errors.Trace(err)
			}
			return updateSystemIdentityInAgentConfig(context, stateInfo.SystemIdentity)
		}

		logger.Errorf("failed to set system identity: %v", err)
		return errors.Annotate(err, "cannot set state serving info")
	}

	if publicKey != "" {
		if err := writeSystemIdentity(context, privateKey); err != nil {
			return errors.Trace(err)
		}
	}
	return updateSystemIdentityInAgentConfig(context, privateKey)
}
Example #2
0
func (s *systemSSHKeyReduxSuite) TestReduxExistsInStateServingInfo(c *gc.C) {
	err := state.SetSystemIdentity(s.State, "ssh-private-key")
	c.Assert(err, jc.ErrorIsNil)

	err = upgrades.EnsureSystemSSHKeyRedux(s.ctx)
	c.Assert(err, jc.ErrorIsNil)

	info, err := s.State.StateServingInfo()
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(info.SystemIdentity, gc.Equals, "ssh-private-key")
}