Arquitectura

8 crates, um binário — e nenhum processo residente.

Visão geral

delonix (CLI) — delonix-runtime-bin comandos agrupados: container · image · build · vm · volumes · network · stack · cluster
delonix-runtimeclone() + namespaces (mount/pid/ipc/uts/net/user/cgroup), pivot_root, seccomp/caps, cgroups v2 delegados, exec, reconcile
delonix-imagepull OCI (digest verificado), build, export, buildpacks CNB, assinaturas, registo
delonix-netSDN rootless: holder netns + bridge + slirp único, DNAT/firewall nft, DNS interno, overlay WireGuard
delonix-vmmicroVMs (trait VmBackend: Cloud Hypervisor · libvirt), cloud-init
delonix-volumevolumes nomeados, bind mounts, quotas, nfs
delonix-criservidor CRI runtime.v1 — o kubelet fala com o Delonix
delonix-runtime-coretipos partilhados: Container, Vm, Status, Store JSON, Secret Manager

Daemonless a sério

Não há daemon, nem sequer um monitor por container (o conmon do podman). O run faz clone() directo; em modo detached, um shim de logging efémero fica só a escoar o stdout/stderr para o ficheiro de log (com rotação) e morre com o container. O estado (spec completa de cada container/VM/volume/rede) vive em JSON sob $DELONIX_ROOT — o ps/start/inspect reconstruem tudo daí, e reapers oportunistas limpam órfãos (slirp sem alvo, hostfwd sem container) a cada invocação relevante.

Rootless-first

Sem root, o isolamento vem de user namespaces com mapeamento de subuid (newuidmap/newgidmap, como o podman) — o uid 0 do container é um uid não-privilegiado do host. O rootfs é uma cópia flat persistente por container (em root, overlayfs com upper preservado). Com --privileged + labels de node Kind, o runtime prepara a delegação de cgroup v2 dedicada que um systemd aninhado (kindest/node) exige.

Rede rootless: o ingress

hostportas publicadas (127.0.0.1 por omissão; DELONIX_PUBLISH_ADDR para expor)
holder netns (1 por utilizador)bridge delonix0 · slirp4netns único · nft (DNAT «pre», firewall) · DNS interno com os nomes dos containers
containersveth por container, ligados à bridge; IP determinístico por id

Publicar uma porta = um add_hostfwd no api-socket do slirp único + uma regra DNAT na chain de ingress — estado do dataplane, não do container. É por isso que portas (e volumes, via mounts live) se trocam a quente: o processo do container nunca é tocado. Com --net host + -p, o container recebe um netns próprio com um slirp4netns dedicado (modelo podman), que morre com ele.

Segurança

Rootless por omissão; seccomp e drop de capabilities fora de --privileged, com arranque a FALHAR se não ficarem mesmo activos; pull com verificação de digest (incluindo artefactos VM OCI); inputs de manifesto de recursos como Cluster/Vm validados por whitelist antes de chegarem a qualquer shell remoto.

Auditoria de 2026-07-21 — 6 achados de severidade alta, CORRIGIDOS em 2026-07-23 (o COPY do build, por exemplo, era contornável por symlink apesar de uma correcção anterior ter tentado fechá-lo — agora canonicaliza e confirma o confinamento). Não há indícios de RCE pela rede, mas os fixes ainda não foram confirmados por uma 2.ª auditoria independente e o núcleo de syscalls nunca teve revisão de segurança — por prudência, evita ainda imagens/manifestos não confiáveis ou expor o motor num host partilhado até à confirmação. Detalhe completo em AUDITORIA-E2E.md — ver também a comparação com Docker/Podman para o estado geral do projecto.