Pular para o conteúdo

FormatPen: um aplicativo para formatar pendrive no Linux feito em Rust

Brayan Monteiro
14 min de leitura
FormatPen: um aplicativo para formatar pendrive no Linux feito em Rust
Compartilhar:

Quem usa Linux há algum tempo provavelmente já precisou formatar um pendrive e acabou recorrendo ao terminal.

Não que isso seja um problema. Muito pelo contrário. Com alguns comandos é possível fazer praticamente qualquer coisa relacionada a discos no Linux. O problema é que, para uma tarefa relativamente simples, nem sempre é interessante precisar lembrar qual comando usar, qual dispositivo corresponde ao pendrive e quais parâmetros são necessários.

Foi pensando justamente nisso que eu criei o FormatPen, um aplicativo para formatar pendrive no Linux com uma interface gráfica nativa.

O projeto foi desenvolvido em Rust, utilizando GTK4 e Libadwaita para a interface e UDisks2 + Polkit para conversar com o sistema e realizar as operações de armazenamento sem precisar executar o aplicativo como root.

O projeto é open source e está disponível no GitHub:

FormatPen no GitHub

Por que criar mais um formatador de pendrive?

Existem várias ferramentas gráficas para gerenciamento de discos no Linux. Então a ideia do FormatPen não surgiu porque não existiam alternativas.

Na verdade, foi mais uma oportunidade de construir alguma coisa que eu realmente usaria.

Eu queria um aplicativo simples, com uma única finalidade: conectar um pendrive, escolher o dispositivo, selecionar o sistema de arquivos e formatar.

Sem precisar abrir uma ferramenta gigantesca de particionamento para fazer uma operação que deveria ser simples.

E também tinha outro objetivo por trás do projeto: usar Rust para construir uma aplicação desktop Linux real.

Já tinha bastante interesse em explorar Rust, GTK4 e o ecossistema nativo do Linux. O FormatPen acabou sendo um projeto pequeno o suficiente para ser desenvolvido sem virar uma coisa impossível de manter, mas complexo o suficiente para envolver interface gráfica, D-Bus, permissões, particionamento, testes e distribuição.

O que o FormatPen faz?

A aplicação trabalha com o disco inteiro, e não com partições individuais.

Isso é importante.

Ao conectar um pendrive que aparece, por exemplo, como /dev/sdd, o FormatPen identifica esse dispositivo e permite formatá-lo completamente.

A aplicação atualmente suporta:

  • FAT32
  • exFAT
  • NTFS
  • ext4

Também é possível definir o nome do volume, respeitando as limitações de cada sistema de arquivos.

Antes de executar a operação, o aplicativo mostra uma confirmação para evitar que uma formatação seja iniciada acidentalmente.

Outro detalhe importante é que as partições existentes são desmontadas antes da operação.

Isso significa que o FormatPen não foi pensado para simplesmente executar um mkfs em algum dispositivo que o usuário selecionou. Ele possui um fluxo completo para limpar o layout existente, recriar a tabela de partições e criar uma nova partição formatada.

E o mais importante: ele não precisa rodar como root

Uma das decisões que eu quis tomar desde o início foi não fazer o aplicativo simplesmente pedir para o usuário executar tudo como root.

Seria muito mais fácil desenvolver alguma coisa que chamasse comandos com sudo, mas não é uma abordagem que eu considero interessante para uma aplicação desktop.

O FormatPen utiliza UDisks2 através de D-Bus e deixa o Polkit cuidar da autorização.

Na prática, o fluxo é mais ou menos assim:

FormatPen
   ↓
D-Bus
   ↓
UDisks2
   ↓
Polkit
   ↓
Sistema de arquivos / particionamento

Quando uma operação exige privilégios elevados, o próprio sistema pode solicitar a autenticação necessária.

O aplicativo não precisa ser executado como root.

Isso também deixa a arquitetura mais alinhada com a forma como aplicações gráficas Linux normalmente interagem com dispositivos de armazenamento.

Como o aplicativo encontra os pendrives?

Essa foi uma das partes mais interessantes do projeto.

O FormatPen não fica simplesmente procurando arquivos /dev/sd*.

Ele utiliza o UDisks2, que fornece uma API via D-Bus para gerenciamento de dispositivos de armazenamento.

A aplicação chama GetManagedObjects no barramento do sistema e analisa os objetos disponibilizados pelo UDisks2.

