Rake uploads:migrate_from_s3 fallisce

Ho seguito i passaggi indicati qui, ho effettuato un backup dell’intero sito, clonato il mio bucket AWS S3, modificato il nome del bucket nelle impostazioni di Discourse dal bucket originale a quello di backup e disattivato la casella “caricamenti su S3” nelle impostazioni.

Quindi ora sono finalmente pronto per avviare la migrazione da S3… ma fallisce. :frowning:

Il messaggio di errore

root@ubuntu:/var/www/discourse# rake uploads:migrate_from_s3
Migrazione dei caricamenti da S3 a storage locale per 'default'...
rake abort!
NoMethodError: metodo 'downcase' non definito per nil:NilClass
/var/www/discourse/app/models/global_setting.rb:107:in `s3_bucket_name'
/var/www/discourse/app/models/site_setting.rb:157:in `absolute_base_url'
/var/www/discourse/lib/tasks/uploads.rake:138:in `migrate_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:118:in `block in migrate_all_from_s3'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.2.2/lib/rails_multisite/connection_management.rb:68:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.2.2/lib/rails_multisite/connection_management.rb:78:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:118:in `migrate_all_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:93:in `block in <top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => uploads:migrate_from_s3
(Vedi il trace completo eseguendo il task con --trace)

(Ecco la riga su GitHub dove fallisce – immagino non riesca a ottenere il valore di s3_bucket?)

Altre cose che ho provato

  • Ho provato ad aggiungere le credenziali alla riga di comando, ma non ha fatto alcuna differenza. Ad esempio:
    DISCOURSE_S3_BUCKET="dn-forum-storage-backup" DISCOURSE_S3_REGION="us-east-1" DISCOURSE_S3_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxxxxx" DISCOURSE_S3_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxx" DISCOURSE_S3_CDN_URL="https://dn-forum-storage-backup.s3.us-east-1.amazonaws.com" rake uploads:migrate_from_s3

  • Ho anche provato a cambiare il nome del bucket S3 nelle mie impostazioni tornando al nome del bucket originale, ma senza successo, stesso risultato.

  • Ho anche provato a ricompilare l’app. Stesso risultato.

@vinothkannans sai cosa sta succedendo?

Per favore aiutatemi, amici di Discourse!

p.s. piccola nota a margine: rake --tasks non elenca questo task né alcun task che inizi con uploads, non so se questo significhi qualcosa.

Possibile problema correlato? cc @mcdanlj

@pnoeric sì, sembra esattamente la stessa cosa. Non ho ricevuto aggiornamenti in quella discussione riguardo all’intento preciso tra SiteSettings e GlobalSettings per S3, quindi al momento non posso offrire altro aiuto oltre a aggiungerlo a SiteSettings tramite configurazione (punto 1 del mio post).

Ehi, grazie per questa risposta… Non sono nemmeno sicuro di cosa significhi SiteSettings rispetto a GlobalSettings — non sono un programmatore RoR così esperto e non capisco abbastanza bene l’intera configurazione. Sto solo seguendo le istruzioni di base. :wink:

Ma spero che anche @vinothkannans si unisca alla discussione; credo che sia stato lui a scrivere il codice per i task di migrazione. O chiunque altro del @team che potrebbe saperne di più…

Tengiamo d’occhio questo argomento…

s3_bucket si trova in GlobalSettings, che viene impostato dal file config/discourse.conf, solitamente creato dalle variabili di ambiente nel file app.yml. SiteSettings sono le impostazioni che modifichi dalle Impostazioni Amministrative nell’app.

Sembra che, quando è stato creato per la prima volta, fosse possibile modificare S3 solo ricostruendo l’app, e più recentemente è diventato possibile inserire i dati nelle Impostazioni Amministrative. Non riesco a capire quale fosse l’intenzione nel non eseguire una migrazione completa quando è stato aggiunto l’impostamento di S3 in SiteSettings.

[Modifica: ho involontariamente invertito i due termini quando ho pubblicato per la prima volta questa risposta]

Hmmm @mcdanlj, giusto per conferma, non sei ancora riuscito a far funzionare migrate_from_s3, corretto?

Non ho problemi a modificare le impostazioni o i file di basso livello o qualsiasi altra cosa sia necessaria… Devo solo spostarmi da S3 il prima possibile, dato che mi sta costando un occhio della testa.

Ciao @pnoeric e @mcdanlj,

Un approccio di debug potrebbe essere quello di entrare nella console di Rails e dare un’occhiata alle impostazioni del sito S2?

Ad esempio, in una semplice app standalone Docker OOTB di Discourse:

