今まで何度か書いてきたが、結局某所の共用サーバは Ubuntu 10.04 + VirtualBox 3.2 で仮想化することにした。
しかし、VirtualBox を複数のユーザで使用するのは実用的でないことがわかった。また、vboxweb という Web ベースの管理ツールがあるが、Linux 上ではまともに動作しなかった。
そこで、各仮想マシンはひとつのアカウントで管理することにし、利用者には Web ベースの管理 (遠隔操作) ツールを自作して提供することにした。といっても、そんなに高機能なツールを作る体力がなかったので、とりあえずマシンの一覧表示と起動ができるようにした。そのときのことをメモしておく。
Apache のインストール
今回のツールは Perl/CGI で作成することにする。そのために、まずホストの Ubuntu に Apache をインストールする。
- apt-get で Apache をインストールする。
$ sudo apt-get install apache2
- Apache を UserDir で使用できるようにする。
$ sudo a2enmod userdir
- 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>
- 初期状態での 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 を実行するユーザの属するグループ>
- 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 <仮想マシン名>
を追加すれば良い。
コメント