Added better documentation for fixing my own broken installs, and updated the install script to patch issues
Container image / image (push) Successful in 4m40s
Container image / image (push) Successful in 4m40s
This commit is contained in:
@@ -4,6 +4,21 @@ All notable changes to this project are documented here. The format
|
|||||||
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
||||||
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- **`install.sh` now repairs data-dir permissions on every run.**
|
||||||
|
Re-running the installer reasserts the canonical ownership
|
||||||
|
(`quptime:quptime`) and modes across `/etc/quptime/` — `0750` on
|
||||||
|
the dir, `0700` on `keys/`, `0600` on `node.yaml`, `cluster.yaml`,
|
||||||
|
`trust.yaml`, and `keys/private.pem`, `0644` on `keys/public.pem`
|
||||||
|
and `keys/cert.pem`. Makes the installer the one-step recovery
|
||||||
|
path when something has tampered with modes (e.g. a stray
|
||||||
|
`chmod -R`, a backup restore, or an accidental `sudo qu init`
|
||||||
|
that left files owned by root). Unknown files in the dir are left
|
||||||
|
alone.
|
||||||
|
|
||||||
## [v0.1.0] — 2026-05-15
|
## [v0.1.0] — 2026-05-15
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
@@ -70,6 +70,15 @@ What it does:
|
|||||||
`/etc/systemd/system/quptime.service` (hardened — matches the unit
|
`/etc/systemd/system/quptime.service` (hardened — matches the unit
|
||||||
in [systemd.md](deployment/systemd.md)). Enables but does not start
|
in [systemd.md](deployment/systemd.md)). Enables but does not start
|
||||||
the service, so you can configure identity before first boot.
|
the service, so you can configure identity before first boot.
|
||||||
|
5. Repairs ownership and modes under `/etc/quptime/` to the canonical
|
||||||
|
layout (`0750` on the dir, `0700` on `keys/`, `0600` on
|
||||||
|
`node.yaml` / `cluster.yaml` / `trust.yaml` / `keys/private.pem`,
|
||||||
|
`0644` on `keys/public.pem` / `keys/cert.pem`). This makes the
|
||||||
|
installer idempotent for permission damage — if something
|
||||||
|
tightened or loosened modes (a stray `chmod -R`, a misguided
|
||||||
|
backup restore, an accidental `sudo qu init`), re-running
|
||||||
|
`install.sh` puts everything back without touching the contents
|
||||||
|
of those files.
|
||||||
|
|
||||||
## Build from source
|
## Build from source
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,9 @@ still see this error, the most likely causes are:
|
|||||||
|
|
||||||
- The data directory is read-only or owned by a different user — the
|
- The data directory is read-only or owned by a different user — the
|
||||||
bootstrap can't write `node.yaml`. Fix permissions on
|
bootstrap can't write `node.yaml`. Fix permissions on
|
||||||
`$QUPTIME_DIR`.
|
`$QUPTIME_DIR`. The fastest fix on a standard install is just to
|
||||||
|
re-run `install.sh` — it reasserts the canonical ownership and
|
||||||
|
modes on the whole tree without touching your config.
|
||||||
- Something else removed `node.yaml` mid-run (a config-management
|
- Something else removed `node.yaml` mid-run (a config-management
|
||||||
tool, a misconfigured volume). Re-run `qu serve` and it will
|
tool, a misconfigured volume). Re-run `qu serve` and it will
|
||||||
rebuild from env, or run `qu init` manually with the flags you
|
rebuild from env, or run `qu init` manually with the flags you
|
||||||
@@ -197,7 +199,9 @@ load private key: ...
|
|||||||
```
|
```
|
||||||
|
|
||||||
Permissions on `keys/private.pem` are wrong — should be 0600 and owned
|
Permissions on `keys/private.pem` are wrong — should be 0600 and owned
|
||||||
by the daemon user. Fix and restart.
|
by the daemon user. Fix and restart. Re-running `install.sh` on a
|
||||||
|
standard install is the easiest path: it repairs ownership and modes
|
||||||
|
on the entire data dir.
|
||||||
|
|
||||||
## Probes look much slower than expected
|
## Probes look much slower than expected
|
||||||
|
|
||||||
|
|||||||
+48
-6
@@ -175,21 +175,63 @@ fi
|
|||||||
|
|
||||||
install -d -o "$SERVICE_USER" -g "$SERVICE_GROUP" -m 0750 "$DATA_DIR"
|
install -d -o "$SERVICE_USER" -g "$SERVICE_GROUP" -m 0750 "$DATA_DIR"
|
||||||
|
|
||||||
# Reassert ownership on the dir's contents. Two cases this catches:
|
# Repair ownership and permissions on the data dir's contents. Catches:
|
||||||
# - re-running the installer over a previous install where the
|
# - re-running the installer over a previous install where the
|
||||||
# service user/group changed
|
# service user/group changed.
|
||||||
# - the operator ran `qu init` or `qu serve` as root once (easy
|
# - the operator ran `qu init` or `qu serve` as root once (easy
|
||||||
# mistake: `sudo qu init` is shorter than the documented
|
# mistake: `sudo qu init` is shorter than the documented
|
||||||
# `sudo -u quptime qu init`). When the daemon runs as root its
|
# `sudo -u quptime qu init`). When the daemon runs as root its
|
||||||
# DataDir() resolves to /etc/quptime, so any files it writes land
|
# DataDir() resolves to /etc/quptime, so any files it writes land
|
||||||
# here owned by root:root mode 0600 — the systemd service then
|
# owned by root:root — the systemd service then fails with
|
||||||
# fails with `open node.yaml: permission denied`.
|
# `open node.yaml: permission denied`.
|
||||||
# chown -R only changes ownership, not perms, so file modes set by
|
# - someone or something (a stray `chmod -R`, a misguided backup
|
||||||
# the daemon (0600 for node.yaml, 0700 for keys/) are preserved.
|
# restore) tightened or loosened modes. Re-running the installer
|
||||||
|
# should be enough to get back to a working baseline.
|
||||||
|
# The canonical layout (mirrors the modes the daemon writes itself
|
||||||
|
# in internal/config and internal/crypto):
|
||||||
|
# /etc/quptime/ quptime:quptime 0750
|
||||||
|
# /etc/quptime/keys/ quptime:quptime 0700
|
||||||
|
# /etc/quptime/node.yaml quptime:quptime 0600
|
||||||
|
# /etc/quptime/cluster.yaml quptime:quptime 0600
|
||||||
|
# /etc/quptime/trust.yaml quptime:quptime 0600
|
||||||
|
# /etc/quptime/keys/private.pem quptime:quptime 0600
|
||||||
|
# /etc/quptime/keys/public.pem quptime:quptime 0644
|
||||||
|
# /etc/quptime/keys/cert.pem quptime:quptime 0644
|
||||||
|
# The runtime dir /var/run/quptime is owned by systemd via
|
||||||
|
# RuntimeDirectory= and rebuilt at each service start, so we leave it
|
||||||
|
# alone.
|
||||||
|
repair_perms() {
|
||||||
|
# Always reset the top-level dir mode — `install -d` only sets it
|
||||||
|
# on creation, not on re-run.
|
||||||
|
chown "$SERVICE_USER:$SERVICE_GROUP" "$DATA_DIR"
|
||||||
|
chmod 0750 "$DATA_DIR"
|
||||||
|
|
||||||
|
# Reassert ownership across the whole tree in one pass.
|
||||||
if [ -n "$(ls -A "$DATA_DIR" 2>/dev/null)" ]; then
|
if [ -n "$(ls -A "$DATA_DIR" 2>/dev/null)" ]; then
|
||||||
chown -R "$SERVICE_USER:$SERVICE_GROUP" "$DATA_DIR"
|
chown -R "$SERVICE_USER:$SERVICE_GROUP" "$DATA_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# keys/ is a directory with its own tighter mode.
|
||||||
|
if [ -d "$DATA_DIR/keys" ]; then
|
||||||
|
chmod 0700 "$DATA_DIR/keys"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Each known file gets its canonical mode if it exists. We don't
|
||||||
|
# create anything that isn't already there — that's `qu init`'s
|
||||||
|
# job — and we don't touch unknown files an operator may have
|
||||||
|
# parked in the dir.
|
||||||
|
local f
|
||||||
|
for f in node.yaml cluster.yaml trust.yaml keys/private.pem; do
|
||||||
|
[ -f "$DATA_DIR/$f" ] && chmod 0600 "$DATA_DIR/$f"
|
||||||
|
done
|
||||||
|
for f in keys/public.pem keys/cert.pem; do
|
||||||
|
[ -f "$DATA_DIR/$f" ] && chmod 0644 "$DATA_DIR/$f"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
repair_perms
|
||||||
|
echo "> reasserted ownership ($SERVICE_USER:$SERVICE_GROUP) and modes under $DATA_DIR"
|
||||||
|
|
||||||
echo "> writing $SERVICE_FILE"
|
echo "> writing $SERVICE_FILE"
|
||||||
cat > "$SERVICE_FILE" <<'EOF'
|
cat > "$SERVICE_FILE" <<'EOF'
|
||||||
[Unit]
|
[Unit]
|
||||||
|
|||||||
Reference in New Issue
Block a user