carlos / platform Public

console: clear the geoip staging directory at startup (geoip spec §4.2, codex R6-2)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 5a67a0b4046cc850c739b867da3b675e35c57844 parent 474636c
2 files changed, +31 −0
  • internal/console/geoippublish.go +11 −0
  • internal/console/geoippublish_test.go +20 −0
diff --git a/internal/console/geoippublish.go b/internal/console/geoippublish.go
index f75668643..50935360a 100644
--- a/internal/console/geoippublish.go
+++ b/internal/console/geoippublish.go
@@ -52,7 +52,18 @@ type geoipPublishOpts struct {
Force bool
}
+// newGeoipPublisher clears tmpRoot (the dedicated geoip-staging directory)
+// before anything can stage into it: a console that crashed mid-upload or
+// mid-job must not leave its 1 GiB behind for good (spec §4.2, codex R6-2).
func newGeoipPublisher(store release.Store, tmpRoot string) *geoipPublisher {
+ if tmpRoot != "" {
+ if err := os.RemoveAll(tmpRoot); err != nil {
+ log.Printf("console: geoip staging directory could not be cleared: %v", err)
+ }
+ if err := os.MkdirAll(tmpRoot, 0o700); err != nil {
+ log.Printf("console: geoip staging directory could not be created: %v", err)
+ }
+ }
return &geoipPublisher{store: store, tmpRoot: tmpRoot, maxBytes: geoip.MaxBlobBytes,
deadline: 15 * time.Minute, now: time.Now}
}
diff --git a/internal/console/geoippublish_test.go b/internal/console/geoippublish_test.go
index 106190a70..c055dbfa2 100644
--- a/internal/console/geoippublish_test.go
+++ b/internal/console/geoippublish_test.go
@@ -5,6 +5,7 @@ import (
"context"
"errors"
"os"
+ "path/filepath"
"strings"
"sync"
"testing"
@@ -223,3 +224,22 @@ func putPointer(t *testing.T, s release.Store, p geoip.Pointer) {
}
var _ = sync.Mutex{}
+
+func TestPublisherStartupClearsAbandonedStaging(t *testing.T) {
+ withFixtureProbes(t)
+ root := filepath.Join(t.TempDir(), "geoip-staging")
+ abandoned := filepath.Join(root, "geoip-publish-123")
+ if err := os.MkdirAll(abandoned, 0o700); err != nil {
+ t.Fatal(err)
+ }
+ if err := os.WriteFile(filepath.Join(abandoned, "db.mmdb"), []byte("half an upload"), 0o600); err != nil {
+ t.Fatal(err)
+ }
+ p := newGeoipPublisher(release.NewDirStore(t.TempDir()), root)
+ if entries, _ := os.ReadDir(root); len(entries) != 0 {
+ t.Fatalf("staging not cleared at startup: %v", entries)
+ }
+ if _, err := p.Publish(context.Background(), bytes.NewReader(fixture(t, "GeoIP2-City-Test.mmdb")), geoipPublishOpts{Origin: "manual"}); err != nil {
+ t.Fatalf("publish after restart: %v", err)
+ }
+}