Multi-server CLI, more reverse zones, and a fix for new view directories
- CLI: name several servers and groups in the config file; select them with -s/--server NAME|GROUP|all|URL or JARL_SERVER. A command aimed at several servers is dry-run on all of them first and only runs if every one accepts it. Named servers always use their own token. - Reverse zones: /32 and /128 get single-address zones; networks between octet or nibble boundaries (e.g. a /22) are covered by several zones created together, from the CLI and the web UI. - Fix: under jarl.service's RestrictSUIDSGID, creating a view directory failed on chmod with the setgid bit; fall back to the permission bits. - Web UI: the review/live switch is a small header button, and the pending-changes bar only shows when there are pending changes. - TSIG key wording; the keys page points to restricted API tokens. - Docs: several servers (cli.md), a secondary server (operations.md), tokens vs TSIG keys (permissions.md); CHANGELOG. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a7d389be27
commit
785b0006f9
22 files changed
+1375
-185
No files matched your search
@@ -108,9 +108,32 @@ func (d *Deployer) EnsureDir(dir string, mode fs.FileMode) error {
|
||||
return fmt.Errorf("chgrp %s: %w", dir, err)
|
||||
}
|
||||
}
|
||||
return os.Chmod(dir, mode)
|
||||
fi, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// mkdir applies the umask, and a setgid parent passes its bit on, so
|
||||
// the mode usually needs fixing. Under systemd's RestrictSUIDSGID (as in
|
||||
// jarl.service) any chmod that includes the setgid bit fails with
|
||||
// EPERM; the permission bits matter more (named writes journals here),
|
||||
// and every file Jarl writes gets the group explicitly, so fall back to
|
||||
// them alone.
|
||||
if fi.Mode()&(fs.ModePerm|fs.ModeSetgid) == mode&(fs.ModePerm|fs.ModeSetgid) {
|
||||
return nil
|
||||
}
|
||||
err = chmod(dir, mode)
|
||||
if errors.Is(err, fs.ErrPermission) && mode&fs.ModeSetgid != 0 {
|
||||
err = chmod(dir, mode.Perm())
|
||||
}
|
||||
if err != nil {
|
||||
return fmt.Errorf("chmod %s: %w", dir, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// chmod is os.Chmod; tests replace it to simulate a sandbox.
|
||||
var chmod = os.Chmod
|
||||
|
||||
func (d *Deployer) writeAtomic(path string, content []byte, mode fs.FileMode) error {
|
||||
dir := filepath.Dir(path)
|
||||
if err := d.EnsureDir(dir, d.dirMode(dir)); err != nil {
|
||||
|
||||
Reference in new issue
Block a user