1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Proxmox VEでVM/コンテナをまとめてハイバネート・シャットダウンするスクリプト

Posted at

定時シャットダウン用。基本的に全部ディスクにハイバネートして、コンテナとか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とかで通知できるようにしたほうが良いかも。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?