mirror of
https://github.com/melgarafael/DeskcommCRM.git
synced 2026-10-02 01:28:34 +08:00
feat(installer): support ARM64 VPS deployments
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
impacto: capacidade_nova
|
||||
secao: adicionado
|
||||
titulo: Instalação em VPS ARM64
|
||||
---
|
||||
|
||||
O instalador padrão agora atende VPS ARM64/aarch64, como Oracle Ampere A1, usando as imagens nativas do DeskcommCRM e a variante NOWEB ARM64 oficial do WAHA. O caminho usa Supabase externo e não exige compilação na VPS. O instalador alternativo que hospeda o Supabase junto continua limitado a amd64.
|
||||
@@ -262,6 +262,9 @@ jobs:
|
||||
labels: |
|
||||
org.opencontainers.image.title=${{ matrix.title }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Buildx
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
@@ -270,8 +273,8 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
file: ${{ matrix.dockerfile }}
|
||||
# linux/amd64: o VPS HostGator e a imagem do WAHA são amd64.
|
||||
platforms: linux/amd64
|
||||
# Build multi-arquitetura no CI; o cliente só puxa o manifesto nativo.
|
||||
platforms: linux/amd64,linux/arm64
|
||||
# PR de fork não tem permissão de escrita no GHCR, e publicar imagem
|
||||
# de código não revisado seria pior que não gatear. Em PR: constrói
|
||||
# (que é o gate) e descarta.
|
||||
@@ -309,9 +312,17 @@ jobs:
|
||||
# Na `main` e em tag esta imagem vira a que o parque instala: ela se constrói
|
||||
# nas máquinas do GitHub, nunca numa máquina nossa. Guarda contra fork:
|
||||
# comentário do e2e-parte no e2e.yml.
|
||||
runs-on: ${{ vars.EXECUTOR_PROPRIO == 'ligado' && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && 'deskcomm-proprio' || 'ubuntu-latest' }}
|
||||
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || (vars.EXECUTOR_PROPRIO == 'ligado' && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && 'deskcomm-proprio' || 'ubuntu-latest') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: amd64
|
||||
platform: linux/amd64
|
||||
- arch: arm64
|
||||
platform: linux/arm64
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-imagem-do-app-sobe-${{ github.event.pull_request.number || github.ref }}${{ github.event_name == 'pull_request' && github.run_attempt != '1' && format('-reentrada-{0}', github.event.pull_request.head.sha) || '' }}
|
||||
group: ${{ github.workflow }}-imagem-do-app-sobe-${{ matrix.arch }}-${{ github.event.pull_request.number || github.ref }}${{ github.event_name == 'pull_request' && github.run_attempt != '1' && format('-reentrada-{0}', github.event.pull_request.head.sha) || '' }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main') }}
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -326,7 +337,7 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
platforms: linux/amd64
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: false
|
||||
load: true
|
||||
tags: deskcomm-smoke:pr
|
||||
@@ -334,11 +345,13 @@ jobs:
|
||||
APP_VERSION=smoke
|
||||
# Mesmo escopo de cache do build-and-push: as camadas são idênticas,
|
||||
# então na prática este job reaproveita aquele build em vez de repeti-lo.
|
||||
cache-from: type=gha,scope=deskcommcrm
|
||||
cache-from: |
|
||||
type=gha,scope=deskcommcrm-${{ matrix.arch }}
|
||||
type=gha,scope=deskcommcrm
|
||||
# Em PR o build-and-push não roda, então quem grava o cache do PR é
|
||||
# este job — sem isto o segundo push do mesmo PR reconstruiria do
|
||||
# zero. Fora de PR continua só lendo: quem grava é o build-and-push.
|
||||
cache-to: ${{ github.event_name == 'pull_request' && 'type=gha,mode=max,scope=deskcommcrm' || '' }}
|
||||
cache-to: ${{ github.event_name == 'pull_request' && format('type=gha,mode=max,scope=deskcommcrm-{0}', matrix.arch) || '' }}
|
||||
|
||||
- name: O container chega a servir?
|
||||
run: |
|
||||
@@ -526,9 +539,17 @@ jobs:
|
||||
# Na `main` e em tag esta imagem vira a que o parque instala: ela se constrói
|
||||
# nas máquinas do GitHub, nunca numa máquina nossa. Guarda contra fork:
|
||||
# comentário do e2e-parte no e2e.yml.
|
||||
runs-on: ${{ vars.EXECUTOR_PROPRIO == 'ligado' && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && 'deskcomm-proprio' || 'ubuntu-latest' }}
|
||||
runs-on: ${{ matrix.arch == 'arm64' && 'ubuntu-24.04-arm' || (vars.EXECUTOR_PROPRIO == 'ligado' && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && 'deskcomm-proprio' || 'ubuntu-latest') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: amd64
|
||||
platform: linux/amd64
|
||||
- arch: arm64
|
||||
platform: linux/arm64
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-imagens-de-fundo-sobem-${{ github.event.pull_request.number || github.ref }}${{ github.event_name == 'pull_request' && github.run_attempt != '1' && format('-reentrada-{0}', github.event.pull_request.head.sha) || '' }}
|
||||
group: ${{ github.workflow }}-imagens-de-fundo-sobem-${{ matrix.arch }}-${{ github.event.pull_request.number || github.ref }}${{ github.event_name == 'pull_request' && github.run_attempt != '1' && format('-reentrada-{0}', github.event.pull_request.head.sha) || '' }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref == 'refs/heads/main') }}
|
||||
# Só leitura, explícita: sem o bloco o GITHUB_TOKEN herda o default do
|
||||
# REPOSITÓRIO — configuração que vive fora do repo, muda num clique e não
|
||||
@@ -546,7 +567,7 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.worker
|
||||
platforms: linux/amd64
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: false
|
||||
load: true
|
||||
tags: deskcomm-worker:pr
|
||||
@@ -555,21 +576,25 @@ jobs:
|
||||
# de um push e quente nos seguintes — "reaproveita aquele build" só
|
||||
# vale a partir do segundo. Medido em 16/09/2026 no primeiro run deste
|
||||
# gate: manifesto importado, camadas reconstruídas.
|
||||
cache-from: type=gha,scope=deskcommcrm-worker
|
||||
cache-from: |
|
||||
type=gha,scope=deskcommcrm-worker-${{ matrix.arch }}
|
||||
type=gha,scope=deskcommcrm-worker
|
||||
# Mesma razão do job do app: em PR, quem grava o cache é este job.
|
||||
cache-to: ${{ github.event_name == 'pull_request' && 'type=gha,mode=max,scope=deskcommcrm-worker' || '' }}
|
||||
cache-to: ${{ github.event_name == 'pull_request' && format('type=gha,mode=max,scope=deskcommcrm-worker-{0}', matrix.arch) || '' }}
|
||||
|
||||
- name: Build local da imagem do scheduler (sem push)
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.scheduler
|
||||
platforms: linux/amd64
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: false
|
||||
load: true
|
||||
tags: deskcomm-scheduler:pr
|
||||
cache-from: type=gha,scope=deskcommcrm-scheduler
|
||||
cache-to: ${{ github.event_name == 'pull_request' && 'type=gha,mode=max,scope=deskcommcrm-scheduler' || '' }}
|
||||
cache-from: |
|
||||
type=gha,scope=deskcommcrm-scheduler-${{ matrix.arch }}
|
||||
type=gha,scope=deskcommcrm-scheduler
|
||||
cache-to: ${{ github.event_name == 'pull_request' && format('type=gha,mode=max,scope=deskcommcrm-scheduler-{0}', matrix.arch) || '' }}
|
||||
|
||||
# A QUARTA imagem (módulo opcional de telefonia, #677). Ela entrou na
|
||||
# `main` sem nunca ter sido construída: `build-and-push` tem a matriz com
|
||||
@@ -584,12 +609,14 @@ jobs:
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.voice-agent
|
||||
platforms: linux/amd64
|
||||
platforms: ${{ matrix.platform }}
|
||||
push: false
|
||||
load: true
|
||||
tags: deskcomm-voice-agent:pr
|
||||
cache-from: type=gha,scope=deskcommcrm-voice-agent
|
||||
cache-to: ${{ github.event_name == 'pull_request' && 'type=gha,mode=max,scope=deskcommcrm-voice-agent' || '' }}
|
||||
cache-from: |
|
||||
type=gha,scope=deskcommcrm-voice-agent-${{ matrix.arch }}
|
||||
type=gha,scope=deskcommcrm-voice-agent
|
||||
cache-to: ${{ github.event_name == 'pull_request' && format('type=gha,mode=max,scope=deskcommcrm-voice-agent-{0}', matrix.arch) || '' }}
|
||||
|
||||
- name: O laço do event_log CARREGA dentro da imagem do worker?
|
||||
run: |
|
||||
|
||||
@@ -483,7 +483,7 @@ Lei completa em [`docs/doctrine/packaging.md`](docs/doctrine/packaging.md). O n
|
||||
declara `image:` de uma imagem publicada; `build:` só existe **ao lado**, como escape.
|
||||
Serviço `build:`-only é pulado por `docker compose pull` e imune a `up -d` sem `--build` —
|
||||
ele não é só caro de instalar, ele **nunca é atualizado**.
|
||||
- **Publicação é ato do CI**, nunca da sua máquina: build ARM local não roda na VPS amd64.
|
||||
- **Publicação é ato do CI**, nunca da sua máquina: as imagens publicadas atendem linux/amd64 e linux/arm64.
|
||||
- **Instalação de cliente aponta para número de versão**, nunca para tag móvel. Aqui `latest`
|
||||
significa **topo da `main`**, não última release — quem quer a última release usa `stable`.
|
||||
- **Dependência upstream é referenciada com tag fixa, nunca republicada** (WAHA é licenciado).
|
||||
|
||||
@@ -140,7 +140,7 @@ DeskcommCRM é um sistema operacional de vendas open source com agentes de IA na
|
||||
- Action audit obrigatória: `lgpd.data_request_received`, `lgpd.export_generated`, `lgpd.redact_executed`, `lgpd.consent_changed`
|
||||
|
||||
### WAHA
|
||||
- Default fixo `devlikeapro/waha:latest-2026.7.2`, NOWEB. A prova local criou duas sessões CORE simultâneas até `SCAN_QR_CODE`; não prova pairing, duas contas `WORKING` nem envio. Não bloquear segunda sessão por tier: conferir resposta estruturada e pós-condição da operação.
|
||||
- Imagem NOWEB pinada por arquitetura: `latest-2026.7.2` em x86 e `noweb-arm-2026.7.2` em ARM64. A prova local criou duas sessões CORE simultâneas até `SCAN_QR_CODE`; não prova pairing, duas contas `WORKING` nem envio. Não bloquear segunda sessão por tier: conferir resposta estruturada e pós-condição da operação.
|
||||
- Engine NOWEB default; WEBJS apenas se precisar stickers animados / botões
|
||||
- Auth: env do WAHA recebe **hash SHA512 hex** da api key; cliente envia plaintext em `X-Api-Key`
|
||||
- Webhooks: HMAC SHA512 com `crypto.timingSafeEqual`
|
||||
@@ -277,8 +277,9 @@ O não-negociável, em quatro linhas:
|
||||
só existe **ao lado**, como escape. Serviço `build:`-only é invisível para
|
||||
`docker compose pull` e imune a `up -d` sem `--build` — ele não é só caro de
|
||||
instalar, ele **nunca é atualizado**.
|
||||
2. **Publicação é ato do CI.** Nunca da sua máquina: build ARM local não roda
|
||||
na VPS amd64 do cliente, e a falha só aparece no `up -d` dele. O job
|
||||
2. **Publicação é ato do CI.** Nunca da sua máquina: o CI publica as imagens
|
||||
nativas para linux/amd64 e linux/arm64, e a falha de arquitetura precisa
|
||||
aparecer antes do `up -d` do cliente. O job
|
||||
`imagens-ok` reprova quando qualquer uma das três imagens não constrói, e
|
||||
**é status check obrigatório desde 2026-08-13** — a branch protection tem
|
||||
`verify, build-and-size, invariants, e2e, imagens-ok`. (Este parágrafo dizia
|
||||
|
||||
@@ -90,6 +90,10 @@ Se faltar Docker, o instalador pergunta e instala sozinho.
|
||||
| **IA** | Uma chave de **OpenRouter**, **Anthropic** ou **OpenAI** — o instalador pergunta qual você quer |
|
||||
| **WhatsApp** | Seu número, conectado por QR code no onboarding (ou o canal oficial da Meta) |
|
||||
|
||||
O instalador padrão também atende VPS ARM64/aarch64, como a Oracle Ampere A1, e escolhe a imagem
|
||||
NOWEB oficial do WAHA compatível com essa arquitetura. Esse caminho usa Supabase externo. O
|
||||
instalador alternativo que coloca o Supabase na mesma VPS continua restrito a amd64.
|
||||
|
||||
> 💡 **O Supabase pode ser criado pelo próprio instalador.** Exporte um
|
||||
> `SUPABASE_ACCESS_TOKEN` antes de rodar e ele cria o projeto, espera o banco ficar saudável,
|
||||
> busca as 4 credenciais e descobre o host do pooler testando conexão real — sem copiar e colar.
|
||||
|
||||
@@ -127,11 +127,10 @@ services:
|
||||
# precisar de multi-número/retry/S3 (licença paga).
|
||||
#
|
||||
# Tag PINADA: `devlikeapro/waha` sem tag é `:latest`, e o `dc pull` do
|
||||
# update.sh entregava ao cliente qualquer versão que o upstream tivesse
|
||||
# publicado — inclusive uma nunca testada por nós, no meio de uma
|
||||
# atualização. `latest-2026.7.2` é o mesmo digest de `latest` hoje
|
||||
# (65e593e30bb7…), então o pin não muda um bit; muda quem escolhe quando
|
||||
# o WhatsApp do cliente troca de motor. Bumpar faz parte do release.
|
||||
# update.sh entregaria ao cliente qualquer versão que o upstream tivesse
|
||||
# publicado. O instalador grava `latest-2026.7.2` em x86 e
|
||||
# `noweb-arm-2026.7.2` em ARM64; as duas tags fixam a versão NOWEB.
|
||||
# Bumpar faz parte do release.
|
||||
image: ${WAHA_IMAGE:-devlikeapro/waha:latest-2026.7.2}
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
|
||||
+1
-1
@@ -231,7 +231,7 @@ No menu lateral → **Storage** → **New bucket**:
|
||||
|
||||
## 3. WAHA — WhatsApp
|
||||
|
||||
**O que é:** Servidor que se conecta ao WhatsApp e expõe API HTTP. O default fixo é `devlikeapro/waha:latest-2026.7.2`, engine NOWEB. A prova local desta versão criou duas sessões CORE simultâneas até `SCAN_QR_CODE`; não houve pairing nem envio real. Versão/engine e pós-condição da operação determinam a compatibilidade; o tier sozinho não bloqueia um segundo número.
|
||||
**O que é:** Servidor que se conecta ao WhatsApp e expõe API HTTP. O instalador fixa a imagem NOWEB por arquitetura: `devlikeapro/waha:latest-2026.7.2` em x86 e `devlikeapro/waha:noweb-arm-2026.7.2` em ARM64. A prova local desta versão criou duas sessões CORE simultâneas até `SCAN_QR_CODE`; não houve pairing nem envio real. Versão/engine e pós-condição da operação determinam a compatibilidade; o tier sozinho não bloqueia um segundo número.
|
||||
|
||||
### Passo 1 — gerar a API key (plaintext + hash)
|
||||
|
||||
|
||||
@@ -94,10 +94,11 @@ worker:
|
||||
### 2. Publicação é ato do CI, e carrega procedência
|
||||
|
||||
Imagem nossa só existe se saiu de `.github/workflows/publish-image.yml`. Ela carrega os labels
|
||||
OCI — no mínimo `source`, `revision`, `version`, `licenses` — e é construída para `linux/amd64`.
|
||||
OCI — no mínimo `source`, `revision`, `version`, `licenses` — e é construída para `linux/amd64` e `linux/arm64`.
|
||||
|
||||
- **Por quê:** duas razões distintas. **(a) Arquitetura:** um `docker build` num Mac ARM produz
|
||||
imagem que não roda na VPS amd64 do cliente, e a falha aparece só no `up -d` dele. **(b)
|
||||
- **Por quê:** duas razões distintas. **(a) Arquitetura:** um `docker build` local pode produzir
|
||||
imagem para a plataforma errada; o CI publica manifestos linux/amd64 e linux/arm64 e os testa
|
||||
em runners nativos, antes de qualquer cliente chegar ao `up -d`. **(b)
|
||||
Rastreabilidade:** sem `org.opencontainers.image.revision` não existe resposta para "que
|
||||
código está rodando neste cliente?", e o suporte vira adivinhação.
|
||||
- **Verificação:** o job **`imagens-ok`** de `publish-image.yml` reprova quando qualquer uma
|
||||
|
||||
@@ -13,7 +13,7 @@ Este kit sobe o **DeskcommCRM** no seu servidor VPS da HostGator. Você tem dois
|
||||
> ```
|
||||
|
||||
> **Outra hospedagem?** O kit é feito para a HostGator (é a parceria do projeto e o caminho
|
||||
> testado de ponta a ponta), mas roda em qualquer VPS **x86_64/amd64** com Docker. Se a sua já vem com um
|
||||
> testado de ponta a ponta), mas roda em qualquer VPS **x86_64/amd64 ou ARM64/aarch64** com Docker. Se a sua já vem com um
|
||||
> **proxy reverso próprio** ocupando as portas 80/443 — caso de Hostinger, Coolify, Dokploy
|
||||
> e CapRover —, o instalador **detecta isso sozinho** e publica o CRM através dele, em vez
|
||||
> de tentar subir um Caddy que não caberia. Ver
|
||||
@@ -104,9 +104,10 @@ Owner/Admin. Não dá para hospedar vários clientes numa conta só.
|
||||
|
||||
## Requisitos do VPS
|
||||
|
||||
- **Arquitetura x86_64/amd64.** As imagens oficiais publicadas atualmente são `linux/amd64`.
|
||||
VPS ARM64/aarch64 ainda não são suportadas pelo kit; use uma VPS x86_64/amd64 enquanto
|
||||
não houver imagens multi-arquitetura.
|
||||
- **Arquitetura x86_64/amd64 ou ARM64/aarch64.** As imagens DeskcommCRM são publicadas para
|
||||
`linux/amd64` e `linux/arm64`; o instalador seleciona a variante oficial ARM64 NOWEB do WAHA.
|
||||
Este caminho usa Supabase externo. O instalador alternativo com Supabase self-hosted na mesma
|
||||
VPS continua limitado a amd64.
|
||||
- **4 GB RAM recomendados.** A imagem é pré-buildada, então o servidor não compila nada e a
|
||||
stack SOBE com 2 GB — mas operar é outra coisa: são 7 contêineres, e o WAHA consome
|
||||
~150 MB por sessão de WhatsApp além de ~300 MB de overhead do Node. Com 2 GB você roda
|
||||
|
||||
@@ -18,37 +18,47 @@ COMPOSE_NPM="docker-compose.npm.yml"
|
||||
COMPOSE_BUILD="docker-compose.build.yml"
|
||||
|
||||
# ── Arquitetura das imagens publicadas ───────────────────────────────────────
|
||||
# O registry publica hoje somente linux/amd64. Sem esta guarda, ARM64 chega até
|
||||
# o pull e morre com "no matching manifest"; o update.sh traduzia isso como
|
||||
# pacote ainda publicando/privado, um diagnóstico que manda repetir algo que
|
||||
# nunca vai funcionar nessa máquina.
|
||||
# O CI publica app, worker, scheduler e agente de voz em linux/amd64 e
|
||||
# linux/arm64. O instalador escolhe também a imagem oficial WAHA NOWEB ARM64;
|
||||
# Redis, Caddy e SRH já publicam manifestos ARM64. Sem reconhecer a arquitetura
|
||||
# aqui, uma VPS A1 seria recusada antes de chegar ao fluxo que já tem imagens
|
||||
# nativas para ela.
|
||||
#
|
||||
# A decisão fica pura no argumento para os testes simularem a arquitetura sem
|
||||
# depender do runner. A leitura de `uname -m` é o único ponto ligado ao host.
|
||||
arquitetura_suportada_pelo_kit() {
|
||||
case "${1:-}" in
|
||||
x86_64|amd64) return 0 ;;
|
||||
x86_64|amd64|aarch64|arm64) return 0 ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# WAHA publica NOWEB em tags distintas por arquitetura. O instalador grava
|
||||
# essa referência no .env; `enter_project` também cobre um .env antigo sem a
|
||||
# variável. A tag é fixa e corresponde à mesma versão funcional em ambas.
|
||||
imagem_waha_padrao_para_host() {
|
||||
case "$(uname -m 2>/dev/null || true)" in
|
||||
aarch64|arm64) printf '%s' 'devlikeapro/waha:noweb-arm-2026.7.2' ;;
|
||||
*) printf '%s' 'devlikeapro/waha:latest-2026.7.2' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# ── JÁ EXISTE UMA INSTALAÇÃO REAL AQUI? (#1266, corrigido pelo #1778) ───────
|
||||
#
|
||||
# A guarda do #1042 vivia no TOPO dos dois scripts, e por isso matava antes de
|
||||
# chegar ao `construir_aqui_e_subir` (#1060/#1143) — a recuperação por build
|
||||
# local que existe exatamente para a VPS cuja arquitetura não bate com a das
|
||||
# imagens publicadas. As duas mudanças tinham teste verde isoladamente e
|
||||
# ninguém rodou as duas juntas: o resultado foi um `exit 1` na PRIMEIRA linha,
|
||||
# que deixava quem já tinha uma instalação ARM funcionando PERMANENTEMENTE sem
|
||||
# poder rodar `update.sh` de novo, e sem bandeira nenhuma.
|
||||
# local para uma arquitetura sem imagem publicada. As duas mudanças tinham
|
||||
# teste verde isoladamente e ninguém rodou as duas juntas: o resultado foi um
|
||||
# `exit 1` na PRIMEIRA linha, que deixava uma instalação existente nessa
|
||||
# arquitetura sem poder rodar `update.sh` de novo, e sem bandeira nenhuma.
|
||||
#
|
||||
# O sinal NÃO pode ser o estado do DIRETÓRIO. "compose + `.env`" chega junto
|
||||
# numa instalação NOVA: o `.env` pode ter sido copiado de outra máquina, gerado
|
||||
# por automação, ou deixado por uma rodada anterior do `--yes` que parou no
|
||||
# meio. Com esse critério, um `install.sh --yes` numa VPS ARM NOVA com o `.env`
|
||||
# já preenchido passava pela guarda como se fosse instalação existente e ia
|
||||
# construir as imagens na própria VPS (15–25 min) — exatamente o que a guarda
|
||||
# do #1042 existe para impedir. E o `.env` sozinho nunca provou nada: o
|
||||
# meio. Com esse critério, um `install.sh --yes` numa VPS de arquitetura sem
|
||||
# imagem publicada e com o `.env` já preenchido passava pela guarda como se
|
||||
# fosse instalação existente e ia construir as imagens na própria VPS (15–25
|
||||
# min) — exatamente o que a guarda do #1042 existe para impedir. E o `.env` sozinho nunca provou nada: o
|
||||
# `git clone` de uma instalação nova pode trazer um `.env` de exemplo.
|
||||
#
|
||||
# O sinal do DIRETÓRIO entra como CONDIÇÃO, nunca como prova: sem compose nem
|
||||
@@ -141,14 +151,17 @@ marcar_instalacao_feita() { # marcar_instalacao_feita [versão]
|
||||
chmod 600 "$marca" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Ecoa: amd64 | recuperar | nova
|
||||
# Ecoa: amd64 | arm64 | recuperar | nova
|
||||
#
|
||||
# A decisão é PURA no que recebe: `uname` e a leitura do disco ficam fora, para
|
||||
# o teste simular as três respostas sem depender do runner nem de um diretório
|
||||
# de verdade. Quem traduz em mensagem é `verificar_arquitetura_do_kit`.
|
||||
veredito_da_arquitetura() { # veredito_da_arquitetura <arquitetura> [0=nova | 1=instalação existente]
|
||||
local arch="${1:-}" existe="${2:-0}"
|
||||
arquitetura_suportada_pelo_kit "$arch" && { printf 'amd64'; return 0; }
|
||||
case "$arch" in
|
||||
x86_64|amd64) printf 'amd64'; return 0 ;;
|
||||
aarch64|arm64) printf 'arm64'; return 0 ;;
|
||||
esac
|
||||
[ "$existe" = 1 ] && { printf 'recuperar'; return 0; }
|
||||
printf 'nova'
|
||||
}
|
||||
@@ -157,17 +170,17 @@ verificar_arquitetura_do_kit() {
|
||||
local arch existe=0
|
||||
arch="$(uname -m 2>/dev/null || t "desconhecida")"
|
||||
# O sinal de "instalação real" SÓ é perguntado quando a arquitetura não é
|
||||
# suportada. Em amd64 o veredito já é `amd64` e a guarda atravessa, então
|
||||
# perguntar seria trabalho inútil — e, com o critério do #1778, trabalho que
|
||||
# chama o `docker` no TOPO do install.sh, antes de qualquer passo do
|
||||
# instalador. A seção 4 do teste de #1778 mede isso: em x86_64 a guarda não
|
||||
# fala com o Docker.
|
||||
# suportada. Em amd64 ou arm64 o veredito já está definido e a guarda
|
||||
# atravessa, então perguntar seria trabalho inútil — e, com o critério do
|
||||
# #1778, trabalho que chama o `docker` no TOPO do install.sh, antes de
|
||||
# qualquer passo do instalador. A seção 4 do teste de #1778 mede isso em
|
||||
# x86_64.
|
||||
if ! arquitetura_suportada_pelo_kit "$arch"; then
|
||||
instalacao_real_do_kit_aqui && existe=1
|
||||
fi
|
||||
|
||||
case "$(veredito_da_arquitetura "$arch" "$existe")" in
|
||||
amd64) return 0 ;;
|
||||
amd64|arm64) return 0 ;;
|
||||
recuperar)
|
||||
# O update.sh relê este arquivo depois do checkout da versão nova, e a
|
||||
# guarda roda de novo no topo: sem esta trava o dono lia o mesmo aviso
|
||||
@@ -180,15 +193,15 @@ verificar_arquitetura_do_kit() {
|
||||
# recusa logo abaixo). O aviso vai para o STDERR, como a recusa: o
|
||||
# agent.sh manda a saída do update.sh para arquivo e o dono lê o fim dela.
|
||||
printf '%s\n' \
|
||||
"⚠ $(t "Este servidor usa arquitetura '{1}', e as imagens publicadas do DeskcommCRM são só linux/amd64." "$arch")" \
|
||||
"⚠ $(t "Este servidor usa arquitetura '{1}', e as imagens publicadas do DeskcommCRM são linux/amd64 e linux/arm64." "$arch")" \
|
||||
" $(t "Como esta instalação JÁ EXISTE, sigo em frente: as imagens da versão alvo serão construídas nesta própria VPS.")" \
|
||||
" $(t "Leva de 15 a 25 minutos. Uma instalação NOVA nesta arquitetura precisaria de imagens multi-arquitetura, que o DeskcommCRM ainda não publica.")" >&2
|
||||
" $(t "Leva de 15 a 25 minutos. Uma instalação NOVA exige x86_64/amd64 ou ARM64/aarch64 com imagens publicadas.")" >&2
|
||||
return 0 ;;
|
||||
esac
|
||||
|
||||
printf '%s\n' \
|
||||
"✖ $(t "Este servidor usa arquitetura '{1}', mas as imagens publicadas do DeskcommCRM hoje são linux/amd64." "$arch")" \
|
||||
" $(t ' Use uma VPS x86_64/amd64. Repetir o download não resolve; ARM64 só será suportado quando houver imagens multi-arquitetura.' | sed 's/^ //')" >&2
|
||||
"✖ $(t "Este servidor usa arquitetura '{1}', mas o DeskcommCRM não publica imagens para ela (linux/amd64 e linux/arm64 estão disponíveis)." "$arch")" \
|
||||
" $(t ' Use uma VPS x86_64/amd64 ou ARM64/aarch64. Repetir o download não resolve.' | sed 's/^ //')" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -1061,6 +1074,10 @@ enter_project() {
|
||||
else die "$(t "Não achei {1}. Rode a partir da pasta do projeto." "$COMPOSE")"; fi
|
||||
[ -f .env ] || die "$(t "Falta o .env (rode install.sh primeiro).")"
|
||||
load_env .env
|
||||
if [ -z "${WAHA_IMAGE:-}" ]; then
|
||||
WAHA_IMAGE="$(imagem_waha_padrao_para_host)"
|
||||
export WAHA_IMAGE
|
||||
fi
|
||||
PROJECT_DIR="$(pwd)"
|
||||
}
|
||||
|
||||
|
||||
@@ -33,11 +33,11 @@ _I18N_TABELA=0
|
||||
if [ $((BASH_VERSINFO[0] * 100 + BASH_VERSINFO[1])) -ge "${I18N_BASH_MINIMO:-404}" ]; then
|
||||
_I18N_TABELA=1
|
||||
declare -A _ES=(
|
||||
["Este servidor usa arquitetura '{1}', mas as imagens publicadas do DeskcommCRM hoje são linux/amd64."]="Este servidor usa arquitectura '{1}', pero las imágenes publicadas de DeskcommCRM hoy son linux/amd64."
|
||||
[" Use uma VPS x86_64/amd64. Repetir o download não resolve; ARM64 só será suportado quando houver imagens multi-arquitetura."]=" Usa una VPS x86_64/amd64. Repetir la descarga no soluciona nada; ARM64 solo se admitirá cuando existan imágenes multiarquitectura."
|
||||
["Este servidor usa arquitetura '{1}', e as imagens publicadas do DeskcommCRM são só linux/amd64."]="Este servidor usa arquitectura '{1}', y las imágenes publicadas de DeskcommCRM son solo linux/amd64."
|
||||
["Este servidor usa arquitetura '{1}', mas o DeskcommCRM não publica imagens para ela (linux/amd64 e linux/arm64 estão disponíveis)."]="Este servidor usa arquitectura '{1}', pero DeskcommCRM no publica imágenes para ella (linux/amd64 y linux/arm64 están disponibles)."
|
||||
[" Use uma VPS x86_64/amd64 ou ARM64/aarch64. Repetir o download não resolve."]=" Usa una VPS x86_64/amd64 o ARM64/aarch64. Repetir la descarga no soluciona nada."
|
||||
["Este servidor usa arquitetura '{1}', e as imagens publicadas do DeskcommCRM são linux/amd64 e linux/arm64."]="Este servidor usa arquitectura '{1}', y las imágenes publicadas de DeskcommCRM son linux/amd64 y linux/arm64."
|
||||
["Como esta instalação JÁ EXISTE, sigo em frente: as imagens da versão alvo serão construídas nesta própria VPS."]="Como esta instalación YA EXISTE, sigo adelante: las imágenes de la versión destino se construirán en esta misma VPS."
|
||||
["Leva de 15 a 25 minutos. Uma instalação NOVA nesta arquitetura precisaria de imagens multi-arquitetura, que o DeskcommCRM ainda não publica."]="Tarda de 15 a 25 minutos. Una instalación NUEVA en esta arquitectura necesitaría imágenes multiarquitectura, que DeskcommCRM todavía no publica."
|
||||
["Leva de 15 a 25 minutos. Uma instalação NOVA exige x86_64/amd64 ou ARM64/aarch64 com imagens publicadas."]="Tarda de 15 a 25 minutos. Una instalación NUEVA requiere x86_64/amd64 o ARM64/aarch64 con imágenes publicadas."
|
||||
[" (rede '{1}' criada — é por ela que o Traefik alcança o CRM)"]=" (red '{1}' creada: por ella Traefik llega al CRM)"
|
||||
["A rede Docker '{1}' (a do Nginx Proxy Manager) não existe.
|
||||
Rode 'docker network ls', identifique a rede do seu NPM (Settings > a que o
|
||||
@@ -120,7 +120,7 @@ sin eso un contenedor de compose común no puede entrar en ella."
|
||||
["derruba o que subiu"]="derriba lo que se levantó"
|
||||
["começa de novo"]="empieza de nuevo"
|
||||
["apaga o marcador desta instalação"]="borra el marcador de esta instalación"
|
||||
["⚠ Não consegui gravar o marcador desta instalação (arquivo .deskcomm-instalado). O CRM está no ar; numa VPS ARM a atualização pode pedir a VPS x86_64 até o marcador existir."]="⚠ No pude escribir el marcador de esta instalación (archivo .deskcomm-instalado). El CRM está en línea; en una VPS ARM la actualización puede pedir la VPS x86_64 hasta que el marcador exista."
|
||||
["⚠ Não consegui gravar o marcador desta instalação (arquivo .deskcomm-instalado). O CRM está no ar; numa arquitetura sem imagens publicadas, a atualização pode pedir uma VPS suportada até o marcador existir."]="⚠ No pude escribir el marcador de esta instalación (archivo .deskcomm-instalado). El CRM está en línea; en una arquitectura sin imágenes publicadas, la actualización puede pedir una VPS compatible hasta que exista el marcador."
|
||||
["Se o schema chegou a ser aplicado e você quer o banco limpo de novo,"]="Si el esquema llegó a aplicarse y quieres la base de datos limpia de nuevo,"
|
||||
["abra o Supabase > SQL Editor e rode (ATENÇÃO: apaga todos os dados):"]="abre Supabase > SQL Editor y ejecuta (ATENCIÓN: borra todos los datos):"
|
||||
|
||||
|
||||
@@ -1781,12 +1781,9 @@ esac
|
||||
printf '# Sem isto o número segue pareado no volume e MUDO até alguém abrir a tela\n'
|
||||
printf '# e clicar Reconectar — nada entra nem sai nesse meio-tempo.\n'
|
||||
envq WHATSAPP_RESTART_ALL_SESSIONS "${WHATSAPP_RESTART_ALL_SESSIONS:-True}"
|
||||
# PINADA. Sem a tag, `devlikeapro/waha` é `:latest`, e esta linha gravava isso
|
||||
# no .env de todo cliente — por cima do default pinado do compose, que então
|
||||
# nunca chegava a ninguém. O `dc pull` de cada update entregava qualquer versão
|
||||
# que o upstream tivesse publicado, sem ninguém ter testado.
|
||||
# `latest-2026.7.2` é o mesmo digest de `latest` hoje (65e593e30bb7…).
|
||||
envq WAHA_IMAGE "${WAHA_IMAGE:-devlikeapro/waha:latest-2026.7.2}"
|
||||
# WAHA publica variantes x86 e ARM separadas para NOWEB. O padrão acompanha
|
||||
# uname -m; uma WAHA_IMAGE escolhida pelo operador continua prevalecendo.
|
||||
envq WAHA_IMAGE "${WAHA_IMAGE:-$(imagem_waha_padrao_para_host)}"
|
||||
envq WAHA_DEFAULT_ENGINE "${WAHA_DEFAULT_ENGINE:-NOWEB}"
|
||||
envq UPSTASH_REDIS_REST_URL "http://srh:80"
|
||||
envq UPSTASH_REDIS_REST_TOKEN "$UPSTASH_REDIS_REST_TOKEN"
|
||||
@@ -2278,8 +2275,9 @@ setup_update_agent_cron
|
||||
# "instalação nova" de "instalação que já está no ar", e ela não pode usar
|
||||
# "tem compose e tem `.env`" como prova: o `.env` chega pronto numa instalação
|
||||
# NOVA (copiado, gerado por automação, ou deixado por um `--yes` que parou no
|
||||
# meio), e com esse critério uma VPS ARM nova começava a instalação construindo
|
||||
# as imagens na própria VPS — o que a guarda existe para impedir.
|
||||
# meio), e com esse critério uma VPS numa arquitetura sem imagens publicadas
|
||||
# começava a instalação construindo as imagens na própria VPS — o que a guarda
|
||||
# existe para impedir.
|
||||
#
|
||||
# O marcador vai aqui, e não antes, porque só a partir daqui é verdade que a
|
||||
# instalação EXISTE: os contêineres subiram e o app respondeu. Gravar antes
|
||||
@@ -2290,7 +2288,7 @@ setup_update_agent_cron
|
||||
# contêiner, que é o mesmo que ela usava para quem instalou numa versão
|
||||
# anterior.
|
||||
if [ "${APP_SAUDAVEL:-0}" = 1 ]; then
|
||||
marcar_instalacao_feita "$VERSAO_ALVO" || c_ylw "$(t "⚠ Não consegui gravar o marcador desta instalação (arquivo .deskcomm-instalado). O CRM está no ar; numa VPS ARM a atualização pode pedir a VPS x86_64 até o marcador existir.")"
|
||||
marcar_instalacao_feita "$VERSAO_ALVO" || c_ylw "$(t "⚠ Não consegui gravar o marcador desta instalação (arquivo .deskcomm-instalado). O CRM está no ar; numa arquitetura sem imagens publicadas, a atualização pode pedir uma VPS suportada até o marcador existir.")"
|
||||
fi
|
||||
|
||||
# ── Final ───────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -77,13 +77,11 @@ crontab -l >"$CRONTAB_REAL_ANTES" 2>/dev/null || : >"$CRONTAB_REAL_ANTES"
|
||||
|
||||
# dublar_uname_amd64 <diretório bin do sandbox>
|
||||
#
|
||||
# O `_common.sh` recusa, logo que é carregado, todo install.sh/update.sh que não
|
||||
# roda em amd64 — a imagem publicada é só linux/amd64. Os cenários que executam
|
||||
# esses scripts de verdade medem o INSTALADOR, não o processador de quem roda a
|
||||
# suíte: sem este dublê, num Mac Apple Silicon (`arm64`) todos eles paravam na
|
||||
# guarda (medido: 22 asserções vermelhas, a maioria "inconclusivo"). A recusa de
|
||||
# ARM tem prova própria em tests/shell/arquitetura-kit.test.sh. Só `uname -m` é
|
||||
# dublado; qualquer outro uso vai ao `uname` real.
|
||||
# Os cenários abaixo medem o instalador, não o processador de quem roda a
|
||||
# suíte. Fixamos o ambiente em x86_64 para que os fixtures e valores de imagem
|
||||
# desses casos permaneçam determinísticos; a aceitação de ARM64 tem prova
|
||||
# própria em tests/shell/arquitetura-kit.test.sh. Só `uname -m` é dublado;
|
||||
# qualquer outro uso vai ao `uname` real.
|
||||
UNAME_REAL="$(command -v uname)"
|
||||
dublar_uname_amd64() {
|
||||
cat > "$1/uname" <<STUB
|
||||
|
||||
@@ -726,11 +726,11 @@ step "Conferindo se o app voltou no ar"
|
||||
ok=""
|
||||
wait_app_healthy 20 3 >/dev/null && ok=1
|
||||
if [ -n "$ok" ]; then
|
||||
# O marcador que a guarda de ARM lê (#1778). Instalação ARM nova é recusada,
|
||||
# então toda instalação ARM que existe veio de antes do marcador e só seria
|
||||
# reconhecida pelo contêiner — que um `down` sem `-v` apaga. Gravar aqui, com
|
||||
# o app saudável, fecha esse caso a partir desta atualização. Falhar em
|
||||
# gravar não desfaz nada: a guarda segue caindo no sinal do contêiner.
|
||||
# O marcador que a guarda de arquitetura lê (#1778). Instalações antigas só
|
||||
# seriam reconhecidas pelo contêiner — que um `down` sem `-v` apaga. Gravar
|
||||
# aqui, com o app saudável, fecha esse caso a partir desta atualização.
|
||||
# Falhar em gravar não desfaz nada: a guarda segue caindo no sinal do
|
||||
# contêiner para arquiteturas que ainda não têm imagens publicadas.
|
||||
marcar_instalacao_feita "$TARGET_TAG" || true
|
||||
if [ -n "$BANCO_INCOMPLETO" ]; then
|
||||
c_ylw "⚠ App no ar e saudável, mas o banco NÃO terminou limpo — o que fazer está no fim desta saída."
|
||||
|
||||
@@ -69,33 +69,62 @@ SH
|
||||
}
|
||||
|
||||
for nome in install.sh update.sh; do
|
||||
rodar_como "$nome" aarch64
|
||||
rc="$(cat "$TMP/rc-$nome-aarch64")"
|
||||
out="$(cat "$TMP/out-$nome-aarch64")"
|
||||
rodar_como "$nome" riscv64
|
||||
rc="$(cat "$TMP/rc-$nome-riscv64")"
|
||||
out="$(cat "$TMP/out-$nome-riscv64")"
|
||||
|
||||
if [ "$rc" -eq 0 ]; then
|
||||
printf '✗ %s aceitou aarch64\n' "$nome"; fail=1
|
||||
elif ! printf '%s' "$out" | grep -q 'aarch64'; then
|
||||
printf '✗ %s aceitou riscv64\n' "$nome"; fail=1
|
||||
elif ! printf '%s' "$out" | grep -q 'riscv64'; then
|
||||
printf '✗ %s recusou sem dizer a arquitetura encontrada\n' "$nome"; fail=1
|
||||
elif ! printf '%s' "$out" | grep -q 'linux/amd64'; then
|
||||
printf '✗ %s recusou sem dizer qual imagem existe hoje\n' "$nome"; fail=1
|
||||
elif ! printf '%s' "$out" | grep -q 'x86_64/amd64'; then
|
||||
printf '✗ %s recusou sem orientar a arquitetura de VPS suportada\n' "$nome"; fail=1
|
||||
elif ! printf '%s' "$out" | grep -q 'linux/amd64 e linux/arm64'; then
|
||||
printf '✗ %s recusou sem dizer quais imagens estão disponíveis\n' "$nome"; fail=1
|
||||
elif ! printf '%s' "$out" | grep -q 'x86_64/amd64 ou ARM64/aarch64'; then
|
||||
printf '✗ %s recusou sem orientar as arquiteturas de VPS suportadas\n' "$nome"; fail=1
|
||||
elif printf '%s' "$out" | grep -q 'DEPOIS_DA_GUARDA'; then
|
||||
printf '✗ %s continuou depois da recusa\n' "$nome"; fail=1
|
||||
else
|
||||
printf '✓ %s recusa ARM64 com a causa correta\n' "$nome"
|
||||
printf '✓ %s recusa riscv64 com a causa correta\n' "$nome"
|
||||
fi
|
||||
done
|
||||
|
||||
for cmd in docker curl git; do
|
||||
if [ -e "$TMP/tocou-$cmd" ]; then
|
||||
printf '✗ a guarda tocou em %s antes de recusar ARM64\n' "$cmd"; fail=1
|
||||
printf '✗ a guarda tocou em %s antes de recusar riscv64\n' "$cmd"; fail=1
|
||||
else
|
||||
printf '✓ _common.sh recusa ARM64 antes de tocar em %s\n' "$cmd"
|
||||
printf '✓ _common.sh recusa riscv64 antes de tocar em %s\n' "$cmd"
|
||||
fi
|
||||
done
|
||||
|
||||
# Contrapeso: ARM64 agora atravessa a guarda sem consultar Docker nem tentar
|
||||
# construir imagem na VPS; a seleção de WAHA fica a cargo do instalador.
|
||||
for arch in aarch64 arm64; do
|
||||
rodar_como install.sh "$arch"
|
||||
rc="$(cat "$TMP/rc-install.sh-$arch")"
|
||||
out="$(cat "$TMP/out-install.sh-$arch")"
|
||||
if [ "$rc" -ne 0 ] || ! printf '%s' "$out" | grep -q 'DEPOIS_DA_GUARDA'; then
|
||||
printf '✗ ARM64 (%s) deveria atravessar a guarda\n' "$arch"; fail=1
|
||||
else
|
||||
printf '✓ ARM64 (%s) atravessa a guarda\n' "$arch"
|
||||
fi
|
||||
|
||||
imagem_waha="$(cd "$TMP" && env FAKE_ARCH="$arch" PATH="$TMP/bin:$PATH" \
|
||||
bash -c '. "$1"; imagem_waha_padrao_para_host' _ "$COMMON")"
|
||||
if [ "$imagem_waha" != 'devlikeapro/waha:noweb-arm-2026.7.2' ]; then
|
||||
printf '✗ ARM64 (%s) escolheu WAHA inesperado: %s\n' "$arch" "$imagem_waha"; fail=1
|
||||
else
|
||||
printf '✓ ARM64 (%s) escolhe WAHA NOWEB ARM64 pinado\n' "$arch"
|
||||
fi
|
||||
done
|
||||
|
||||
imagem_waha="$(cd "$TMP" && env FAKE_ARCH=x86_64 PATH="$TMP/bin:$PATH" \
|
||||
bash -c '. "$1"; imagem_waha_padrao_para_host' _ "$COMMON")"
|
||||
if [ "$imagem_waha" != 'devlikeapro/waha:latest-2026.7.2' ]; then
|
||||
printf '✗ x86_64 escolheu WAHA inesperado: %s\n' "$imagem_waha"; fail=1
|
||||
else
|
||||
printf '✓ x86_64 mantém o WAHA NOWEB pinado atual\n'
|
||||
fi
|
||||
|
||||
# Contrapeso: a guarda não pode transformar o requisito amd64 numa recusa geral.
|
||||
rodar_como update.sh x86_64
|
||||
rc="$(cat "$TMP/rc-update.sh-x86_64")"
|
||||
|
||||
@@ -4,25 +4,27 @@
|
||||
# O DEFEITO, e por que os dois testes que já existiam não o pegaram:
|
||||
#
|
||||
# A guarda de arquitetura (#1042) estava no TOPO do `source _common.sh`, e
|
||||
# saía com `exit 1` assim que `uname -m` não era x86_64/amd64. A recuperação
|
||||
# saía com `exit 1` assim que `uname -m` não era uma arquitetura publicada.
|
||||
# A recuperação
|
||||
# por build local (#1060/#1143, `construir_aqui_e_subir` + o overlay
|
||||
# `docker-compose.build.yml`) vive bem DEPOIS, no corpo do update.sh. As duas
|
||||
# mudanças tinham teste verde ISOLADAMENTE — `arquitetura-kit.test.sh` prova
|
||||
# que a recusa acontece; nenhum teste rodava `update.sh` de ponta a ponta com
|
||||
# um `uname` de ARM. Juntas, a recusa matava o script na primeira linha e a
|
||||
# recuperação ficava inalcançável: quem JÁ TINHA uma instalação ARM
|
||||
# funcionando ficava sem poder rodar `update.sh` nunca mais, sem bandeira.
|
||||
# um `uname` de arquitetura sem imagem. Juntas, a recusa matava o script na
|
||||
# primeira linha e a recuperação ficava inalcançável: quem JÁ TINHA uma
|
||||
# instalação nessa arquitetura funcionando ficava sem poder rodar `update.sh`
|
||||
# nunca mais, sem bandeira.
|
||||
#
|
||||
# O QUE ESTE ARQUIVO PROVA, e o que NÃO prova:
|
||||
#
|
||||
# Prova que com `uname -m` = aarch64 e uma instalação que JÁ EXISTE
|
||||
# Prova que com `uname -m` = riscv64 (arquitetura ainda não publicada) e uma instalação que JÁ EXISTE
|
||||
# (compose + `.env`), o `update.sh` ALCANÇA o caminho de recuperação: o
|
||||
# `docker compose -f docker-compose.build.yml build` é executado e o update
|
||||
# termina com o CRM no ar. Prova também que a instalação NOVA em ARM
|
||||
# continua recusada com a mesma mensagem do #1042, e que x86_64 não mudou
|
||||
# termina com o CRM no ar. Prova também que uma instalação NOVA em riscv64
|
||||
# continua recusada com a mensagem atual, ARM64 nova é aceita e x86_64 não mudou
|
||||
# nada.
|
||||
#
|
||||
# NÃO prova nada numa VPS ARM de verdade: `docker`, `curl`, `crontab`, `psql`
|
||||
# NÃO prova nada numa VPS de verdade: `docker`, `curl`, `crontab`, `psql`
|
||||
# e `uname` são dublês, o repositório git é descartável (mktemp) e nenhum
|
||||
# contêiner sobe. O que se prova é o CAMINHO DO SCRIPT, que é onde as duas
|
||||
# mudanças se cruzavam.
|
||||
@@ -201,7 +203,7 @@ rodar_update() {
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
echo '── 1. A DEFEITO: aarch64 numa instalação que JÁ EXISTE tem que alcançar a'
|
||||
echo '── 1. A RECUPERAÇÃO: riscv64 numa instalação que JÁ EXISTE alcança a'
|
||||
echo ' recuperação por build local, e não morrer na guarda do #1042'
|
||||
# É o relato da issue, palavra por palavra: um clone de ARM, com o CRM no ar,
|
||||
# e o `bash hostgator-setup-kit/update.sh` não passando de "Procurando
|
||||
@@ -209,13 +211,13 @@ echo ' recuperação por build local, e não morrer na guarda do #1042'
|
||||
# o overlay de build foi MESMO executado, e o update terminou bem.
|
||||
R1="$WORK/caso1"; mkdir -p "$R1"; montar_instalacao "$R1" 0
|
||||
OUT1="$WORK/saida1.txt"
|
||||
rodar_update "$R1" aarch64 1 "$OUT1"; RC1="$RC"
|
||||
rodar_update "$R1" riscv64 1 "$OUT1"; RC1="$RC"
|
||||
check "o update.sh NÃO morre na guarda de arquitetura (o 'Procurando atualizações' aparece)" \
|
||||
grep -q 'Procurando atualizações' "$OUT1"
|
||||
check "a guarda em vez de recusar AVISA que a instalação já existe" \
|
||||
grep -q 'JÁ EXISTE' "$OUT1"
|
||||
check "a arquitetura encontrada é dita ao dono (aarch64)" \
|
||||
grep -q 'aarch64' "$OUT1"
|
||||
check "a arquitetura encontrada é dita ao dono (riscv64)" \
|
||||
grep -q 'riscv64' "$OUT1"
|
||||
# O update.sh relê o _common.sh depois do checkout (update.sh, passo 3), e a
|
||||
# guarda roda de novo no topo dele: sem a trava por processo, o mesmo aviso
|
||||
# saía duas vezes na mesma atualização.
|
||||
@@ -231,29 +233,28 @@ check "e o serviço subiu pelo mesmo overlay" \
|
||||
check "a atualização terminou com o CRM no ar" \
|
||||
grep -q 'containers no ar\|Atualização concluída\|construídas aqui' "$OUT1"
|
||||
check "o update.sh saiu com 0 (rc=$RC1)" test "$RC1" -eq 0
|
||||
# O aviso da guarda não pode ser a recusa: a recusa do #1042 começa com '✖' e
|
||||
# manda usar VPS x86_64, e é a mensagem que o dono lia antes.
|
||||
check "a saída NÃO diz 'Use uma VPS x86_64/amd64' (a recusa do #1042)" \
|
||||
nao_contem 'Use uma VPS x86_64/amd64' "$OUT1"
|
||||
# O aviso de recuperação não pode virar a recusa de uma instalação nova.
|
||||
check "a saída NÃO traz a recusa de instalação nova" \
|
||||
nao_contem 'Use uma VPS x86_64/amd64 ou ARM64/aarch64' "$OUT1"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
echo
|
||||
echo '── 2. A GUARDA DO #1042 CONTINUA: instalação NOVA em aarch64 é recusada'
|
||||
echo '── 2. A GUARDA CONTINUA: instalação NOVA numa arquitetura sem imagem é recusada'
|
||||
# Contrapeso obrigatório, e é o motivo de a guarda não ter sido removida: numa
|
||||
# instalação nova não existe build local para recuperar — não há imagem, não há
|
||||
# `.env`, e o `construir_aqui_e_subir` só é alcançado DEPOIS do provisionamento
|
||||
# do banco. O que muda é que a recusa volta a ser a do #1042, com a causa certa.
|
||||
R2="$WORK/caso2"; mkdir -p "$R2"; montar_instalacao "$R2" 1
|
||||
OUT2="$WORK/saida2.txt"
|
||||
rodar_update "$R2" aarch64 1 "$OUT2"; RC2="$RC"
|
||||
check "a instalação NOVA em ARM é recusada (rc=$RC2, e != 0)" test "$RC2" -ne 0
|
||||
rodar_update "$R2" riscv64 1 "$OUT2"; RC2="$RC"
|
||||
check "a instalação NOVA em riscv64 é recusada (rc=$RC2, e != 0)" test "$RC2" -ne 0
|
||||
check "a recusa diz qual arquitetura foi encontrada" \
|
||||
grep -q 'aarch64' "$OUT2"
|
||||
check "a recusa diz qual é a imagem que existe hoje" \
|
||||
grep -q 'linux/amd64' "$OUT2"
|
||||
check "a recusa orienta a VPS suportada (o texto do #1042, intacto)" \
|
||||
grep -q 'Use uma VPS x86_64/amd64' "$OUT2"
|
||||
check "a instalação NOVA em ARM NÃO tenta construir imagens aqui" \
|
||||
grep -q 'riscv64' "$OUT2"
|
||||
check "a recusa lista as arquiteturas publicadas" \
|
||||
grep -q 'linux/amd64 e linux/arm64' "$OUT2"
|
||||
check "a recusa orienta a VPS suportada" \
|
||||
grep -q 'Use uma VPS x86_64/amd64 ou ARM64/aarch64' "$OUT2"
|
||||
check "a instalação NOVA em arquitetura sem imagem NÃO tenta construir imagens aqui" \
|
||||
nao_contem '-f docker-compose.build.yml build' "$DOCKER_LOG"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -276,14 +277,14 @@ check "em x86_64 a atualização pullou a imagem do app" \
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
echo
|
||||
echo '── 4. A DECISÃO, isolada: a função pura que decide'
|
||||
# As três respostas, sem `uname` e sem disco — é o que permite ao gate ler a
|
||||
# decisão sem montar instalação nenhuma, e cobre o limite: em amd64, existir ou
|
||||
# não uma instalação é a MESMA resposta.
|
||||
# As respostas, sem `uname` e sem disco — é o que permite ao gate ler a decisão
|
||||
# sem montar instalação nenhuma. amd64 e arm64 são nativas; só uma arquitetura
|
||||
# sem imagem depende de haver instalação anterior para recuperar.
|
||||
R4="$WORK/caso4"; mkdir -p "$R4"
|
||||
OUT4="$R4/veredito.txt"
|
||||
(
|
||||
. "$REPO_ROOT/hostgator-setup-kit/_common.sh"
|
||||
for par in "x86_64 0" "amd64 1" "aarch64 0" "aarch64 1" "arm64 1" "riscv64 0"; do
|
||||
for par in "x86_64 0" "amd64 1" "aarch64 0" "aarch64 1" "arm64 1" "riscv64 0" "riscv64 1"; do
|
||||
# shellcheck disable=SC2086
|
||||
set -- $par
|
||||
printf '%s %s → %s\n' "$1" "$2" "$(veredito_da_arquitetura "$1" "$2")"
|
||||
@@ -293,21 +294,24 @@ check "amd64 (nova ou existente) → amd64" \
|
||||
grep -q '^x86_64 0 → amd64$' "$OUT4"
|
||||
check "amd64 em instalação existente também é amd64" \
|
||||
grep -q '^amd64 1 → amd64$' "$OUT4"
|
||||
check "aarch64 em instalação NOVA → nova (a recusa do #1042)" \
|
||||
grep -q '^aarch64 0 → nova$' "$OUT4"
|
||||
check "aarch64 em instalação existente → recuperar" \
|
||||
grep -q '^aarch64 1 → recuperar$' "$OUT4"
|
||||
check "arm64 em instalação existente → recuperar" \
|
||||
grep -q '^arm64 1 → recuperar$' "$OUT4"
|
||||
check "outra arquitetura em instalação NOVA → nova" \
|
||||
check "aarch64 em instalação NOVA → arm64" \
|
||||
grep -q '^aarch64 0 → arm64$' "$OUT4"
|
||||
check "aarch64 em instalação existente → arm64" \
|
||||
grep -q '^aarch64 1 → arm64$' "$OUT4"
|
||||
check "arm64 em instalação existente → arm64" \
|
||||
grep -q '^arm64 1 → arm64$' "$OUT4"
|
||||
check "arquitetura sem imagem em instalação NOVA → nova" \
|
||||
grep -q '^riscv64 0 → nova$' "$OUT4"
|
||||
check "arquitetura sem imagem em instalação existente → recuperar" \
|
||||
grep -q '^riscv64 1 → recuperar$' "$OUT4"
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
echo
|
||||
echo '── 5. QUEM JÁ ESTÁ PRESO: o kit do disco é o da guarda velha, e o passo'
|
||||
echo ' único que o fragmento de release ensina tem de funcionar'
|
||||
# O update.sh dá `source` no _common.sh que está NO DISCO antes do checkout da
|
||||
# versão nova. Numa VPS ARM que já tem a guarda do #1042 (v1.35.0 em diante),
|
||||
# versão nova. Num kit antigo, uma VPS ARM ainda era bloqueada pela guarda
|
||||
# (#1042, v1.35.0 em diante),
|
||||
# esse kit velho morre no topo e nunca baixa este conserto — nem pelo terminal
|
||||
# nem pelo botão "Atualizar", que roda o mesmo update.sh. A saída é trocar o
|
||||
# código à mão uma vez e rodar o update.sh da versão nova. Este caso prova as
|
||||
@@ -315,7 +319,7 @@ echo ' único que o fragmento de release ensina tem de funcionar'
|
||||
# publicado no fragmento `.changes/guarda-arm-nao-mata-a-recuperacao.md` a solta.
|
||||
#
|
||||
# O kit "velho" é o do próprio PR com a detecção de instalação desligada, que
|
||||
# é exatamente o comportamento da guarda do #1042: recusa ARM sem olhar nada.
|
||||
# é exatamente o comportamento da guarda antiga do #1042: recusa ARM sem olhar nada.
|
||||
R5="$WORK/caso5"; mkdir -p "$R5"; montar_instalacao "$R5" 0
|
||||
(
|
||||
cd "$R5/deskcommcrm" || exit 1
|
||||
@@ -346,10 +350,10 @@ check "depois do checkout à mão, o update.sh da versão nova sai com 0 (rc=$RC
|
||||
check "e ele chega à recuperação por build local" \
|
||||
grep -q -- '-f docker-compose.build.yml build' "$DOCKER_LOG"
|
||||
|
||||
printf '\nstatus: caso1(ARM+recuperação)=%s caso2(nova ARM)=%s caso3(amd64)=%s\n' \
|
||||
printf '\nstatus: caso1(arquitetura sem imagem+recuperação)=%s caso2(nova arquitetura sem imagem)=%s caso3(amd64)=%s\n' \
|
||||
"$RC1" "$RC2" "$RC3"
|
||||
if [ "$FAILS" -eq 0 ]; then
|
||||
echo "OK — a guarda não mata a recuperação (#1266) e continua recusando a instalação nova (#1042)."
|
||||
echo "OK — a guarda preserva a recuperação de arquiteturas sem imagem e aceita as arquiteturas publicadas."
|
||||
else
|
||||
echo "FALHOU — $FAILS prova(s)."
|
||||
fi
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# ── #1778 — a guarda de ARM só considera instalação REAL ─────────────────────
|
||||
# ── #1778 — a guarda de arquitetura sem suporte só considera instalação REAL ───────────────────────
|
||||
#
|
||||
# O DEFEITO, e por que o teste do #1775 não podia pegá-lo:
|
||||
#
|
||||
# O #1775 separou instalação NOVA (recusa em não-x86_64) de instalação
|
||||
# EXISTENTE (aviso, e o script segue até o build local). O critério de
|
||||
# "existente" lia o estado do DIRETÓRIO — compose E um `.env` — e um
|
||||
# `install.sh --yes` numa VPS ARM NOVA com o `.env` já preenchido (copiado de
|
||||
# `install.sh --yes` numa VPS com arquitetura sem suporte e `.env` já preenchido (copiado de
|
||||
# outra máquina, gerado por automação, ou deixado por uma rodada anterior que
|
||||
# parou no meio) passava como existente e ia construir as imagens na própria
|
||||
# VPS. O caminho alcançado é o mesmo build local que o install.sh já tem
|
||||
# (por volta da linha 2209), então não é risco de segurança: é a instalação
|
||||
# NOVA em ARM deixar de ser recusada, que é o que a guarda do #1042 existe
|
||||
# NOVA em arquitetura sem suporte deixar de ser recusada, que é o que a guarda do #1042 existe
|
||||
# para impedir.
|
||||
#
|
||||
# O teste do #1775 não podia ver isso porque a fixture dele (`montar_instalacao`)
|
||||
@@ -24,13 +24,13 @@
|
||||
#
|
||||
# Prova que a guarda decide pelo que a instalação DEIXOU (marcador, contêiner
|
||||
# do projeto, contêiner do Supabase single-server) e não pelo que chegou
|
||||
# pronto na pasta: com `.env` e nada instalado, aarch64 é recusada com a
|
||||
# pronto na pasta: com `.env` e nada instalado, riscv64 é recusada com a
|
||||
# recusa do #1042. Prova que os três sinais de instalação real continuam
|
||||
# passando, que o filtro de contêiner é por PROJETO (o de outra instalação na
|
||||
# mesma VPS não vale), que `docker` indisponível não vira instalação inventada,
|
||||
# e que em x86_64 o `docker` nem é chamado — a guarda não perguntou nada.
|
||||
#
|
||||
# NÃO prova nada numa VPS ARM de verdade: `uname` e `docker` são dublês, o
|
||||
# NÃO prova nada numa VPS com arquitetura sem suporte de verdade: `uname` e `docker` são dublês, o
|
||||
# diretório é descartável (mktemp) e nenhum contêiner sobe. O que se prova é
|
||||
# a DECISÃO da guarda, que é onde o critério mora.
|
||||
#
|
||||
@@ -70,7 +70,7 @@ mkdir -p "$WORK/bin"
|
||||
# binário de verdade.
|
||||
cat > "$WORK/bin/uname" <<STUB
|
||||
#!/usr/bin/env bash
|
||||
[ "\$*" = "-m" ] && { printf '%s\n' "\${FAKE_ARCH:-aarch64}"; exit 0; }
|
||||
[ "\$*" = "-m" ] && { printf '%s\n' "\${FAKE_ARCH:-riscv64}"; exit 0; }
|
||||
exec "$REAL_UNAME" "\$@"
|
||||
STUB
|
||||
# `docker` responde ao ÚNICO comando que a guarda faz: `ps -a -q --filter
|
||||
@@ -160,21 +160,21 @@ nome_derivado() { basename "$1" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9_-'
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
echo '── 1. A DEFÉITO DA #1778: .env preenchido + NADA instalado é instalação'
|
||||
echo ' NOVA, e aarch64 é recusada com a recusa do #1042'
|
||||
# A receita do relato: `install.sh --yes` numa VPS ARM NOVA cujo `.env` veio
|
||||
echo ' NOVA, e riscv64 é recusada com a recusa do #1042'
|
||||
# A receita do relato: `install.sh --yes` numa VPS com arquitetura sem suporte e instalação NOVA cujo `.env` veio
|
||||
# pronto (copiado de outra máquina, gerado por automação, ou deixado por uma
|
||||
# rodada que parou no meio). Compose e `.env` estão lá — que era o que bastava.
|
||||
# O resultado tem de ser a RECUSA, com o texto do #1042, e sem a palavra do
|
||||
# aviso de instalação existente.
|
||||
R1="$WORK/caso1"; mkdir -p "$R1"; montar_pasta "$R1/deskcommcrm" 0
|
||||
guarda "$R1" aarch64
|
||||
guarda "$R1" riscv64
|
||||
check ".env + compose e NADA instalado → a instalação NÃO é real" \
|
||||
test "$VEREDITO" = NOVA
|
||||
check "e aarch64 é recusada (rc=$RC, e != 0)" test "$RC" -ne 0
|
||||
check "e riscv64 é recusada (rc=$RC, e != 0)" test "$RC" -ne 0
|
||||
check "a recusa é a do #1042 (orienta a VPS suportada)" \
|
||||
grep -q 'Use uma VPS x86_64/amd64' "$WORK/guarda.out"
|
||||
grep -q 'Use uma VPS x86_64/amd64 ou ARM64/aarch64' "$WORK/guarda.out"
|
||||
check "a recusa diz qual arquitetura foi encontrada" \
|
||||
grep -q 'aarch64' "$WORK/guarda.out"
|
||||
grep -q 'riscv64' "$WORK/guarda.out"
|
||||
check "e NÃO diz que a instalação já existe (o aviso do #1775)" \
|
||||
nao_contem 'JÁ EXISTE' "$WORK/guarda.out"
|
||||
|
||||
@@ -182,7 +182,7 @@ check "e NÃO diz que a instalação já existe (o aviso do #1775)" \
|
||||
echo
|
||||
echo '── 2. OS TRÊS SINAIS DE INSTALAÇÃO REAL CONTINUAM PASSANDO (#1775 intacto)'
|
||||
# O contrapeso obrigatório: o que o #1775 consertou não pode ser desfeito. Sem
|
||||
# esta seção, um conserto que recusasse TUDO em ARM também ficaria verde.
|
||||
# esta seção, um conserto que recusasse TUDO em arquitetura sem suporte também ficaria verde.
|
||||
R2="$WORK/caso2"; mkdir -p "$R2"; montar_pasta "$R2/deskcommcrm" 0
|
||||
marcar_instalacao() { # marcar_instalacao <diretório> [versão]
|
||||
printf 'instalado_em=2026-09-27T00:00:00Z\nversao=%s\n' "${2:-0.9.0}" \
|
||||
@@ -192,30 +192,30 @@ marcar_instalacao() { # marcar_instalacao <diretório> [versão]
|
||||
# 2a. O marcador, que o install.sh grava com a stack no ar. É o sinal mais
|
||||
# forte: a instalação em si escreveu que terminou.
|
||||
marcar_instalacao "$R2/deskcommcrm"
|
||||
guarda "$R2" aarch64
|
||||
guarda "$R2" riscv64
|
||||
check "o marcador .deskcomm-instalado → a instalação é real" test "$VEREDITO" = REAL
|
||||
check "e aarch64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
check "e riscv64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
check "com o aviso de que a instalação já existe, e não com a recusa" \
|
||||
grep -q 'JÁ EXISTE' "$WORK/guarda.out"
|
||||
check "e a recusa do #1042 NÃO aparece" \
|
||||
nao_contem 'Use uma VPS x86_64/amd64' "$WORK/guarda.out"
|
||||
nao_contem 'Use uma VPS x86_64/amd64 ou ARM64/aarch64' "$WORK/guarda.out"
|
||||
|
||||
# 2b. O contêiner do projeto, que é o caso de quem instalou numa versão
|
||||
# anterior e por isso não tem marcador. Precisa ser o contêiner do projeto
|
||||
# DESTA instalação — daí o nome derivado da pasta, e não um nome qualquer.
|
||||
R2B="$WORK/caso2b"; mkdir -p "$R2B"; montar_pasta "$R2B/deskcommcrm" 0
|
||||
guarda "$R2B" aarch64 "$(nome_derivado "$R2B/deskcommcrm")"
|
||||
guarda "$R2B" riscv64 "$(nome_derivado "$R2B/deskcommcrm")"
|
||||
check "contêiner do projeto DESTA instalação → é real" test "$VEREDITO" = REAL
|
||||
check "e aarch64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
check "e riscv64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
check "com o aviso de instalação existente" grep -q 'JÁ EXISTE' "$WORK/guarda.out"
|
||||
|
||||
# 2c. O contêiner do Supabase single-server, que o modo single-server cria com
|
||||
# o sufixo `-supabase` no nome do projeto. Sem este sinal, quem instalou em
|
||||
# single-server passaria a ser recusado numa VPS ARM — uma regressão nova.
|
||||
# single-server passaria a ser recusado numa VPS com arquitetura sem suporte — uma regressão nova.
|
||||
R2C="$WORK/caso2c"; mkdir -p "$R2C"; montar_pasta "$R2C/deskcommcrm" 0
|
||||
guarda "$R2C" aarch64 "$(nome_derivado "$R2C/deskcommcrm")-supabase"
|
||||
guarda "$R2C" riscv64 "$(nome_derivado "$R2C/deskcommcrm")-supabase"
|
||||
check "contêiner do Supabase single-server → é real" test "$VEREDITO" = REAL
|
||||
check "e aarch64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
check "e riscv64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
|
||||
# 2d. O COMPOSE_PROJECT_NAME do `.env` manda sobre o nome derivado da pasta, e
|
||||
# o guard tem de procurar pelo que os contêineres carregam de verdade. Uma
|
||||
@@ -223,10 +223,10 @@ check "e aarch64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
# nomeia o projeto no `.env` justamente para não disputar o parque com a outra.
|
||||
R2D="$WORK/caso2d"; mkdir -p "$R2D"; montar_pasta "$R2D/deskcommcrm" 0
|
||||
printf 'COMPOSE_PROJECT_NAME=deskcommcrm-2\n' >> "$R2D/deskcommcrm/.env"
|
||||
guarda "$R2D" aarch64 "deskcommcrm-2"
|
||||
guarda "$R2D" riscv64 "deskcommcrm-2"
|
||||
check "COMPOSE_PROJECT_NAME do .env manda sobre o nome da pasta → é real" \
|
||||
test "$VEREDITO" = REAL
|
||||
check "e aarch64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
check "e riscv64 passa pela guarda (rc=$RC, e == 0)" test "$RC" -eq 0
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
echo
|
||||
@@ -238,19 +238,19 @@ echo ' que não respondeu'
|
||||
# projeto, qualquer VPS com Docker vira "instalação existente" e a recusa do
|
||||
# #1042 deixa de existir em cima de um `docker ps` qualquer.
|
||||
R3="$WORK/caso3"; mkdir -p "$R3"; montar_pasta "$R3/deskcommcrm" 0
|
||||
guarda "$R3" aarch64 "wordpress_app_pljr imobplus-server-app-1 traefik"
|
||||
guarda "$R3" riscv64 "wordpress_app_pljr imobplus-server-app-1 traefik"
|
||||
check "contêiner de OUTRO programa na mesma VPS → a instalação NÃO é real" \
|
||||
test "$VEREDITO" = NOVA
|
||||
check "e aarch64 é recusada (rc=$RC, e != 0)" test "$RC" -ne 0
|
||||
check "a recusa é a do #1042" grep -q 'Use uma VPS x86_64/amd64' "$WORK/guarda.out"
|
||||
check "e riscv64 é recusada (rc=$RC, e != 0)" test "$RC" -ne 0
|
||||
check "a recusa é a do #1042" grep -q 'Use uma VPS x86_64/amd64 ou ARM64/aarch64' "$WORK/guarda.out"
|
||||
|
||||
# Um `docker` que não responde (fora do PATH, daemon parado, sem permissão no
|
||||
# socket) devolve vazio, e vazio é "não achei" — a resposta que manda RECUSAR.
|
||||
# O contrário seria adivinhar instalação a partir de um Docker que não falou.
|
||||
R3B="$WORK/caso3b"; mkdir -p "$R3B"; montar_pasta "$R3B/deskcommcrm" 0
|
||||
guarda "$R3B" aarch64
|
||||
guarda "$R3B" riscv64
|
||||
: > "$DOCKER_LOG"
|
||||
( cd "$R3B" && env -i PATH="/usr/bin:/bin" HOME="${HOME:-/root}" FAKE_ARCH=aarch64 \
|
||||
( cd "$R3B" && env -i PATH="/usr/bin:/bin" HOME="${HOME:-/root}" FAKE_ARCH=riscv64 \
|
||||
bash -c '. "$0"
|
||||
if instalacao_real_do_kit_aqui; then echo REAL; else echo NOVA; fi' "$COMMON" \
|
||||
) > "$WORK/sem-docker.txt" 2>&1
|
||||
@@ -260,10 +260,10 @@ check "sem docker no PATH, a instalação NÃO é inventada" \
|
||||
# Sem `.env` não há nem nome de projeto para procurar — e a pasta nem é uma
|
||||
# instalação. O guard nem deve chamar o docker aqui.
|
||||
R3C="$WORK/caso3c"; mkdir -p "$R3C"; montar_pasta "$R3C/deskcommcrm" 1
|
||||
guarda "$R3C" aarch64 "$(nome_derivado "$R3C/deskcommcrm")"
|
||||
guarda "$R3C" riscv64 "$(nome_derivado "$R3C/deskcommcrm")"
|
||||
check "sem .env (e com contêiner do projeto lá) → a instalação NÃO é real" \
|
||||
test "$VEREDITO" = NOVA
|
||||
check "e aarch64 é recusada (rc=$RC, e != 0)" test "$RC" -ne 0
|
||||
check "e riscv64 é recusada (rc=$RC, e != 0)" test "$RC" -ne 0
|
||||
check "e o docker nem é chamado sem .env" docker_nao_falou
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
@@ -359,7 +359,7 @@ check "e o painel de recuperação do install.sh também o apaga" \
|
||||
check "e o marcador está no .gitignore (estado da VPS, não do repositório)" \
|
||||
grep -qx '.deskcomm-instalado' "$REPO_ROOT/.gitignore"
|
||||
# O update.sh também grava, com o app saudável. Depois deste conserto, uma
|
||||
# instalação ARM NOVA é recusada — então toda instalação ARM que existe veio
|
||||
# instalação NOVA numa arquitetura sem suporte é recusada — então toda instalação nessa arquitetura que existe veio
|
||||
# de antes e NÃO tem marcador; o único sinal dela seria o contêiner, e um
|
||||
# `down` sem `-v` (ou um `prune`) a faria ser recusada como nova, o mesmo
|
||||
# defeito do #1775. Gravar no update fecha isso a partir da atualização
|
||||
|
||||
Reference in New Issue
Block a user