## 知りたいこと

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が起動するまでに約１分かかるのでウエイトを挟む
    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が立ち上がったタイミングを取得できる方法をご存知のかたよろしくおねがいします。
CC BY-SA 3.0
2016-01-22T02:52:29.870
21166
2016-03-22T06:34:10.070
2020-06-17T08:14:45.997
-1
13295
question
linux shellscript virtualbox
VirtualBox仮想マシンのOS起動完了を検知する方法
一般論として「ＯＳが起動した」ということをどう定義しましょうか。  
\- OS Kernel 部がロードされた状況（まだ daemon/service 類は起動していない）  
\- コンソールログインができる状況  
\- GUI ログインができる状況  
\- 使いたい daemon/service 類が接続を受け付ける状況

今回の場合、使いたいのは [ssh](/questions/tagged/ssh "'ssh' のタグが付いた質問を表示") なので  
\- [ssh](/questions/tagged/ssh "'ssh' のタグが付いた質問を表示") で接続しようとして、できたら
[ssh](/questions/tagged/ssh "'ssh' のタグが付いた質問を表示") 起動済み  
というのが最適（つまり現状が最適）だと、オイラ個人としては思います。

同様  
\- [mysql](/questions/tagged/mysql "'mysql' のタグが付いた質問を表示") に接続しようとして、できたら
[mysql](/questions/tagged/mysql "'mysql' のタグが付いた質問を表示") 起動済み  
\- [http](/questions/tagged/http "'http' のタグが付いた質問を表示") 接続しようとして、できたら
[apache](/questions/tagged/apache "'apache' のタグが付いた質問を表示") 起動済み  
ってことだと思います ([mysql](/questions/tagged/mysql "'mysql' のタグが付いた質問を表示") や
[apache](/questions/tagged/apache "'apache' のタグが付いた質問を表示") が自動起動/手動起動のどっちでも）。

こういうとき、よく `ping` が通ったら・・・という回答を見かけますが  
`ping` が通ってもそれは単に `ICMP` 起動済みでという意味でしかないのであまり役に立たないっす。  
（目的のサービスはまだ実行されていないかもしれない）

使いたいサービスに対して接続できたらＯＫ以上に確実な方法は無いでしょう。
CC BY-SA 3.0
2016-01-22T05:17:28.977
21173
2016-01-22T05:17:28.977
8589
21166
answer