# Runbook — corte EVEO → WCI de 3 clientes numa janela longa

**Clientes:** IT995476 Multiseg (Sankhya) · IT590768 CHPL · IT228334 KAMELL
**Preparado em 25/09/2026.** Tudo que está em "Preparado" já foi executado e validado; a janela
só executa a parte "Corte".

Base: `runbook-corte-eveo-wci-2026-09.md` (LEADS/MARK), skill
`cloud-base/.claude/skills/migrate-vcloud-to-wevy-v2v`, e as memórias de Guimarães (IT951754),
que é o precedente direto do Multiseg.

---

## 0. O que já está preparado (não precisa refazer na janela)

| item | IT995476 Multiseg | IT590768 CHPL | IT228334 KAMELL |
|---|---|---|---|
| rede WCI | `IT995476` 10.1.1.0/24 `a0b5a758-…` ✅ (22/09) | **`IT590768` 192.168.127.0/24 `4c48d3ee-53a5-4c05-8293-3d370e17872c`** ✅ novo | **`IT228334` 192.168.121.0/24 `8f377482-7fcc-43b3-b2b3-ea3aef02c41b`** ✅ novo |
| CIDR validado | sim (VMs rodando) | **sim** — helper subiu `Running` | **sim** — helper subiu `Running` |
| IP público (source-NAT) | **177.85.38.249** `76d319b4-…` | **177.85.38.85** `6031c3d3-c95d-4863-b26d-c7c6518719ea` | **177.85.38.88** `49aafdf4-d78d-477a-b7ed-5f59046aa810` |
| ingress (firewall) | 80, 443, 22 ✅ | 80, 443, udp/1194, 22 ✅ | udp/1194, 8443, 1433 (4 IPs TID), 22 ✅ |
| egress | all (10.1.1.0/24) ✅ | **all** ✅ criado hoje | **all** ✅ criado hoje |
| IP interno reservado | VMs já ocupam .250/.254 | `IT590768-RESERVA-IP` → 192.168.127.5 | `IT228334-RESERVA-IP` → 192.168.121.5 |
| helper de cópia | `IT995476-SNK-APP-WCI` 10.1.1.254 | `IT590768-HELPER-MIG` 192.168.127.240 | `IT228334-HELPER-MIG` 192.168.121.240 |
| SSH do CLOUDADMIN01 → helper | ✅ `ubuntu@177.85.38.249` | ✅ `ubuntu@177.85.38.85` | ✅ `ubuntu@177.85.38.88` |
| zstd/pigz no helper | ✅ | ✅ | ✅ |

Outros fatos de preparação confirmados hoje:

- **Os 3 nós do Proxmox alcançam a WCI direto na 22** (`177.85.38.x`) e têm **`zstd`** (256 cores).
  `pigz` **não** existe nos nós — use `zstd -1 -T8`. Isso permite copiar **direto do LV**, sem
  passar pelo qcow2 no NFS01, para tudo que **não** precisa de `virt-v2v` (Linux e discos de dados).
  A chave `wci-dep` **já foi distribuída** para `/root/.ssh/wci-dep` nos nós `.11`, `.12` e `.14`,
  e o SSH nó→helper está provado nos três.
- **Vazão medida hoje nesse caminho: 309 MB/s** (3,1 GB de dado real do disco `F:` do KAMELL,
  do nó `-2` até o helper, em 10,2 s). É ~3× a medição de 22/09 via `transfer.cloudax.cloud`
  (115 MB/s) — o ganho vem do `zstd` sobre dado compressível, com o fio saturando ~1 Gbps.
  Trate 309 MB/s como teto otimista e ~150–200 MB/s como número de planejamento.
- **nfs01 tem tudo o que o caminho Windows precisa**: `virt-v2v 2.4.0`, `ntfsfix`, `ms-sys`,
  `sgdisk`, `sfdisk`, `qemu-nbd`, `pigz`, **`zstd`**, `/NFS01/migrate/fix-boot-windows.sh` +
  `gpt_to_mbr_layout.py` e `/tmp/virtio-win.iso`. São **8 cores** — use `zstd -T8` ali.
- **`/NFS01` tem ~1,2 TB livres** (3,9 T no total) — cabe o que falta. Conte que o disco de boot
  ocupa **duas vezes**: o qcow2 convertido **mais** a saída do `virt-v2v` (o KAMELL virou
  86 G + 86 G). CHPL será ~196 G + 196 G. Apagar o qcow2 de entrada depois do v2v alivia.
- `STAGING-FIXBOOT` (`841df317-a5ed-4b4b-b08c-5896f96c38bb`) **está de pé** (10.1.1.237 +
  192.168.125.210) — é onde roda o `bcdboot`.
- `IT995476-database-raw` foi **aumentado de 602 → 800 GiB** (o `/database` da origem está com
  **96%** de uso; depois do `dd` é `growpart` + `resize2fs`).

### Scripts prontos em `/NFS01/migrate/corte-3clientes/`

(no CLOUDADMIN01 o mesmo diretório é `/mnt/nfs01/migrate/corte-3clientes/`; nos nós Proxmox é
`/mnt/pve/NFS01/migrate/corte-3clientes/`)

