5776dbe1bf
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>
130 lines
3.0 KiB
YAML
130 lines
3.0 KiB
YAML
---
|
|
# NUT server. The UPS is on USB here, so this host drives it and serves
|
|
# status to truenas.localdomain over the network.
|
|
|
|
- name: set NUT run mode to netserver
|
|
become: true
|
|
ansible.builtin.template:
|
|
src: nut.conf.j2
|
|
dest: /etc/ups/nut.conf
|
|
owner: root
|
|
group: nut
|
|
mode: '0640'
|
|
notify:
|
|
- reload nut driver units
|
|
- restart nut driver
|
|
- restart nut server
|
|
- restart nut monitor
|
|
tags: ups
|
|
|
|
- name: deploy NUT driver configuration
|
|
become: true
|
|
ansible.builtin.template:
|
|
src: ups.conf.j2
|
|
dest: /etc/ups/ups.conf
|
|
owner: root
|
|
group: nut
|
|
mode: '0640'
|
|
notify:
|
|
- reload nut driver units
|
|
- restart nut driver
|
|
- restart nut server
|
|
tags: ups
|
|
|
|
- name: deploy upsd listener configuration
|
|
become: true
|
|
ansible.builtin.template:
|
|
src: upsd.conf.j2
|
|
dest: /etc/ups/upsd.conf
|
|
owner: root
|
|
group: nut
|
|
mode: '0640'
|
|
notify: restart nut server
|
|
tags: ups
|
|
|
|
- name: deploy upsd users
|
|
become: true
|
|
ansible.builtin.template:
|
|
src: upsd.users.j2
|
|
dest: /etc/ups/upsd.users
|
|
owner: root
|
|
group: nut
|
|
mode: '0640'
|
|
notify:
|
|
- restart nut server
|
|
- restart nut monitor
|
|
tags: ups
|
|
|
|
- name: deploy upsmon configuration
|
|
become: true
|
|
ansible.builtin.template:
|
|
src: upsmon.conf.j2
|
|
dest: /etc/ups/upsmon.conf
|
|
owner: root
|
|
group: nut
|
|
mode: '0640'
|
|
notify: restart nut monitor
|
|
tags: ups
|
|
|
|
- name: deploy upssched configuration
|
|
become: true
|
|
ansible.builtin.template:
|
|
src: upssched.conf.j2
|
|
dest: /etc/ups/upssched.conf
|
|
owner: root
|
|
group: nut
|
|
mode: '0640'
|
|
notify: restart nut monitor
|
|
tags: ups
|
|
|
|
# The nut package ships /usr/lib/udev/rules.d/62-nut-usbups.rules, which
|
|
# hands the UPS USB device to the nut user. Reload and retrigger so the
|
|
# driver can claim it without physically replugging the UPS.
|
|
- name: reload udev rules for NUT USB access
|
|
become: true
|
|
ansible.builtin.command:
|
|
cmd: udevadm control --reload-rules
|
|
changed_when: false
|
|
tags: ups
|
|
|
|
- name: retrigger UPS USB device
|
|
become: true
|
|
ansible.builtin.command:
|
|
cmd: >-
|
|
udevadm trigger --subsystem-match=usb
|
|
--attr-match=idVendor={{ ups_vendorid }}
|
|
changed_when: false
|
|
tags: ups
|
|
|
|
# nut-driver-enumerator reads ups.conf and generates nut-driver@{{ ups_name }}.
|
|
# The .service is oneshot (so never "started" for long) and is triggered by
|
|
# the .path unit watching ups.conf - enable both, but only start the .path.
|
|
- name: enable NUT driver enumerator
|
|
become: true
|
|
ansible.builtin.systemd:
|
|
name: nut-driver-enumerator.service
|
|
enabled: true
|
|
daemon_reload: true
|
|
tags: ups
|
|
|
|
- name: enable and start NUT driver enumerator path trigger
|
|
become: true
|
|
ansible.builtin.systemd:
|
|
name: nut-driver-enumerator.path
|
|
enabled: true
|
|
state: started
|
|
tags: ups
|
|
|
|
- name: enable and start NUT services
|
|
become: true
|
|
ansible.builtin.systemd:
|
|
name: "{{ item }}"
|
|
enabled: true
|
|
state: started
|
|
loop:
|
|
- "nut-driver@{{ ups_name }}.service"
|
|
- nut-server.service
|
|
- nut-monitor.service
|
|
- nut.target
|
|
tags: ups
|