Geralmente eu costumo rodar algumas máquinas virtuais no notebook para efetuar testes e configurações personalizadas, mas se eu tento executar mais de 3 VMs ao mesmo tempo meu notebook não aguenta o tranco.
Obviamente que a solução seria trocar de notebook e pegar um mais potente, mas para mim a máquina atual está de bom tamanho, ao invés de trocar de hardware por que não usar o poder de processamento e memória disponíveis em meu antigo core 2 duo com windows 7 que fica na sala e possuí o virtualbox instalado?
No próprio site do virtualbox é indicado o uso do phpvirtualbox mas eu descartei essa possibilidade pois é necessário ter um webserver instalado com php e isso já basta como um problema!
Como tenho preguiça de ter que ir até ele toda hora para realizar alguma ação no virtualbox e o mesmo possuí o python instalado, resolvi criar uma simples aplicação web com python3 e bottle para manipular o virtualbox do meu antigo pc pelo navegador, para pelo menos iniciar e salvar o estado da VM.
Sim eu poderia ter configurado o acesso remoto na maquina mas qual a graça que teria isso ? =D
O virtualbox possuí uma API para python através de seu sdk, porém pelo que andei vendo pelo web o mesmo não é muito estável e nada fácil de utilizar, por conta disso eu criei um módulo em cima da linha de comando do virtualbox que aparentemente é mais estável e não quebra a cada atualização (apesar de reportar uns erros sem sentido).
Segue abaixo o módulo em torno da linha de comando do virtualbox
""" Simple wrapper around VirtualBox command line however this don't support the full command line This is a free software, use like you want.""" # Author: rafael@sourcecode.net.br import sys import re from subprocess import Popen, PIPE from os import path class VBoxManage(object): def __init__(self, PATH): # Check OS if "win" in sys.platform: # Set path for Windows OS self.PATH = path.join(PATH, "VBoxManage.exe") # Set path for Linux/Unix OS self.PATH = path.join(PATH, "VBoxManage") def get_vms(self, run=False): """Get vms from VBoxManage list vms output and return into a dict. if 'run' arg is set True, will return only running vms""" # Check run arg if run: cmd = Popen(["%s" % self.PATH, "list", "runningvms"], stdout=PIPE) else: # Run list vms command cmd = Popen(["%s" % self.PATH, "list", "vms"], stdout=PIPE) # Dicty that will receive vms name and uuid VMs = {} # Parse output list and add name and uuid into dict for vm in cmd.stdout.readlines(): name = re.search(r'".*"', str(vm)).group().strip("\"") uuid = re.search(r'{.*}', str(vm)).group().strip("{}") VMs[name] = uuid return VMs def control_vm(self, name, action): """Control vm from the name or uuid given You can start|poweroff|savestate|reset""" # Check if the action is start with is not on controlvm command if action == "start": cmd = Popen(["%s" % self.PATH, "startvm", "%s" % name], stdout=PIPE, stderr=PIPE) # Control VM with the given action cmd = Popen(["%s" % self.PATH, "controlvm", "%s" % name, "%s" % action], stdout=PIPE, stderr=PIPE) # check if method poll is None with means that is still running. while cmd.poll is None: pass # Get stdout and stderr out, err = cmd.communicate() # If something get wrong then return it if err: return err return out def get_vm_info(self, name): """Get Information about given vm""" cmd = Popen(["%s" % self.PATH, "showvminfo", "%s" % name], stdout=PIPE, stderr=PIPE) # check if cmd still running while cmd.poll is None: pass out, err = cmd.communicate() if err: return err return out
Obviamente o módulo não cobre todas as opções disponíveis pela linha de comando, eu apenas acrescentei as que são necessárias para mim, mas acredito que não será nada difícil acrescentar outras opções caso deseje.
A aplicação no bottle é bem simples também, basicamente fará um import do módulo mostrado acima e utilizará o PATH completo para o VBoxManage que é a interface da linha de comando do virtualbox.
É necessário a informação completa do PATH do VboxManage para que a aplicação funcione corretamente, no meu caso eu estou utilizando o virtualbox instalado no windows 7 em uma partição diferente da padrão, localizado em E:\Rafael\Documentos\VirtualBox onde o padrão geralmente é em C:\Program Files\.
A aplicação funciona no linux também e o path tem que ser informado corretamente, geralmente o VBoxManage no linux se encontra em /usr/bin.
Segue abaixo a aplicação bottle
import bottle from vbox.VBoxManage import VBoxManage # VBoxManage instance with full PATH of VirtualBox manage = VBoxManage("E:\Rafael\Documentos\VirtualBox") @bottle.route("/", ["GET", "POST"]) def index(): # Get all available VMs vms = manage.get_vms() # Set action as None for GET requests work action = None # Check if request method is a POST if bottle.request.method == "POST": # Get action option and name for some Virtual Machine VM, action = bytes.decode(bottle.request.body.read()).split("=") # Replace all "+" character with one empty space " " VM = VM.replace("+", " ") # Run action for given VM action = manage.control_vm(VM, action) return bottle.template("index.html", vms = vms, output = action) @bottle.route("/Running") def running(): vms = manage.get_vms(run=True) return bottle.template("running.html", vms = vms) @bottle.route("/vm/") def vm(name): info = manage.get_vm_info(name) return bottle.template("vm.html", name = name, info = info) bottle.debug(True) bottle.run(host="0.0.0.0", port=8082)
Perceba que na variável manage onde eu obtenho uma instância do VBoxManage eu informo o path da instalação do virtualbox.
Eu não me preocupei muito com a interface, um simples html com os devidos links e botões dentro de um form para realizar as alterações estão de bom tamanho para mim.
Veja a aplicação em execução
Index listando as maquinas existentes |
Iniciando uma VM (geralmente o VBoxManage apresenta esse erro estranho mas a máquina inicia sem problemas) |
/running lista as VMs que estão em execução no momento. |
/vm/VMname mostra informações a respeito da Maquina Virtual |
Salvando o estado da Máquina Virtual |
A aplicação cumpre seu papel e executa as operações sem problema, muito embora a linha de comando do virtualbox informe uma mensagem de erro que não interfere com o processo da solicitado para determinada máquina virtual.
Para instalar no windows é simples, assumindo que você tenha o python3.3 instalado, crie um ambiente isolado com o virtualenv
C:\Python33\python.exe -m venv D:\vboxweb
Acesse o diretório criado e ative o ambiente
Scripts\active.bat
Baixe o bottle aqui, descompacte o instale da seguinte forma
python setup.py install
Ou você pode simplismente instalar o bottle através do pip ou easy_install caso os tenha instalado.
Baixe a aplicação aqui e descompacte dentro do diretório criado com o virtualenv
Dentro da pasta da aplicação vbox edite o arquivo vbox_web.py e altere a linha 8 informando o PATH completo da instalação do seu virtualbox
manage = VBoxManage("INFORME O PATH AQUI")
Agora basta executar a aplicação
python vbox_web.py
Se você não alterou a porta de execução basta acessar localhost:8082 ou seuip:8082 para acessar a aplicação.
Para facilitar você pode adicionar o seguinte arquivo .bat na rais do diretório virtual
cd vbox @echo Running vbox_web.py ..\Scripts\python.exe vbox_web.py pause
E com um clique nesse aquivo .bat você executa a aplicação.
Na primeira vez que tentar executar o windows perguntará se você deseja liberar a porta em que a aplicação está sendo executada e para que funcione você terá que liberá-la.
run.bat em execução, com informações de requisição a aplicação |