| script | roda em | o quê |
|---|---|---|
| `cs` | CLOUDADMIN01 | atalho para a API nativa da WCI pela ponte |
| `checklist-janela.md` | — | a lista para marcar durante a janela |
| `volumes-dados.sh <PREFIXO> <uuid-helper> <nome:GiB>…` | CLOUDADMIN01 | cria volumes vazios, anexa no helper e imprime o `deviceid` de cada um |
| `copia-lv.sh <lv> <ip-helper> <dev>` | nó Proxmox | cópia genérica LV→volume com `zstd` |
| `dados-kamell.sh` / `dados-chpl.sh` | nó `-2` / nó `-4` | os `dd` dos discos de dados, já com os LVs certos |
| `boot-1-convert.sh <vmid> <n> <DEST>` | nó do cliente | converte o disco de boot para qcow2 no NFS01 (destacado, com log) |
| `boot-2-v2v.sh <DEST> <n>` (`SUDOPW=…`) | nfs01 | `ntfsfix` → `virt-v2v` → renomeia → `fix-boot` **só se a origem for GPT** → layout final |
| `boot-3-para-volume.sh <qcow2> <ip-helper> <dev>` (`SUDOPW=…`) | nfs01 | `qemu-nbd` + `zstd` + `dd` do boot tratado para o volume |
| `bcdboot-staging.py` | container do painel | lista os discos do `STAGING-FIXBOOT` e imprime o bloco do `bcdboot` |
| `chk-bcd.sh` | nfs01 | diz se o `\Boot\BCD`, o `bootmgr` e o `viostor.sys` estão no disco tratado |
| `ensaio-kamell-{1,2}*.sh` | — | as versões do ensaio de 25-26/09 (equivalentes às `boot-*` acima) |
| `multiseg-db.sh` | nó `-1` | `dd` do `/database` (543 G) e do root do banco |
| `multiseg-db-pos-boot.sh` | guest do banco | o roteiro do fstab/UUID, mkfs do backup, `growpart` e subida do Oracle |
| `copia-payload-multiseg.sh` | nó `-1` | **leva todos os arquivos do Sankhya para o Docker** (wildfly prd/tst/treina, repositório, licença byte-exata) |
| `nat-IT590768.sh` / `nat-IT228334.sh <uuid-vm>` | CLOUDADMIN01 | recria os port-forwards |
| `IT*-cloudax.ovpn` | — | perfis OpenVPN com IP antigo + novo, para distribuir às lojas antes da janela |

### Acessos usados neste runbook

| onde | como |
|---|---|
| plano de controle | `ssh CLOUDADMIN01` → `sudo docker exec -i cloudaxadmin-web python manage.py shell` |
| API CloudStack | `scratchpad/cs <Cmd> k=v` (salta CLOUDADMIN01 → `wci-dep` → ponte `177.85.38.108:32855`) |
| nfs01 (virt-v2v) | de CLOUDADMIN01: `sshpass -p 'In0v@t3ch' ssh …inovatech@10.0.10.45` |
| nós Proxmox | do nfs01: `ssh -i ~/.ssh/id_rsa root@192.168.100.{11,12,14}` |
| Proxmox API (HA) | token **`vmadmin@pve!vmadmin_ansible`**; o `cloudadmin@pam!cloudadmin` lê mas **não** faz `agent/exec` (403 VM.Monitor) |
| guests Linux do Multiseg | `svc_ansible` + chave do Vault (já em `nfs01:/tmp/svc_mig.key` e `/tmp/iaas_mig.key`) |
| Windows CHPL/KAMELL | WinRM 5985, `get_ansible_credentials(<code>, <server>)`; `sa` do SQL está em `db_users` no Vault |

---

## 1. Inventário medido (25/09/2026)

### IT995476 Multiseg — Sankhya, nós `sp1-sd-inovatech-1` e `-2`

| origem | vmid | disco | uso real | destino |
|---|---|---|---|---|
| `IT995476-DB-SNK` 20.0.20.120 (OL 8.9, 2 vCPU/10 GB) | **147** (nó -1) | virtio0 50G · virtio1 **602G** · virtio2 1000G | root 5,9 G · `/database` **543 G (96%)** · `/database-backup` 0,85 G | VM nova 10.1.1.250, 4 vCPU/16 GB |
| `IT995476-SNK-APP` 20.0.20.121 + **192.168.117.4** (LXC Ubuntu) | **3212** (nó -1) | rootfs 130G · mp0 15G | 49 G (prd 24 G + tst 15 G) · `/volumes` **5,0 G** | **`IT995476-SNK-APP-WCI` 10.1.1.254** (já existe, 16 vCPU/128 GB) |
| `IT995476-IAAS-INSTANCE01` 192.168.117.5 (CentOS 7.9) | **3213** (nó -2) | scsi0 65G | root 33 G (82%) | VM nova, sugestão **10.1.1.117** |

- Oracle 21c CDB `SANKHYAC` / PDB `SANKHYAPDB`, **NOARCHIVELOG** ⇒ só cópia a frio.
  `oratab` do Multiseg é **`Y`**. Schemas `MULTISEGPRD`/`MULTISEGTST`. 3 empresas, 146 usuários.
- **`/database` monta por `/dev/vdb1` no fstab** — repetir o fix do Guimarães: reescrever para
  `UUID=` antes do primeiro boot (o `dd` preserva o UUID).
- **`/database-backup` (1000G, 852 MB usados) não se copia**: o volume
  `IT995476-database-backup` (200 G) já existe vazio → `mkfs.ext4` + fstab por UUID.
- O IaaS é a **Força de Venda = SalesFusion em Docker** (`salesfusion_producao_1`,
  `_agent_1`, `_db_1` mariadb; `_testes_1` está em loop de restart **desde antes**, não é
  regressão do corte). Expõe 9101/9103 só internamente.
- **`192.168.117.x` desaparece na WCI** (tudo cai em 10.1.1.0/24). Antes de ligar, `grep -r
  192\.168\.117` no SalesFusion e no Sankhya, e `/etc/hosts` nas duas pontas.

### IT590768 CHPL — `CHPL-SRV001`, Win Server 2019, **UEFI/GPT**, nó `sp1-sd-inovatech-4`, vmid **185**, HA `started`

16 vCPU / 128 GB · `cpu=host` · NIC **e1000** · discos **já virtio-scsi**

