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

C4 Componente: Runtime (C3)

Este diagrama amplia o container Runtime do Diagrama de Container C2 para mostrar seus componentes internos -- as interfaces, implementações concretas e tipos de suporte que compõem a camada de execução de comandos do Invowk.

observação

O pacote runtime (internal/runtime/) é responsável por executar comandos definidos pelo usuário. Ele fornece três backends de execução intercambiáveis por trás de uma hierarquia de interfaces comum, um registry para despacho de runtime, e um contexto de execução estruturado que desacopla I/O, ambiente e preocupações de TUI.

Diagrama

Diagram: architecture/c4-component-runtime

Interfaces

InterfaceMétodosPapel
RuntimeName(), Execute(), Available(), Validate()Contrato principal de execução. Todos os runtimes implementam este. Execute retorna um *Result com exit code e erro -- exit code diferente de zero sem erro é uma saída normal de processo; erro indica falha de infraestrutura.
CapturingRuntimeExecuteCapture()Capacidade opcional de captura de saída. Retorna um *Result com campos Output e ErrOutput preenchidos. Não embarca Runtime.
InteractiveRuntimeSupportsInteractive(), PrepareInteractive()Capacidade de attachment de PTY. Embarca Runtime. Retorna um PreparedCommand com um exec.Cmd pronto para attachment de PTY e uma função de cleanup.
EnvBuilderBuild()Construção de variáveis de ambiente seguindo uma hierarquia de precedência de 10 níveis (env do host no nível 1 até flags CLI --ivk-env-var no nível 10).

Implementações

ComponenteTecnologiaResponsabilidade
NativeRuntimeGoExecuta comandos via shell do host (bash/sh no Unix, PowerShell no Windows). Opção mais rápida. Shell override configurável. Implementa Runtime, CapturingRuntime e InteractiveRuntime.
VirtualRuntimeGo/mvdan-shInterpretador de shell POSIX embarcado com utilitários built-in u-root opcionais. Sem dependência de shell do host. Cria um subprocesso de si mesmo para modo interativo baseado em PTY. Implementa Runtime, CapturingRuntime e InteractiveRuntime.
ContainerRuntimeGoExecuta comandos dentro de containers Docker/Podman. Depende de container.Engine, provision.LayerProvisioner, sshserver.Server e config.Config. Somente containers Linux. Implementa Runtime, CapturingRuntime e InteractiveRuntime.
DefaultEnvBuilderGoImplementação padrão de precedência de 10 níveis: env do host (filtrado) -> env files root/command/impl -> env vars root/command/impl -> ExtraEnv -> env files do runtime -> env vars do runtime.
MockEnvBuilderGoHelper de teste que retorna um mapa de ambiente fixo. Permite testar runtimes isoladamente sem acesso real ao sistema de arquivos ou carregamento de env.

Tipos de Suporte

TipoPapel
RegistryDespachante de runtime baseado em mapa. Armazena mapeamentos RuntimeType -> Runtime. Fornece Get(), GetForContext(), Available() e Execute() (que encadeia validar-e-executar).
RuntimeTypeTipo string identificando variantes de runtime: "native", "virtual", "container".
ExecutionContextEstrutura de dados principal para execução de comandos. Composta de subtipos IOContext, EnvContext e TUIContext mais metadados do comando, runtime/implementação selecionados e ID de execução.
IOContextAgrupa streams de I/O: Stdout, Stderr, Stdin. Funções factory DefaultIO() e CaptureIO() fornecem configurações comuns.
EnvContextAgrupa configuração de variáveis de ambiente: ExtraEnv (INVOWK_FLAG_*, INVOWK_ARG_*), RuntimeEnvVars (--ivk-env-var), RuntimeEnvFiles (--ivk-env-file) e overrides de herança.
TUIContextAgrupa detalhes de conexão do servidor TUI: ServerURL e ServerToken.
ResultResultado de execução: ExitCode, Error, Output (stdout capturado), ErrOutput (stderr capturado).
PreparedCommandRetornado por PrepareInteractive(): contém um exec.Cmd pronto para attachment de PTY e uma função Cleanup opcional.

