定時シャットダウン用。基本的に全部ディスクにハイバネートして、コンテナとかPCIパススルーとか失敗したVMはシャットダウンする。
shutdown.sh
#!/bin/bash
# VMとコンテナのリストを取得
VMS=$(qm list | awk 'NR>1 {if ($3=="running") print $1}')
CTIDS=$(pct list | awk 'NR>1 {if ($2=="running") print $1}')
# VMをハイバネートする関数
hibernate_vm() {
local vmid=$1
# PCIパススルーをチェック
if qm config ${vmid} | grep -q 'hostpci'; then
echo "VM $vmid はPCIパススルーを使用しているため、シャットダウンします。"
qm shutdown $vmid --timeout 300
else
echo "VM $vmid をハイバネートを試みます..."
if ! qm suspend $vmid --todisk; then
echo "VM $vmid をハイバネートできませんでした。シャットダウンします。"
qm shutdown $vmid --timeout 300
fi
fi
}
shutdown_ct() {
local ctid=$1
echo "コンテナ $ctid をシャットダウンします..."
pct shutdown $ctid
}
# すべてのVMを処理する
for vm in $VMS; do
hibernate_vm $vm
done
# すべてのコンテナを処理する
for ctid in $CTIDS; do
shutdown_ct $ctid
done
# VMとコンテナのシャットダウンが完了するのを待つ
for vm in $VMS; do
while qm status $vm | grep -qw "running"; do
echo "VM $vm がまだシャットダウンしていません。待機中..."
sleep 1
done
done
for ctid in $CTIDS; do
while pct status $ctid | grep -qw "running"; do
echo "コンテナ $ctid がまだシャットダウンしていません。待機中..."
sleep 1
done
done
# 全てのVMとコンテナがシャットダウンした後、ホストをシャットダウン
echo "全てのVMとコンテナをシャットダウンしました。ホストをシャットダウン出来ます..."
shutdown -h now
あとは適当な場所に突っ込んでcrontab -e
とかで定時シャットダウンさせればOK。
なお失敗してVMやコンテナやデータがぶっ壊れても自己責任でお願いします。
また、何らかの原因でVMやらコンテナがロック状態でループした場合の処理を入れてないので、一生シャットダウンできない場合があります。slackのwebhookとかで通知できるようにしたほうが良いかも。