// 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) }
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") }