G findings: distribution and gitea's package registry delete their old finding keys once at start
Builds: design 47 G A-31, A-14, A-22 Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -517,6 +517,10 @@ func main() {
|
||||
// the runtime answers the writer's subscription only once Serve has its channel
|
||||
go func() {
|
||||
<-stdio.Served()
|
||||
// the keys of the older form end in no kind the writer owns, so it does not clear them (A-31)
|
||||
if err := holder.DeleteOldFindings(stdio.State("findings"), holder.Self, holder.TransferFindingKinds); err != nil {
|
||||
logf("the old findings are not deleted: %v", err)
|
||||
}
|
||||
if err := w.Start(context.Background()); err != nil {
|
||||
logf("%v", err)
|
||||
os.Exit(1)
|
||||
|
||||
@@ -74,6 +74,10 @@ func run(ctx context.Context, getenv func(string) string) error {
|
||||
return err
|
||||
}
|
||||
findings.Writer = w
|
||||
// the keys of the older form end in no kind the writer owns, so it does not clear them (A-31)
|
||||
if err := holder.DeleteOldFindings(calls.State("findings"), holder.Self, holder.DriverFindingKinds); err != nil {
|
||||
logger.Printf("the old findings are not deleted: %v", err)
|
||||
}
|
||||
if err := w.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package holder
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -75,3 +76,28 @@ func (k *Findings) Observed(context.Context) (views.Observed[meshconditions.Find
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DeleteOldFindings deletes, once at a module's start, the findings the keys of an older form hold (design 47 G A-31): the form
|
||||
// `seat.<seat>.<kind>_<subject>`, whose kind is no kind the writer owns in its key, so the writer's own first statement does not
|
||||
// clear it. Only a key of one of kinds is deleted; the keys of the writer's form (`seat.<seat>.<subject>.<kind>`) are left.
|
||||
func DeleteOldFindings(state views.FindingState, seat string, kinds []string) error {
|
||||
keys, err := state.Keys()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, k := range keys {
|
||||
rest, ok := strings.CutPrefix(k, "seat."+seat+".")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, kind := range kinds {
|
||||
if strings.HasPrefix(rest, kind+"_") {
|
||||
if err := state.Delete(k); err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package holder
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
)
|
||||
|
||||
// A-31: the keys of the older form (`seat.<seat>.<kind>_<subject>`) are deleted once; a key of the writer's form, another seat's
|
||||
// and another kind's stay.
|
||||
func TestTheOldFindingKeysAreDeletedOnce(t *testing.T) {
|
||||
state := &oldKeysState{keys: map[string]bool{}}
|
||||
for _, k := range []string{
|
||||
"seat.distribution.publish-refused_write", "seat.distribution.publish-refused_a_b_c",
|
||||
"seat.distribution.sub.publish-refused", "seat.other.publish-refused_write", "seat.distribution.unrelated_write"} {
|
||||
state.keys[k] = true
|
||||
}
|
||||
if err := DeleteOldFindings(state, "distribution", []string{"publish-refused", "incoming-full"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var left []string
|
||||
for k := range state.keys {
|
||||
left = append(left, k)
|
||||
}
|
||||
sort.Strings(left)
|
||||
if got, want := strings.Join(left, " "), "seat.distribution.sub.publish-refused seat.distribution.unrelated_write seat.other.publish-refused_write"; got != want {
|
||||
t.Errorf("left %s, want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type oldKeysState struct{ keys map[string]bool }
|
||||
|
||||
func (s *oldKeysState) Get(string) (*stdio.StateEntry, error) { return nil, nil }
|
||||
func (s *oldKeysState) Put(string, any) (uint64, error) { return 0, nil }
|
||||
func (s *oldKeysState) Delete(k string) error { delete(s.keys, k); return nil }
|
||||
func (s *oldKeysState) Keys() ([]string, error) {
|
||||
var out []string
|
||||
for k := range s.keys {
|
||||
out = append(out, k)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -74,3 +75,28 @@ func (k *Findings) Observed(context.Context) (views.Observed[meshconditions.Find
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// DeleteOldFindings deletes, once at a module's start, the findings the keys of an older form hold (design 47 G A-31): the form
|
||||
// `seat.<seat>.<kind>_<subject>`, whose kind is no kind the writer owns in its key, so the writer's own first statement does not
|
||||
// clear it. Only a key of one of kinds is deleted; the keys of the writer's form (`seat.<seat>.<subject>.<kind>`) are left.
|
||||
func DeleteOldFindings(state views.FindingState, seat string, kinds []string) error {
|
||||
keys, err := state.Keys()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, k := range keys {
|
||||
rest, ok := strings.CutPrefix(k, "seat."+seat+".")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for _, kind := range kinds {
|
||||
if strings.HasPrefix(rest, kind+"_") {
|
||||
if err := state.Delete(k); err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
)
|
||||
|
||||
// A-31: the keys of the older form (`seat.<seat>.<kind>_<subject>`) are deleted once; a key of the writer's form, another seat's
|
||||
// and another kind's stay.
|
||||
func TestTheOldFindingKeysAreDeletedOnce(t *testing.T) {
|
||||
state := &oldKeysState{keys: map[string]bool{}}
|
||||
for _, k := range []string{
|
||||
"seat.gitea.packages-token-refused_write", "seat.gitea.packages-token-refused_a_b_c",
|
||||
"seat.gitea.sub.packages-token-refused", "seat.other.packages-token-refused_write", "seat.gitea.unrelated_write"} {
|
||||
state.keys[k] = true
|
||||
}
|
||||
if err := DeleteOldFindings(state, "gitea", []string{"packages-token-refused", "publish-refused", "incoming-full"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var left []string
|
||||
for k := range state.keys {
|
||||
left = append(left, k)
|
||||
}
|
||||
sort.Strings(left)
|
||||
if got, want := strings.Join(left, " "), "seat.gitea.sub.packages-token-refused seat.gitea.unrelated_write seat.other.packages-token-refused_write"; got != want {
|
||||
t.Errorf("left %s, want %s", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type oldKeysState struct{ keys map[string]bool }
|
||||
|
||||
func (s *oldKeysState) Get(string) (*stdio.StateEntry, error) { return nil, nil }
|
||||
func (s *oldKeysState) Put(string, any) (uint64, error) { return 0, nil }
|
||||
func (s *oldKeysState) Delete(k string) error { delete(s.keys, k); return nil }
|
||||
func (s *oldKeysState) Keys() ([]string, error) {
|
||||
var out []string
|
||||
for k := range s.keys {
|
||||
out = append(out, k)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -40,6 +40,10 @@ func main() {
|
||||
// the runtime answers the writer's subscription only once Serve has its channel
|
||||
go func() {
|
||||
<-stdio.Served()
|
||||
// the keys of the older form end in no kind the writer owns, so it does not clear them (A-31)
|
||||
if err := DeleteOldFindings(stdio.State("findings"), packageseats.Self, findingKinds); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "the old findings are not deleted:", err)
|
||||
}
|
||||
if err := w.Start(context.Background()); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
|
||||
Reference in New Issue
Block a user