mirror of
https://github.com/hanzoai/s3-csi.git
synced 2026-09-30 23:52:32 +00:00
* fix(docker): clone the fork that exists, at a commit that exists
The s3-mount image has never built. A global rename turned the upstream
seaweedfs reference into `github.com/s3/s3`, which is not a repository, so the
build died on `git clone ... exit code 128` before compiling anything.
Three more things were wrong behind it, each of which would have failed the next
step in turn:
clone github.com/s3/s3 -> github.com/hanzoai/s3
path /go/src/github.com/s3/s3 -> /go/src/github.com/hanzoai/s3
dir cd weed -> cd s3 (the fork renamed it)
commit 19ce7c0b6fdb -> 6dda4e4d6bca
That commit is the real one. 19ce7c0b6fdb is an UPSTREAM seaweedfs hash and does
not exist in our fork — the API 422s on it — so the checkout could never have
succeeded even with the URL fixed. The ARG stays so a build can still pin.
SEAWEEDFS_COMMIT is renamed S3_COMMIT while we are here; nothing consumed it yet.
* chore: no seaweed, no weed — it is s3
369 occurrences across 33 files, plus nine files whose names carried it. All of
it gone: manifests, helm chart, nomad jobs, workflows, docs and code.
Two of these were not cosmetic.
The driver spawned a binary called "weed":
DefaultWeedBinary = "weed"
Our fork builds it as `s3` — the running filer pod has /usr/bin/s3 and no weed
at all — so every mount would have failed with an executable that is not there,
however well the image built.
And the crash-recovery integration test killed processes matching `pgrep -x
weed`. Nothing is named that any more, so it would have found no pids, killed
nothing, and passed while testing exactly nothing. It now matches `s3`. The test
already had a guard that fails when there is nothing to kill, which is the only
reason this would have been noticed at all.
The rest follows the same rename the Dockerfile got: SEAWEEDFS_COMMIT is
S3_COMMIT, and the release/sync workflows that patch that ARG were updated with
it or they would silently stop pinning anything.
No upstream import paths were touched — go.mod depends on github.com/hanzoai/s3,
not on anything upstream, so nothing here was load-bearing for the build.
Verified: go build clean, all three test packages pass.
---------
Co-authored-by: hanzo-dev <[email protected]>
Co-authored-by: Hanzo Dev <[email protected]>
104 lines
2.8 KiB
Go
104 lines
2.8 KiB
Go
package mountmanager
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// TestWatchProcessExitRemovesStaleEntry verifies that the manager's
|
|
// background watcher clears a mount entry from its map when the s3
|
|
// mount process exits on its own. Without this, a future Mount call for
|
|
// the same volume would falsely receive an "already mounted" no-op
|
|
// because the manager's state never noticed the dead process.
|
|
// Regression test for s3/s3-csi#261.
|
|
func TestWatchProcessExitRemovesStaleEntry(t *testing.T) {
|
|
m := NewManager(Config{})
|
|
|
|
process := &s3MountProcess{
|
|
target: "/tmp/test-target",
|
|
exited: make(chan struct{}),
|
|
done: make(chan struct{}),
|
|
}
|
|
entry := &mountEntry{
|
|
volumeID: "vol-1",
|
|
targetPath: "/tmp/test-target",
|
|
cacheDir: "/tmp/test-cache",
|
|
localSocket: "/tmp/test.sock",
|
|
process: process,
|
|
}
|
|
m.mounts["vol-1"] = entry
|
|
|
|
go m.watchProcessExit("vol-1", entry)
|
|
|
|
// Sanity: entry is still tracked while the process is alive.
|
|
if got := m.getMount("vol-1"); got != entry {
|
|
t.Fatalf("expected entry tracked before process exit, got %v", got)
|
|
}
|
|
|
|
// Simulate the s3 mount process dying.
|
|
close(process.exited)
|
|
close(process.done)
|
|
|
|
// The watcher should remove the entry; poll briefly to give it time.
|
|
deadline := time.Now().Add(1 * time.Second)
|
|
for time.Now().Before(deadline) {
|
|
if m.getMount("vol-1") == nil {
|
|
return
|
|
}
|
|
time.Sleep(10 * time.Millisecond)
|
|
}
|
|
t.Fatal("watcher did not remove stale entry after s3 mount process exited")
|
|
}
|
|
|
|
// TestWatchProcessExitLeavesReplacedEntry verifies that if a fresh
|
|
// mount has replaced the original entry by the time the watcher fires,
|
|
// the watcher does not delete the new entry. The identity check in
|
|
// watchProcessExit guards against the watcher and a concurrent
|
|
// Unmount/re-Mount racing on the same volumeID slot.
|
|
func TestWatchProcessExitLeavesReplacedEntry(t *testing.T) {
|
|
m := NewManager(Config{})
|
|
|
|
oldProcess := &s3MountProcess{
|
|
target: "/tmp/test-target",
|
|
exited: make(chan struct{}),
|
|
done: make(chan struct{}),
|
|
}
|
|
oldEntry := &mountEntry{
|
|
volumeID: "vol-1",
|
|
process: oldProcess,
|
|
}
|
|
|
|
newProcess := &s3MountProcess{
|
|
target: "/tmp/test-target",
|
|
exited: make(chan struct{}),
|
|
done: make(chan struct{}),
|
|
}
|
|
newEntry := &mountEntry{
|
|
volumeID: "vol-1",
|
|
process: newProcess,
|
|
}
|
|
|
|
// Put the new entry in the map (as if a fresh mount had replaced
|
|
// the old one) before kicking off the watcher for the old entry.
|
|
m.mounts["vol-1"] = newEntry
|
|
|
|
watcherDone := make(chan struct{})
|
|
go func() {
|
|
m.watchProcessExit("vol-1", oldEntry)
|
|
close(watcherDone)
|
|
}()
|
|
|
|
close(oldProcess.exited)
|
|
close(oldProcess.done)
|
|
|
|
select {
|
|
case <-watcherDone:
|
|
case <-time.After(1 * time.Second):
|
|
t.Fatal("watcher did not finish")
|
|
}
|
|
|
|
if got := m.getMount("vol-1"); got != newEntry {
|
|
t.Fatalf("expected new entry preserved, got %v", got)
|
|
}
|
|
}
|