| disco | letra | tamanho | usado | levar? |
|---|---|---|---|---|
| virtio0 | **C:** Windows | 230 G | 195,9 G | sim (boot — v2v + fix-boot + bcdboot) |
| virtio1 | **Z:** `DB_OLD` | 100 G | 95,8 G | **não** — é a cópia de rollback do B: antigo (17/08). Fica na origem |
| virtio2 | **F:** DADOS | 100 G | 60,1 G | sim (`SISTEMA TID`, `MDFSQL`, `ARQUIVOS`) |
| virtio3 | **B:** DB | 200 G | 97,8 G | sim (`DB`, `Binarios`, `Shares`, `tempbackup`) |

- **É DC do domínio `tarx.local`** (DomainRole 5, PDC/GC), **sem parceiro de replicação**
  (`repadmin /showrepl` lista só ele) e com DNS cliente em **8.8.8.8**. Floresta isolada —
  migra sozinho, não há risco de replicação. Não "consertar" o DNS durante o corte.
- SQL Server 2022 CU26, instância **`TIDSCI`, porta 62087** — **não publicada**; as lojas
  entram por **OpenVPN**.
- **Quem atende o público é o `nginx 1.29.8` (`C:\tools`) nas portas 90 e 443**; o IIS está atrás
  dele em 91/92/8088/4443 (sites `CHL` e `CHPL` em `F:\SISTEMA TID\TIDVendas_*`).
- OpenVPN **servidor** UDP **1194**, `config-auto\server.ovpn`, rede **12.8.0.0/24**, auth AD por
  `C:\tarx\Scripts\auth_ad.ps1` (`verify-client-cert none`). ~44 perfis em `ipp.txt`.
- Tarefas: `Cloudax-Backup-TID-MinIO` (~01:23) e `Cloudax-Clean-TID-Temp` (04:30).

### IT228334 KAMELL — `TARX-TID`, Win Server 2016, **UEFI/GPT**, nó `sp1-sd-inovatech-2`, vmid **172**, HA `started`

4 vCPU / 28 GB · NIC **e1000** · discos **SATA** (precisam de virtio injetado)

| disco | letra | tamanho | usado | observação |
|---|---|---|---|---|
| sata0 | **C:** | 93 G | 86,0 G | boot — v2v + fix-boot + bcdboot. **C: com só 6,4 G livres** |
| sata1 | **B:** | 60 G | 9,6 G | tem o **SQL Express** instalado (`B:\Program Files\…MSSQL15.SQLEXPRESS`) |
| sata2 | **F:** | 65 G | 60,9 G | **só 4,0 G livres** |

- Também é **DC de `tarx.local`** (PDC/GC, sem parceiro, DNS 8.8.8.8) — mesma situação do CHPL.
  As duas florestas se chamam igual mas **não se falam**; cada uma migra sozinha.
- **SQL Express (MSSQL15) na 1433** + `sqlbrowser` 1434/UDP. `SQLAgent$SQLEXPRESS` desabilitado.
- **PostgreSQL 9.6** na 5432. **Alterdata Backup-Service** em 8768/9257. IIS: `siteapi` (80) e
  `IntegradorTotvsKamell` (8780, `F:\IIS_PROJECTS`). **nginx 1.31.1** na 8443 (é o que o
  público consome). `nginx` como *serviço* está `Stopped` — quem sobe é outro caminho, conferir.
- OpenVPN servidor UDP 1194, mesma estrutura do CHPL, 12.8.0.0/24, ~40 perfis.
- Está na **malha wg**: `wg0` 10.200.0.4 e **`wg1` 10.201.0.11** (dois túneis — levar os dois).
- Tarefas: `Cloudax-Backup-TID-MinIO`, `Cloudax-Clean-TID-Temp`, `RUN CLEAN TID`, `BackupTask`.

---

## 2. NAT — o que reproduzir (medido no FortiGate com hit_count)

| origem (VIP / policy) | hits | vira na WCI |
|---|---|---|
| **CHPL** `IT590768-TCP-443-443` 138.59.146.35:443 → .127.5:443 (pol 273) | **34.673.171** | PF `177.85.38.85:443 → 443` |
| **CHPL** `IT590768-TCP-80-90` 138.59.146.35:80 → .127.5:**90** (pol 272) | **5.560.815** | PF `177.85.38.85:80 → 90` (tradução de porta) |
| **CHPL** `IT590768-IPPUBLIC-CHPL-OPENVPN` :1194 udp (pol 122) | **56.910** | PF `177.85.38.85:1194 udp → 1194` |
| **KAMELL** `IT228334-KAMELL-APITIDSOFT` 138.59.146.29:8443 (pol 275) | **95.179** | PF `177.85.38.88:8443 → 8443` |
| **KAMELL** `IT228334_OPENVPN-KAMELL` :1194 udp (pol 103) | **59.668** | PF `177.85.38.88:1194 udp → 1194` |
| **KAMELL** `IT228334-KAMELL-SQLSERVER-TID` :1433, src `TID-IPS-PUBLIC` (pol 127) | **15.853** | PF `177.85.38.88:1433 → 1433`, ingress restrito a `181.191.206.123/32, 187.72.206.33/32, 177.157.108.212/32, 177.130.239.40/32` |
| **Multiseg** via `PROXY-SANKHYAS-CLOUDFLARE` 138.59.146.8 → 20.0.20.9 | — | PF 80/443 no `177.85.38.249` (**já criados**) |
| **Multiseg** `IT995476-MULTISEG-FORCAVENDA` 138.59.146.24 → 192.168.117.5 (pol 72, SSH) | **0** | **não reproduzir** (publicação sem acesso; confirma a nota do runbook anterior) |

Os **ingress (firewall) já estão criados** nos 3 IPs. Os **port-forwards morrem com a VM shell**
— por isso os PFs finais são um script só, rodado depois que a VM definitiva existe:
`/mnt/nfs01/migrate/corte-3clientes/nat-<CODE>.sh <vm-uuid>`.

### Os perfis OpenVPN das lojas — **decisão tomada: migrar para o IP público novo**

