I was tired of spamming F11 when I want to switch between Linux and Windows. I also wanted to be able to switch between Linux and Windows from home assistant.
So, I developed a grub module and server daemon that can remotely set the default boot option in grub.
I’ve tried to make it as user-friendly as possible. The default entry for a mac address can be set by writing to a fifo at /tmp/remote-bootselect/config. The full details are in the readme. The docker container also has MQTT integration built in, so it’s easy to connect it to home assistant. You just have to send MQTT the discovery message for home assistant.
The protocol works on layer 2. The grub module will send broadcast packet with my custom ethertype. The server listens for that ethertype and will respond with the default entry data for the source mac address of the packet it received. The grub module will listen for this response, and then set the default boot entry. The grub module will timeout after 500ms if it doesn’t get a response, and won’t touch the default entry in that case.
This is a full solution to these questions:
I’d appreciate any feedback or suggestions to improve this. I don’t have it in any distro repositories yet, so it has to be manually installed.
Thanks for sharing. Adding the capability to grub to pull input (a boot entry) via api call (ultimately it should be an api) is quite interesting.
I have to admit that I struggle with the use case for it.
I am not sure how much is gained if the boot entry selection needs to happen during the boot process (a human receiving a pop-up from Home Assistant, e.g. allowing to tap an entry from a list). It feels technically complicated compared to more traditional remote-control solutions, such as (Pi-)KVM
if the decision of the boot entry for the next boot is taken while the computer is still running, I feel there may be an easier solution for that, too.
That leaves the scenario where the boot entry selection needs to be taken when the computer is shut down, but independent from the boot process itself (“whenever the computer will boot next - start Windows”). I assume that the real use case lies in this scenario, but more from an automation point of view: start into windows by default (when someone sits in front of computer intending to work interactively), but enable a HA automation that boots into, say Linux, starting some workload (folding@Home, cryptomining, AI training, …)
I typically solve that last use case with virtualization (start either a Windows VM or a Linux VM).
But technically interesting as a capability nonetheless.
The server saves the boot entry in memory. You don’t have to push the button on home assistant only when it boots. You can push it at any time, and the next time grub starts, it will get that latest boot option from the server.
In a way, it already has an API through the named pipe it listens to for configuration information. I’ve integrated it with home assistant by subscribing to an MQTT topic and forwarding that to the pipe. You can see how that works in entrypoint.sh.
I created this because I wanted the functionality of your last point. I can have a button in home assistant that says ‘reboot into windows’ or ‘reboot into linux’, assuming I have a home assistant agent running on windows and linux.
I could extend this to allow grub to read any environment variable from the network, but I don’t have a use case for that. The only other environment variable I might use is timeout, but since I can read the default entry from the network, there’s no need for a timeout anymore.