After the host rebooted, truenas began mailing NOCOMM continuously. The UPS driver was fine throughout -- nut-driver@cyberpower stayed running and the CyberPower is still on USB here. What died was upsd, which publishes its state to truenas over the network: upsd: not listening on 192.168.1.10 port 3493 upsd: Fatal error: some listening interfaces were not available nut-server.service: Start request repeated too quickly upsd binds an explicit address, but the packaged unit only orders itself After=network.target, which is satisfied when networking STARTS rather than when an address exists. It tried to bind 11 seconds into boot, before NetworkManager had assigned the address, then burned all five default restart attempts inside one second, tripped the start limit and stayed dead. The shipped unit carries these two lines commented out, because upstream knows the case. network-online.target is the correct ordering; NetworkManager-wait-online is enabled here so it genuinely waits for addresses. StartLimitIntervalSec=0 and RestartSec are belt and braces: a slow address can no longer exhaust the attempts, and retries are spaced instead of hammered. truenas needs no change -- it is a correctly configured SLAVE that reconnected on its own, and its NUT config is regenerated from the middleware database anyway. Verified: upsd listening on both addresses, UPS OL at 100%, and truenas querying it again with zero failures since. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Deploy Home
There's no place like home!
Just as Dorothy managed the simple task of clicking her heels together, the desire for an equally simple one-button push deployment was in my heart. Thus, this repository was made.
Ansible
Ansible, along with double encrypted secrets, deploys the necessary configurations to make the home fit for certain needs and desires. Namely, having access to my home from anywhere, securely, and a self-hosted CI server that easily ties into existing workflows.
Makefile
The makefile is primarily used as a wrapper script to ensure that necessary
files, such as the secret vault password file, are provisioned as part of this.
One such addition to the task is utilizing dependency pinning through the
utilization of Python's virtualenv to lock down the specific dependency
versions within the requirements.txt file. This, ideally, prevents any
deployment issues with dependency version woes (e.g. version conflicts, major
updates in newest versions, etc.)
| Target Name | Description |
|---|---|
lint |
(default) Runs yamllint and ansible-lint on all YAML files in ansible/ |
deploy |
Deploys everything, or only tasks specified in TAGS= environment variable |
check |
Runs deploy in a "dry-run", showing diff-style outputs on tasks indicating changes |
vault |
Opens the Ansible vault file for editing |