Shares of other services and RepoISO integration
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>
This commit is contained in:
2026-10-03 15:06:17 +03:00
co-authored by Claude Opus 5.5
parent 661a862f8d
commit 30dbb00dd1
22 changed files with 656 additions and 19 deletions
+23 -8
View File
@@ -29,12 +29,17 @@ type Manager struct {
UID, GID string
SMBConf string
Exports string
Timeout time.Duration
// IncludeDir holds Samba drop-ins of other services, included into smb.conf;
// ExportsDir is scanned for other services' NFS exports (both: "" = none).
IncludeDir string
ExportsDir string
Timeout time.Duration
}
func New(run hostrun.Runner) *Manager {
m := &Manager{Run: run, LookPath: exec.LookPath, UID: DefaultOwnerUID, GID: DefaultOwnerUID,
SMBConf: DefaultSMBConf, Exports: DefaultExports, Timeout: 90 * time.Second}
SMBConf: DefaultSMBConf, Exports: DefaultExports, IncludeDir: DefaultSMBIncludeDir,
ExportsDir: DefaultExportsDir, Timeout: 90 * time.Second}
m.Owner = m.UID
if u, err := user.LookupId(m.UID); err == nil {
m.Owner, m.GID = u.Username, u.Gid
@@ -74,14 +79,19 @@ func (m *Manager) Apply(c Config) error {
func (m *Manager) applySMB(c Config) error {
ctx, cancel := m.ctx()
defer cancel()
if err := hostrun.WriteFile(ctx, m.Run, m.SMBConf, RenderSMB(c, m.Owner)); err != nil {
own := c
if !c.SMB.Enabled {
own.SMB.Shares = nil // other services may keep smbd running; don't serve disabled shares
}
external := countKind(m.External(), "smb")
if err := hostrun.WriteFile(ctx, m.Run, m.SMBConf, RenderSMB(own, m.Owner, IncludeFiles(m.IncludeDir)...)); err != nil {
return fmt.Errorf("write %s: %w", m.SMBConf, err)
}
if out, err := m.Run(ctx, "", "testparm", "-s", "--suppress-prompt", m.SMBConf); err != nil {
_ = hostrun.Restore(ctx, m.Run, m.SMBConf)
return fmt.Errorf("testparm rejected the config, previous file restored: %s", firstLines(out, 4))
}
active := c.SMB.Enabled && len(c.SMB.Shares) > 0
active := len(own.SMB.Shares) > 0 || external > 0
if !active {
_, err := m.Run(ctx, "", "systemctl", "disable", "--now", "smbd", "nmbd")
if err != nil {
@@ -96,17 +106,22 @@ func (m *Manager) applySMB(c Config) error {
if out, err := m.Run(ctx, "", "smbcontrol", "all", "reload-config"); err != nil {
return fmt.Errorf("reload smbd: %s", firstLines(out, 2))
}
log.Printf("shares: SMB config applied, %d shares", len(c.SMB.Shares))
log.Printf("shares: SMB config applied, %d shares, %d from other services", len(own.SMB.Shares), external)
return nil
}
func (m *Manager) applyNFS(c Config) error {
ctx, cancel := m.ctx()
defer cancel()
if err := hostrun.WriteFile(ctx, m.Run, m.Exports, RenderExports(c, m.UID, m.GID)); err != nil {
own := c
if !c.NFS.Enabled {
own.NFS.Exports = nil
}
external := countKind(m.External(), "nfs")
if err := hostrun.WriteFile(ctx, m.Run, m.Exports, RenderExports(own, m.UID, m.GID)); err != nil {
return fmt.Errorf("write %s: %w", m.Exports, err)
}
active := c.NFS.Enabled && len(c.NFS.Exports) > 0
active := len(own.NFS.Exports) > 0 || external > 0
if !active {
if _, err := m.Run(ctx, "", "systemctl", "disable", "--now", "nfs-server"); err != nil {
return fmt.Errorf("stop nfs-server: %w", err)
@@ -122,7 +137,7 @@ func (m *Manager) applyNFS(c Config) error {
_, _ = m.Run(ctx, "", "exportfs", "-ra")
return fmt.Errorf("exportfs rejected the exports, previous file restored: %s", firstLines(out, 4))
}
log.Printf("shares: NFS exports applied, %d exports", len(c.NFS.Exports))
log.Printf("shares: NFS exports applied, %d exports, %d from other services", len(own.NFS.Exports), external)
return nil
}