Não existe registro DNS para o VPN: os perfis das ~40 estações de cada cliente apontam para o
**IP fixo** `138.59.146.29` (KAMELL) / `138.59.146.35` (CHPL), e é por esse túnel que o SQL é
consumido. A decisão é **levar as lojas para o IP novo**.

Para que isso **não** exija tocar as estações dentro da janela, os perfis prontos usam
**dois `remote`** — o OpenVPN tenta o primeiro e, se não responder em 10 s, vai para o segundo:

```
remote 138.59.146.29 1194      # IP atual (EVEO) — apagar depois que estabilizar
remote 177.85.38.88  1194      # IP novo (WCI)
connect-timeout 10
connect-retry 2 10
```

Arquivos gerados, com o **CA embutido** (validado: `O=TARX`, válido até 2034/2035) e sem
certificado de cliente (o servidor usa `verify-client-cert none` + auth AD):

- `/NFS01/migrate/corte-3clientes/IT228334-KAMELL-cloudax.ovpn`
- `/NFS01/migrate/corte-3clientes/IT590768-CHPL-cloudax.ovpn`

**Distribuir esses perfis ANTES da janela.** Assim o corte fica transparente para as lojas: antes
conecta no IP antigo, depois no novo, sem ninguém mexer na estação. Depois que estabilizar,
apagar a linha do IP antigo.

Se a distribuição prévia não acontecer, o corte **derruba as lojas** até o perfil novo chegar a
cada estação — é o custo de não ter nome DNS.

---

## 3. Caminho técnico por tipo de disco

| caso | caminho | vazão |
|---|---|---|
| **Linux / discos de dados** (Multiseg todo, B: e F: do CHPL e do KAMELL) | `dd` do **LV no nó** → `zstd -1 -T8` → ssh → helper → `unzstd \| dd of=/dev/vdX conv=sparse`. **Não passa pelo NFS01 e não converte para qcow2.** Script pronto: `copia-lv.sh` | **309 MB/s medido** (planejar com 150–200) |
| **boot Windows** | nó: `qemu-img convert -O qcow2` LV → `/mnt/pve/NFS01/migrate/<DEST>/` → nfs01: `ntfsfix` em todas as NTFS → `virt-v2v` → `fix-boot-windows.sh` → `dd` para o volume (use **`zstd -T8`**, não `pigz`) → **`bcdboot` no STAGING-FIXBOOT** → `createTemplate` → `deployVirtualMachine` | conversão ~120 MiB/s; cópia 45–55 MB/s com pigz, mais com zstd |

**Nunca** `registerTemplate url=` (7 MB/s) nem `uploadVolume` de disco grande (morre no meio e o
CloudStack apaga o volume sem erro). **`attachVolume` não promove a ROOT** — só `createTemplate`.

`ostypeid` conferidos nesta zona (26/09):

| SO | ostypeid |
|---|---|
| Windows Server 2016 (KAMELL) | `2bb22aee-19a0-11f1-8872-52540098a0e8` |
| Windows Server 2019 (CHPL) | `2c54d0b7-19a0-11f1-8872-52540098a0e8` |
| Oracle Linux 8 (banco do Multiseg) | `2c6ed6da-19a0-11f1-8872-52540098a0e8` |
| CentOS 7 (SalesFusion do Multiseg) | `284d5109-19a0-11f1-8872-52540098a0e8` |

Offerings: `wci.default.disk` (volume custom) = `f1baa864-c5d1-416d-a38d-b232214bd3cd` ·
`wci.g1.medium` 4/16 = `8468fb15-…` · `wci.g1.xlarge` 16/64 = `daba85d6-…` ·
`wci.m1.2xlarge` 16/128 = `dd531aac-…` (é o da VM de app do Multiseg).

`dd` lê **`/dev/nbd0`**, nunca o `.qcow2` direto.

### O risco herdado: Windows UEFI que não boota

CHPL e KAMELL são **os dois `bios: ovmf`**. Foi exatamente esse perfil que falhou no LEADS
(`0xc000000f` — `\Boot\BCD` só na ESP) e que exigiu `bcdboot` na `STAGING-FIXBOOT`. O MARK
(2016, mesmo caminho) bootou; **a contradição do MARK segue aberta** — não há prova de que o
`bcdboot` seja suficiente nem de que seja necessário.

### ✅ O ensaio foi feito em 25-26/09 e o caminho está provado

Disco de boot do KAMELL copiado **a quente** (origem seguiu no ar), `ntfsfix` → `virt-v2v` →
`fix-boot-windows.sh v2` → `dd` para volume → `bcdboot` na `STAGING-FIXBOOT` → `createTemplate` →
`deployVirtualMachine` em `192.168.121.6`. **A VM bootou por completo.** Provas:

- LDAP rootDSE respondendo: `dnsHostName: TARX-TID.tarx.local`,
  `defaultNamingContext: DC=tarx,DC=local`, `currentTime` correto.
- Portas abertas: **53, 88, 135, 389, 445, 464, 636, 3268, 3269, 3389, 5985 e 8443** — ou seja
  AD DS, DNS, SMB, RDP, WinRM **e o nginx do ERP**.
- Métricas da API saíram do padrão de falha: `diskkbswrite` chegou a 60 MB/s e a rede a
  ~1,3 MB/s (o `0xc000000f` fica com escrita e rede em **zero** para sempre).

**Os quatro aprendizados do ensaio:**

1. **O `bcdboot` é obrigatório e o motivo está medido.** Depois do `fix-boot`, a NTFS tinha
   `bootmgr` (392.732 B) e `viostor.sys` (65.176 B) mas **nenhum `\Boot\BCD`** — o BCD ficou só
   na ESP. O `bcdboot` criou um de **20.480 bytes** com `{default}` →
   `\Windows\system32\winload.exe`, descrição "Windows Server 2016". Não é azar do LEADS: é
   determinístico para origem UEFI.
