ups role: NUT server on home.debyl.io for the CyberPower PR1500RT2U that backs both it and truenas.localdomain, with staged shutdown (TrueNAS sheds at t+2min, host at 10% charge) and best-effort IPMI power-on when mains returns. The 10% threshold leans on ignorelb + override.battery.charge.low rather than a custom poller, because CyberPower asserts its own low-battery flag far too early. Credentials come from vault vars; nothing sensitive is templated in the clear. Nextcloud background jobs: both instances have backgroundjobs_mode "cron", which expects an external caller every ~5 minutes, and nothing was calling. The personal instance had not run a background job since 2026-05-14 and skudak since 2024-11-20. Consequently trash and file versions never expired, stale chunked uploads accumulated, calendar reminders never fired, and nextcloud.log was never rotated -- which quietly made the existing log_rotate_size cap inert. Added a systemd timer per instance, skipping cleanly when the container is down or in maintenance so deploy windows don't show up as failed units. Trash retention on the personal instance: the default "auto" only expires when disk space demands it, so 66 GB of >30-day deletions sat on a host with 1.3 TB free -- effectively unbounded. "auto, 30" makes the 30-day expiry unconditional while still purging early under pressure. Image bumps: nextcloud 33.0.0 -> 34.0.2 (both cloud and skudak-cloud) greg-time-bot 3.9.25 -> 3.10.0 fulfillr 20260723.2044 -> 20260728.2155 (prod and dev) The fulfillr bump records what is already deployed: both containers were rolled to that image on 2026-07-29 for SCRUM-156 (digital product releases + customer update campaign). Committing it keeps the repo from claiming an older tag than the host is actually running, which would otherwise roll fulfillr backwards on the next clean-checkout deploy. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4.6 KiB
ups
UPS monitoring and staged shutdown for the home rack.
A CyberPower PR1500RT2U (0764:0601) is cabled by USB to home.debyl.io and
backs both that host and truenas.localdomain (Dell PowerEdge R415). This role
makes home.debyl.io the NUT server and gives it the ability to power TrueNAS
back on over IPMI.
Outage sequence
| When | What happens | Driven by |
|---|---|---|
| t+0 | UPS goes on battery, ONBATT logged to journald → Graylog |
upsmon |
| t+2min | TrueNAS shuts itself down cleanly, shedding ~200 W | TrueNAS UPS service, Slave mode, Shutdown Timer 120 |
| 10% charge | home.debyl.io shuts itself down and tells the UPS to cut its output |
upsmon SHUTDOWNCMD + /lib/systemd/system-shutdown/nutshutdown |
| mains returns | UPS re-energizes; both machines power themselves back up | R415 always-on restore policy; home.debyl.io BIOS After Power Loss → Power On |
| mains back +5min | Best-effort IPMI power-on, if a dedicated iDRAC is ever fitted | upssched → ups-restore.sh |
| host boot | Same restore check, for the deep-drain case | ups-restore.service |
The 10% threshold is not a custom poller. CyberPower asserts its own low-battery
flag around 20–35%, so ups.conf sets ignorelb plus
override.battery.charge.low, and stock upsmon fires at exactly the
configured percentage.
Likewise, the 2-minute TrueNAS shed is TrueNAS's own native "shutdown timer" setting — no SSH key and no shutdown script from this side.
Powering TrueNAS back on
Neither Wake-on-LAN nor IPMI works on this box today, so restore is done with the chassis power restore policy instead.
Wake-on-LAN is out. bce0 advertises no WOL capability (ifconfig -m bce0
has no WOL_MAGIC) and both NICs are bonded into an LACP lagg0.
IPMI is out too, for now. The iDRAC is in shared / LOM1 mode and the
Enterprise card that would provide a dedicated management port is not fitted:
$ ipmitool sdr elist | grep -i idrac
iDRAC6 Ent Pres | 70h | ok | 7.1 | Absent
A shared-LOM iDRAC6 Express has no standby power. Measured directly: with the chassis powered off the BMC does not even answer ARP, and it only reappears ~200s into POST, at the moment the host brings the NIC link up. That is a hardware limitation, not a switch or BIOS problem.
So restore works like this instead. ipmitool chassis policy always-on is
set on the R415. On a deep outage home.debyl.io halts at 10% and NUT's
shutdown hook tells the UPS to cut its output; when mains returns the UPS
re-energizes, the R415 sees AC and boots itself.
The gap is the medium outage — mains returns after TrueNAS has shed but before
the battery reaches 10%. The UPS never cuts power, so TrueNAS stays off and
needs a manual power button press. Fitting a used iDRAC6 Enterprise card and
running ipmitool delloem lan set dedicated (plus a cable to the dedicated
port) closes that gap, and ups-restore.sh starts working with no code
changes — it is already deployed and simply logs and exits while the BMC is
unreachable.
One-time setup outside Ansible
These are not managed by this role.
iDRAC (already done, via ipmitool on TrueNAS):
ipmitool lan set 1 ipsrc static
ipmitool lan set 1 ipaddr 192.168.1.12
ipmitool lan set 1 netmask 255.255.255.0
ipmitool lan set 1 defgw ipaddr 192.168.1.1
ipmitool lan set 1 access on # was disabled - nothing answers without this
ipmitool channel setaccess 1 2 callin=on ipmi=on link=on privilege=4
ipmitool user set password 2 '<idrac_password>'
ipmitool chassis policy always-on # this is what restores power after an outage
idrac_password is also the iDRAC web UI password for root - they share a
user database.
TrueNAS UI → Services → UPS (enable + start automatically):
| Field | Value |
|---|---|
| UPS Mode | Slave |
| Remote Host | 192.168.1.10 |
| Remote Port | 3493 |
| Identifier | cyberpower |
| Monitor User | truenas |
| Monitor Password | vault nut_truenas_password |
| Shutdown Mode | UPS goes on battery |
| Shutdown Timer | 120 |
| Shutdown Command | /sbin/shutdown -p now |
| Power Off UPS | unchecked |
BIOS on home.debyl.io (Lenovo 10MR0004US): Power → After Power Loss →
Power On. On a full drain the NUT shutdown hook
(/lib/systemd/system-shutdown/nutshutdown) tells the UPS to cut its own
output; this BIOS setting is what brings the host back when mains returns.
Vault keys
nut_upsmon_password, nut_truenas_password, idrac_password
Operating
upsc cyberpower # full UPS status
upsc cyberpower battery.charge
sudo /usr/local/bin/truenas-power.sh status|on|soft|off
journalctl -t ups-restore -t ups-sched