Pular para o conteúdo principal
Versão: Próxima

C4 Componente: Container (C3)

Este diagrama amplia o container Container Engine Abstraction do Diagrama de Container C2 para mostrar os componentes internos do pacote internal/container. Ele revela como o Invowk fornece uma interface unificada sobre os CLIs do Docker e Podman, lida com preocupações específicas do Podman (SELinux, rootless) e se adapta de forma transparente a ambientes sandboxed (Flatpak, Snap).

Diagrama

Diagram: architecture/c4-component-container

Interface

ComponenteTecnologiaResponsabilidade
EngineInterface GoContrato de 10 métodos para operações de container: Name, Available, Version, Build, Run, Remove, ImageExists, RemoveImage, BinaryPath, BuildRunArgs. Todas as funções factory retornam este tipo.

Implementações

ComponenteTecnologiaResponsabilidade
BaseCLIEngineStruct GoBase compartilhada para engines baseados em CLI. Fornece construtores de argumentos (BuildArgs, RunArgs, ExecArgs) e execução de comandos (RunCommand, CreateCommand). Configurado via functional options.
DockerEngineStruct GoEmbarca *BaseCLIEngine. Implementa Engine. Localiza o binário docker via exec.LookPath.
PodmanEngineStruct GoEmbarca *BaseCLIEngine. Implementa Engine. Busca podman ou podman-remote (fallback para distros imutáveis). Injeta labels de volume SELinux e tratamento de user namespace rootless.
SandboxAwareEngineStruct Go (decorator)Encapsula qualquer Engine. Detecta sandboxes Flatpak/Snap e prefixa comandos com flatpak-spawn --host ou snap run --shell. Passa direto quando nenhuma sandbox é detectada (overhead zero).

Functional Options

TipoPropósito
BaseCLIEngineOptionTipo de opção func(*BaseCLIEngine) para customização do construtor.
ExecCommandFuncPonto de injeção para exec.CommandContext. Permite que testes mockem a execução de comandos.
VolumeFormatFuncTransforma strings de volume. Podman usa para adicionar labels SELinux (:z) no Linux.
RunArgsTransformerPós-processa argumentos de run. Podman usa para injetar --userns=keep-id para compatibilidade rootless.
SELinuxCheckFuncDetermina se labeling SELinux deve ser aplicado. Injetado no formatter de volume do Podman.

Tipos de Request/Response

TipoPropósito
BuildOptionsEntrada para Engine.Build(): diretório de contexto, Dockerfile, tag, build args, controle de cache.
RunOptionsEntrada para Engine.Run(): imagem, comando, diretório de trabalho, env, volumes, portas, TTY, modo interativo.
RunResultSaída de Engine.Run(): ID do container, exit code, erro.
VolumeMountEspecificação estruturada de montagem de volume com suporte a labels SELinux.
PortMappingMapeamento estruturado de portas com suporte a protocolo.

Funções Factory

FunçãoComportamento
NewEngineCria o engine preferido (Docker ou Podman) com fallback automático. Encapsula com SandboxAwareEngine.
AutoDetectEngineTenta Podman primeiro (padrão amigável a rootless), depois Docker. Encapsula com SandboxAwareEngine.

Dependências Externas

DependênciaPacoteUso
platform.DetectSandbox()pkg/platformRetorna tipo de sandbox (None, Flatpak, Snap) usado pelo SandboxAwareEngine.
issue.NewErrorContext()internal/issueCria erros acionáveis com contexto de operação e sugestões para o usuário.
os/execstdlibExecução CLI subjacente. exec.LookPath encontra binários dos engines; exec.CommandContext os executa.

Padrões Principais

Composição via Embedding

DockerEngine e PodmanEngine ambos embarcam *BaseCLIEngine. A base fornece toda a construção de argumentos e execução de comandos, enquanto engines concretos implementam apenas métodos da interface Engine e construção específica do engine. Isso evita duplicação de código sem exigir herança.

Padrão Decorator

SandboxAwareEngine encapsula qualquer Engine para lidar com sandboxes Flatpak/Snap. Ele intercepta todos os métodos para opcionalmente prefixar invocações CLI com o mecanismo de host spawn da sandbox. Quando nenhuma sandbox é detectada, NewSandboxAwareEngine retorna o engine não-encapsulado diretamente, adicionando overhead zero.

Functional Options

BaseCLIEngineOption segue o padrão functional options de Dave Cheney. O construtor define defaults sensatos (exec.CommandContext real, formatters identidade) e as options os sobrescrevem:

  • Testes: Injetar um ExecCommandFunc mock para verificar a construção de argumentos sem executar containers.
  • Comportamento específico do engine: O construtor do Podman adiciona WithVolumeFormatter (SELinux) e WithRunArgsTransformer (rootless userns) antes das options fornecidas pelo usuário.

Auto-Detecção com Fallback

Tanto NewEngine quanto AutoDetectEngine seguem uma estratégia de tentar-preferido-depois-fallback. AutoDetectEngine usa Podman como padrão primeiro porque é mais comumente disponível em setups rootless (Fedora, distros imutáveis). Ambas as funções factory sempre encapsulam o resultado com SandboxAwareEngine.

Decisões de Design

Por que embedding ao invés de interfaces tradicionais?

Docker e Podman compartilham formatos de argumentos idênticos para a maioria das operações. Embarcar *BaseCLIEngine permite que engines concretos reutilizem a construção de argumentos sem delegação boilerplate. Comportamento específico do engine é injetado via functional options, mantendo a base genérica.

Por que um decorator para tratamento de sandbox?

Consciência de sandbox é uma preocupação transversal ortogonal ao tipo de engine. Um decorator mantém as implementações Docker/Podman limpas -- elas nunca precisam saber sobre Flatpak ou Snap. O decorator também curto-circuita em ambientes não-sandbox.

Por que functional options?

Options como ExecCommandFunc existem primariamente para injeção em testes. Uma struct de configuração exporia internos na API pública. Functional options mantêm construtores limpos para uso em produção enquanto permitem controle granular para testes.

Por que Podman primeiro no AutoDetectEngine?

Podman é o engine de container padrão no Fedora e outras distribuições baseadas em Red Hat. Ele roda rootless por padrão, não requer daemon, e funciona em distros imutáveis via podman-remote.

Diagramas Relacionados