Add storage keepalive (upholds) across services, Nextcloud cron, disable Nextcloud PHP JIT
Requires= doesn't restart a service once its required mount comes back after a USB disconnect/remount, so a dedicated storage-keepalive unit now Upholds= every storage-dependent service to bring it back automatically. Also adds the missing Nextcloud cron.php timer (background jobs were never triggered), and disables opcache.jit in the Nextcloud container — PHP 8.4's JIT was miscompiling OC\Config\UserConfig::getValueBool(), crashing every session-bootstrapping request with a bogus strtolower() TypeError. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -79,6 +79,28 @@ in
|
||||
default = [];
|
||||
description = "Per-service directories to create under mountPoint. Each service module contributes its own entries.";
|
||||
};
|
||||
|
||||
upholds = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Systemd unit names (e.g. "podman-openldap.service") that must come
|
||||
back up on their own after the external drive remounts.
|
||||
|
||||
These units already have Requires=mnt-data.mount, so they correctly
|
||||
stop when the drive disappears. The problem is the reverse direction:
|
||||
a plain Requires= dependency does NOT restart when the required unit
|
||||
becomes available again — systemd treats a Requires-propagated stop
|
||||
the same as a deliberate "systemctl stop", so Restart= policies on
|
||||
the unit itself never fire either. Verified empirically on 2026-10-02
|
||||
after a USB disconnect/remount left 11 services dead for ~4 hours.
|
||||
|
||||
The fix is a dedicated keepalive unit bound to the mount (below) that
|
||||
Upholds= every unit listed here — Upholds continuously (re)starts its
|
||||
targets for as long as the upholding unit is active, which is exactly
|
||||
the "come back when the mount comes back" behavior Requires= lacks.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf (cfg.device != "") {
|
||||
@@ -95,6 +117,23 @@ in
|
||||
];
|
||||
};
|
||||
|
||||
# See the `upholds` option doc above for why this unit exists.
|
||||
systemd.services.storage-keepalive =
|
||||
let
|
||||
mountUnit = "${lib.replaceStrings [ "/" ] [ "-" ] (lib.removePrefix "/" cfg.mountPoint)}.mount";
|
||||
in {
|
||||
description = "Keeps storage-dependent services running whenever ${cfg.mountPoint} is mounted";
|
||||
bindsTo = [ mountUnit ];
|
||||
after = [ mountUnit ];
|
||||
wantedBy = [ mountUnit ];
|
||||
unitConfig.Upholds = cfg.upholds;
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
ExecStart = "${pkgs.coreutils}/bin/true";
|
||||
};
|
||||
};
|
||||
|
||||
# Mount point root + shared infrastructure dirs (restic cache, shared media).
|
||||
# Per-service dirs are contributed via homey.storage.extraDirs by each
|
||||
# service module, so adding a new service only requires editing that module.
|
||||
|
||||
Reference in New Issue
Block a user