2. **O guest sobe por DHCP, não no IP estático.** A NIC muda de `e1000` para virtio, o Windows
   vê adaptador novo e a configuração estática antiga fica órfã: a VM pegou **`.6`** (o endereço
   que o CloudStack reservou), não o `.5` da origem. ⇒ **no corte, faça o deploy com
   `ipaddress=<IP da origem>`** e o DHCP entrega exatamente o endereço antigo. Depois do corte,
   vale limpar a configuração órfã do adaptador antigo.
3. **Tempos reais do disco de boot de 93 GiB:** `qemu-img convert` **~14 min** · `virt-v2v`
   **~5 min** · `dd` para o volume **~11 min a 149 MB/s** · `createTemplate` **~3 min** ·
   deploy + boot até os serviços subirem **~8 min**. **Total ~40 min.** Para o CHPL (230 G),
   escale por ~2,5×.
4. **WinRM funciona** na VM migrada, com a credencial do Vault. O 401 que apareceu na primeira
   tentativa era **túnel errado**: `pgrep -f "L 0.0.0.0:15986"` dentro de um `bash -c` **casa com a
   própria linha de comando**, então o guard achou que já havia túnel e não criou nenhum — e a
   porta estava ocupada por um túnel antigo apontando para `192.168.125.5` (LEADS). Eu autentiquei
   contra outra máquina. **Confira o listener com `ss -ltn | grep <porta>`, nunca com `pgrep -f`.**
   Pela porta livre o WinRM mostrou `TARX-TID`, `FIRMWARE: Bios` e NTDS/DNS/W3SVC/OpenVPN/QEMU-GA
   `Running`.
5. **A NIC segue `Intel PRO/1000 MT` (e1000) e o ROOT vem como `bus=ATA`** — o `virt-v2v` injetou
   só `VirtIO Balloon` e `VirtIO Serial`; nenhum `viostor` em uso. Boota e opera, mas não é o
   controlador rápido. Se o desempenho de disco incomodar depois do corte, é aí que se mexe
   (`rootDiskController` — que o `cs.py` não consegue passar: quebra o HMAC).
6. ⚠️ **O clone subiu com `wg0` e `wg1` `Up`, com as mesmas chaves da produção.** No ensaio não
   houve dano (o peer `10.200.0.4` no hub seguiu apontando para `138.59.146.29` e com
   `handshake=0` — nunca fechou handshake nesta instância do `wg0`, condição **pré-existente**;
   e a produção segue com uptime intacto). Mas em ensaio futuro, **desabilite os serviços
   WireGuard antes de ligar o clone**.

ℹ️ **Achado colateral:** o KAMELL de produção **não está alcançável pela malha** (`10.200.0.4` não
responde, `handshake=0` no hub). É anterior ao ensaio e não bloqueia nada — a gestão dele hoje é
por WinRM em `192.168.121.5` pela rede do EVEO. Vale arrumar depois do corte, quando o gateway
muda de qualquer jeito.

Restos a limpar **antes** da janela: VM `ENSAIO-KAMELL-BOOT` (já **parada** — um DC duplicado não
pode ficar de pé na mesma ilha do KAMELL real), template `ENSAIO-KAMELL-boot`
(`ab80e0c5-…`, 93 G) e `/NFS01/migrate/ENSAIO-KAMELL/` (~172 G).

---

## 4. Ordem e orçamento da janela

O link EVEO→WCI satura em **~1 Gbps agregado** — paralelizar transferências **não** acumula
vazão. O que dá para sobrepor é **conversão local (CPU/disco do nó) de um cliente com
transferência de outro**.

| # | bloco | estimativa | por quê nessa ordem |
|---|---|---|---|
| 1 | **Multiseg** — parar Oracle/WildFly, `qm shutdown`, disparar o `dd` do `/database` (543 G) | transferência **~45 min – 1 h** | é o maior volume; roda sozinho enquanto o KAMELL anda |
| 2 | **KAMELL** — conversão do boot (86 G) em paralelo ao passo 1, depois v2v + fix-boot + bcdboot + dados (71 G ≈ 8 min) | 1 h – 1 h 30 | menor; valida o caminho Windows cedo |
| 3 | **Multiseg** — fechar: root do DB, fstab por UUID, payload do Docker (44 G ≈ 5 min), SalesFusion (33 G), subir Oracle + containers | 1 h 30 | o `dd` grande já terminou |
| 4 | **CHPL** — boot 196 G (conversão ~28 min + v2v ~25 min) + dados 158 G (≈ 15 min) | 1 h 30 – 2 h | maior dos Windows |
| 5 | DNS, painel, Zabbix, snapshots, job de backup, validações finais | 40 min | |
| | **total** | **~5 – 6 h** | |

Com a vazão de 309 MB/s medida hoje, o gargalo deixou de ser a rede e passou a ser a
**conversão local para qcow2 + `virt-v2v` dos dois discos de boot Windows** (~1 h 40 somados).
Dá para sobrepor: converter o boot do CHPL no nó `-4` enquanto o KAMELL transfere do nó `-2`.

Se o ensaio de boot do §3 for feito **antes** da janela, corta-se o maior risco e provavelmente
1 h de tentativa-e-erro.

---

## 5. Corte — IT228334 KAMELL

```bash
CODE=IT228334; VMID=172; NODE=sp1-sd-inovatech-2; NODEIP=192.168.100.12
NET=8f377482-7fcc-43b3-b2b3-ea3aef02c41b; PUBIP=49aafdf4-d78d-477a-b7ed-5f59046aa810
HELPER=177.85.38.88                    # IT228334-HELPER-MIG (192.168.121.240)
```

1. **Avisar/confirmar** que ninguém está no ERP. Conferir `Get-ScheduledTaskInfo` para não cair
   no meio do backup (01:23) nem da limpeza (04:30).
2. **Baseline de paridade** (medir ANTES): nº de bancos no SQL Express, contagem de uma tabela
   grande do TID, `curl -sk https://138.59.146.29:8443/` (título/status), `openvpn-status.log`
   (nº de clientes conectados).
