bobbintb Posted August 31, 2019 Share Posted August 31, 2019 (edited) I'm trying to think of a way to power on a specific VM using a power button. I want to get it as close operating a normal PC as possible. Either wake it from the attached mouse/keyboard or some kind on custom made button or something that powers it on. Maybe it sends a WOL packet. I know sending a WOL packet from my phone is an option but that's not quite what I'm looking for. Any ideas? Anyone know what options there are? Maybe even something like a hacked Amazon Dash button or Raspberry Pi Zero or something? Or something less complicated. Edited August 31, 2019 by bobbintb 1 Quote Link to comment
meep Posted September 8, 2019 Share Posted September 8, 2019 I have a similar need for one of my VMs that occasionally locks up. The screen and keyboard/mouse is some distance from my unRaid server so I need to find a way to force reset the vm that’s easy for the family. Fortunately, I’m into home automation and have a Node-Red docker running on my server. In there, I’ll be able to set up a flow to call virsh reset and power on commands to the unRaid server. Once that’s set up, I’ll just need to trigger them. One idea is to use an amazon echo so it can be done via voice eg “Alexa, turn on the computer”. another is to use a physical button such as this z-wave remote to get the job done: https://amzn.to/2ZX1MF9 it's a high priority project for me so will be done soon. I’ll report back on success, or otherwise. Quote Link to comment
bobbintb Posted September 11, 2019 Author Share Posted September 11, 2019 On 9/7/2019 at 3:04 PM, TSM said: That's useful, thanks. I'd still like to keep power button functionality though, if possible. Quote Link to comment
mtongnz Posted July 27, 2020 Share Posted July 27, 2020 (edited) I know this is a slightly older thread but I thought I'd share what I've done. The power button on my rig will power the system on as normal. I'd imagine holding it once on will force a power off but I don't really want to test this - worst case, I can just pull power. If I want to shutdown the server, I use the web gui. Once unRaid is botoed, the power button will toggle my Windows VM on or off. In Windows power management, I've set it so the power button puts the machine to sleep - this makes it start up faster. First create a script in User Scripts. I called mine vmStartStop and it toggles a VM called Windows 10. #! /bin/bash # if domain is running, shut down if virsh list | grep "Windows 10 .*running" ; then virsh shutdown "Windows 10" # resume domain if it's paused elif virsh list | grep "Windows 10 .*paused" ; then virsh resume "Windows 10" elif virsh list | grep "Windows 10 .*pmsuspended" ; then virsh dompmwakeup "Windows 10" # otherwise start domain else virsh start "Windows 10" fi Than edit /etc/acpi/acpi_handler.sh as per the post above. Change the power line to point at your user script (the path is at the top of the edit script page). Don't forget the . at the start of the line: power) . /boot/config/plugins/user.scripts/scripts/vmStartStop/script Hope this helps someone. Edited July 27, 2020 by mtongnz 1 Quote Link to comment
naughty beatle Posted July 27, 2020 Share Posted July 27, 2020 Thanks for sharing @mtongnz. Here's my script I guess I'll share as well. This has more special haling built in for 1 GPU/multiple VM configurations to check and shutdown other VMs. In a way I like your simplified approach better but if you need to check for other running VMs you can steal from some of my functions below. Use at your own risk, I'm not a coder and I don't have much bash scripting experience. Hopefully the experts on this forum can give me some feedback on what I can improve, I would really appreciate that! Particularly, I'm calling this script from Home-Assistant and the only way I know how to is via SSH as the root user, would prefer a more secure solution if anybody has any suggestions. Here's the User Script: #!/bin/bash # Script for starting stopping VMs via homeassitant # Takes two arguments, a command (start or stop) and a VM name. # If a start command issued, the script checks for any running VMs and shuts them down as I have a 1 GPU configuration at home # Personally, I have this script run at array start up so it's loaded into RAM and can be called from the tmp folder by HASS, or manually ## Script includes a function to check for empty arguments or empty space and exits for the above reason (User Scripts provides an empty space as the first argument for some reason) comm="$1" vm_given="$2" #List OSX VMs for special handling osx_vm0="MacinaboxHighSierra" function get_vm_names { readarray -t vm_list < <(virsh list --all --name) unset vm_list[-1] } function get_vm_state { state=$(virsh domstate "$1") } # This function is not currently invoked, but can be usedful for debugging function get_vm_info { info=$(virsh dominfo "$1") echo -e "$info \n\n" } function check_vm_name { get_vm_names for vm in "${vm_list[@]}" do if [[ "$vm" = "$vm_given" ]]; then echo "$vm_given is a valid VM name, proceding" return 1 else : fi done echo "$vm_given is not a valid VM name, go home" exit } ## Haven't finished writting this part yet, script will just exit at this point for OSX ## Reason for special handling is OSX doesn't shutdown when asked to by qemu function check_if_OSX { if [[ "$vm_given" == "$osx_vm0" ]] || [[ "$vm_given" == "$osx_vm1" ]] || [[ "$vm_given" == "$osx_vm2" ]]; then echo "VM is one of listed OSX VMs, initiating special handling" exit else return 1 fi } function start_vm { echo "Starting $vm_given" virsh start "$vm_given" } function shut_down_vm { echo -e "Sending Shutdown signal to $vm" virsh shutdown "$vm" get_vm_state "$vm" while [ "$state" != "shut off" ]; do vm_down_poll "$vm" done } function vm_down_poll { get_vm_state "$vm" echo "$vm is still running" sleep 1 } function loop_vms_for_shutdown { for vm in "${vm_list[@]}" do get_vm_state "$vm" if [ "$state" == "shut off" ] then echo -e "$vm is $state" else echo -e "$vm is $state, initiaing shutdown" shut_down_vm "$vm" fi #Leaving this here for de-bugging purposes if needed #get_vm_info "$vm" done } ## Checking if arguments were supplied, otherwise exit (or shuttdown all VMs if the flag is enabled to do so) ## Arguments will be provided by HASS automation (or you can manually invoke this via command line). ## Example of how to call this script from the terminal: /tmp/user.scripts/tmpScripts/00_start_stop_VMs/script start "Ubuntu" if [[ $# -eq 0 ]] || [[ "$1" == "" ]]; then if [[ shutdown_all == "enabled" ]]; then echo "No arguments supplied, shutting down all running VMs"; loop_vms_for_shutdown; else echo "No arguments provided"; fi elif [[ "$1" == "start" ]]; then echo "Starting $2 VM, shutting down other running VMs first" check_vm_name "$2" loop_vms_for_shutdown sleep 5 start_vm elif [[ "$1" == "stop" ]]; then echo "Shutting down $2 VM" check_vm_name "$2" shut_down_vm "$2" else echo "Ok I don't what you're trying to do here, $1 doesn't mean anything to me" fi Here's the switch configured in Home-Assistant (in configuration.yaml). Once it's an entity in HASS there are endless possibilities for adding buttons or starting/stopping VMs via automation. switch: - platform: command_line switches: win10_vm: command_on: "ssh [email protected] '/tmp/user.scripts/tmpScripts/00_start_stop_VMs/script start \"Windows 10\"'" command_off: "ssh [email protected] '/tmp/user.scripts/tmpScripts/00_start_stop_VMs/script stop \"Windows 10\"'" command_state: "ssh [email protected] 'if [[ $(virsh domstate \"Windows 10\") == \"shut off\" ]]; then echo 1; else echo 0; fi'"" value_template: '{{ value == "0" }}' friendly_name: Windows 10 VM ubuntu_vm: command_on: "ssh [email protected] '/tmp/user.scripts/tmpScripts/00_start_stop_VMs/script start \"Ubuntu\"'" command_off: "ssh [email protected] '/tmp/user.scripts/tmpScripts/00_start_stop_VMs/script stop \"Ubuntu\"'" command_state: "ssh [email protected] 'if [[ $(virsh domstate \"Ubuntu\") == \"shut off\" ]]; then echo 1; else echo 0; fi'" value_template: '{{ value == "0" }}' friendly_name: Ubuntu VM 1 Quote Link to comment
planetwilson Posted August 6, 2020 Share Posted August 6, 2020 Thanks for your script @naughty beatle it has given me some ideas. I have some iOS Shortcuts on my daughter and wife's phones which simply make an SSH call with virsh but I don't like it because they have to have my root password in there. I wanted something a bit easier like a button but Alexa and voice control might work too... Did you get to the bottom of clean shutdown of MacOS? I haven't ben able to find a way to get it to respond to the qemu shutdown. I suppose you might need to have something listening inside the VM which initiates the shutdown but that feels very messy Quote Link to comment
bobbintb Posted August 6, 2020 Author Share Posted August 6, 2020 Thank you both @mtongnz and @naughty beatle. I think those both will be very useful for what I am trying to do. Quote Link to comment
planetwilson Posted August 6, 2020 Share Posted August 6, 2020 So using HOOB/Homebridge I’ve got the ability to turn on my VMs by asking Siri using my Apple Watch! Feels quite cool but I would still like to sleep/wake cleanly with macOS Quote Link to comment
Vaggeto Posted August 16, 2021 Share Posted August 16, 2021 On 7/26/2020 at 7:06 PM, mtongnz said: I know this is a slightly older thread but I thought I'd share what I've done. The power button on my rig will power the system on as normal. I'd imagine holding it once on will force a power off but I don't really want to test this - worst case, I can just pull power. If I want to shutdown the server, I use the web gui. Once unRaid is botoed, the power button will toggle my Windows VM on or off. In Windows power management, I've set it so the power button puts the machine to sleep - this makes it start up faster. First create a script in User Scripts. I called mine vmStartStop and it toggles a VM called Windows 10. #! /bin/bash # if domain is running, shut down if virsh list | grep "Windows 10 .*running" ; then virsh shutdown "Windows 10" # resume domain if it's paused elif virsh list | grep "Windows 10 .*paused" ; then virsh resume "Windows 10" elif virsh list | grep "Windows 10 .*pmsuspended" ; then virsh dompmwakeup "Windows 10" # otherwise start domain else virsh start "Windows 10" fi Than edit /etc/acpi/acpi_handler.sh as per the post above. Change the power line to point at your user script (the path is at the top of the edit script page). Don't forget the . at the start of the line: power) . /boot/config/plugins/user.scripts/scripts/vmStartStop/script Hope this helps someone. Hello, this is very helpful! Are you able to provide any recommendations on editing the acpi_handler file on each boot? Is it just a script that runs on startup to modify that line of code? Or replace the entire acpi_handler file each time? Any example of how this can/should be done? I tried googling but am not coming up with anything that's helpful for someone without a ton of experience. Quote Link to comment
mtongnz Posted August 18, 2021 Share Posted August 18, 2021 I have a user script that overwrites the entire file. I have it set to run "At First Array Start Only" Quote Link to comment
Adem Posted October 13, 2021 Share Posted October 13, 2021 On 7/27/2020 at 2:06 AM, mtongnz said: I know this is a slightly older thread but I thought I'd share what I've done. The power button on my rig will power the system on as normal. I'd imagine holding it once on will force a power off but I don't really want to test this - worst case, I can just pull power. If I want to shutdown the server, I use the web gui. Once unRaid is botoed, the power button will toggle my Windows VM on or off. In Windows power management, I've set it so the power button puts the machine to sleep - this makes it start up faster. First create a script in User Scripts. I called mine vmStartStop and it toggles a VM called Windows 10. #! /bin/bash # if domain is running, shut down if virsh list | grep "Windows 10 .*running" ; then virsh shutdown "Windows 10" # resume domain if it's paused elif virsh list | grep "Windows 10 .*paused" ; then virsh resume "Windows 10" elif virsh list | grep "Windows 10 .*pmsuspended" ; then virsh dompmwakeup "Windows 10" # otherwise start domain else virsh start "Windows 10" fi Than edit /etc/acpi/acpi_handler.sh as per the post above. Change the power line to point at your user script (the path is at the top of the edit script page). Don't forget the . at the start of the line: power) . /boot/config/plugins/user.scripts/scripts/vmStartStop/script Hope this helps someone. here how i "overwrite" it after first array start with user scripts: #!/bin/bash sed -i 's|power) /sbin/init 0|power) . /boot/config/plugins/user.scripts/scripts/vmStartStop/script|g' /etc/acpi/acpi_handler.sh Quote Link to comment
bobbintb Posted March 10, 2022 Author Share Posted March 10, 2022 I can't believe it's been this long but I have an update. I have a physical power button that will start, stop, and restart my VM. Here is a guide I plan on updating when I get some more time: Quote Link to comment
miibrito92 Posted May 24, 2023 Share Posted May 24, 2023 On 10/13/2021 at 9:55 PM, Adem said: here how i "overwrite" it after first array start with user scripts: #!/bin/bash sed -i 's|power) /sbin/init 0|power) . /boot/config/plugins/user.scripts/scripts/vmStartStop/script|g' /etc/acpi/acpi_handler.sh I did this but my power button still shuts down my unraid server. Any tips? Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.