Sob o capô🔗

Esta página fornece uma visão geral de como o Flatpak funciona internamente. Embora não seja necessário estar familiarizado com isso para usar o Flatpak, algumas pessoas podem achar interessante. Conhecer a arquitetura do Flatpak também ajuda a entender melhor como e por que funciona da maneira que funciona, da perspectiva do usuário e do desenvolvedor de aplicativos.

“Git para aplicativos”🔗

O Flatpak é construído sobre uma tecnologia chamada OSTree, que é influenciada e muito semelhante ao sistema de controle de versão Git. Como o Git, o OSTree permite que os dados versionados sejam rastreados e distribuídos entre diferentes repositórios. Porém, enquanto o Git é projetado para rastrear arquivos fonte, o OSTree é projetado para rastrear arquivos binários e outros dados grandes.

Internamente, o Flatpak, portanto, funciona de maneira semelhante ao Git, e muitos conceitos do Flatpak são análogos aos conceitos do Git. Como o Git, o Flatpak usa repositórios para armazenar dados e rastreia as diferenças entre as versões.

Com o Flatpak, cada aplicativo, runtime e extensão é um ramo em um repositório. Um trio identificador, como com.empresa.Aplicativo/x86_64/stable é uma referência a esse ramo. A saída de um processo de compilação do Flatpak é um diretório de arquivos do qual é feito commit para um desses ramos.

Quando um aplicativo é instalado com o Flatpak, ele é extraído do remoto para um novo ramo em um repositório local. Em seguida, são gerados links que apontam dos lugares certos no sistema de arquivos para os arquivos do aplicativo no repositório (estes são links físicos, que são rápidos para resolver e espaço em disco eficiente). Em outras palavras, todos os aplicativos instalados são armazenados em um repositório de controle de versão local e, em seguida, são mapeados no sistema de arquivos local.

O rastreamento de versão é, portanto, uma parte essencial da arquitetura do Flatpak, e isso torna a atualização do software para a versão mais recente muito eficiente. O controle de versão também possibilita reversões, por isso é fácil voltar para uma versão anterior, se necessário.

Armazenar aplicativos em um repositório OSTree local tem outras vantagens. Por exemplo, ele permite que os arquivos armazenados no disco sejam deduplicados, portanto, o mesmo arquivo que pertence a vários aplicativos (ou runtimes) é armazenado apenas uma vez.

This blog post explains the underlying structure of a Flatpak repository in more detail.

Conditional permission system🔗

Since Flatpak 1.17.0, conditional permissions allow permissions to be granted only when certain runtime conditions are satisfied, with fallback to unconditional grants for compatibility with older versions.

Permissions are internally represented as:

  • unconditionally allowed or denied

  • a reset flag indicating whether the current layer overrides rules from lower layers

  • a set of conditional rules under which the permission may be allowed

For example:

  • --socket=NAME unconditionally allows the permission and resets any previously defined rules for that permission

  • --nosocket=NAME unconditionally denies the permission and resets any previously defined rules

  • --socket-if=NAME:CONDITION adds a conditional rule without resetting existing rules

Conditions may be negated using !.

Multiple conditional rules can be specified for the same permission. In this case, the permission is granted if any condition evaluates to true.

Duplicate conditions are ignored. The order of conditions does not affect evaluation.

If no conditional rules are present, the permission is granted only if it is unconditionally allowed.

If conditional rules are present, the permission is granted if any condition evaluates to true, and denied otherwise, unless it is also unconditionally allowed.

If an unconditional entry follows a conditional entry for the same grant in commandline flags, the earlier unconditional entry is treated as backwards compatibility fallback and does not affect the final permission state.

A --socket-if=NAME:CONDITION is written in the metadata as:

sockets=NAME;if:NAME:CONDITION;

Permissions are written to metadata using the following rules:

  • Unconditionally allowed permissions are written as NAME

  • Unconditionally denied permissions are written as !NAME

  • Conditionally allowed permissions are written as:

    • unconditional NAME entry for compat

    • if:NAME:CONDITION entries

If the permission resets previously defined rules, an explicit !NAME entry is written first, followed by the unconditional NAME entry and then the if:NAME:CONDITION entries. This is omitted when saving an application’s own metadata, as opposed to overrides.

When parsing metadata, a non-negated unconditional NAME entry appearing before a if:NAME:CONDITION entry is treated as a compatibility fallback and does not affect the final permission state. Eg. sockets=x11;if:x11:!has-wayland; is effectively treated as if:x11:!has-wayland in Flatpak versions supporting conditional permissions.

Tecnologias subjacentes🔗

O Flatpak utiliza várias tecnologias preexistentes. Esses incluem:

  • O utilitário bubblewrap do Project Atomic, que permite que usuários sem privilégios configurem e executem contêineres, usando recursos do kernel, como:

    • Espaços de nomes

    • Montagens vinculadas (“bind”)

    • Regras seccomp

  • systemd para configurar cgroups para sandboxes

  • D-Bus, uma maneira bem estabelecida de fornecer APIs de alto nível para aplicativos

  • The OSTree system for versioning and distributing filesystem trees

  • O formato OCI da Open Container Initiative, como uma alternativa ao OSTree usado pela infraestrutura do Fedora

  • Flatpak pode usar OSTree ou OCI para pacotes de arquivo único.

  • Metadados de Appstream, para permitir que os aplicativos Flatpak apareçam bem nos aplicativos de centros de software