build / build (push) Successful in 1m43s
- include SMB drop-ins from /etc/samba/smb.conf.d into the generated smb.conf - keep smbd/nfs-server running while other services (/etc/exports.d, drop-ins) share, instead of disabling them when nasmon has no shares of its own - list those shares read-only on /shares - settings: RepoISO URL; poll its /api/integration/status, dashboard card, menu link, alerts for portal down, stale worker, failed jobs, unmounted publications Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
112 lines
3.5 KiB
Go
112 lines
3.5 KiB
Go
package shares
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
const repoisoSMB = `# Managed by repoiso — do not edit
|
|
|
|
[iso-pve]
|
|
path = /tank/iso/export/pve
|
|
read only = yes
|
|
guest ok = yes
|
|
|
|
[global]
|
|
; ignored
|
|
`
|
|
|
|
func writeDropIns(t *testing.T) (smbDir, nfsDir string) {
|
|
t.Helper()
|
|
root := t.TempDir()
|
|
smbDir, nfsDir = filepath.Join(root, "smb.conf.d"), filepath.Join(root, "exports.d")
|
|
for _, d := range []string{smbDir, nfsDir} {
|
|
if err := os.MkdirAll(d, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
must := func(p, s string) {
|
|
if err := os.WriteFile(p, []byte(s), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
must(filepath.Join(smbDir, "repoiso.conf"), repoisoSMB)
|
|
must(filepath.Join(smbDir, "notes.txt"), "[ignored]\n")
|
|
must(filepath.Join(nfsDir, "repoiso.exports"), "# Managed by repoiso\n\"/tank/iso/export/pve\" 10.10.0.0/24(ro,root_squash)\n")
|
|
must(filepath.Join(nfsDir, "nasmon.exports"), "\"/data\" *(rw)\n")
|
|
return
|
|
}
|
|
|
|
func TestParseDropIns(t *testing.T) {
|
|
smb := ParseSMBDropIn(repoisoSMB, "repoiso")
|
|
if len(smb) != 1 || smb[0].Name != "iso-pve" || smb[0].Path != "/tank/iso/export/pve" || smb[0].Source != "repoiso" {
|
|
t.Fatalf("smb: %+v", smb)
|
|
}
|
|
nfs := ParseExportsFile("# c\n/plain host(ro)\n\"/with space\" 10.0.0.0/8(ro)\n\n", "x")
|
|
if len(nfs) != 2 || nfs[0].Path != "/plain" || nfs[1].Path != "/with space" || nfs[1].Clients != "10.0.0.0/8(ro)" {
|
|
t.Fatalf("nfs: %+v", nfs)
|
|
}
|
|
}
|
|
|
|
func TestExternalSkipsOwnExports(t *testing.T) {
|
|
smbDir, nfsDir := writeDropIns(t)
|
|
m := newManager(newFake())
|
|
m.IncludeDir, m.ExportsDir, m.Exports = smbDir, nfsDir, filepath.Join(nfsDir, "nasmon.exports")
|
|
ext := m.External()
|
|
if countKind(ext, "smb") != 1 || countKind(ext, "nfs") != 1 {
|
|
t.Fatalf("external: %+v", ext)
|
|
}
|
|
if got := IncludeFiles(smbDir); len(got) != 1 || !strings.HasSuffix(got[0], "repoiso.conf") {
|
|
t.Fatalf("includes: %v", got)
|
|
}
|
|
}
|
|
|
|
func TestRenderSMBIncludes(t *testing.T) {
|
|
out := RenderSMB(sample(), "ansible", "/etc/samba/smb.conf.d/repoiso.conf")
|
|
if !strings.HasSuffix(strings.TrimSpace(out), "include = /etc/samba/smb.conf.d/repoiso.conf") {
|
|
t.Fatalf("include not at the end:\n%s", out)
|
|
}
|
|
if strings.Contains(RenderSMB(sample(), "ansible"), "include =") {
|
|
t.Fatal("include rendered without drop-ins")
|
|
}
|
|
}
|
|
|
|
// The bug this guards against: nasmon without own shares disabled smbd and
|
|
// nfs-server and killed the shares RepoISO publishes for Proxmox.
|
|
func TestApplyKeepsServicesForOtherServices(t *testing.T) {
|
|
smbDir, nfsDir := writeDropIns(t)
|
|
f := newFake()
|
|
m := newManager(f)
|
|
m.IncludeDir, m.ExportsDir, m.Exports = smbDir, nfsDir, filepath.Join(nfsDir, "nasmon.exports")
|
|
if err := m.Apply(Defaults()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if f.has("systemctl disable") {
|
|
t.Fatalf("services disabled although other services share: %v", f.calls)
|
|
}
|
|
if !f.has("systemctl enable --now smbd nmbd") || !f.has("systemctl enable --now nfs-server") || !f.has("exportfs -ra") {
|
|
t.Fatalf("services not kept running: %v", f.calls)
|
|
}
|
|
wi := f.index("sh -c")
|
|
if !strings.Contains(f.stdin[f.calls[wi]], "include = "+filepath.Join(smbDir, "repoiso.conf")) {
|
|
t.Errorf("smb.conf lacks the drop-in include")
|
|
}
|
|
}
|
|
|
|
func TestApplyDisabledSMBHidesOwnShares(t *testing.T) {
|
|
smbDir, _ := writeDropIns(t)
|
|
f := newFake()
|
|
m := newManager(f)
|
|
m.IncludeDir = smbDir
|
|
c := sample()
|
|
c.SMB.Enabled = false
|
|
if err := m.Apply(c); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strings.Contains(f.stdin[f.calls[f.index("sh -c")]], "[documents]") {
|
|
t.Errorf("disabled nasmon shares still rendered while smbd stays up for others")
|
|
}
|
|
}
|