Indice dei contenuti dell'articolo:
Ci sono migrazioni difficili perché l’infrastruttura è complessa. Ci sono migrazioni difficili perché i dati sono tanti, perché un’applicazione è stata sviluppata male, perché un database è enorme o perché bisogna intervenire su sistemi legacy che nessuno tocca da anni.
E poi ci sono migrazioni che diventano difficili per un motivo che, francamente, dopo tanti anni di questo mestiere continuiamo a fare fatica ad accettare: la mancanza di collaborazione tra fornitori.
Questo articolo racconta un caso reale che abbiamo affrontato nei giorni scorsi.
Non citeremo il cliente e chiameremo i suoi due domini esempio.com ed esempiodue.com, perché il punto di questo articolo non è il cliente.
Il punto siamo noi fornitori.
Il punto è capire cosa dovrebbe succedere quando un’azienda decide di cambiare partner tecnologico e, soprattutto, cosa invece non dovrebbe succedere mai.
Tutto nasce da due WooCommerce molto lenti
Il cliente ci contatta perché gestisce due siti WooCommerce con importanti problemi di Web Performance.
Tempi di risposta elevati, backend poco reattivo e una situazione complessiva che rendeva necessario valutare un’infrastruttura differente di cui ne abbiamo discusso ieri sul nostro blog a questo post.
Dopo le verifiche iniziali viene presa la decisione di migrare i servizi verso Managed Server S.r.l..
Una situazione assolutamente normale.
Chi lavora nell’hosting sa perfettamente che i clienti arrivano e i clienti se ne vanno. Succede a noi, succede ai nostri concorrenti e continuerà a succedere.
Non esiste un fornitore perfetto per qualsiasi progetto e per qualsiasi fase della vita di un’azienda.
Un cliente può scegliere un altro hosting perché cerca prestazioni differenti, perché ha bisogno di competenze più verticali, perché cambia budget, perché cambia management o semplicemente perché ritiene di voler provare qualcosa di nuovo.
Fa parte del mercato.
Nel caso specifico, oltre ai siti Web, dovevano essere trasferite anche le caselle di posta elettronica associate ai due domini.
Ed è qui che una migrazione tecnicamente ordinaria si è trasformata in qualcosa di completamente diverso.
La richiesta era molto semplice: non toccate altro
Per organizzare correttamente una migrazione di questo tipo non serve nulla di particolarmente esotico.
Avevamo chiesto sostanzialmente due cose: consegnare il backup dei siti e modificare i nameserver dei domini.
Nient’altro.
Non avevamo chiesto la cancellazione degli account. Non avevamo chiesto la sospensione immediata dei servizi. Non avevamo chiesto di eliminare le mailbox.
Non l’avevamo chiesto noi, e non l’aveva chiesto tantomeno il cliente.
Al contrario, durante una migrazione è fondamentale che la vecchia infrastruttura rimanga disponibile per il tempo strettamente necessario a completare le sincronizzazioni.
Questo vale soprattutto per la posta elettronica.
Un sito può essere copiato in un determinato momento e successivamente riallineato. La posta, invece, continua a cambiare: arrivano nuovi messaggi, gli utenti rispondono, spostano e cancellano e-mail, inviano allegati, creano bozze e modificano continuamente lo stato delle proprie cartelle.
Una mailbox è un dataset vivo.
Per questo motivo una migrazione IMAP eseguita correttamente viene normalmente effettuata in più passaggi, mantenendo accessibile il server sorgente fino al completamento del cut-over.
La strategia prevista: imapsync
Per trasferire le mailbox avevamo predisposto una normale migrazione tramite imapsync.
Chi amministra server di posta conosce bene questo strumento. Il principio di funzionamento è relativamente semplice:
SERVER IMAP SORGENTE | | IMAP v imapsync | | IMAP v SERVER IMAP DESTINAZIONE
imapsync si autentica sulla mailbox sorgente, legge cartelle e messaggi e li replica sulla destinazione.
Uno dei grandi vantaggi di questa metodologia è che, dal punto di vista della migrazione, non è necessario conoscere nel dettaglio il formato con cui il server sorgente memorizza fisicamente la posta.
Il server potrebbe utilizzare Maildir, mdbox oppure un altro backend supportato dal relativo servizio IMAP.
Dal punto di vista del client di migrazione vediamo semplicemente qualcosa del genere:
INBOX Sent Drafts Trash Archive spam
e, naturalmente, i relativi messaggi.
È il server sorgente che si occupa di tradurre il proprio storage fisico nella rappresentazione logica esposta tramite IMAP.
C’è inoltre un’altra caratteristica fondamentale: imapsync può essere eseguito più volte.
Possiamo quindi effettuare una prima sincronizzazione di una mailbox da 20 GB, attendere il completamento e, poche ore prima dello switch definitivo, eseguire nuovamente il processo.
La seconda sincronizzazione non deve necessariamente trasferire nuovamente tutti i dati. Il suo scopo principale è recuperare il delta, cioè tutto ciò che è cambiato tra la prima copia e il momento del passaggio definitivo.
È una metodologia assolutamente comune nelle migrazioni di posta elettronica e consente di ridurre sensibilmente il rischio di perdita di messaggi durante il trasferimento.
Poi, nemmeno 24 ore dopo, gli account vengono sospesi
La vecchia infrastruttura era gestita da una società che opera nel settore Sviluppo Web, SEO e Web Marketing.
Ed è a questo punto che è avvenuto qualcosa che, professionalmente, ci ha lasciati molto delusi.
Nonostante fosse stato richiesto di non intervenire ulteriormente sui servizi durante la migrazione, nemmeno 24 ore dopo gli account sono stati sospesi, rendendo di fatto non più raggiungibili le caselle IMAP necessarie per completare le sincronizzazioni.
L’effetto tecnico è stato immediato:
imapsync | X | SERVER IMAP SORGENTE NON PIÙ ACCESSIBILE
Da quel momento non potevamo più effettuare il normale riallineamento delle mailbox.
E, soprattutto, non potevamo più recuperare tramite IMAP i messaggi arrivati successivamente all’ultima copia dei dati disponibile.
Su questo punto vogliamo essere molto precisi: non stiamo discutendo le intenzioni di chi abbia preso questa decisione.
Di certo non l’abbiamo ordinato noi, ne tantomeno il cliente che invece si è prodigato senza successo di far riattivare l’account senza successo.
Stiamo descrivendo l’effetto tecnico oggettivo che abbiamo riscontrato: la sospensione degli account ha impedito il completamento della procedura IMAP che avevamo pianificato.
Da quel momento siamo stati costretti a cambiare completamente strategia.
Due PEC, e-mail, WhatsApp e telefonate
La parte che ci ha amareggiati maggiormente non è stata neppure la difficoltà tecnica.
I problemi tecnici si risolvono. È il nostro lavoro.
Quello che abbiamo trovato molto più difficile da comprendere è stata l’impossibilità di stabilire un confronto tecnico diretto con il precedente fornitore.
Abbiamo inviato due PEC, scritto tramite e-mail, inviato comunicazioni via WhatsApp e provato a telefonare.
E lo ha fatto anche il cliente.
Nonostante i ripetuti tentativi, non siamo riusciti a instaurare un confronto tecnico diretto che permettesse di coordinare la migrazione.
Ed è probabilmente questo l’aspetto sul quale vorremmo invitare tutti noi operatori del settore a riflettere.
Perché sarebbe bastata una telefonata.
Cinque minuti.
“Quando avete finito con la posta?”
“Domani alle 18.”
“Perfetto, lasciamo IMAP attivo fino a domani sera.”
Fine.
Nessuna guerra. Nessuna procedura straordinaria. Nessuna necessità di recuperare manualmente uno storage di posta da un backup.
Avevamo però un backup cPanel
Fortunatamente disponevamo di un backup cPanel sufficientemente recente.
A quel punto abbiamo iniziato a studiare la possibilità di recuperare direttamente la posta contenuta nel backup.
Ed è qui che la vicenda diventa tecnicamente interessante.
Aprendo la struttura delle mailbox ci siamo accorti che non ci trovavamo davanti a una normale Maildir.
Ci siamo trovati davanti a Dovecot mdbox.
Maildir e mdbox non sono la stessa cosa
Sulla nostra infrastruttura la posta viene gestita tramite Dovecot utilizzando Maildir.
Una Maildir tradizionale presenta una struttura facilmente riconoscibile:
Maildir/ ├── cur/ ├── new/ ├── tmp/ ├── .Sent/ ├── .Drafts/ ├── .Trash/ └── .Archive/
Il concetto fondamentale è relativamente semplice: un messaggio corrisponde sostanzialmente a un file.
Se apriamo la directory cur/ troviamo centinaia, migliaia o, nei casi più importanti, milioni di file. Ognuno di quei file rappresenta un messaggio.
mdbox funziona in maniera completamente differente.
Nel backup cPanel ci siamo trovati davanti a strutture di questo tipo:
storage/ ├── dovecot.map.index ├── dovecot.map.index.log ├── m.1 ├── m.2 ├── m.3 ├── m.100 ├── m.305 └── ...
e, contemporaneamente:
mailboxes/ ├── INBOX/ │ └── dbox-Mails/ │ ├── dovecot.index │ ├── dovecot.index.cache │ └── dovecot.index.log ├── Sent/ ├── Drafts/ ├── Trash/ ├── Archive/ └── spam/
Qui cambia completamente il paradigma.
In mdbox un file come:
m.305
non rappresenta la mail numero 305.
È un contenitore.
Al suo interno possono essere memorizzati più messaggi. Dovecot utilizza quindi mappe e indici per determinare dove si trovi ciascun messaggio e a quale mailbox appartenga.
Tra i file fondamentali troviamo elementi come:
dovecot.map.index dovecot.map.index.log dovecot.index dovecot.index.cache dovecot.index.log
Di conseguenza non era possibile prendere banalmente:
m.1 m.2 m.3 ...
e copiarli nella nuova Maildir.
Non avrebbe avuto alcun senso dal punto di vista del formato dello storage.
Da una migrazione a un vero recupero dello storage
A questo punto quella che doveva essere una normale migrazione IMAP era diventata una vera e propria operazione di recupero.
Dovevamo fare in modo che Dovecot interpretasse correttamente il vecchio storage mdbox e ricostruisse logicamente le mailbox.
Abbiamo quindi predisposto un ambiente di lavoro separato.
La prima regola in un’attività di questo genere è molto semplice: non lavorare direttamente sull’unica copia disponibile del backup.
Le singole mailbox sono state copiate in directory temporanee e tutte le operazioni sono state eseguite sulle copie di lavoro.
Abbiamo quindi utilizzato doveadm per verificare se Dovecot fosse effettivamente in grado di leggere lo storage.
Dopo aver gestito UID, GID e permessi dell’utente tecnico utilizzato per la conversione, siamo finalmente riusciti a interrogare una mailbox mdbox.
Il risultato era qualcosa di questo tipo:
Archive Sent Drafts Trash spam INBOX
Quello è stato il momento decisivo.
Significava che Dovecot stava correttamente interpretando:
- i file
m.*contenenti i messaggi; - il file
dovecot.map.index; - gli indici delle singole mailbox;
- la relazione tra messaggi, storage fisico e cartelle logiche.
Il backup era utilizzabile.
Il problema successivo: mdbox e Maildir hanno layout differenti
A quel punto potevamo leggere correttamente la sorgente.
Restava da trasformarla.
Abbiamo quindi iniziato a utilizzare doveadm e dsync per effettuare una conversione dal formato mdbox al formato Maildir:
Dovecot mdbox | | dsync v Dovecot Maildir
Anche qui, però, non è stato sufficiente indicare semplicemente una sorgente e una destinazione.
Uno dei primi problemi incontrati riguardava il virtual mailbox hierarchy separator.
In sostanza, lo storage mdbox di origine e il Maildir++ tradizionale di destinazione non utilizzavano la medesima rappresentazione della gerarchia delle mailbox.
Il risultato era un errore del tipo:
Mail locations must use the same virtual mailbox hierarchy separator
È stato quindi necessario rendere compatibili namespace e layout della destinazione utilizzando un Maildir con:
LAYOUT=fs
ottenendo finalmente una struttura coerente:
utente/ ├── cur/ ├── new/ ├── tmp/ ├── Archive/ │ ├── cur/ │ ├── new/ │ └── tmp/ ├── Drafts/ │ ├── cur/ │ ├── new/ │ └── tmp/ ├── Sent/ ├── Trash/ └── spam/
A quel punto avevamo nuovamente a disposizione veri messaggi nel formato Maildir, utilizzabili sulla nuova infrastruttura.
Anche le quote hanno voluto partecipare alla festa
Durante la conversione è comparso un ulteriore problema.
Il Dovecot della macchina utilizzata per la procedura disponeva di un backend quota-dict.
dsync, mentre scriveva i messaggi convertiti, tentava quindi di aggiornare anche le quote delle mailbox:
quota-dict: Quota update failed Quota is now desynced
In una normale attività sul server di produzione questo comportamento avrebbe avuto perfettamente senso.
Durante una conversione offline, invece, no.
Non ci interessava aggiornare in tempo reale la quota di una mailbox temporanea. Ci interessava recuperare correttamente i messaggi.
Abbiamo quindi escluso il plugin quota dalle invocazioni utilizzate per la conversione:
mail_plugins=''
e completato il recupero.
Una volta posizionate le mailbox nella destinazione definitiva, le quote possono essere ricostruite tramite Dovecot con una normale procedura di ricalcolo, ad esempio:
doveadm quota recalc -u [utente@esempio.com](mailto:utente@esempio.com)
seguita dalla relativa verifica:
doveadm quota get -u [utente@esempio.com](mailto:utente@esempio.com)
Quello che inizialmente avrebbe dovuto essere un semplice:
imapsync sorgente → destinazione
era ormai diventato:
backup cPanel | v analisi storage | v riconoscimento mdbox | v copia di sicurezza | v lettura indici Dovecot | v ricostruzione mailbox | v gestione UID/GID | v gestione namespace | v conversione mdbox → Maildir | v gestione quota | v importazione | v ricalcolo quote
Tutto questo per ottenere ciò che, in condizioni normali, avremmo potuto trasferire attraverso una normale sincronizzazione IMAP.
Il backup ci ha salvati, ma un backup è una fotografia
Fortunatamente siamo riusciti a recuperare la posta presente nel backup.
Esiste però un problema che nessuna competenza sistemistica può risolvere: un backup può contenere soltanto ciò che esisteva nel momento in cui è stato generato.
Il backup disponibile era aggiornato al 6 agosto.
Quando abbiamo dovuto effettuare il recupero eravamo ormai al 10 agosto.
Backup disponibile: 6 agosto Data del recupero: 10 agosto Gap temporale: circa 4 giorni
Un backup è una fotografia.
Puoi conoscere Dovecot in ogni dettaglio, puoi ricostruire gli indici, convertire lo storage, riparare i permessi e interpretare correttamente mdbox, ma non puoi recuperare da una fotografia del 6 agosto qualcosa che è accaduto il 7, l’8, il 9 o il 10 agosto.
Se quei dati non sono presenti nel backup, semplicemente non esistono all’interno di quel dataset.
Ed è esattamente per questo che avevamo previsto di utilizzare imapsync.
Avremmo potuto utilizzare il backup o una prima sincronizzazione per trasferire la massa principale dei dati e poi interrogare nuovamente il vecchio server per acquisire tutto ciò che era cambiato nel frattempo.
In altre parole: il delta.
Ma se il server sorgente non è più accessibile, quel delta non può essere acquisito.
Il risultato concreto è stato quindi un intervallo di circa quattro giorni di storico della posta non disponibile all’interno del backup utilizzato per il recupero.
Ed è probabilmente questa la parte dell’intera vicenda che ci lascia più amareggiati.
Non è una questione di essere concorrenti
Noi e l’latra azienda siamo, almeno in parte, operatori dello stesso mercato.
Si tratta quindi di realtà che, sotto alcuni aspetti, possono essere considerate concorrenti.
Ma essere competitor non significa essere nemici.
Negli anni abbiamo ricevuto decine e decine di richieste relative a migrazioni di clienti Managed Server verso altri fornitori.
Capita.
Quando un cliente decide di andare via, la cosa professionalmente corretta da fare è consegnare ciò che serve e consentire al nuovo fornitore di lavorare.
Se domani ci chiamasse un sistemista dicendoci:
“Sto migrando un vostro ex cliente. Mi lasciate IMAP disponibile altre 48 ore per terminare il delta?”
la risposta tecnicamente sensata dovrebbe essere:
“Certo.”
Non perché siamo buoni.
Perché è tecnicamente corretto.
Perché il dato appartiene al cliente.
Perché dall’altra parte c’è un professionista che sta cercando di fare il proprio lavoro.
E perché dopodomani potremmo essere noi a dover chiamare lui.
Il cliente non deve diventare ostaggio della rivalità tra fornitori
C’è un principio che nel nostro settore dovremmo ricordare più spesso.
Quando un cliente cambia fornitore, il passaggio dovrebbe essere il più trasparente possibile per il cliente stesso.
Non dovrebbe essere necessario coinvolgerlo nelle discussioni tecniche tra due aziende.
Non dovrebbe fare da centralinista tra due fornitori IT.
Non dovrebbe essere costretto a capire cosa sia un record MX, un nameserver, mdbox, Maildir, rsync, imapsync o una sincronizzazione incrementale.
Dovremmo parlarci noi.
“Che cosa ti serve?”
“Questo.”
“Fino a quando?”
“Domani.”
“Va bene.”
In molti casi sarebbe davvero sufficiente questo.
La nostra profonda delusione professionale
Quello che proviamo alla fine di questa vicenda è soprattutto profonda delusione professionale.
Non perché abbiamo dovuto lavorare di più.
Abbiamo scelto di fare i sistemisti anche perché ci piace risolvere problemi complessi.
E, da un punto di vista puramente tecnico, trasformare un backup cPanel contenente mailbox mdbox in mailbox Maildir perfettamente leggibili è stato persino un problema interessante da affrontare.
La delusione nasce dal fatto che non sarebbe stato necessario fare nulla di tutto questo.
Non sarebbe stato necessario ricostruire lo storage.
Non sarebbe stato necessario lavorare sugli indici Dovecot.
Non sarebbe stato necessario risolvere incompatibilità tra namespace.
Non sarebbe stato necessario convertire mdbox in Maildir.
Non sarebbe stato necessario gestire offline le quote.
E, soprattutto, sarebbe stato possibile effettuare l’ultima sincronizzazione dei messaggi.
Sarebbe stato sufficiente lasciare disponibili gli account per il tempo necessario a concludere una migrazione già in corso.
Un appello ai colleghi dell’hosting e della sistemistica
Questo articolo non vuole essere soltanto il racconto di una brutta esperienza con un fornitore specifico.
Vuole essere soprattutto un appello a tutte le aziende che lavorano nell’hosting, nello sviluppo Web, nelle Web Agency e nella sistemistica.
Collaboriamo.
Anche quando perdiamo un cliente.
Anche quando il nuovo fornitore è un concorrente.
Anche quando pensiamo che il cliente stia facendo la scelta sbagliata.
Possiamo spiegarglielo. Possiamo essere contrari. Possiamo persino essere convinti che tornerà da noi dopo tre mesi.
Ma nel momento in cui un cliente decide di migrare, facciamo in modo che possa farlo in maniera ordinata.
- Se il nuovo fornitore chiede 48 ore aggiuntive di accesso IMAP, lasciamogliele.
- Se chiede un dump MySQL, forniamolo.
- Se chiede di non spegnere il vecchio virtual host fino alla propagazione DNS, aspettiamo.
- Se serve concordare una finestra di cut-over, sentiamoci al telefono.
- e soprattutto se il cliente pagante non ORDINA di cessare il servizio non fate di testa vostra.
Perché alla fine il nostro mestiere è questo.
Non mettere ostacoli.
Risolvere problemi.
Alla fine ce l’abbiamo fatta
Nonostante tutto, siamo riusciti a recuperare la posta presente nel backup.
Abbiamo interpretato lo storage mdbox, verificato gli indici Dovecot, ricostruito le mailbox, convertito i messaggi in Maildir e predisposto le caselle per la nuova infrastruttura.
La posta disponibile è stata recuperata fino alla consistenza del backup del 6 agosto.
Rimane il rammarico per il gap successivo, che una normale sincronizzazione IMAP avrebbe potuto evitare.
E rimane soprattutto una domanda.
Era davvero necessario arrivare a tutto questo?
Secondo noi no.
Per questo, dopo questa esperienza, il messaggio che vogliamo lasciare è estremamente semplice:
Cari “colleghi”, possiamo anche essere concorrenti. Ma collaboriamo e non mettiamoci i bastoni tra le ruote.
Ne guadagniamo noi.
Ne guadagna chi viene dopo di noi.
Ma soprattutto ne guadagna il cliente, che dovrebbe essere l’unica persona a non dover pagare le conseguenze della mancata collaborazione tra due fornitori.