phpVirtualBox em Go — parte 3: roteiro de implementação e testes

Mascote LinuxPro e cachorro caramelo cyborg em laboratório de virtualização, com PHP, Go e Vue nos monitores.

Antes de começar: conheça o projeto original no artigo phpVirtualBox: gerencie o VirtualBox pelo navegador.

Nesta série: Parte 1: phpVirtualBox, Echo e Vue · Parte 2: IA e OpenSpec · Parte 3: implementação e testes

Série phpVirtualBox em Go — parte 3 de 3. Depois de analisar o phpVirtualBox e organizar a migração com IA e OpenSpec, chegou a hora de definir como implementar e validar o novo painel. O objetivo não é lançar uma reescrita completa de uma vez: é construir uma sequência de entregas verificáveis.

Entrega 1: provar a distribuição, sem tocar em VMs

Comece com um serviço Echo, uma rota de saúde e uma página Vue que consulta essa rota. Compile o frontend e incorpore sua saída usando go:embed. Nessa etapa, o painel não precisa conhecer nenhuma máquina virtual: a pergunta é se a API e a interface funcionam no artefato distribuído.

O Echo possui um exemplo oficial de recursos incorporados, e a documentação do pacote embed descreve como os arquivos são incluídos na compilação. Os caminhos são relativos ao pacote; não planeje incorporar arquivos de diretórios superiores com ../. Gere os arquivos do Vue antes de compilar Go.

Código Vue → build do frontend → web/dist
                                   ↓
Código Go + Echo + go:embed → executável do painel

Critério de aceitação: copie apenas o executável para uma pasta vazia, inicie-o no loopback e confira a página, os arquivos JavaScript e a rota de saúde. Pare o servidor de desenvolvimento do frontend antes desse teste. Isso demonstra a distribuição do painel, mas ainda não demonstra integração com o VirtualBox.

Não incorpore arquivos de ambiente, credenciais ou bancos de dados. Esses itens precisam continuar externos ao binário. Se a interface usar rotas de aplicação, defina o tratamento de caminhos do frontend sem transformar erros de /api/ em uma página HTML com status de sucesso.

Entrega 2: segurança e contratos antes do host real

Antes de liberar o painel para outras pessoas, implemente autenticação, sessão, expiração e autorização. Autenticação identifica o usuário; autorização decide quais máquinas e ações ele pode acessar. Um usuário autenticado não deve ganhar acesso automático a todos os hosts.

A API deve distinguir entrada inválida, falta de autenticação, falta de permissão e falha do serviço externo. Não envie mensagens SOAP completas ou caminhos sensíveis para o navegador. Registre detalhes técnicos de maneira sanitizada no servidor e devolva erros que a interface consiga apresentar.

Para o laboratório inicial, configure o serviço no endereço de loopback e use credenciais de teste. O desenho de produção deve explicitar transporte protegido, configuração externa, gerenciamento de segredos e política de acesso.

Entrega 3: inventário real em modo somente leitura

Implemente um adaptador dedicado à integração. A camada HTTP não deve conhecer cada detalhe de SOAP: ela chama um serviço de inventário que retorna a representação de máquina definida na especificação. Isso permite testar regras sem um host real e, separadamente, testar o adaptador contra o VirtualBox.

Compare os resultados com um conjunto controlado de máquinas: uma desligada, uma em execução e, quando possível, estados adicionais que seu contrato se comprometa a suportar. Registre quais versões e cenários foram realmente verificados. Não use a expressão “compatível com todas as versões” para um teste feito em um único ambiente.

O teste somente leitura deve confirmar que a consulta não dispara comandos de alteração. Não basta a interface esconder botões: essa restrição precisa existir no backend. Limite também o número de consultas e defina timeout para não esgotar conexões quando um host estiver indisponível.

Uma matriz de testes para acompanhar as entregas

Camada O que verificar Evidência esperada
Distribuição API e Vue fora da árvore de código Executável funcionando sem servidor Node
Contrato HTTP Autenticação, campos e erros Testes automatizados por cenário
Adaptador Respostas, falhas e timeout SOAP Fixtures sanitizadas e testes de integração
Interface Carregamento, vazio e falha Testes de navegação e inspeção visual
Operações Estado inicial, resultado e recuperação Execução em VMs descartáveis
Implantação Reinício e retorno à versão anterior Procedimento reproduzido no laboratório

Mocks ajudam a repetir falhas difíceis de provocar, mas não provam compatibilidade com o serviço real. Testes de integração ajudam a validar a comunicação, mas não substituem testes de autorização. Cada camada responde a uma pergunta diferente.

Entrega 4: operações com segurança

Com a leitura validada, eu criaria mudanças separadas para iniciar máquinas, solicitar desligamento, acompanhar operações e, por último, administrar recursos mais delicados. Solicitar desligamento pelo sistema convidado não é a mesma ação que cortar a energia da VM; a interface e as permissões devem distinguir essas operações.

