Files
DDI/agent/role/internal/fsutil/fsutil_unix.go
T
sir_melonchenandClaude Opus 5.5 70643f8146 feat(agent/dns): keys file, secondary zones and their health
The DNS role installs ddi-suite-keys.conf (a keys file without keys for
revisions from before M5, so that named.conf can always include it),
includes it before ddi-suite.conf in the validation named.conf, accepts
secondary zone files in <zone_dir>/secondary/ and creates that
directory with the mode and owner of zone_dir without ever touching its
content. The health check queries secondary zones too; a zone still
waiting for its first transfer is reported but does not fail the
deployment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 19:30:40 +02:00

50 lines
1.1 KiB
Go

// SPDX-License-Identifier: Apache-2.0
//go:build unix
package fsutil
import (
"os"
"syscall"
)
func ownerOf(path string) (Owner, bool) {
fi, err := os.Lstat(path)
if err != nil {
return Owner{}, false
}
st, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
return Owner{}, false
}
return Owner{UID: int(st.Uid), GID: int(st.Gid), Valid: true}, true
}
// chown applies owner if the process may change ownership (root). Other
// users cannot give files away, and their files belong to them anyway.
func chown(f *os.File, owner Owner) error {
if !owner.Valid || os.Geteuid() != 0 {
return nil
}
return f.Chown(owner.UID, owner.GID)
}
// chownPath is chown for a path (not following a final symbolic link).
func chownPath(path string, owner Owner) error {
if !owner.Valid || os.Geteuid() != 0 {
return nil
}
return os.Lchown(path, owner.UID, owner.GID)
}
// SyncDir flushes directory entries (renames, removals) to disk.
func SyncDir(dir string) error {
d, err := os.Open(dir) //nolint:gosec // dir is a configured directory of the role
if err != nil {
return err
}
defer func() { _ = d.Close() }()
return d.Sync()
}