A partir daí, são aplicados alguns filtros.

Por exemplo, o dispositivo precisa ser:

  • removível;
  • gravável;
  • particionável;
  • não ignorado pelo sistema;
  • não ser um dispositivo de sistema;
  • representar o disco inteiro, e não uma partição.

Isso é importante porque um computador pode ter vários dispositivos disponíveis ao mesmo tempo.

Não seria nada legal o aplicativo listar o SSD principal do computador junto com o pendrive e deixar o usuário descobrir sozinho qual deles deveria selecionar.

O FormatPen trabalha com o disco inteiro

Outra decisão importante do projeto é que a aplicação não tenta ser um particionador genérico.

Se você possui um pendrive com várias partições, a proposta do FormatPen é justamente limpar esse layout e devolver o dispositivo para um estado simples.

O fluxo de formatação é basicamente:

Pendrive
   ↓
Desmontar partições
   ↓
Excluir partições existentes
   ↓
Criar nova tabela de partição
   ↓
Criar uma nova partição
   ↓
Formatar
   ↓
Pendrive pronto

Isso também significa que o aplicativo pode remover layouts criados por ferramentas como Ventoy ou imagens híbridas de sistemas operacionais.

Portanto, existe uma diferença importante entre formatar uma partição e formatar o pendrive inteiro.

O FormatPen trabalha com a segunda opção.

O que acontece quando clico em formatar?

Internamente, a operação passa por um serviço responsável pela formatação.

Primeiro, o FormatPen conecta ao barramento D-Bus do sistema.

Depois, desmonta as partições existentes no dispositivo.

Em seguida, as partições são removidas. A aplicação faz isso considerando primeiro os caminhos mais profundos, evitando problemas durante a remoção.

Depois disso, uma nova tabela de partições é criada.

Para FAT32, exFAT e NTFS, o FormatPen utiliza uma tabela MBR/dos.

Para ext4, utiliza GPT.

Depois é criada uma única partição ocupando o restante do dispositivo e o sistema de arquivos escolhido é aplicado.

Tudo isso acontece através das interfaces disponibilizadas pelo UDisks2.

Por que não chamar mkfs diretamente?

Porque o objetivo do projeto não é simplesmente criar um sistema de arquivos em um dispositivo.

Existe todo um fluxo envolvendo desmontagem, remoção das partições, criação da tabela de partições e autorização.

O UDisks2 funciona como uma camada de integração com o sistema operacional.

Ele conhece os dispositivos, partições e sistemas de arquivos e consegue realizar essas operações de uma forma mais integrada ao desktop Linux.

Além disso, o FormatPen ainda depende das ferramentas existentes no sistema para criar os sistemas de arquivos.

Por exemplo:

Sistema de arquivos Ferramenta
FAT32 dosfstools
exFAT exfatprogs
NTFS ntfs-3g
ext4 e2fsprogs
Particionamento parted

Essas ferramentas não são empacotadas dentro do FormatPen.

Elas continuam sendo responsabilidade da distribuição Linux.

Um AppImage, mas sem tentar empacotar o Linux inteiro

Para distribuir a aplicação, escolhi o AppImage.

Mas existe um detalhe interessante.

O FormatPen utiliza um AppImage relativamente pequeno, porque ele não tenta carregar dentro do arquivo todas as bibliotecas e ferramentas necessárias para trabalhar com discos.

O AppImage contém basicamente:

  • o binário;
  • metadados;
  • ícones;
  • arquivo .desktop.

As dependências relacionadas ao sistema continuam vindo do próprio Linux.

Isso inclui GTK4, Libadwaita, UDisks2, Polkit e as ferramentas de formatação.

A ideia é interessante porque mantém o pacote simples, mas também significa que existe uma responsabilidade maior sobre as dependências do sistema.

Por isso, o aplicativo verifica o ambiente na inicialização.

Se alguma dependência importante estiver faltando, ele consegue mostrar um aviso e sugerir os pacotes necessários.

Por exemplo, o projeto consegue identificar se está rodando em Fedora ou em uma distribuição baseada em Debian/Ubuntu e apresentar comandos diferentes para instalação das dependências.

Auto-update com zsync

Outra coisa que coloquei no projeto foi atualização automática para as versões distribuídas como AppImage.

O FormatPen utiliza o mecanismo de atualização do AppImage junto com zsync.

