知りたいこと

VirtualBox仮想マシン(以下VM)のOSが起動完了したことを検知する方法


状況

VirtualBoxでVMを立ち上げて開発等の作業をしています。

今まで作業開始時に、VMの立ち上げ、SSHログイン等を手動で行ってきましたが、自動化できないかと思い、シェルスクリプトにて実現しようとしていますが、一つ壁に当たりました。

VMのOSが起動完了したタイミングが分からない。

というものです。

SSHで接続するところまで自動化しようとすると、OSが(sshdと言ったほうがいいのでしょうか?)起動完了しているかがわからないとSSHが弾かれます。

Virtualboxで仮想マシンが起動完了したことを確認するコマンドはあるのですが、これはあくまでマシンが立ち上がったことを確認できるものであり、OSが立ち上がったかどうかを確認するものではないようです。


現状での妥協案 シェルスクリプト

現状では「OSが立ち上がってる≒SSHでの接続が可能」という認識のもと、逆転の発想で「OSが立ち上がっていない≒SSH接続が弾かれる」という状況を利用しています。

自分の環境ではVMのOSが起動に大体1分くらいかかるので、まず1分ウエイトしてから、SSH接続が成立するまで繰り返し試行する方法をとるものです。以下は下手で恥ずかしいですが、作成したシェルスクリプトです。

#!/bin/bash

white_green="\e[37;42;1m"
white_red="\e[37;41;1m"
colorEnd="\e[m"

#引数確認
if [ $# -eq 0 ]; then
    /bin/echo -e "${white_red}VM名を指定してください${colorEnd}"
    exit 1
fi

VBoxManage list vms | grep "$1";isvms=$?
if [ $isvms -ne 0 ]; then
    /bin/echo -e "${white_red}指定されたVM名は存在しません${colorEnd}"
    /bin/echo -e "${white_red}存在するVM名は以下です${colorEnd}"
    VBoxManage list vms
    exit 1
fi

#起動確認
VBoxManage list runningvms | grep "$1";isRunning=$?
if [ $isRunning -eq 0 ]; then
    /bin/echo -e "${white_red}$1はすでに起動しています${colorEnd}"
    exit 1
fi

#VM起動
VBoxManage startvm "$1" --type headless > /dev/null 2>&1
/bin/echo -e "${white_green}VM起動${colorEnd}"
#OSが起動するまでに約1分かかるのでウエイトを挟む
e=0
/bin/echo -e "${white_green}OS起動待機中(60秒待ちます)${colorEnd}"
for e in 0 5 10 15 20 25 30 35 40 45 50 55 60; do
    echo -n "$e秒…\r" 
    sleep 5s
done

#ssh接続
vmname="ssh -p22 -i ~/.ssh/id_rsa hoge@host"
count=0
/bin/echo -e "${white_green}ssh接続中…${colorEnd}"
until eval ${vmname}
do
    echo -n "…"
    sleep 5s    
    count=$((count+1))
    if [ $count -gt 20 ]; then
    /bin/echo -e "${white_red}20回試行したがダメでした${colorEnd}"
    exit 255
    fi    
done 

exit 0

ベストプラクティスは?

一応目的は果たせているのですが、SSHの接続可否を用いるのはいまいちスマートではないように感じています。

VMのOSが立ち上がったタイミングを取得できる方法をご存知のかたよろしくおねがいします。