備忘録のため,内容の正当性については責任を持ちません。

今まで何度か書いてきたが、結局某所の共用サーバは Ubuntu 10.04 + VirtualBox 3.2 で仮想化することにした。

しかし、VirtualBox を複数のユーザで使用するのは実用的でないことがわかった。また、vboxweb という Web ベースの管理ツールがあるが、Linux 上ではまともに動作しなかった。

そこで、各仮想マシンはひとつのアカウントで管理することにし、利用者には Web ベースの管理 (遠隔操作) ツールを自作して提供することにした。といっても、そんなに高機能なツールを作る体力がなかったので、とりあえずマシンの一覧表示と起動ができるようにした。そのときのことをメモしておく。

作成した簡易的な管理ツール



Apache のインストール

今回のツールは Perl/CGI で作成することにする。そのために、まずホストの Ubuntu に Apache をインストールする。

  1. apt-get で Apache をインストールする。
    $ sudo apt-get install apache2
  2. Apache を UserDir で使用できるようにする。
    $ sudo a2enmod userdir
  3. UserDir で CGI を実行できるようにする。
    $ sudo vi /etc/apache2/mods-enabled/userdir.conf
    <IfModule mod_userdir.c>
        UserDir public_html
        UserDir disabled root

        <Directory /home/*/public_html>
            AllowOverride FileInfo AuthConfig Limit Indexes
            Options SymLinksIfOwnerMatch IncludesNoExec ExecCGI
            AddHandler cgi-script .cgi .pl
            <LimitExcept GET POST OPTIONS>
                Order deny,allow
                Deny from all
            </LimitExcept>
        </Directory>
    </IfModule>
  4. 初期状態での Apache の実行ユーザ (www-data) では VirtualBox を起動できないので、実行ユーザを変更する。
    $ sudo vi /etc/apache2/envvars

    export APACHE_RUN_USER=www-data
      (変更↓)
    export APACHE_RUN_USER=<VirtualBox を実行するユーザ>

    export APACHE_RUN_GROUP=www-data
      (変更↓)
    export APACHE_RUN_GROUP=<VirtualBox を実行するユーザの属するグループ>
  5. Apache を再起動する。
    $ sudo /etc/init.d/apache2 restart

これで /home/username/public_html 以下で、CGI をユーザ権限で動かせるようになった。

※ はじめ,sudo で実現しようとしたが無理だった。


自作の管理ツール

CGI/Perl で VirtualBox を管理する関数を作成する。基本的に VBoxManage コマンドを叩くだけ。

  • 仮想マシン一覧を取得する関数
    sub get_list {
        my $mode = shift;
        my $result;

        if ($mode eq 'vms') {
            $result = `/usr/bin/VBoxManage list vms`;
        } elsif ($mode eq 'runningvms') {
            $result = `/usr/bin/VBoxManage list runningvms`;
        } else {
            return 0;
        }

        my @lines = split(/\n/, $result);
        my @machines;

        for (my $i = 4; $i <= $#lines; $i++) {
            if ($lines[$i] !~ /^\"([a-zA-Z0-9_\-]+)\"/) { next; }
            my $vm = $1;
            push (@machines, $vm);
        }
        @machines = sort @machines;

        return @machines;
    }
  • 仮想マシンを起動する関数
    sub startvm {
        my $vm = shift;

        # マシンが存在するか確認
        my @vms = &get_list('vms');
        if (!in_array($vm, @vms)) { return 0; }

        # マシンを起動
        my $result = `/usr/bin/VBoxManage startvm -type vrdp $vm`;

        return ($result =~ /VM has been successfully started./);
    }

    sub in_array() {
        my (@arr) = @_;
        my ($val) = shift(@arr);

        foreach my $elem (@arr) {
            if ($val=~m/^[0-9]+$/){
                if ($val == $elem) { return 1; }
            } else {
                if ($val eq $elem) { return 1; }
            }
        }

        return 0;
    }
  • 仮想マシンを強制終了する関数
    sub poweroff {
        my $vm = shift;

        # マシンが稼働中か確認
        my @runningvms = &get_list('runningvms');
        if (!in_array($vm, @runningvms)) { return 0; }

        # マシンをシャットダウン
        my $result = `/usr/bin/VBoxManage controlvm $vm poweroff`;

        return ($result =~ /100\%/);
    }

あとは、適当なフロントエンドを作れば完了。

上記の関数では、VirtualBox を起動するときに -type vrdp として、VRDP モード (バックグラウンドで実行かつリモートディスプレイ機能が有効) にしているのがミソ。これにより、Windows のリモートデスクトップで接続できるようになる。リモートディスプレイ機能の設定は、各マシンの設定で「ディスプレイ」の「リモートディスプレイ」タブで行う。

リモートディスプレイの設定

ちなみに、ホストが起動したときに、自動的に仮想マシンも起動したい場合は、「システム」→「設定」→「自動起動するアプリ」で

VBoxManage startvm -type vrdp <仮想マシン名>

を追加すれば良い。

コメント

コメントする




CAPTCHA