Operações longas merecem um modelo explícito de tarefas: identificador, estado, início, resultado e erro. Após um timeout, o backend precisa consultar o estado real antes de tentar novamente. Repetir automaticamente uma ação pode duplicar trabalho ou produzir um efeito inesperado.

  • Iniciar e desligar: validar estado atual, permissões e acompanhamento.
  • Snapshots: tratar criação, remoção e restauração como ações distintas.
  • Discos: diferenciar remover um vínculo de apagar o arquivo físico.
  • Múltiplos hosts: limitar falhas e permissões por destino.
  • Auditoria: registrar ator, alvo e resultado, sem registrar credenciais.

Antes de liberar escrita, acrescente proteção contra CSRF quando houver autenticação por cookies, autorização por objeto e confirmação clara para operações destrutivas. O laboratório deve usar VMs descartáveis. Snapshot não substitui uma estratégia de backup e restauração testada.

Timeout de escrita não significa operação cancelada

O navegador pode perder a conexão enquanto o hipervisor continua trabalhando. Por isso, o painel precisa distinguir falha confirmada de resultado desconhecido. Depois de um timeout, não ofereça um botão que simplesmente reenvia a mesma operação sem verificar o que aconteceu.

Modelo de operações: solicitação aceita, execução, resultado confirmado ou reconciliação após perda de comunicação.
Resultado desconhecido exige reconciliação. Uma interrupção do HTTP não desfaz uma ação já aceita pelo hipervisor.

Proponho estados internos como accepted, running, succeeded, failed e unknown. Eles pertencem ao painel, não são uma enumeração copiada do VirtualBox. Registre alvo, ator, tipo de ação e identificador da operação antes de informar sua aceitação; após reiniciar, recupere os registros pendentes e consulte o estado real.

Uma chave de idempotência ajuda a reconhecer pedidos repetidos, desde que seja persistida e vinculada à mesma identidade, alvo e ação. Ela não cria execução “exatamente uma vez” entre banco e hipervisor. Se o processo cair entre o envio e o registro do resultado, a reconciliação continua necessária. Nem toda ação tem o mesmo mecanismo de acompanhamento: não assuma que toda chamada SOAP retorna um objeto de progresso.

Teste a falha entre as etapas

  • Requisição recusada antes de tocar no host: nenhuma alteração.
  • Resposta perdida depois da aceitação: operação marcada para investigação, sem repetição automática.
  • Reinício do painel durante a execução: registro recuperável e resultado reconciliado.
  • Usuário perde permissão: novas consultas e ações continuam sujeitas à autorização.
  • Host inacessível: falha isolada, sem bloquear indefinidamente outros pedidos.

Critérios de liberação por entrega

Entrega Só avance quando
Executável Vue e API funcionam em diretório vazio; rotas /api/ inexistentes não retornam o HTML da SPA.
Segurança 401/403 são testados e impedem chamadas SOAP; erros não revelam dados internos.
Inventário GET /api/v1/vms corresponde ao host configurado e não altera VMs.
Escrita Autorização por objeto, acompanhamento e cenários de resultado desconhecido funcionam em VMs descartáveis.
Implantação Backup, reinício e retorno controlado à versão anterior foram ensaiados.

Nos builds, preserve os arquivos de lock do frontend e as dependências Go; registre os comandos e o ambiente que produziram o artefato. Para detalhar a distribuição, veja Vue e Go com embed e Docker.

Rollback do painel não é rollback das máquinas

Voltar ao executável anterior não desfaz um snapshot removido nem restaura um disco apagado. Antes da troca, suspenda novas escritas, acompanhe ou reconcilie operações em andamento e confirme a compatibilidade dos dados persistidos. Reative apenas um controlador de escrita. O painel antigo só deve voltar depois dessa verificação, não como tentativa cega de resolver um erro.

Licença e implantação: duas etapas que não podem ficar para o fim

O arquivo de licença do phpVirtualBox indica GNU GPL versão 3. Reescrever em outra linguagem não é motivo para ignorar a licença do código, dos recursos visuais ou das dependências utilizados. Registre a origem do material reaproveitado e avalie as obrigações aplicáveis antes de distribuir o novo projeto. Licença do projeto original.

Na implantação, mantenha a possibilidade de voltar ao painel anterior, mas não deixe dois controladores executando alterações concorrentes sobre a mesma máquina. Comece com consultas, compare os resultados e libere operações progressivamente. Se a necessidade for mudar de hipervisor, esse é outro trabalho: o guia do ova2xva discute conversão de máquinas para XCP-ng, não substituição da interface de gerenciamento do VirtualBox.

Conclusão da série: distribuir é simples; operar exige evidência

Como projeto de engenharia, a proposta faz sentido se resolver um problema concreto: distribuição mais simples, interface melhor, API clara e manutenção previsível. O phpVirtualBox oferece uma referência valiosa, mas o novo painel precisaria conquistar confiança com testes e compatibilidade, não apenas com uma linguagem diferente.

O primeiro marco deveria ser pequeno e demonstrável: um executável com Echo e Vue incorporado, autenticação e inventário real de VMs em modo somente leitura. IA e OpenSpec podem acelerar o caminho até ele — desde que as tarefas sejam verificáveis e ninguém confunda código gerado com integração validada.

Nesta série: Parte 1: phpVirtualBox, Echo e Vue · Parte 2: IA e OpenSpec · Parte 3: implementação e testes