3. **Desarmar HA e desligar**:
   ```
   PUT /cluster/ha/resources/vm:172 -d state=disabled      # token vmadmin
   qm shutdown 172                                         # dispare e verifique por qm status em loop
   ```
   ⚠️ com HA `disabled` o `qm shutdown` **não retorna**. Confirme `qmshutdown OK` na task list.
4. **Boot disk** (no nó -2):
   ```
   lvchange -ay /dev/VG_Storage0/vm-172-disk-0
   mkdir -p -m 777 /mnt/pve/NFS01/migrate/KAMELL-WCI
   setsid nohup qemu-img convert -O qcow2 /dev/VG_Storage0/vm-172-disk-0 \
     /mnt/pve/NFS01/migrate/KAMELL-WCI/KAMELL-disk-0.qcow2 </dev/null \
     >/mnt/pve/NFS01/migrate/logs/kamell-conv.log 2>&1 &
   ```
5. **Discos de dados, direto do LV** (pode rodar em paralelo à conversão acima — um é
   disco→NFS, o outro é rede). Dois scripts, nessa ordem:
   ```
   # no CLOUDADMIN01: cria os volumes vazios e anexa no helper
   bash /mnt/nfs01/migrate/corte-3clientes/volumes-dados.sh KAMELL \
        64114922-784d-407a-b6da-78cd43d7669f B:60 F:65
   # no nó -2: copia (a chave /root/.ssh/wci-dep JÁ está nos 3 nós)
   bash /mnt/pve/NFS01/migrate/corte-3clientes/dados-kamell.sh
   ```
   ⚠️ Confira no `volumes-dados.sh` qual `deviceid` virou `/dev/vdb` / `/dev/vdc` **antes** do
   `dd` — escrever no disco errado sobrescreve o volume errado.
6. **nfs01** — limpar NTFS, converter, arrumar boot:
   ```
   modprobe nbd max_part=16; qemu-nbd -c /dev/nbd0 KAMELL-disk-0.qcow2; sleep 4; partprobe /dev/nbd0
   for P in /dev/nbd0p*; do [ "$(blkid -o value -s TYPE $P)" = ntfs ] && ntfsfix -d "$P"; done
   qemu-nbd -d /dev/nbd0
   VIRTIO_WIN=/tmp/virtio-win.iso sudo virt-v2v -i disk KAMELL-disk-0.qcow2 -o local -of qcow2 \
        -os /NFS01/migrate/KAMELL-WCI -on KAMELL-boot     # saída: KAMELL-boot-sda (sem extensão)
   bash /NFS01/migrate/fix-boot-windows.sh /NFS01/migrate/KAMELL-WCI/KAMELL-boot-sda
   ```
   ⚠️ **origem é GPT/UEFI → roda fix-boot.** Nunca rodar fix-boot em disco que já é MBR.
   ℹ️ O `0xc0000428` (viostor SHA-256) **não se aplica aqui**: é problema de 2012 R2. KAMELL é
   2016 (14393) e CHPL é 2019 — os dois validam SHA-2. Se aparecer, o sintoma é outro
   (`cpuused` 40–70% com disco **e** rede em zero).
7. **Levar o boot** para um volume de 93 G e **rodar o `bcdboot`**:
   ```
   # tunel para o STAGING-FIXBOOT (validado hoje; se ja houver listener na 15985, reaproveite)
   ssh -N -i ~/.ssh/wci-dep -L 0.0.0.0:15985:192.168.125.210:5985 ubuntu@177.85.38.42 &
   # anexa o volume migrado na VM de apoio
   bash cs attachVolume id=<vol-boot> virtualmachineid=841df317-a5ed-4b4b-b08c-5896f96c38bb
   # roteiro guiado (lista os discos e imprime o bloco a executar)
   ssh CLOUDADMIN01 'sudo docker exec -i cloudaxadmin-web python manage.py shell' \
       < /mnt/nfs01/migrate/corte-3clientes/bcdboot-staging.py
   ```
   No guest: `Set-Disk -IsReadOnly $false -IsOffline $false` → achar a NTFS grande →
   `bcdboot <L>:\Windows /s <L>: /f BIOS` → **`Test-Path <L>:\Boot\BCD` tem que dar `True`**.
   Credencial validada hoje: **`.\administrator` / `Mudar@123!`** por NTLM (se o primeiro
   handshake for rejeitado, tente de novo — o túnel recém-aberto derruba a primeira tentativa).
   Depois `detachVolume` → `createTemplate ostypeid=2bb22aee-19a0-11f1-8872-52540098a0e8`
   (2016) → `deployVirtualMachine ipaddress=192.168.121.5` (destruir antes o `IT228334-RESERVA-IP`).
8. `attachVolume` dos dois discos de dados na VM nova; ligar; console.
9. Dentro do guest: discos Offline → Online, letras **B:** e **F:** conforme a origem
   (o SQL Express mora em `B:` — sem a letra certa ele não sobe), `Get-Service QEMU-GA`.
10. **NAT**: `bash nat-IT228334.sh <uuid-da-vm-nova>` (1194/udp, 8443, 1433 restrito).
11. **Validar pelo IP público**: `https://177.85.38.88:8443/` com conteúdo, `nc -zu` 1194,
    `sqlcmd` de um dos IPs TID (ou, na falta, provar que a porta responde).
12. **DNS**: `it228334-api-tid.cloudax.cloud` (proxied, `973b32172a646447d5af4354afc42e9e`) →
    `177.85.38.88`. Troca instantânea.
13. **OpenVPN**: aplicar a decisão do §2 (relé no FortiGate, ou perfis novos).
14. Painel, Zabbix (proxy `proxy-wci-br-sp2-02`, proxyid 2), malha wg (wg0 **e wg1**),
    snapshots DAILY maxsnaps=7, job de backup 7 dias na madrugada.

