Go Auto-Shutdown Daemon For Proxmox
Preface
I have two Proxmox servers in my home lab that are always on. One has a TrueNAS virtual machine and a container for running LLMs locally. The other runs Gitea and a MariaDB database in their containers. Other services usually run in other containers, but the ones mentioned are always running. These Proxmox nodes are plugged into a 1000-watt UPS to ensure that I can safely shut everything down during a power outage. That's fine if I'm home when the power is out; what would happen if I wasn't home to shut everything down? I needed something to detect a power outage and safely shut down the various virtual machines and containers running on the Proxmox nodes and then the Proxmox nodes themselves. Some UPSs have a feature that allows connected computers to react to the status of the UPS, but my UPS does not have that feature. Replacing my UPS did cross my mind, but it still works fine, and I knew I would have more fun building my solution.
Ping
I wondered if I could use ping to detect a power outage. I considered the obvious drawback: network outages would be indistinguishable. I concluded that it would be of no consequence if I pinged another node on my network that's not on a UPS. After all, if my home network is down and the power is still on, I will probably be dealing with a bigger issue. The node I had in mind that I could ping is a DNS server running on a Raspberry Pi. I decided this would be perfect because it's always on and doesn't do anything besides DNS. To make this work, I needed a way to send a ping, capture and check the result, and take action if needed. I considered doing all this in bash but ultimately wrote a daemon using Go.
Daemon
Go was chosen because it can be compiled into a native binary, and the available libraries would make this easier. These are the libraries used.
- go-systemd
- Provides the ability to interact with Systemd and log events to the Systemd journal
- Cobra
- Provides the ability to easily create commands for starting the daemon
- pro-bing
- Provides the ability to send ICMP packets from Go
The other packages used are part of the Go standard library: "os" and "time." I wanted to be able to start the daemon with a command that takes one argument: the IP address to which ICMP packets will be sent. The daemon sends an ICMP packet every minute and tracks failures. If 5 ICMP packets go unanswered, the daemon issues shutdown commands to the virtual machines and containers running on the Proxmox node and finally shuts down the Proxmox node. If you are interested in seeing the code, please visit my GitHub.
Form Builder - Learning Drag-and-Drop
I made a form builder!
It's a drag-and-drop form builder application and supports basic form elements. The grid style layout and snapping means it's easy to build a form that looks nice. Form elements use Bootstrap 4. All of the JavaScript for adding, removing, dragging, and dropping form elements is plain JavaScript, no jQuery here.
I avoided using jQuery's draggable() method because I wanted to learn how drag-and-drop worked with plain JavaScript. I had a lot of fun building this little form builder application. Check out the application here or the source code here.