From 9c4c280d829f4fa91e7bb548410caa9c2eab2f8c Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Fri, 3 Jul 2026 19:53:23 +0300 Subject: Fix --sync remote path and permissions after pi0/pi1 NetBSD migration The default sync target directory was still /var/www/html/snonux/, but that directory was renamed to snonux.foo/ on both pi0 and pi1 as part of a bozohttpd vhost fix. Also add --chmod=D755,F644 to the rsync invocation: locally-generated output is mode 600, which lighttpd apparently tolerated but bozohttpd's separate _httpd service user does not (403 Forbidden). Co-Authored-By: Claude Sonnet 5 --- cmd/snonux/sync.go | 8 ++++++-- cmd/snonux/sync_test.go | 2 +- internal/config/config.go | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cmd/snonux/sync.go b/cmd/snonux/sync.go index 3e4155e..1eb549e 100644 --- a/cmd/snonux/sync.go +++ b/cmd/snonux/sync.go @@ -23,7 +23,7 @@ var defaultSyncTargets = []string{ "pi1.lan.buetow.org", } -const defaultSyncRemoteDir = "/var/www/html/snonux/" +const defaultSyncRemoteDir = "/var/www/html/snonux.foo/" // resolveSyncConfig populates cfg.SyncTargets and cfg.SyncRemoteDir from the // environment if they are empty, applying sensible defaults. @@ -89,7 +89,11 @@ func syncOutput(ctx context.Context, cfg *config.Config) error { for _, host := range cfg.SyncTargets { dest := fmt.Sprintf("%s@%s:%s", sshUser, host, cfg.SyncRemoteDir) log.Printf("rsync %s -> %s", src, dest) - cmd := exec.CommandContext(ctx, "rsync", "-az", "-e", ssh, src, dest) + // --chmod overrides the locally-generated (mode 600) output permissions: + // the remote webserver runs as its own unprivileged user (e.g. bozohttpd's + // _httpd), not as the SSH login user, so published files must be + // world-readable regardless of local perms. + cmd := exec.CommandContext(ctx, "rsync", "-az", "--chmod=D755,F644", "-e", ssh, src, dest) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { diff --git a/cmd/snonux/sync_test.go b/cmd/snonux/sync_test.go index b8e8701..8fe34e1 100644 --- a/cmd/snonux/sync_test.go +++ b/cmd/snonux/sync_test.go @@ -40,7 +40,7 @@ func TestResolveSyncConfig_defaults(t *testing.T) { if !reflect.DeepEqual(cfg.SyncTargets, want) { t.Fatalf("got targets %v, want %v", cfg.SyncTargets, want) } - if cfg.SyncRemoteDir != "/var/www/html/snonux/" { + if cfg.SyncRemoteDir != "/var/www/html/snonux.foo/" { t.Fatalf("got remote dir %q", cfg.SyncRemoteDir) } } diff --git a/internal/config/config.go b/internal/config/config.go index f310a6f..d2042f5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -33,6 +33,6 @@ type Config struct { SyncTargets []string // SyncRemoteDir is the destination directory on each target host. - // Defaults to "/var/www/html/snonux/". Override with SNONUX_SYNC_REMOTE_DIR env var. + // Defaults to "/var/www/html/snonux.foo/". Override with SNONUX_SYNC_REMOTE_DIR env var. SyncRemoteDir string } -- cgit v1.2.3