A vantagem é que não necessariamente precisamos baixar novamente o arquivo inteiro quando uma nova versão é disponibilizada.

O aplicativo possui uma informação de atualização apontando para os releases do GitHub.

Na primeira execução, o usuário pode autorizar a verificação de atualizações.

Depois disso, o aplicativo pode verificar uma nova versão automaticamente e também possui uma opção para realizar a atualização manualmente.

E, claro, existe uma variável de ambiente para desativar completamente esse comportamento:

FORMATPEN_NO_UPDATE=1 ./FormatPen-*.AppImage

A interface foi feita com GTK4 e Libadwaita

Como o objetivo era criar um aplicativo realmente integrado ao desktop Linux, escolhi GTK4 + Libadwaita para a interface.

A janela possui uma estrutura relativamente simples.

Existe um cabeçalho com as ações principais, uma área de avisos, seleção do dispositivo, formulário de formatação e mensagens de feedback.

A aplicação também utiliza componentes como ToastOverlay para mostrar o resultado das operações sem interromper o fluxo do usuário.

A ideia não era criar uma interface cheia de opções.

É literalmente um aplicativo para formatar pendrive no Linux.

Quanto menos coisa desnecessária aparecer na tela, melhor.

A interface não pode travar durante a formatação

Uma coisa que parece pequena, mas faz bastante diferença em aplicações desktop, é não bloquear a thread principal.

Formatação e operações relacionadas a dispositivos podem demorar.

Se você executar tudo diretamente na thread responsável pela interface, a janela pode simplesmente congelar durante a operação.

No FormatPen, essas tarefas são executadas em background utilizando gio::spawn_blocking.

Quando a operação termina, o resultado retorna para o event loop do GTK através de tarefas assíncronas.

Em outras palavras:

GTK Main Loop
     │
     ├── Interface continua responsiva
     │
     └── Worker
          ├── D-Bus
          ├── UDisks2
          ├── desmontagem
          ├── particionamento
          └── formatação

É um detalhe de implementação que o usuário provavelmente nunca vai perceber.

E esse é justamente o objetivo.

Validação do nome do pendrive

Também existe uma validação específica para o label do volume.

Cada sistema de arquivos possui suas próprias limitações.

No FormatPen:

  • FAT32: até 11 caracteres
  • exFAT: até 11 caracteres
  • NTFS: até 32 caracteres
  • ext4: até 16 caracteres

Também são bloqueados caracteres problemáticos, como:

\ / : * ? " < > |

Isso evita que o usuário preencha um nome inválido e descubra somente depois, durante a formatação, que alguma ferramenta recusou o valor.

Os erros também são tratados para tentar apresentar uma mensagem mais útil.

Por exemplo, se uma ferramenta como mkfs não estiver instalada, o aplicativo consegue informar isso em vez de simplesmente apresentar uma mensagem genérica de falha.

O projeto também possui testes

Como o FormatPen mexe diretamente com armazenamento, testar o projeto é particularmente importante.

Não seria uma boa ideia depender apenas de testes manuais em um pendrive.

Por isso existem diferentes níveis de testes.

Os testes unitários cobrem coisas como validação de labels, tratamento de erros, ambiente e funções auxiliares.

Também existem testes de integração com UDisks2.

A parte de interface possui testes específicos para GTK4.

E existe ainda um teste de formatação real de ponta a ponta.

Mas esse último é opt-in, justamente porque ele realmente pode apagar um dispositivo.

A ideia é deixar explícito que testes destrutivos não devem ser executados acidentalmente.

CI também faz parte do projeto

O GitHub Actions é utilizado para automatizar os testes.

A cada push e pull request, o projeto executa os testes unitários, testes de integração e testes da interface gráfica.

Para os testes de UI, é utilizado um ambiente com display virtual.

Também existe um workflow separado para gerar o AppImage quando uma nova tag de versão é criada.

Ou seja, o processo fica mais ou menos assim:

git tag v1.0.x
       ↓
GitHub Actions
       ↓
Testes
       ↓
Build
       ↓
AppImage
       ↓
.zsync
       ↓
GitHub Release

Isso reduz bastante o trabalho manual para publicar uma nova versão.

A estrutura do projeto

Uma das coisas que tentei manter desde o começo foi uma separação razoável das responsabilidades.

A estrutura principal ficou aproximadamente assim:

