Ir para o conteúdo

Atualização

Mudanças de schema do banco são migrações forward-only, e o processo recusa subir contra um banco desatualizado em vez de migrar em silêncio no boot. Então uma atualização é sempre: pegar a nova versão, rodar a migração, reiniciar. Faça backup antes.

Backup antes

peart backup -config /etc/peart/config.yaml -out /caminho/do/artefato-pre-upgrade

O artefato é cifrado e exclui a chave mestra (ver Diretório de dados e backups).

Rodar a migração

O peart migrate aplica todas as migrações pendentes, ou nenhuma: ele nunca deixa o banco pela metade, então é sempre seguro rodar de novo. Ele cria o banco se não existir e não muta nada sozinho no boot; migrar é um passo explícito.

Bare-metal / systemd:

sudo systemctl stop peart peart-portal
sudo -u peart peart migrate --config /etc/peart/config.yaml
sudo systemctl start peart-render peart peart-portal

Container:

docker compose pull
docker compose run --rm peart migrate
docker compose up -d

Por que o processo recusa um banco desatualizado

A superfície interna confere a versão do schema na subida e recusa rodar se o banco está atrás, em vez de migrar por conta própria. Isso é deliberado: uma migração automática no boot é o tipo de passo que muda dado em silêncio num reinício que ninguém pretendia como atualização. Tornar a migração um comando explícito e rodado à parte deixa o reinício previsível e permite o backup acontecer primeiro.

O sidecar de renderização agora sobe por um socket

Só para instalações bare-metal; o caminho por container não muda. O sidecar é iniciado pelo peart-render.socket, que abre o 127.0.0.1:8090 no host e entrega o socket ouvindo a um serviço que continua sem rede própria. Habilite o socket e pare de habilitar o serviço:

sudo cp deploy/systemd/*.service deploy/systemd/*.socket /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl disable peart-render.service
sudo systemctl enable --now peart-render.socket

O disable importa tanto quanto o resto: um serviço ainda habilitado sozinho sobe sem o socket, faz bind no loopback privado dele, e volta a ficar inalcançável.

Se você contornou o sidecar inalcançável com um drop-in que punha PrivateNetwork=no e IPAddressAllow=localhost, remova-o na mesma passada, com sudo systemctl revert peart-render.service. Enquanto não remover, o processo que interpreta HTML derivado de conteúdo hostil continua alcançando todo serviço no loopback do host, incluindo a API interna do PEART.

Outro contorno pode sair na mesma passada: se você deu um home gravável ao serviço interno com um drop-in (CacheDirectory mais Environment=HOME) porque toda geração de PDF terminava em panic: config problem: mkdir /home/peart: permission denied, remova-o com sudo systemctl revert peart.service. A normalização do PDF não usa mais nenhum diretório de configuração sob o $HOME, então uma conta de serviço sem home é o que ela agora espera.

O diretório de job agora é um contrato de grupo

Só instalações bare metal, e vale para toda instalação feita antes desta versão: a geração de relatório falha enquanto o grupo não existir. O peart e o peart-render compartilham o mesmo diretório de job, e o grupo que permite isso é o peart-work. O compartilhamento é de mão única: o peart prepara o job ali e o peart-render só lê, então o grupo precisa carregar a leitura e mais nada. Crie o grupo, passe o diretório de trabalho para ele, e reinicie as duas units:

sudo groupadd --system peart-work
sudo chgrp peart-work /var/lib/peart/work
sudo chmod 2750 /var/lib/peart/work
sudo cp deploy/systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl restart peart.service peart-render.socket

As units são copiadas porque a participação no grupo é declarada nelas, com SupplementaryGroups=peart-work, em vez de ficar num usermod no host. O peart-render.service é reiniciado reiniciando o socket dele; ele sobe na conexão seguinte.

O caminho por container não precisa de nada aqui: os dois serviços recebem o gid compartilhado da imagem e do compose.yaml. Puxe as imagens novas e recrie.

O diretório de evidências é conferido no arranque

Vale nas duas topologias. O diretório de evidências guarda os originais, e o 0700 é o modo que a configuração sempre pediu. A partir desta versão o processo confere em vez de supor: se o diretório já existir aberto para o grupo ou para outros, o peart serve recusa subir e imprime o modo que encontrou e o chmod que resolve.

Isso morde o caminho por container em especial. Um volume nomeado mantém o dono e as permissões com que foi populado da primeira vez, então uma instalação criada antes desta versão ainda carrega o que a umask do build da imagem antiga deixou lá -- 0755 -- e o 0700 da imagem nova não chega até ele. Rode o chmod que a recusa imprime, contra o volume, e suba de novo.

Os segredos saem do config.yaml

Vale para toda instalação, e é consequência do conserto de permissão acima: o config.yaml passou a ser legível pelo grupo peart-portal, porque as duas superfícies o abrem e até agora nenhuma conseguia. Isso está certo, e quer dizer que um config.yaml que ainda carregue o render.token e o webhook.secret entrega os dois ao processo exposto à internet. Mova-os:

# ponha os valores em /etc/peart/peart.env, root:root 0600
PEART_RENDER_TOKEN=<o valor que estava em render.token>
PEART_WEBHOOK_SECRET=<o valor que estava em webhook.secret, se você usa o webhook>

Depois devolva os placeholders ao config.yaml, deixe o webhook.url onde está (destino não é segredo) e rode systemctl restart peart.service. O /etc/peart/render.env do renderizador já carrega o mesmo token e não muda. A página Rodar como serviço traz o conteúdo completo de cada arquivo.

Não mover é uma escolha, não um esquecimento, e este é o custo: o portal fica com leitura do token em que o renderizador confia e da chave com que a notificação de saída é assinada. Nada quebra e nada avisa.

O renderizador para de escrever, e o diretório de trabalho aperta

Instalações bare metal. O PDF agora volta pela conexão que pediu a renderização, em vez de por um arquivo no diretório de job, então o peart-render lê aquele diretório e não escreve em lugar nenhum da árvore de dados. A unit dele diz isso, e o diretório pode perder a escrita de grupo que existia só para o renderizador criar o out.pdf ali:

sudo chmod 2750 /var/lib/peart/work
sudo cp deploy/systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl restart peart.service peart-render.socket

Se você tem um drop-in com RestrictSUIDSGID=no em alguma unit, remova agora com sudo systemctl revert peart.service (e o mesmo nas outras que tiverem um) e recarregue. Aquele drop-in era o contorno deste defeito: a geração precisava de um chmod carregando o bit setgid, que a unit endurecida nega. Nada mais pede esse bit ao kernel, então o endurecimento volta.

Se uma atualização anterior deixou o diretório em 2770, estreite agora com sudo chmod 2750 /var/lib/peart/work, que é o modo instalado pela Primeira execução e configuração. A escrita de grupo que ele concede ninguém usa mais, e o processo a quem ele concede é o que abre HTML derivado de conteúdo hostil: modo mais largo que a coisa que ele protege é como começa o próximo achado de instalação, e duas instalações da mesma versão discordando disso é como ninguém percebe.

A superfície interna entra no grupo do portal

Instalações bare metal, todas as feitas antes desta versão. As duas superfícies abrem o mesmo banco em modo WAL, e os companheiros peart.db-wal e peart.db-shm são criados por quem abrir primeiro, caindo no grupo peart-portal por causa do setgid do diretório. A superfície interna não era membro desse grupo, então um boot em que o portal abriu primeiro a deixava sem conseguir abrir o banco, reiniciando em laço, com unable to open database file (14) no journal dela. Nada muda no sistema de arquivos aqui, nem dono nem modo, só a unit:

sudo cp deploy/systemd/*.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl restart peart.service peart-portal.service

Uma instalação que nunca reiniciou pode nunca ter visto isso, porque a ordem é decidida no boot e a ordem que funciona é exatamente tão provável quanto a que falha. Nunca ter visto não é evidência de não ter. A página Verificar a instalação traz o passo que força a ordem ruim de propósito.

O caminho por container não precisa de nada: lá os dois processos rodam sob o mesmo usuário, então nenhum dos dois encontrou isto.

Se você já chmodou os companheiros do WAL

Só se você seguiu a redação antiga da Primeira execução e configuração, que mandava rodar chmod 0660 no peart.db-wal e no peart.db-shm quando eles saíssem errados. Aquele conselho tratava o sintoma. O SQLite tira o modo dos companheiros do peart.db, então companheiro errado queria dizer banco errado, e o chmod valia só até a última conexão fechar de forma limpa: o SQLite apaga os dois companheiros nessa hora e os cria de novo, a partir do banco, na abertura seguinte. A instalação funciona, nada muda, e ela falha num login algum tempo depois.

Confira o banco em si e conserte lá:

ls -l /var/lib/peart/db/peart.db
sudo chown peart:peart-portal /var/lib/peart/db/peart.db
sudo chmod 0660 /var/lib/peart/db/peart.db

Nada a reiniciar: a abertura seguinte já pega.

Renditions e relatórios gerados antes desta versão

Toda instalação que publicou um achado com imagem, ou gerou um relatório, antes desta versão.

O portal serve duas coisas a partir do disco: as renditions das evidências e os relatórios gerados. As duas nasciam 0600, dentro de diretórios criados 0700, escritas pelo peart e lidas pelo peart-portal, que é outro usuário. Numa instalação com usuários separados o portal não conseguia nem entrar no diretório nem abrir o arquivo: as evidências apareciam quebradas e o download do relatório respondia 500, com o resto da tela funcionando.

A página Primeira execução e configuração já mandava criar renditions/ e reports/ como 2750 peart:peart-portal. Isso está certo, e não bastava: o bit setgid dá o grupo a tudo o que nasce dentro daqueles diretórios, e o modo vinha de quem criava. Arquivo e diretório novos passam a ser 0640 e 0750. O que já está no disco mantém o modo com que nasceu, e migração nenhuma alcança permissão de arquivo.

Conserte a árvore existente. O comando toca só os dois diretórios de que o portal serve, deixa o resto como está, e pode ser repetido sem efeito:

sudo find /var/lib/peart/renditions /var/lib/peart/reports -type d -exec chmod 2750 {} +
sudo find /var/lib/peart/renditions /var/lib/peart/reports -type f -exec chmod 0640 {} +
sudo chown -R peart:peart-portal /var/lib/peart/renditions /var/lib/peart/reports

Confira com a identidade do portal, não com a sua. A sua conta provavelmente lê aqueles arquivos com qualquer modo, que é justamente por que isto passou despercebido até uma instalação relatar:

sudo -u peart-portal test -r "$(sudo find /var/lib/peart/renditions -type f | head -1)" && echo legivel

Nada a reiniciar.

Não rode os mesmos comandos em /var/lib/peart/evidence, nos logos dos clientes, nos avatares nem em /var/lib/peart/installation. Esses são 0700 por decisão: o portal nunca recebe o caminho deles e não pode conseguir lê-los.

A trilha nomeia quem agiu

Toda instalação. Até esta versão, cinco transições de conta (criada, desativada, excluída, segundo fator redefinido, segundo fator rebaixado) se registravam como a CLI agindo como sistema, sem ator nenhum, mesmo quando quem as fez foi um administrador pela interface. Duas das cinco nem são alcançáveis pela CLI, então para elas o rótulo nunca esteve certo.

Nada é reescrito. Não há migração nem como recuperar quem agiu nas linhas já gravadas, porque o campo que falta é justamente o do ator. O que você precisa saber ao ler a própria trilha: uma entrada de uma dessas cinco ações, anterior a esta versão e rotulada cli / system, pode ter sido um administrador agindo pela interface. Depois desta versão as duas se distinguem.

Depois de atualizar

Confirme que os serviços estão saudáveis (no caminho por container, docker compose ps deve mostrar peart-render como Up (healthy) antes de a geração de relatório funcionar), e que um relatório ainda renderiza pelo sidecar. Esta última é a checagem que prova que as duas mudanças acima chegaram; a página Verificar a instalação diz o que o journal mostra quando não chegaram.