Dependências Externas

DependênciaUsado PorPropósito
container.EngineContainerRuntimeAbstração unificada de engine de container Docker/Podman
provision.LayerProvisionerContainerRuntimeCria camadas de imagem efêmeras com binário invowk e módulos
sshserver.ServerContainerRuntimeServidor SSH baseado em token para callbacks container-para-host
config.ConfigContainerRuntimeConfiguração da aplicação (preferência de engine de container, etc.)
mvdan.cc/sh/v3VirtualRuntimeInterpretador de shell POSIX embarcado
internal/urootVirtualRuntimeUtilitários built-in para o shell virtual (cp, mv, cat, etc.)
pkg/invowkfileExecutionContextTipos de Command e Invowkfile, RuntimeMode, EnvInheritMode

Relacionamentos Principais

Segregação de Interface

O pacote runtime usa segregação de interface para permitir que chamadores dependam apenas das capacidades que precisam:

  • Runtime é o contrato base -- qualquer chamador que apenas precisa executar um comando aceita Runtime.
  • CapturingRuntime é uma interface standalone para captura de saída. Chamadores que precisam de saída capturada podem fazer type-assert para ela.
  • InteractiveRuntime embarca Runtime e adiciona suporte a PTY. A função helper GetInteractiveRuntime() combina type assertion com verificação de capacidade SupportsInteractive().

Todos os três runtimes concretos (Native, Virtual, Container) implementam todas as três interfaces.

Despacho via Registry

O Registry desacopla seleção de runtime da execução:

  1. A camada CLI resolve o RuntimeType dos defaults do comando ou flag --ivk-runtime.
  2. Registry.GetForContext() busca o Runtime correspondente.
  3. Registry.Execute() encadeia: obter runtime -> verificar disponibilidade -> validar -> executar.

Composição do ExecutionContext

ExecutionContext usa composição de três subtipos focados:

  • IOContext -- Streams de I/O, facilmente trocados entre modos real e captura.
  • EnvContext -- Configuração de variáveis de ambiente, incluindo overrides de herança de flags CLI.
  • TUIContext -- Detalhes de conexão do servidor TUI, valor zero significa "não configurado".

Precedência de 10 Níveis do EnvBuilder

NívelOrigem
1Ambiente do host (filtrado por modo de herança)
2-4env.files no nível root/command/implementation
5-7env.vars no nível root/command/implementation
8ExtraEnv (INVOWK_FLAG_*, INVOWK_ARG_*, ARGC, ARGn)
9Flag --ivk-env-file
10Flag --ivk-env-var (prioridade mais alta)

Decisões de Design

Por que Segregação de Interface?

Chamadores dependem apenas das capacidades que realmente usam. Um resolvedor de dependências que apenas verifica disponibilidade chama Runtime.Available(). O sistema de captura de saída faz assert de CapturingRuntime apenas quando captura é necessária. O sistema TUI verifica InteractiveRuntime apenas para comandos interativos.

Por que Composição para ExecutionContext?

Uma struct plana com mais de 15 campos seria mais difícil de testar e mais difícil de ler. Ao agrupar em IOContext, EnvContext e TUIContext, cada subtipo pode ser construído e testado independentemente.

Por que uma Interface EnvBuilder?

MockEnvBuilder permite que testes foquem na lógica de execução do runtime fornecendo um mapa de ambiente fixo, eliminando testes frágeis por estado do sistema de arquivos.

Por que um Registry?

O padrão Registry permite que a aplicação configure todos os runtimes uma vez na inicialização, e o pipeline de execução simplesmente pede um runtime por tipo. Adicionar um novo runtime significa registrá-lo -- sem mudanças no pipeline de execução.

Diagramas Relacionados