src/
├── main.rs
├── lib.rs
├── app.rs
├── environment.rs
├── window.rs
├── label_validation.rs
├── format_errors.rs
├── models/
│   └── drive.rs
├── services/
│   ├── udisks.rs
│   └── format.rs
└── updater/

A interface não precisa conhecer os detalhes de como o D-Bus funciona.

O serviço responsável pelo UDisks2 fica encarregado dessa parte.

Da mesma forma, as regras relacionadas à formatação ficam concentradas no serviço de formatação.

Isso deixa o código mais organizado e facilita bastante os testes.

Por que Rust?

Esse projeto também foi uma forma de explorar mais o ecossistema Rust para aplicações desktop.

Rust é uma linguagem que vem ganhando bastante espaço em aplicações de infraestrutura e ferramentas de sistema, e faz bastante sentido quando estamos trabalhando diretamente com recursos do sistema operacional.

No FormatPen, ela acabou encaixando muito bem.

A aplicação é compilada para um binário nativo, não depende de um runtime pesado e possui um ecossistema interessante para trabalhar com GTK, D-Bus e aplicações Linux.

E tem outra coisa.

Construir uma aplicação pequena em Rust é uma ótima maneira de aprender a linguagem.

É muito diferente de simplesmente fazer um tutorial de Hello World.

Quando você precisa lidar com D-Bus, concorrência, erros, testes, interface gráfica, empacotamento e integração com o sistema operacional, a linguagem começa a fazer muito mais sentido.

O que eu aprendi fazendo o FormatPen

Apesar de ser um projeto relativamente pequeno, o FormatPen acabou envolvendo muito mais conceitos do que eu imaginava inicialmente.

Eu precisei lidar com:

  • Rust;
  • GTK4;
  • Libadwaita;
  • D-Bus;
  • UDisks2;
  • Polkit;
  • particionamento;
  • sistemas de arquivos;
  • concorrência;
  • testes de interface;
  • testes de integração;
  • GitHub Actions;
  • AppImage;
  • zsync;
  • integração com diferentes distribuições Linux.

E talvez essa seja a parte mais interessante de projetos open source.

Você começa pensando:

"Vou fazer um programinha para formatar pendrive."

E algumas horas depois está estudando como o Linux gerencia dispositivos de armazenamento através de D-Bus.

Vale a pena usar o FormatPen?

Se você usa Linux e quer uma ferramenta simples para formatar um pendrive inteiro, essa é exatamente a proposta do projeto.

Ele não tenta substituir ferramentas completas como gerenciadores de partições.

A ideia é muito mais simples:

selecionar o pendrive, escolher o sistema de arquivos, colocar o nome e formatar.

O projeto é open source, então qualquer pessoa também pode olhar o código, abrir uma issue, sugerir melhorias ou contribuir.

Confira o FormatPen no GitHub

Só existe uma regra que continua valendo independentemente da ferramenta utilizada:

tenha certeza de que você selecionou o pendrive correto.

Formatação de disco não tem botão mágico de desfazer.

Conclusão

O FormatPen começou como uma ideia simples para criar um aplicativo para formatar pendrive no Linux e acabou virando um projeto bem interessante para explorar desenvolvimento desktop nativo no Linux.

A combinação de Rust + GTK4 + Libadwaita + UDisks2 + Polkit permite construir uma aplicação relativamente pequena, mas integrada ao sistema operacional de verdade.

E foi justamente isso que tornou o projeto interessante para mim.

Em vez de criar mais uma aplicação web, API ou CRUD, dessa vez a ideia foi fazer alguma coisa que conversa diretamente com o sistema operacional.

O resultado é uma ferramenta simples para o usuário, mas com bastante coisa acontecendo por baixo dos panos.

E, sinceramente, é esse tipo de projeto que eu mais gosto de fazer.

A interface pode ser simples.

O código por trás dela é que pode ser interessante.

Palavras-chave:

#FormatPen #Linux #Formatar Pendrive Linux #AppImage

Sobre o autor

Brayan Monteiro

Bacharel em Sistemas de Informação pela Faculdade Maurício de Nassau e desenvolvedor de software. Produzo conteúdo e gerencio blogs. Sou especialista em desenvolvimento web e SEO de sites.

Continue lendo

Postagens relacionadas

Discussão

Comentários

Nenhum comentário ainda. Seja o primeiro a comentar.