Imagens e microVMs
Construir microVMs
Antes de leres: Preparar o ambiente, Clonar, compilar e testar, a secção de virtualização do Manual de cloud native, e a Parte 2 de Delonixfile e VMfile.
Esta página leva um contribuidor de um host Linux sem nada até construir, arrancar e testar VMs com o Delonix, e mostra onde vive o código quando algo precisa de mudar. Depois dela consegues preparar um host para o Cloud Hypervisor e o libvirt, prever que backend uma VM recebe, e testar uma mudança de VM através da CLI. Assume que já leste Preparar o ambiente e que consegues construir a árvore (Clonar, compilar e testar).
O que foi verificado para esta página. Cada comando e flag abaixo foi verificado contra o
delonix <group> --helpde um binário construído a partir desta árvore, e os comandos só de leitura / de configuração (vm ls,vm reach,vm default-backend,image vm ls,manifest validate,stack apply --dry-run, os erros de selecção de backend) foram corridos comDELONIX_ROOTeDELONIX_NET_RUNTIME_DIRapontados para um directório de rascunho. Arrancar uma VM, construir uma imagem e fazer pull do registo não foram executados nesta revisão — o comportamento desses vem do código, dos ADRs e dos testes em script referidos abaixo.
Usa sempre o binário que construíste (./target/debug/delonix), não um que esteja no teu PATH, e
isola sempre os dois state roots enquanto fazes experiências — ver Isolamento.
1. Pré-requisitos do host#
KVM#
Os dois backends locais precisam de virtualização por hardware:
ls -l /dev/kvm # must exist; missing = VT-x/AMD-V off in firmware, or no nested virt
id -nG | tr ' ' '\n' | grep -x kvm # your user must be in the kvm group
O scripts/install.sh (por omissão, ou seja sem --no-vm) acrescenta-te aos grupos kvm e
libvirt e avisa quando falta o /dev/kvm. As mudanças de grupo precisam de uma sessão de login
nova.
Cloud Hypervisor e o seu firmware#
O backend está disponível quando o cloud-hypervisor está no PATH
(CloudHypervisorBackend::available em crates/adapters/delonix-vm/src/lib.rs). Onde a
distribuição não o empacota, o instalador descarrega o binário estático de upstream para
/usr/local/bin/cloud-hypervisor, fixado a uma versão e a um SHA-256 em scripts/install.sh.
Para arrancar uma cloud image sem --kernel, o CH precisa de firmware UEFI. O default_ch_firmware
usa $DELONIX_HYPERVISOR_FW se estiver definida, caso contrário o primeiro ficheiro que exista em
DEFAULT_CH_FIRMWARES:
/usr/local/share/delonix/CLOUDHV.fd ← EDK2 build from cloud-hypervisor/edk2 (preferred)
/usr/share/delonix/CLOUDHV.fd
/usr/local/share/delonix/hypervisor-fw ← rust-hypervisor-firmware (fallback)
/usr/share/delonix/hypervisor-fw
A ordem importa. Medido e registado no doc comment da constante: com o rust-hypervisor-fw
nenhuma das imagens que este projecto constrói arranca em CH; com o EDK2 CLOUDHV.fd arrancam. O
hypervisor-fw fica como recurso para hosts que só o têm a ele. O instalador obtém os dois (cada um
fixado por tag e SHA-256). O teste unitário o_edk2_vem_antes_do_hypervisor_fw_na_procura_de_firmware
guarda a ordem.
libvirt / QEMU#
O backend libvirt está disponível quando virsh e qemu-system-x86_64 estão ambos no PATH
(LibvirtBackend::available). O instalador instala o QEMU e um pacote do daemon libvirt e activa o
libvirtd (por socket activation, onde for suportado).
Que ligação libvirt é usada importa mais do que parece (libvirt_uri_for):
| Situação | Ligação | Consequência |
|---|---|---|
--net-mode nat ou bridge |
qemu:///system |
IP alcançável; precisa do grupo libvirt (ou de root) |
sem --net-mode, ligação de sistema utilizável |
qemu:///system, nat escolhido automaticamente |
IP por DHCP a partir da rede libvirt (virbr0) |
sem --net-mode, ligação de sistema não utilizável, rootless |
qemu:///session, user-mode |
nenhum IP visível nem alcançável; vm create avisa |
Em qemu:///system o QEMU corre como o utilizador do serviço libvirt, que não consegue ler um disco
debaixo de uma home 0700. Para um chamador rootless, o XML do domínio recebe um seclabel DAC
estático que fixa o QEMU ao teu uid/gid com relabel='no', para que o teu próprio overlay arranque
sem lhe mudarem o dono.
Ferramentas que o código de VM invoca#
| Ferramenta | Pacote (Debian / Fedora) | Usada por |
|---|---|---|
qemu-img |
qemu-utils / qemu-img |
overlays por VM, vm convert, snapshots em CH, builds de imagem |
cloud-localds |
cloud-image-utils / cloud-utils |
ISO de seed NoCloud — gerado em cada vm create de uma imagem cloud-init, a menos que seja dado --seed (crates/) |
virsh |
libvirt-clients / libvirt-client |
backend libvirt |
virt-customize, virt-sparsify, virt-copy-out |
libguestfs-tools / guestfs-tools |
só vm build / image vm build |
O vmimage::tool_package faz corresponder um binário em falta ao seu pacote, para que uma
ferramenta em falta seja reportada pelo nome e não como um No such file or directory seco.
Só para construir imagens: --with-image-build#
O image vm build corre o virt-customize, que constrói um pequeno appliance com o supermin. Três
problemas do host partem-no de maneiras que não parecem problemas do host; o
scripts/install.sh --with-image-build trata deles, e o tool_failure_hint (cmd/vmimage.rs)
nomeia-os quando um build falha:
- Nenhum cliente DHCP no host. O supermin copia pacotes do host para o appliance; sem
isc-dhcp-cliento appliance não tem rede e o build morre emTemporary failure resolving …. O instalador instala-o. - O
/boot/vmlinuz-*está a 0600 (Debian/Ubuntu). O supermin copia o kernel do host e falha comPermission denied. O instalador correchmod 0644 /boot/vmlinuz-*— isto baixa uma fronteira de segurança do host (qualquer utilizador local consegue ler a imagem do kernel), por isso é opt-in e imprime como reverter (sudo chmod 0600 /boot/vmlinuz-*). A dica de falha mostra também como fazer com que sobreviva às actualizações do kernel. - passt, só com
image vm build --network. O libguestfs dá rede ao appliance através do passt. O perfil AppArmor dele (Debian/Ubuntu) proíbe o directório de runtime que o libguestfs usa, e o passt empacotado no Ubuntu 24.04 arranca mas nunca entrega um lease — odhclientespera ~300 s e o build continua sem rede, falhando mais tarde num mirror de pacotes. Remédios:
mkdir -p /tmp/delonix-run && chmod 700 /tmp/delonix-run
XDG_RUNTIME_DIR=/tmp/delonix-run ./target/debug/delonix image vm build --network …
e, se ainda falhar, um passt actual primeiro no PATH (o instalador constrói um em
/usr/local/bin). Não «desligues» o passt com um stub que falha: o libguestfs passa então a usar o
stub e morre nele.
O modo --offline da receita dourada evita a armadilha 3 por completo: obtém e verifica os pacotes
no host e corre o convidado com --no-network.
Isolamento primeiro#
Esta máquina pode estar a correr outras cargas. Antes de qualquer comando vm para além de --help:
export DELONIX_ROOT=$HOME/dlx-dev/root
export DELONIX_NET_RUNTIME_DIR=/tmp/dlx-dev-run # keep it SHORT (AF_UNIX sun_path is 108 bytes)
export TMPDIR=$HOME/dlx-dev/tmp # VMfile builds put whole disks here
mkdir -p "$DELONIX_ROOT" "$DELONIX_NET_RUNTIME_DIR" "$TMPDIR"
Os dois roots, sempre: isolar só o DELONIX_ROOT deixa os sockets de rede partilhados com o estado
real e já reiniciou cargas reais antes (ver Clonar, compilar e testar). Uma VM Cloud Hypervisor
também recusa logo à partida quando <root>/vms/<name>.sock não cabe em sun_path
(ch_socket_paths_fit), por isso evita caminhos de DELONIX_ROOT muito profundos.
2. Backends e como um é escolhido#
A porta e o registo#
O VmBackend (crates/adapters/delonix-vm/src/lib.rs) é a porta que cada hypervisor implementa:
id, available, boot, is_running, ip, stop, mais métodos com implementação por omissão
(destroy, pause, unpause, resume, snapshot/restore/snapshots/delete_snapshot,
preserve_snapshots, ip_is_predicted, manages_own_storage, auto_selectable, disk_health).
Um default que não pode ser honrado falha fechado com uma mensagem, nunca é um no-op silencioso.
Os backends vivem num registo (BACKENDS), não num match:
| Backend | Crate | Aliases | Auto-seleccionável |
|---|---|---|---|
cloud-hypervisor |
delonix-vm (embutido) |
ch, cloudhypervisor |
sim |
libvirt |
delonix-vm (embutido) |
kvm, qemu |
sim |
proxmox |
delonix-proxmox (registado pela CLI) |
— | não — seleccionado só pelo nome |
O register_backend recusa um id/alias que pertença a outro backend, e recusa
auto_selectable: true para tudo o que não seja embutido: a auto-detecção pergunta available() a
cada candidato, e um backend remoto só consegue responder a isso pela rede. Registar não faz I/O; a
factory corre na primeira vez que o backend é seleccionado. O backend_for numa VM existente
resolve o backend registado, e um nome desconhecido é um erro (antes caía para o CH).
Precedência de selecção para uma VM nova#
A partir de delonix_vm::create_with e resolve_vm_defaults (cmd/vm.rs), ganha a primeira que
corresponder:
--backend(oubackend:no manifesto).- O
HYPERVISORda imagem (registado por um build de VMfile), quando--disknomeia uma imagem local. DELONIX_VM_BACKEND(para toda a sessão).delonix vm default-backend --set <backend>(para toda a máquina, guardado em<DELONIX_ROOT>/vm-default-backend).- Heurística de capacidade:
volumespresentes ⇒libvirt(só o libvirt faz virtio-9p); uma cloud image sem--kernel⇒libvirtse o libvirt estiver disponível; caso contrário auto-detecção — o primeiro backend registado auto-seleccionável que esteja instalado (CH, depois libvirt).
Por isso, num host com os dois hypervisors, um vm create simples de uma cloud image vai parar ao
libvirt; passa --backend cloud-hypervisor (ou define um default) para teres uma microVM na SDN.
$ delonix vm default-backend
none (auto-detection: cloud-hypervisor if installed, else libvirt)
$ delonix vm default-backend --set ch
default backend set to cloud-hypervisor
$ delonix vm default-backend --set bogus
error invalid argument: unknown VM backend: 'bogus' (use 'cloud-hypervisor', 'libvirt')
$ delonix vm default-backend --clear
default backend cleared (falls back to auto-detection)
Proxmox VE (remoto)#
O bins/delonix-runtime-bin/src/cmd/vmbackends.rs::register_configured regista o backend Proxmox
no arranque quando configurado através do ambiente (uma má configuração é um aviso, nunca fatal para
comandos sem relação):
| Variável | Significado |
|---|---|
DELONIX_PROXMOX_URL |
URL base da API, p. ex. https:/. Não definida = backend não registado. |
DELONIX_PROXMOX_NODE |
Obrigatória. O único nó a que este backend se dirige (tal como GET /nodes o nomeia). |
DELONIX_PROXMOX_SECRET |
Credencial preferida: nome de um kind: Secret com tokenId+tokenSecret (ou username+password). |
DELONIX_PROXMOX_TOKEN_ID + DELONIX_PROXMOX_TOKEN |
API token a partir do ambiente. |
DELONIX_PROXMOX_USER + DELONIX_PROXMOX_PASSWORD |
Login por password (ticket, reautenticado num 401). |
DELONIX_PROXMOX_INSECURE_TLS |
1/true/yes para saltar a verificação do certificado. Opt-in, nunca um recurso. |
DELONIX_PROXMOX_BRIDGE |
Bridge por omissão no nó (um bridge por VM ganha). |
DELONIX_PROXMOX_VLAN |
Tag VLAN por omissão, 1–4094; fora da gama é um erro, não uma NIC sem tag em silêncio. |
Sem configuração, --backend proxmox responde que o backend «não está disponível nesta build» e diz
o que definir (corrido). O backend é dono do seu armazenamento (manages_own_storage), por isso
não é feito nenhum overlay local nem seed NoCloud; --hostname/--ssh-key vão para o cloud-init do
nó, e --user-data é recusado. Desenho e limites: ADR-0008.
Um backend OpenStack está só proposto (ADR-0039); não
há código para ele.
3. Imagens#
As imagens de VM vivem no VmImageStore (cmd/vmimage.rs) em <DELONIX_ROOT>/vm-images/: um qcow2
mais um registo JSON de metadados (VmImage) por imagem. O delonix image vm ls lista-as com TYPE
(cloud-init / appliance) e DEFAULTS (vCPU/memória registados).
Imagens oficiais#
OFFICIAL_REPOS em cmd/vmimage.rs:
| Chave | Repositório | Conteúdo |
|---|---|---|
k8s |
ghcr. |
nó Kubernetes (kubeadm/kubelet/kubectl + delonix-cri) |
base |
ghcr. |
SO base com o motor delonix, sem Kubernetes (p. ex. ubuntu-24.04) |
appliances |
ghcr. |
appliances de fabricantes, sem cloud-init |
delonix vm ls-remote # tags of the Kubernetes golden repo
delonix vm ls-remote --no-k8s # tags of the base repo
delonix vm pull # the official Kubernetes golden
delonix vm pull --no-k8s # the official base image
delonix vm pull <oci-ref> --name <local-name>
As imagens são artefactos OCI de blob único; o pull verifica os digests do manifesto e do blob e
repõe os metadados a partir das annotations do manifesto. Os mesmos verbos existem como
delonix image vm pull/ls-remote/push.
Nota: um vm create sem --disk e sem imagem local descarrega a imagem dourada oficial, por
isso precisa de rede.
Construir a receita dourada#
delonix vm build -t <tag> (o mesmo comando que delonix image vm build; os dois partilham um só conjunto de
argumentos) sem vm.yaml nem VMfile no contexto corre a receita embutida. Os exemplos abaixo usam a grafia
image vm:
# Kubernetes node, packages fetched and verified on the HOST, guest offline
delonix image vm build --offline --k8s-version 1.34 -t delonix-vm-k8s:1.34
# no Kubernetes: just the engine, rootless-ready
delonix image vm build --no-k8s --distro debian --debian-release bookworm -t delonix-vm-base:debian-bookworm
Flags relevantes (consulta image vm build --help para os defaults): --distro ubuntu|debian|rocky|fedora,
--ubuntu-release, --debian-release, --rocky-release, --fedora-release (release e build,
p. ex. 42-1.1), --k8s-version, --offline, --no-k8s, --extra-package, --extra-run,
--cri-bin, --delonix-bin, --root-password (sem ela nenhuma conta tem password),
--node-exporter[=<addr>], --no-compress. A tua própria receita é um VMfile ou um vm.yaml — ver
Delonixfile e VMfile. A pasta images/ do repositório traz um
vm.yaml por distro (ubuntu, debian, rocky, fedora, construídas offline) e por appliance;
o scripts/verify-images.sh constrói-as num DELONIX_ROOT isolado e lê o qcow2 de volta
(--self-test prova que as suas verificações conseguem falhar). A instalação de pacotes, os perfis
da receita dourada, o arranque das imagens construídas e os builders de appliances ainda não foram
validados (notas da release v4.2.0). Os builds de imagem são só amd64
(ADR-0018).
Converter e importar#
delonix vm convert <image-or-path> --to raw|qcow2|vmdk|vdi|vhdx|vhd [-o out] [--compress]
delonix image vm import disk.qcow2 -t opnsense:26.1 --appliance --default-vcpus 2 --default-memory 3G
O vm convert achata (sem cadeia de backing); --compress só é aceite para qcow2 e vmdk. O
import --appliance regista cloud_init: false: o vm create passa então a não anexar nenhum
seed e recusa --hostname/--ssh-key/--user-data pelo nome, porque o convidado nunca os leria.
Os scripts de build de appliances vivem em scripts/appliances/.
4. Criar e correr#
vm create#
delonix vm create dev --disk delonix-vm-base:ubuntu-24.04 \
--backend cloud-hypervisor --vcpus 2 --memory 2G \
--ssh-key @$HOME/.ssh/id_ed25519.pub --hostname dev --wait
O que acontece (cmd/vm.rs → delonix_vm::create_with):
- A política do nó é imposta antes de qualquer imagem ser resolvida (
policy::enforce). - Resolução do disco (
resolve_image_ref):--url-imgganha (descarregado, em cache, verificado contra<url>.sha256quando disponível); senão--diské procurado como nome de imagem local, depois como caminho para o qcow2 de uma imagem guardada; senão é usado como caminho simples; sem--disk, a única imagem dourada local, ou é feito pull da oficial. - Os defaults dos metadados da imagem preenchem
--vcpus/--memory/--backendsó onde não estão definidos. - Seed: é gerado um ISO NoCloud (configuração de rede por MAC, hostname, chaves) a menos que
seja dado
--seed, que a imagem seja um appliance, ou que o backend seja remoto.--user-datasubstitui o user-data gerado. - Backend escolhido (secção 2); uma verificação de admissão recusa quando o host não tem RAM
suficiente; um
--namespacediferente dedefaulté recusado em libvirt (a VM vive navirbr0, fora da SDN do Delonix). - Overlay:
<root>/vms/<name>.qcow2, um qcow2 fino sobre a base (prepare_local_overlay);--disk-size <GiB>fá-lo crescer e não pode ser menor do que a base. - Boot: o
bootdo backend. Ocreateé idempotente: uma VM existente e a correr é devolvida tal como está.
As imagens publicadas não definem password em nenhuma conta (ver --root-password acima), por isso
passa --ssh-key se quiseres entrar por SSH.
--wait e o IP previsto. Em libvirt o IP vem de um lease DHCP real, por isso ter um é evidência
de que o convidado arrancou. Em Cloud Hypervisor o IP é calculado a partir do MAC antes de o
convidado correr (ip_is_predicted), por isso o --wait também sonda o endereço por ARP de dentro
do holder de rede (delonix_sdn::infra::sdn_reachable) até ao --boot-timeout (por omissão 120 s).
Três desfechos: de pé; «which could not be verified from here» (não foi possível fazer a pergunta à
sonda); «is running but never answered … computed from the MAC, not observed». Usa vm console para
ver porquê.
Verbos do dia-2#
| Comando | Notas |
|---|---|
delonix vm ls [--namespace <ns>] [--ports] [-o json] |
lista as VMs |
delonix describe vm <name> / delonix delete vm <name> |
não há vm describe/vm rm; os verbos genéricos substituem-nos |
delonix vm console <name> [-e ^X] |
consola série; desliga com Ctrl-] por omissão ($DELONIX_CONSOLE_ESCAPE). libvirt: virsh console como processo filho; CH: o socket de consola <root>/ |
delonix vm ssh <name|ip> [-l user] [-i key] [-- cmd] |
IP a partir do registo; utilizador por omissão delonix em imagens cloud-init, root em appliances |
delonix vm vnc <name> |
só para VMs libvirt criadas com --vnc (o CH não tem ecrã) |
delonix vm stop <name> |
mantém o disco, o registo e os snapshots. libvirt: o domínio é undefined (os metadados dos snapshots são preservados antes) |
delonix vm start <name> / restart <name> |
reconstroem o boot a partir do registo e reaproveitam o overlay; start numa VM a correr é um no-op, restart reinicia sempre |
delonix vm pause / unpause <name> |
suspendem as vCPUs, a memória fica em RAM; CH e libvirt |
delonix vm migrate <name> --host <h> --network <n> |
stop-copy-start por SSH para outro host; tempo de indisponibilidade real (o ADR-0031 explica porque é que a migração ao vivo está fora de âmbito) |
delonix vm prune |
recupera estado que nenhum registo de VM justifica |
Snapshots#
delonix vm snapshot create|ls|rm|restore <vm> [<snapshot>]:
| Backend | VM a correr | VM parada |
|---|---|---|
| libvirt | create é um checkpoint de sistema (memória + disco) |
só disco; os quatro verbos definem o domínio só durante o comando |
| cloud-hypervisor | só ls (qemu-img info -U); create/restore/rm recusados — o VMM a correr bloqueia o disco e o CH não tem API de snapshot de disco ao vivo |
os quatro, via qemu-img snapshot |
| proxmox | create (com estado da VM), ls, restore |
igual; rm não implementado (falha fechado) |
Os snapshots libvirt sobrevivem a vm stop/vm start: o undefine --snapshots-metadata remove só a
contabilidade do libvirt, por isso o preserve_snapshots despeja o XML de cada snapshot para
<root>/vms/<vm>/snapshots/ antes de parar e o boot redefine-os (reescrevendo o uuid do domínio,
que muda a cada define).
Declarativo#
O kind: VirtualMachine (compute.delonix.io/v1alpha1) espelha o vm create; um exemplo completo
e anotado é o examples/vm.yaml. Um kind: Workload com type: microvm baixa para uma
VirtualMachine com o backend forçado a cloud-hypervisor; pedir outro backend é um erro
(ADR-0006). Os dois foram corridos num root de rascunho:
apiVersion: compute.delonix.io/v1alpha1
kind: VirtualMachine
metadata: { name: dev }
spec:
disk: delonix-vm-base:ubuntu-24.04
resources: { vcpus: 2, memory: 2G }
cloudInit:
hostname: dev
sshKeys: ["@~/.ssh/id_ed25519.pub"]
---
apiVersion: compute.delonix.io/v1alpha1
kind: Workload
metadata: { name: fast }
spec:
type: microvm
microvm: { disk: delonix-vm-base:ubuntu-24.04, vcpus: 1, memory: 1G }
$ delonix manifest validate -f vm.yaml
stack validate: OK — 2 document(s), all references resolved
$ delonix stack apply -f vm.yaml --dry-run | grep backend
backend: null
backend: cloud-hypervisor
Aplica com delonix vm apply -f vm.yaml ou delonix stack apply -f vm.yaml (não executado aqui).
5. Rede para VMs#
| Cloud Hypervisor | libvirt | |
|---|---|---|
| Onde vive a NIC | um tap numa rede Delonix (--network, por omissão ingress) dentro do holder de rede — a mesma SDN dos containers |
virbr0 (nat) ou uma bridge do host, no network namespace do host |
| IP | lease pelo DHCP do holder, determinístico a partir do MAC | DHCP do libvirt; --ip reserva um (só nat) |
| Isolamento de namespace | sim (--namespace) |
recusado |
| VM ↔ container por IP | directo | container → VM funciona através do host; VM → container precisa de uma porta publicada ou de vm bridge |
O vm reach (só leitura, sem privilégio) lista os gateways libvirt e, para cada porta publicada
por um container a correr, se uma VM a consegue alcançar. Uma porta publicada no 127.0.0.1 por
omissão é invisível para as VMs; o comando imprime a republicação exacta, p. ex.
DELONIX_PUBLISH_ADDR=<gateway> delonix net ingress publish <c> <port> — alcançável a partir das
VMs dessa rede, não a partir da LAN externa.
O vm bridge <network> [--vm-subnet <cidr>] [--apply] é experimental e precisa de root: um
veth do host para dentro do holder mais rotas, dando às VMs libvirt alcançabilidade IP directa a uma
rede de containers. Sem --apply só imprime o plano. O vm unbridge <network> desfaz (também um
dry-run sem --apply). É a única excepção deliberada ao rootless no código de VM
(cmd/vmbridge.rs).
6. Resolução de problemas#
| Sintoma | Causa | Correcção |
|---|---|---|
/dev/kvm does not exist / a VM não arranca |
virtualização desligada, ou sem virtualização aninhada | activa VT-x/AMD-V; numa VM, activa a virtualização aninhada |
no VM backend available |
nem cloud-hypervisor nem virsh+qemu-system-x86_64 no PATH |
instala um; o scripts/install.sh fá-lo |
| VM CH «a correr» mas nunca responde; o overlay fica minúsculo | o firmware não consegue arrancar a imagem (p. ex. só o hypervisor-fw instalado) |
instala o EDK2 CLOUDHV.fd em /, ou define DELONIX_HYPERVISOR_FW, ou usa --backend libvirt |
vm ls não mostra IP numa VM libvirt |
caiu para qemu:///session em user-mode |
entra no grupo libvirt e volta a fazer login, ou --net-mode nat |
warning: cannot reach qemu:/ |
não está no grupo libvirt |
sudo usermod -aG libvirt $USER, sessão nova |
vm console em libvirt: «Active console session exists» |
uma sessão anterior morreu de forma não limpa | o código actual passa --force ao virsh console; actualiza o teu binário |
| VM CH recusada antes do boot a mencionar o caminho do socket | <root>/ excede 108 bytes |
DELONIX_ROOT ou nome da VM mais curtos |
namespace '…' is not enforceable on the 'libvirt' backend |
as VMs libvirt ficam fora da SDN | --backend cloud-hypervisor, ou tira o --namespace |
vm snapshot create recusado numa VM CH a correr |
o CH não tem snapshot de disco ao vivo | vm stop primeiro, ou usa libvirt |
--hostname/--ssh-key recusados |
a imagem é um appliance (cloud_init: false) |
configura o appliance pela sua própria consola/UI |
cloud-localds not found |
falta cloud-image-utils |
instala-o (necessário para cada vm create com cloud-init) |
image vm build: cp: cannot open '/ |
o kernel do host está a 0600 | install., ou sudo chmod 0644 / (baixa uma fronteira) |
image vm build: Temporary failure resolving … |
o appliance não tem rede: falta o cliente DHCP do host, ou o passt | instala isc-dhcp-client; para --network usa XDG_RUNTIME_DIR=/ e um passt actual primeiro no PATH; ou constrói com --offline |
| um passo pára ~300 s e depois as instalações de pacotes falham | o passt nunca deu lease; o dhclient esgotou o tempo |
igual ao anterior |
--offline belong to the built-in golden recipe … |
flag da receita dourada usada com um VMfile | tira-a; o VMfile descreve o build |
`--network` is for VMfile builds |
--network sem VMfile |
usa --offline para a receita dourada |
o build do VMfile enche o /tmp |
cada estágio é um disco achatado completo em $TMPDIR |
define TMPDIR para um sistema de ficheiros grande; remove os directórios delonix-vmfile-* que sobrarem depois de falhas |
VM backend 'proxmox' is not available in this build |
o backend não está configurado | define as variáveis DELONIX_PROXMOX_* (secção 2) |
7. Para contribuidores#
Onde vive o código#
| Área | Caminho |
|---|---|
Porta, registo, backends CH e libvirt, create_with, snapshots, procura de firmware |
crates/ |
| Geração do seed NoCloud | crates/ |
| Backend Proxmox | crates/ |
CLI vm, kind: VirtualMachine, vm reach |
bins/ |
| Store de imagens, receita dourada, pull/push/import/convert, dicas de falha | bins/ |
| VMfile | bins/ |
| Registo de backends a partir do ambiente | bins/ |
vm bridge |
bins/ |
Redução do kind: Workload |
bins/ |
| Builds de appliances | scripts/appliances/ |
Acrescentar um backend#
Lê primeiro o ADR-0008; é o modelo. Em resumo:
- Implementa o
VmBackendno seu próprio crate se ele falar com uma API remota (o crate do motor fica livre de clientes HTTP), colocado no directório da sua camada e listado emscripts/arch_fitness.py(ver Arquitectura). - Regista-o com
register_backenda partir do processo que conhece a sua configuração, comauto_selectable: falsea menos que seja um backend local, sem configuração, embutido nodelonix-vm. - Sobrepõe
manages_own_storage,destroy,resumeeip_is_predictedde forma deliberada: para um backend remotostopedestroynão são a mesma operação, e obootnuma VM parada não pode criar uma segunda. - Deixa os verbos não suportados nos seus defaults que falham fechado; recusa os campos de
VmConfignão suportados pelo nome antes de criares seja o que for. - Não publiques um backend que nunca foi visto a arrancar uma VM. Backends novos e fronteiras de hypervisor passam por um ADR (docs/adr/).
Testes#
- Testes unitários puros — os construtores de argv e de XML são funções puras, por isso
testam-se sem hypervisor: p. ex.
libvirt_snapshot_argv_uses_flags_not_positional,snapshot_xml_with_uuid,libvirt_domain_xml, o teste de ordem do firmware acima, os testes do registo e deauto_detect, e os testes de parser/scaffold emcmd/vmfile.rs. Correcargo test -p delonix-vmecargo test -p delonix-runtime-bin vmfile(ver Clonar, compilar e testar para oprotoce o directório de target). scripts/e2e.sh— as secçõesvmcorrem sem hypervisor (listagem, recusas) e, quando disponível, exercitam snapshots através de stop/start em libvirt (precisa devirsh,qemu-imge de umqemu:///systemutilizável) e em Cloud Hypervisor. Isola os dois state roots por omissão; a secção CH recusa-se a correr se só oDELONIX_ROOTestiver isolado. As secções sem o seu hypervisor são reportadas como saltadas, não como passadas.- Teste ao vivo do Proxmox —
crates/providers/delonix-proxmox/tests/live.rscria e destrói uma VM contra um nó real e é saltado a menos queDELONIX_PROXMOX_TEST_URL(mais_NODE,_USER,_PASS) esteja definida:cargo test -p delonix-proxmox --test live -- --nocapture. Usa um nó descartável. - Ciclo de vida do provider — ao mudar o
delonix-vmou um provider, prova o ciclo de vida inteiro (create, stop, start, snapshot, destroy) só através da CLIdelonix, observando o hypervisor em modo só-leitura (virsh -r,GETs da API), nunca o reparando à mão entre passos. - Olha, não adivinhes. Quando um convidado não sobe, a consola série (
vm console) ou um screenshot do libvirt respondem em segundos ao que as hipóteses levam horas a encontrar — e valida com o comando que um utilizador escreveria, não com as flags que são convenientes para depurar (o--vncjá mascarou uma falha de boot que só acontecia sem dispositivo de vídeo).
Seguinte: Resolução de problemas — um índice organizado por sintoma para os gates e as armadilhas de host em que podes cair ao construir e testar.