Skip to content

Commit

Permalink
Merge pull request #9724 from babbageclunk/raftlease-upgrade-blank
Browse files Browse the repository at this point in the history
#9724

## Description of change

These were causing errors reported from migrating the leases to raft during the upgrade. The leases wouldn't cause a problem other than a delay, because nothing would be extending them.

It's not clear why some production systems have these (possibly they used to be created in some much earlier version and have lasted through upgrades), but they're not valid for raft leases so don't try to migrate them.

## QA steps

* Bootstrap a 2.4.x controller.
* Monkey with the database to create some leases with blank names and/or holders.
* Upgrade the controller to this version of Juju.
* There should be no errors about invalid lease names or holders in the controller log, or blank leases in the leaseholders collection.
* There shouldn't be any blank leases in the raft snapshot created when migrating the leases.

## Documentation changes

None

## Bug reference

https://bugs.launchpad.net/juju/+bug/1813995
  • Loading branch information
jujubot committed Feb 11, 2019
2 parents 8d4c9f0 + 88ec9dc commit d7b62a0
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
4 changes: 4 additions & 0 deletions upgrades/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ func MigrateLegacyLeases(context Context) error {

// Populate the snapshot and the leaseholders collection.
for key, info := range legacyLeases {
if key.Lease == "" || info.Holder == "" {
logger.Debugf("not migrating blank lease %#v holder %q", key, info.Holder)
continue
}
entries[raftlease.SnapshotKey{
Namespace: key.Namespace,
ModelUUID: key.ModelUUID,
Expand Down
69 changes: 69 additions & 0 deletions upgrades/raft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,75 @@ func (s *raftSuite) TestMigrateLegacyLeases(c *gc.C) {

}

func (s *raftSuite) TestIgnoresBlankLeaseOrHolder(c *gc.C) {
dataDir := c.MkDir()
context := &mockContext{
agentConfig: &mockAgentConfig{
tag: names.NewMachineTag("23"),
dataDir: dataDir,
},
state: &mockState{
members: []replicaset.Member{{
Address: "somewhere.else:37012",
Tags: map[string]string{"juju-machine-id": "42"},
}},
info: state.StateServingInfo{APIPort: 1234},
},
}
err := upgrades.BootstrapRaft(context)
c.Assert(err, jc.ErrorIsNil)

var zero time.Time

// Now we migrate some leases...
config, err := controller.NewConfig(
coretesting.ControllerTag.Id(),
coretesting.CACert,
nil,
)
c.Assert(err, jc.ErrorIsNil)
var target mockTarget
context.state = &mockState{
config: config,
leases: map[lease.Key]lease.Info{
// Blank lease name.
{"nonagon", "m1", ""}: {
Holder: "knife",
Expiry: zero.Add(30 * time.Second),
},
// Blank lease holder.
{"reyne", "m2", "keening"}: {
Holder: "",
Expiry: zero.Add(45 * time.Second),
},
},
target: &target,
}

err = upgrades.MigrateLegacyLeases(context)
c.Assert(err, jc.ErrorIsNil)
target.assertClaimed(c, map[lease.Key]string{})

expectedLeases := make(map[lease.Key]lease.Info)

// Start up raft with the leases in the snapshot.
fsm := raftlease.NewFSM()
withRaft(c, dataDir, fsm, func(r *raft.Raft) {
// Once the snapshot is loaded the leases should be in the
// FSM.
var leases map[lease.Key]lease.Info
for a := coretesting.LongAttempt.Start(); a.Next(); {
leases = fsm.Leases(func() time.Time { return zero })
if reflect.DeepEqual(leases, expectedLeases) {
return
}
}
c.Assert(leases, gc.DeepEquals, expectedLeases,
gc.Commentf("waited %s but saw unexpected leases",
coretesting.LongAttempt.Total))
})
}

type mockState struct {
upgrades.StateBackend
stub testing.Stub
Expand Down

0 comments on commit d7b62a0

Please sign in to comment.