## 6. Corte — IT590768 CHPL

Igual ao KAMELL, com estas diferenças:

```bash
CODE=IT590768; VMID=185; NODE=sp1-sd-inovatech-4; NODEIP=192.168.100.14
NET=4c48d3ee-53a5-4c05-8293-3d370e17872c; PUBIP=6031c3d3-c95d-4863-b26d-c7c6518719ea
HELPER=177.85.38.85                    # IT590768-HELPER-MIG (192.168.127.240)
```

- **Não levar o `virtio1` (Z: `DB_OLD`, 95,8 G)** — é cópia de rollback de 17/08 e fica na origem.
  Confirmado por conteúdo: `Z:` e `B:` têm a mesma árvore (`DB`, `Binarios`, `Shares`, `tempbackup`).
- Discos: boot `virtio0` (230 G) · dados `virtio2` → **F:** (100 G) · `virtio3` → **B:** (200 G).
- `ostypeid` 2019 = `2c54d0b7-…`.
- Parar o SQL **antes** do `qm shutdown` (`Stop-Service 'MSSQL$TIDSCI'`) para fechar os arquivos
  limpos — o histórico de corrupção de I/O desse servidor recomenda isso.
- Depois de ligar, conferir **`max server memory` = 92160 MB** e `MAXDOP=4` (se a RAM da
  offering nova for diferente de 128 GB, ajustar).
- **NAT**: `bash nat-IT590768.sh <uuid>` — atenção à **tradução 80 → 90**.
- Validar: `curl -skI https://177.85.38.85/` (nginx) e `http://177.85.38.85/` → deve cair na 90.
- **DNS**: `chpl-tidvendas` (`be1ad73074ca38944e13f04adc678fa6`) e `chl-tidvendas`
  (`0c6c969ad3198566ebed9d28442577d0`), ambos proxied → `177.85.38.85`.
- CHPL **não está na malha wg** hoje (o `management_ip` 10.200.0.24 do painel é aspiracional —
  não existe `wg0` no guest). Se quiser gestão pela malha, instalar depois do corte.

## 7. Corte — IT995476 Multiseg

```bash
CODE=IT995476; NET=a0b5a758-95f9-4ad5-a93f-1970c9c3dcc0; PUB=177.85.38.249
DB=147 (nó -1) · APP=3212 LXC (nó -1) · IAAS=3213 (nó -2)
```

### 7.1 Banco (o caminho do Guimarães)

1. Baseline: `2 empresas`? (aqui **3**), 146 usuários, `count(*)` de `TGFCAB` e `TGFITE`,
   `MobileLoginSP` 200 em prd e tst.
2. Parar o WildFly de produção e de teste, depois o Oracle **como CDB**:
   ```
   su - oracle -c "unset ORACLE_PDB_SID; export ORACLE_SID=sankhyacdb; sqlplus -S / as sysdba"
   -- shutdown immediate
   ```
   ⚠️ com `ORACLE_PDB_SID` setado o `shutdown` fecha só o PDB. Confirme
   `sys_context('USERENV','CON_NAME')` = `CDB$ROOT`. (No Multiseg o `oratab` é `Y`, então pode
   haver systemd/dbora — conferir antes.)
3. `qm shutdown 147` (a 147 **não** está em HA — não precisa desarmar).
4. **`/database` (virtio1) direto do LV para o volume `IT995476-database-raw` (800 G)**:
   ```
   cs attachVolume id=6e59147e-7a58-4c5a-bd9a-a3ffdc919337 virtualmachineid=<APP-WCI>  # /dev/vdb
   # no nó -1:
   dd if=/dev/VG_Storage0/vm-147-disk-1 bs=4M status=progress | zstd -1 -T8 | \
     ssh ... ubuntu@177.85.38.249 "unzstd | sudo dd of=/dev/vdb bs=4M conv=sparse"
   ```
5. **root (virtio0, 50 G)** → qcow2 no NFS01 → `dd` para volume de 50 G →
   `createTemplate ostypeid=<Oracle Linux 8 64-bit>` → destruir o placeholder
   `IT995476-DB-SNK-WCI` (que segura o `10.1.1.250`) → `deployVirtualMachine ipaddress=10.1.1.250`.
6. Anexar o `database-raw` e o `database-backup`. **Antes do primeiro boot útil**:
   - `fstab` → `UUID=` para `/database` (hoje é `/dev/vdb1`) — **esse é o erro que travou o
     Guimarães**; sintoma: `/database` com 24 G em vez de 543 G;
   - `/database-backup`: `mkfs.ext4` no volume novo + entrada por `UUID`;
   - `growpart /dev/vdX 1 && resize2fs` para aproveitar os 800 G (o `/database` estava em 96%).
7. Subir o Oracle como CDB, `alter pluggable database all open`, conferir 12 datafiles e os
   tablespaces.

### 7.2 Aplicação — **levar TODOS os arquivos para o Docker**

O molde já está em `IT995476-SNK-APP-WCI:/srv/sankhya` (compose, `cfg/standalone.xml`,
`nginx/conf.d` + TLS, `bin/start-wildfly.sh`, imagens `wildfly-base:4.36`, `sas:latest`,
`nginx:1.27-alpine`). **O que falta é o payload**, e é exatamente o pedido "levar tudo":