root@localhost:~# docker exec -it app rails c
[1] pry(main)> SiteSetting.s3_upload_bucket
=> ""
[2] pry(main)> SiteSetting.enable_s3_uploads
=> false
[3] pry(main)> 

Confrontare le SiteSettings (tramite la console di Rails) con i valori predefiniti, elencati qui:

Forse il debug in questo modo potrebbe essere utile (non ne abbiamo idea, dato che non usiamo AWS o S3)? Forse la console di Rails potrebbe aiutare un po’?

rake --tasks mostra solo i task che hanno una descrizione. Puoi visualizzare tutti i task disponibili tramite rake -AT.

Non credo che aiuterà, perché ho eseguito questi task molto recentemente su un sito di test. Entrambi sembrano dipendere dal fatto che le variabili S3 siano definite nell’env, tuttavia, era un paio di mesi fa e migrate_from_s3 non ha funzionato davvero per me.

Domanda insidiosa. Ho impostato s3_bucket in config/discourse.conf come menzionato nel post a cui hai fatto riferimento, il che ha risolto questo specifico errore, come ho notato lì.

Questo file si trova all’interno del container (./launcher enter app). Nota che affinché questa modifica sopravviva a ./launcher rebuild app, devi anche aggiungere DISCOURSE_S3_BUCKET alla sezione env del tuo file containers/app.yml.

Il fatto che l’abbia risolto è il motivo per cui si tratta di un post di sviluppo e non di una richiesta di supporto; chiedevo cosa pensassero gli sviluppatori fosse la soluzione giusta mentre continuo a lavorare su questo.

Ho circa 100 GB di file su S3, quindi procedo con molta cautela. Ho implementato un limite per i post da esaminare e ora devo implementare un limite per i post da modificare. Ho provato a fare una cosa alla volta. Il fatto che questo sembri essere un codice poco utilizzato e che abbia visto questo errore ripetutamente mi preoccupa per il deterioramento del codice; non voglio rovinare improvvisamente l’intero sito a causa di un bug, e questo sembra essere un ottimo modo per commettere tale errore.

  • Per gli upload upload:// (nel mio caso, gli upload non video), finora sembra funzionare. Ne sto facendo uno alla volta e poi revisionando il post interessato per assicurarmi che tutto funzioni.

  • Per gli upload che non utilizzano la sintassi upload:// (nel mio caso, gli upload video per quanto ne so), dove c’è un riferimento letterale all’URL su S3, gli URL vengono distorti. Non è un bug difficile da correggere non appena capisco con certezza in cosa devo trasformarli, ma non l’ho ancora fatto. Quindi è probabile che sarà una delle PR che pubblicherò a breve.

Questo è un progetto svolto nel tempo libero per me, quindi non ci sono promesse sui tempi.

Aha, grazie! Ci provo.

Ugh, niente da fare, @neounix @mcdanlj @vinothkannans. Continua a fallire. Ma almeno c’è un nuovo messaggio di errore diverso…

Ecco cosa ho provato oggi:

  1. Aggiornato all’ultima versione di Discourse, solo per sicurezza.

  2. Aggiunto il mio s3_bucket in config/discourse.conf

  3. ./launcher enter app

  4. Modificato containers/app.yml e aggiunto la variabile DISCOURSE_S3_BUCKET

  5. Provato rake uploads:migrate_from_s3 e ora fallisce con un nuovo messaggio di errore (prima era downcase a causare il problema, ora sembra essere start_with?):

/var/www/discourse# rake uploads:migrate_from_s3
Migrating uploads from S3 to local storage for 'default'...
rake aborted!
NoMethodError: undefined method `start_with?' for nil:NilClass
/var/www/discourse/app/models/site_setting.rb:161:in `absolute_base_url'
/var/www/discourse/lib/tasks/uploads.rake:138:in `migrate_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:118:in `block in migrate_all_from_s3'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:68:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:78:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:118:in `migrate_all_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:93:in `block in <main>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => uploads:migrate_from_s3
(See full trace by running task with --trace)
  1. Quindi ho provato ./launcher rebuild app

  2. E di nuovo ./launcher enter app, rake uploads:migrate_from_s3

Stesso problema esattamente:

