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.