| origem (LXC 3212) | destino | tamanho | estado |
|---|---|---|---|
| `/home/mgeweb/wildfly_producao` | `/srv/sankhya/prd/mgeweb/wildfly_producao` | **24 G** | **faltando** |
| `/home/mgeweb/wildfly_teste` | `/srv/sankhya/tst/mgeweb/`**renomeado para `wildfly_producao`** | **15 G** | **faltando** (o `tst/mgeweb` está vazio) |
| resto de `/home/mgeweb` | `/srv/sankhya/{prd,tst}/mgeweb` | 8,2 G | prd ✅ / tst faltando |
| **`/volumes/repositorio`** (anexos) | `/srv/sankhya/shared/repositorio` | **5,0 G** | **faltando** (`shared/` tem 12 K) |
| `/home/mgeweb/wildfly_treina` | `/srv/sankhya/extra/` | 420 M | **faltando** — existe na origem e **não está rodando** (só `producao` Xmx48000m e `teste` Xmx4096m têm processo java) |
| `SankhyaW` | `/srv/sankhya/shared/SankhyaW` | — | não existe na origem; criar vazio (é diretório compartilhado do WPM) |
| licença do SAS | `/srv/sankhya/sas/licenca/licenca.dat` | 7.649 B no destino | ⚠️ **ERRADA por 1 byte** — ver abaixo |

**Tudo isso está num script só, já testado ponta a ponta:**
`/NFS01/migrate/corte-3clientes/copia-payload-multiseg.sh`, rodado **no nó `-1`**. O pipe
`pct exec 3212 -- tar | zstd -1 -T8 | ssh helper "unzstd | tar -x"` foi provado em 25/09.
Ele exclui `standalone/{tmp,data,log,sysmon,teapp}` (o `start-wildfly.sh` apaga no boot).
Pode rodar **antes** da janela como pre-seed (origem ligada) e **de novo** no corte com o
WildFly parado.

**Armadilhas do molde — as duas primeiras foram medidas hoje, não são suposição:**

- ⚠️ **A licença no destino está errada por 1 byte.** Origem (`wildfly_producao/standalone/
  configuration/.1416890510/licenca/licenca.dat`): **7.648 bytes, md5
  `b9b2a8f37c62e0a3e282c95700887380`** — e o `wildfly_teste` usa o **mesmo** arquivo. O que está
  em `/srv/sankhya/sas/licenca/licenca.dat` tem **7.649 bytes** (provável newline do método de
  cópia). O script copia byte-exato por `cat | tee` e confere o md5.
- ⚠️ **`/home/mgeweb/repositorio` é um symlink para `/volumes/repositorio`.** Se esse symlink for
  para dentro de `prd/mgeweb` e `tst/mgeweb`, ele briga com o bind mount
  `shared/repositorio:/home/mgeweb/repositorio` do compose. O script **remove o symlink** no
  destino e deixa o Docker criar o ponto de montagem.
- `start-wildfly.sh` é **hardcoded em `wildfly_producao`** → por isso o `tst` recebe o
  `wildfly_teste` **renomeado**.
- **`port-offset` → 0** nos dois `standalone.conf` (a origem usa 100/200).
- `mge-ds.xml` fica em `standalone/deployments/` e carrega o IP do banco → **`10.1.1.250`**
  (o `.env` já está assim).
- **`UPDATE TSIPAR SET TEXTO='sasprd' WHERE CHAVE='IPSERVACESS'`** — com wildfly e SAS em
  containers separados, `127.0.0.1` não alcança o SAS.
- `sas/licenca` é **diretório** montado em `/opt/SAS3.1b26/licenca`.
- Dono dos arquivos do repositório: garantir o **uid que o container usa** (foi `1001` que
  barrou gravação de anexo na frota) — conferir com um upload de teste.
- Heap: `prd 48000m` / `tst 4096m`. A VM tem 128 GB — folga confortável (a origem estava com
  RSS de 52,3 G num LXC de 64 G, com 130 MB livres).

### 7.3 Força de Venda (SalesFusion)

`dd` direto do LV (65 G, 33 usados) → volume → `createTemplate` (CentOS 7 64-bit) → deploy em
**10.1.1.117**. fstab é LVM + UUID → seguro. Antes de ligar, `grep -r 192\.168\.117` nos compose
do SalesFusion e nas configs do Sankhya; ajustar `/etc/hosts` nas duas pontas.

### 7.4 DNS do Multiseg

`multiseg-producao` (`448a9102347fb2724831c712346568d6`) e `multiseg-teste`
(`fb79c7aa351ce487ff0011c8eb30e504`) → hoje `138.59.146.8` **proxied**; apontar para
`177.85.38.249`. Os registros de teste `it995476-prd` / `it995476-tst.cloudax.cloud` já existem
apontando para lá (grey cloud) — use-os para validar **antes** de virar o nome de produção.

---

## 8. Fechamento (para os 3)

1. PFs recriados e **validados pelo IP público com conteúdo**, não só porta aberta.
2. DNS trocado (todos proxied → instantâneo).
3. Painel: `Servers.datacenter=wci-br-sp2-02`, `ip_address`, `id_vm_hypervisor`, `vcpus`,
   `memory_mb`, `disk_gb`, `status_vm='active'`; usar `Servers.all_objects` (soft-delete).
   Para o app do Multiseg: `server_is_docker=True` e `management_ip` = IP **da malha**.
4. Zabbix: host no proxy `proxy-wci-br-sp2-02` (proxyid 2); interface para a malha se houver.
5. Snapshots **DAILY maxsnaps=7** em todos os volumes.
6. **Job de backup 7 dias na madrugada** (passo fixo pós-migração).
7. **Origem fica desligada e fora do HA** — não reverter o `state=disabled`, e **não apagar LV
   nenhum no mesmo dia**.
8. Limpar `/NFS01/migrate/*` só depois de tudo validado.

## 9. Rollback

Enquanto os LVs da origem estiverem intactos (o processo só **lê**), rollback = religar a origem:

```
PUT /cluster/ha/resources/vm:<vmid> -d state=started      # CHPL 185, KAMELL 172
qm start 147 ; pct start 3212 ; qm start 3213             # Multiseg (não está em HA, exceto 3213)
```

DNS volta para `138.59.146.35` / `.29` / `.8`. Se o relé de OpenVPN (§2-A) tiver sido criado,
removê-lo. No Multiseg, subir o Oracle como CDB e conferir os 4 números da baseline.
