v0.325.0: share + escrow limiters reserve first; family sessions as fingerprints; samba renames apply; path guard widened; gates in a worktree
gates / gates (push) Successful in 45s
gates / gates (push) Successful in 45s
R-1111 reserveAttempt is the one limiter body (share password, escrow re-auth, dashboard sign-in). R-1112 family.json holds fingerprints; old files are converted at load. R-1113 the household's pass reuses its family session. R-1109 the samba compose carries the smb.conf hash. R-1110 TestNoBareDrivePathToPathHelpers. R-1114 shared_scripts.py resolves the felhom.eu sibling from a worktree. Each red-proved. Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
package infra
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -96,6 +98,13 @@ func RenderSambaConfig(d SambaData) string {
|
||||
// the default bridge is deaf to LAN multicast), the pinned image, smb.conf bind-mounted read-only,
|
||||
// the passdb named volume, and one bind per share (:ro for read-only shares — defense in depth beside
|
||||
// the smb.conf-level `read only`). Deterministic: share binds are sorted so the output is stable.
|
||||
//
|
||||
// The label felhom.smb-conf-sha256 carries the hash of the smb.conf this compose runs with (R-1109). smb.conf is a
|
||||
// bind-mounted FILE replaced by atomic rename, so a running container keeps the old inode, and `compose up -d`
|
||||
// recreates only when the COMPOSE changes: a share renamed at the same path changed smb.conf alone and was never
|
||||
// served. With the hash in the compose, a config change is a compose change, so compose recreates — and an
|
||||
// unchanged config renders a byte-identical compose, so a pass with nothing new recreates nothing.
|
||||
// Pinned by TestRenderSambaCompose_ConfigHashLabel (infra) and TestSambaReconcile_SamePathRenameChangesCompose.
|
||||
func RenderSambaCompose(d SambaData) string {
|
||||
shares := make([]SambaShareRender, len(d.Shares))
|
||||
copy(shares, d.Shares)
|
||||
@@ -121,6 +130,8 @@ services:
|
||||
container_name: %[1]s
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
labels:
|
||||
- felhom.smb-conf-sha256=%[9]s
|
||||
environment:
|
||||
- FELHOM_SERVER_NAME=%[3]s
|
||||
- FELHOM_IFACE=%[8]s
|
||||
@@ -132,5 +143,12 @@ services:
|
||||
%[7]s
|
||||
volumes:
|
||||
%[5]s:
|
||||
`, SambaContainerName, SambaImage, d.ServerName, d.UID, SambaPassdbVolume, SambaPassdbMount, binds.String(), SambaHostInterface)
|
||||
`, SambaContainerName, SambaImage, d.ServerName, d.UID, SambaPassdbVolume, SambaPassdbMount, binds.String(), SambaHostInterface,
|
||||
SambaConfigHash(d))
|
||||
}
|
||||
|
||||
// SambaConfigHash is the sha256 (hex) of the smb.conf RenderSambaConfig produces for d — the compose label value.
|
||||
func SambaConfigHash(d SambaData) string {
|
||||
sum := sha256.Sum256([]byte(RenderSambaConfig(d)))
|
||||
return hex.EncodeToString(sum[:])
|
||||
}
|
||||
|
||||
@@ -108,3 +108,31 @@ func TestRenderSambaCompose(t *testing.T) {
|
||||
t.Error("writable share must NOT be :ro")
|
||||
}
|
||||
}
|
||||
|
||||
// R-1109: a share renamed at the SAME path changes smb.conf only. The compose must change with it (the config-hash
|
||||
// label), or `compose up -d` keeps the running container on the old bind-mounted inode and the new name is never
|
||||
// served. And an unchanged config must render a byte-identical compose (no recreate on every pass).
|
||||
func TestRenderSambaCompose_ConfigHashLabel(t *testing.T) {
|
||||
path := "/mnt/felhom-drives/hdd_1/userdata/shares/iratok"
|
||||
before := SambaData{ServerName: "FELHOM", UID: 1000, Shares: []SambaShareRender{{Name: "dokumentumok", Path: path}}}
|
||||
after := SambaData{ServerName: "FELHOM", UID: 1000, Shares: []SambaShareRender{{Name: "iratok", Path: path}}}
|
||||
|
||||
if RenderSambaConfig(before) == RenderSambaConfig(after) {
|
||||
t.Fatal("setup: the rename must change smb.conf")
|
||||
}
|
||||
cb, ca := RenderSambaCompose(before), RenderSambaCompose(after)
|
||||
if cb == ca {
|
||||
t.Fatalf("a same-path rename left the compose byte-identical — compose up -d will not recreate (R-1109):\n%s", ca)
|
||||
}
|
||||
if want := "- felhom.smb-conf-sha256=" + SambaConfigHash(after); !strings.Contains(ca, want) {
|
||||
t.Errorf("compose missing the label %q\n%s", want, ca)
|
||||
}
|
||||
if RenderSambaCompose(after) != ca {
|
||||
t.Error("the same data must render the same compose (a recreate on every pass otherwise)")
|
||||
}
|
||||
// The premise of the bug, pinned: the binds are the same on both sides, so before the label nothing else differed.
|
||||
bind := " - " + path + ":" + path + "\n"
|
||||
if !strings.Contains(cb, bind) || !strings.Contains(ca, bind) {
|
||||
t.Errorf("both composes must bind %q", bind)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user