#!/bin/bash
#Define bridge device in use on your system!
# E.G: vmbr0 or vmbr1
vmbr="vmbr0"
#We will use UDP port 9
portnr="9"
# fix: 10-12-24 Can now besides starting also "unpause/resume vm's" (also via Moonlight I tested)
# I will give "NO support" nor "emply" that is this code deemed fit for use!
# Use at your own risk! (people should use API instead)
while true; do
sleep 5
wake_mac=$(tcpdump -c 1 -UlnXi ${vmbr} ether proto 0x0842 or udp port ${portnr} 2>/dev/null |\
sed -nE 's/^.*20: (ffff|.... ....) (..)(..) (..)(..) (..)(..).*$/\2:\3:\4:\5:\6:\7/p')
echo "Captured magic packet for address: \"${wake_mac}\""
echo -n "Looking for existing VM: "
matches=($(grep -il ${wake_mac} /etc/pve/qemu-server/*))
if [[ ${#matches[*]} -eq 0 ]]; then
echo "${#matches[*]} found"
echo -n "Looking for existing LXC: "
matches=($(grep -il ${wake_mac} /etc/pve/lxc/*))
if [[ ${#matches[*]} -eq 0 ]]; then
echo "${#matches[*]} found"
continue
elif [[ ${#matches[*]} -gt 1 ]]; then
echo "${#matches[*]} found, using first found"
else
echo "${#matches[*]} found"
fi
vm_file=$(basename ${matches[0]})
vm_id=${vm_file%.*}
details=$(pct status ${vm_id} -verbose | egrep "^name|^status")
name=$(echo ${details} | awk '{print $2}')
status=$(echo ${details} | awk '{print $4}')
if [[ "${status}" != "stopped" ]]; then
echo "SKIPPED CONTAINER ${vm_id} : ${name} is ${status}"
else
echo "STARTING CONTAINER ${vm_id} : ${name} is ${status}"
pct start ${vm_id}
fi
continue
elif [[ ${#matches[*]} -gt 1 ]]; then
echo "${#matches[*]} found, using first found"
else
echo "${#matches[*]} found"
fi
vm_file=$(basename ${matches[0]})
vm_id=${vm_file%.*}
# (Due to 'bug/odd feature' in qm): qm status ${vm_id} -verbose
# will show paused and suspended vms as 'status: running')
# solution querying only name using 'qm status -verbose'
name=$(qm status ${vm_id} -verbose | egrep "^name" | awk '{print $2}')
# And querying the status using just 'qm status'
status=$(qm status ${vm_id} | awk '{print $2}')
#So now it is possible to start/resume stopped/paused/suspended vms!
if [[ "${status}" != "stopped" ]]; then
if [[ "${status}" == "suspended" ]] || [[ "${status}" == "paused" ]]; then
echo "Resuming VM ${vm_id} Status of ${name} was ${status}"
qm resume ${vm_id}
elif [[ "${status}" != "suspended" ]] || [[ "${status}" != "paused" ]]; then
echo "SKIPPED VM ${vm_id} because ${name} is ${status}"
fi
else
echo "STARTING VM ${vm_id} : ${name} is ${status}"
qm start ${vm_id}
fi
done