Skip to content

Commit

Permalink
code review: use compound index over liveness
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross committed Nov 1, 2022
1 parent 782d03e commit 571118f
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 20 deletions.
26 changes: 21 additions & 5 deletions nomad/core_sched_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2508,14 +2508,26 @@ func TestCoreScheduler_RootKeyGC(t *testing.T) {
require.NoError(t, store.UpsertAllocs(
structs.MsgTypeTestSetup, 850, []*structs.Allocation{alloc}))

// insert an "old" key that's inactive but being used by an alloc
key5 := structs.NewRootKeyMeta()
key5.SetInactive()
require.NoError(t, store.UpsertRootKeyMeta(900, key4, false))

// insert the allocation using key3
alloc2 := mock.Alloc()
alloc2.ClientStatus = structs.AllocClientStatusRunning
alloc2.SigningKeyID = key5.KeyID
require.NoError(t, store.UpsertAllocs(
structs.MsgTypeTestSetup, 950, []*structs.Allocation{alloc2}))

// insert a time table index before the last key
tt := srv.fsm.TimeTable()
tt.Witness(1000, time.Now().UTC().Add(-1*srv.config.RootKeyGCThreshold))

// insert a "new" but inactive key
key5 := structs.NewRootKeyMeta()
key5.SetInactive()
require.NoError(t, store.UpsertRootKeyMeta(1500, key5, false))
key6 := structs.NewRootKeyMeta()
key6.SetInactive()
require.NoError(t, store.UpsertRootKeyMeta(1500, key6, false))

// run the core job
snap, err := store.Snapshot()
Expand Down Expand Up @@ -2544,10 +2556,14 @@ func TestCoreScheduler_RootKeyGC(t *testing.T) {

key, err = store.RootKeyMetaByID(ws, key4.KeyID)
require.NoError(t, err)
require.NotNil(t, key, "old key used to sign an alloc should not have been GCd")
require.NotNil(t, key, "old key used to sign a live alloc should not have been GCd")

key, err = store.RootKeyMetaByID(ws, key5.KeyID)
require.NoError(t, err)
require.Nil(t, key, "old key used to sign a terminal alloc should have been GCd")

key, err = store.RootKeyMetaByID(ws, key6.KeyID)
require.NoError(t, err)
require.NotNil(t, key, "new key should not have been GCd")

}
Expand Down Expand Up @@ -2624,7 +2640,7 @@ func TestCoreScheduler_VariablesRekey(t *testing.T) {
}
keyMeta := raw.(*structs.RootKeyMeta)
if keyMeta.KeyID != newKeyID {
require.True(t, keyMeta.Deprecated())
require.True(t, keyMeta.State == structs.RootKeyStateInactive)
}
}
}
Expand Down
26 changes: 23 additions & 3 deletions nomad/state/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -689,12 +689,32 @@ func allocTableSchema() *memdb.TableSchema {
},
},

// signing_key index is used to lookup live allocations by signing
// key ID
indexSigningKey: {
Name: indexSigningKey,
AllowMissing: true,
AllowMissing: true, // terminal allocations won't be indexed
Unique: false,
Indexer: &memdb.UUIDFieldIndex{
Field: "SigningKeyID",
Indexer: &memdb.CompoundIndex{
Indexes: []memdb.Indexer{
&memdb.StringFieldIndex{
Field: "SigningKeyID",
},
&memdb.ConditionalIndex{
Conditional: func(obj interface{}) (bool, error) {
alloc, ok := obj.(*structs.Allocation)
if !ok {
return false, fmt.Errorf(
"wrong type, got %t should be Allocation", obj)
}
// note: this isn't alloc.TerminalStatus(),
// because we only want to consider the key
// unused if the allocation is terminal on both
// server and client
return !(alloc.ClientTerminalStatus() && alloc.ServerTerminalStatus()), nil
},
},
},
},
},
},
Expand Down
17 changes: 5 additions & 12 deletions nomad/state/state_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -6965,23 +6965,16 @@ func (s *StateStore) GetActiveRootKeyMeta(ws memdb.WatchSet) (*structs.RootKeyMe
func (s *StateStore) IsRootKeyMetaInUse(keyID string) (bool, error) {
txn := s.db.ReadTxn()

iter, err := txn.Get(TableAllocs, indexSigningKey)
iter, err := txn.Get(TableAllocs, indexSigningKey, keyID, true)
if err != nil {
return false, err
}

for {
raw := iter.Next()
if raw == nil {
break
}
alloc := raw.(*structs.Allocation)
if !alloc.TerminalStatus() {
return true, nil
}
alloc := iter.Next()
if alloc != nil {
return true, nil
}

iter, err = txn.Get(TableVariables, indexKeyID)
iter, err = txn.Get(TableVariables, indexKeyID, keyID)
if err != nil {
return false, err
}
Expand Down

0 comments on commit 571118f

Please sign in to comment.