/var/www/discourse# rake uploads:migrate_from_s3
Migrating uploads from S3 to local storage for 'default'...
rake aborted!
NoMethodError: undefined method `start_with?' for nil:NilClass
/var/www/discourse/app/models/site_setting.rb:161:in `absolute_base_url'
/var/www/discourse/lib/tasks/uploads.rake:138:in `migrate_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:118:in `block in migrate_all_from_s3'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:68:in `with_connection'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.3.0/lib/rails_multisite/connection_management.rb:78:in `each_connection'
/var/www/discourse/lib/tasks/uploads.rake:118:in `migrate_all_from_s3'
/var/www/discourse/lib/tasks/uploads.rake:93:in `block in <main>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => uploads:migrate_from_s3
(See full trace by running task with --trace)

Altre idee?

Comunque, fare questo processo è davvero una seccatura: devo pre-programmare e annunciare l’interruzione del forum con giorni di anticipo, poi il giorno stesso modificare il sito principale in modo che nessuno possa accedere al forum, e infine devo spegnere il server del forum su Digital Ocean e creare un’istantanea prima di procedere. Questo richiede già circa 30 minuti. Poi lo riavvio e posso provare i passaggi sopra. Mi sto pentendo moltissimo di aver impostato Amazon S3 per l’archiviazione dei media! Ho perso ore cercando di annullare quella scelta e ancora niente da fare (e ancora una grossa fattura da pagare ad Amazon ogni mese). Mi piacerebbe molto capire cosa sta succedendo. Come posso aiutare?

Quella riga è:

        if SiteSetting.Upload.s3_region.start_with?("cn-")

Sembra che richieda anche s3_region; non è chiaro a me perché non abbia riscontrato questo problema.

Non sono sicuro di seguire la tua logica; la mia migrazione di circa 100 GB di contenuti prevede di essere eseguita online, dopo un normale backup del sito. Tuttavia, sto iniziando in piccolo, ed è per questo che ho lavorato per limitare la quantità migrata in una sola volta. Un avvertimento: il codice sembra sbagliato per le traduzioni letterali degli URL, come ho visto per i caricamenti video, quindi se avessi consentito i caricamenti video potresti avere un problema con il codice nel suo stato attuale.

Quindi forse dovrei ripetere tutti i passaggi che ho fatto sopra, ma inserirò s3_bucket, s3_region, s3_cnd_url, s3_secret_access_key ecc. (in pratica, tutte le variabili che ho) nei file conf e yml? Preferisco fornire più di quanto (forse) necessario, solo per assicurarmi che funzioni davvero.

Ho visto che qualcuno del team di Discourse ha suggerito di eseguire il backup dell’intero sito locale prima di iniziare questa transizione. Il che mi richiede di mettere offline il mio server Digital Ocean. :frowning:

Giusto. Anche io sto iniziando in piccolo… ogni volta che provo, migro 0 file. :grin:

Per fortuna, nel mio forum gli utenti possono caricare solo JPG, GIF e PNG, quindi dovrebbe essere tutto ok.

Tengo le dita incrociate.

Backup e snapshot non sono la stessa cosa. Uno snapshot è la forma più grezza di backup. La console di Amministrazione dispone di una funzionalità di backup. Assicurati di configurarla per eseguire il backup delle miniature nelle impostazioni prima di tutto.

Ora che sai che non devi mettere il sito offline, dovresti riuscire a stare più tranquillo. Puoi usare batch_migrate_from_s3 per migrare al massimo un certo numero di file caricati. Attualmente limita i post considerati anziché le migrazioni effettuate; è un bug che devo risolvere in una futura PR. Ma devo anche risolvere il bug relativo al caricamento dei video, e mi piacerebbe valutare la possibilità di stampare dei feedback, dato che uno degli scopi del limite è poter confermare nei post interessati che la migrazione è andata a buon fine.

È probabile che lo farò tutto nel corso dei prossimi 1-2 mesi, quindi se vuoi aspettare, potrebbe valere la pena pagare ancora qualche mese di S3; sta a te. Non sto facendo promesse, mi sto solo esprimendo sulle mie intenzioni.

@pnoeric dato che sei preoccupato per la disponibilità del sito, ho pensato di condividere con te ciò che ho imparato finora.

Ho eseguito la migrazione in tempo reale, come ho già detto. Se non limito la velocità della migrazione, le code che gestiscono cose come le notifiche agli utenti sull’attività reciproca si intasano e l’esperienza utente del sito ne risente.

Ho migrato circa 500 post con video e circa 30.000 post con immagini, un’operazione che ha richiesto circa due settimane per essere completata.

Se vuoi provare il codice che ho usato, è attualmente disponibile all’indirizzo

Puoi scaricarlo e copiarlo nella tua applicazione per sostituire il contenuto attuale di lib/tasks/uploads.rake.

Con questo codice, puoi fare qualcosa del genere:

bin/rake uploads:batch_migrate_from_s3[100,1000]

Questo considererà solo 1000 post con file caricati in totale e migrerà file da un massimo di 100, prima di fermarsi; ogni volta che modifica effettivamente un post dopo aver migrato i suoi allegati, attenderà che la coda sia vuota prima di procedere con il successivo.

Se copi il file, interromperai gli aggiornamenti futuri del sito finché non annullerai la modifica. Il modo più semplice per annullarla una volta soddisfatto è semplicemente ./launcher rebuild app (anche se, come sviluppatore, uso git checkout HEAD lib/tasks/uploads.rake per annullare le mie modifiche…).

Ho notato che almeno con gli spazi di Digital Ocean, a volte devo riprovare diverse volte prima che una migrazione abbia successo. Lo script, così com’è, non ti avvisa quando ciò accade; devi semplicemente continuare a eseguirlo e aspettare di vedere se funziona. Ho una PR in attesa di revisione che stampa gli errori in questi casi, così almeno sai che qualcosa è andato storto.

Ho aggiunto un semplice ciclo di riprova breve, oltre al messaggio di errore, e sembra che il ciclo di riprova risolva il problema. Inoltre, la convalida rispetto alle regole attuali veniva eseguita sul contenuto grezzo dei post passati, il che poteva interrompere la migrazione e lasciare silenziosamente post che necessitavano di essere rielaborati; ho anche corretto questo problema. Non vorrai assolutamente eseguire una migrazione senza ottenere almeno la correzione della convalida, che è uno dei commit nella mia PR attualmente in fase di revisione.

Ho completato la mia migrazione, per quanto ne so. La mia PR contiene tutto il codice che ho utilizzato per completare la migrazione. Non è ancora stata revisionata. Ti suggerisco di seguire l’evoluzione qui: Migrate_from_s3 problems se lo desideri.

Grazie! Proverò nei prossimi giorni.

Ho appena aggiunto una nota in quel post riguardo a un bug rimasto che abbiamo scoperto oggi: le foto profilo sono scomparse per alcuni utenti e non so il motivo. Ci siamo alzati le spalle e abbiamo chiesto agli utenti interessati di ripristinare, scusandoci per il problema.

Ho fatto sicuramente backup frequenti durante questo processo! :smiling_face:

Buona fortuna!

Davvero, potrebbe rendermi ancora più pazzo? :crazy_face:

Ecco cosa ho fatto:

  1. Ho copiato il tuo nuovo codice lib/tasks/upload.rake nel mio Discourse
  2. Ho aggiunto TUTTE le mie variabili Amazon s3_ a config/discourse.conf
  3. Le ho aggiunte anche a app.yml (non è chiaro se abbia un effetto, ma perché no)
  4. Ho eseguito questo comando e ho ottenuto…
root@:/var/www/discourse/config# rake uploads:batch_migrate_from_s3[100,1000]
Devi disabilitare gli upload su S3 prima di eseguire quel task.

E ho confermato:

Quindi, ok. Ho modificato il file uploads.rake e ho semplicemente rimosso quel controllo.

Ora ottengo:

root@:/var/www/discourse/lib/tasks# rake uploads:batch_migrate_from_s3[100,1000]
Migrazione degli upload da S3 all'archiviazione locale per 'default'...
Migrazione di fino a 100 di 1000 post...
... (molto output qui) ...
Modificati 91/100: 28795: 28486/1 - https://example.com/t/topic-title-here/28486/1
... (molto output qui) ...

Quindi sembrava funzionare! Evviva!

Dopo il primo lotto di 100, ho controllato sidekiq e ho visto che il mio post di test era in coda, quindi ho aspettato che finisse…

…poi sono tornato indietro e ho controllato… e quel post sta ancora recuperando la sua immagine da Amazon S3. :frowning: Ho provato a fare “Ricostruisci HTML” sul post, ma non ha cambiato nulla.

Quindi ho riprovato l’intero processo, da rake fino alla fine, ottenendo gli stessi risultati: gli stessi 100 post sono stati elaborati, le stesse cose in coda in sidekiq, e dopo aver lasciato che funzionasse, l’immagine in quel post di test proviene ancora da S3.

Hmmm, non sono sicuro di cosa provare dopo. :man_shrugging:t2:

@mcdanlj apprezzo qualsiasi suggerimento o consiglio tu possa avere :wink:

È esattamente ciò che mi aspetterei se rimuovessi quel controllo. Non sono sicuro del motivo per cui hai deciso di rimuoverlo. È intenzionale. Disattiva il caricamento su S3 prima di avviare la migrazione.

Erano disattivati—completamente disattivati. (L’immagine della casella di controllo nel mio post rappresenta l’impostazione corretta, giusto?) Li ho anche riattivati e poi disattivati di nuovo. Nulla da fare.