CW(3,x) Náročný naskriptovaný upload Laravel webu na server pomocí LFTP v Linuxu

Jak zautomatizovat složitý upload Laravelu na hosting pomocí pokročilého programu LFTP v jediném Bash skriptu.

Ať u pasivního webu z html stránek nebo u vlastního PHP webu jsem doposud při uploadu řešil jediný problém: Nahrát na na server složku nebo soubor. To mi stačilo dvacet let a vyřešil jsem to nejprimitivnějším protokolem FTP a jeho nejslavnějším klientem Filezilla.

Přechod na Laravel mi však tento postup zcela překopal, respektive již ho nešlo použít. Najednou jsem stál před krkolomným problémem složité stromové struktury tisíců souborů webu, což by ještě bylo to nejmenší. Problém tkví v tom, že strom složek na lokálním serveru je jiný než na hostingu, nelze ho tedy prostě překopírovat. Dále jsou tu různé soubory (DB Sqlite), které jsou jenom na hostingu a na localhost se dostat nesmějí, opačně soubory lokální, které se na server dostat nesmějí. Pak tu jsou různé varianty konfiguračních souborů, které mají stejné jméno, ale obsah na obou umístěních je jiný a v žádném případě se nesmí nahradit. No a nakonec specifika daného hostingu, podle kterých musí být Laravel upraven, aby vůbec fungoval a která na localhostu nejsou vůbec, ale při každém uploadu na server se musí z lokálních poskládat. Pak je tu dočasná cache Laravelu, která se musí při každé změně databáze vyprázdnit. No a nakonec stále nový počet souborů ve stejné složce.

Klienti krátcí

Najednou na to byla i FileZilla krátká. Nejdříve jsem myslel, že si prostě nastavím frontu dopředu a uložím a při každém uploadu pouze loadnu tu samou queue a je to. Tak jsem na to znovu nainstaloval svůj za celý život nejlepší poznaný FTP klient co znám: Cute FTP Pro. Ten toho většinu zvládnul, až na proměnlivý neznámý počet souborů ve složce. Zkusil jsem i všemi doporučovaný WinSCP, ale to je jenom lepší FileZilla, nic víc.

Otřes s FTP

Dodnes se pamatuji, jak mnou otřáslo, když jsem pochopil pravou podstatu problému: On je na to totiž celý FTP protokol krátký a na ten úkol nelze vůbec použít.

Naskriptovat to ručně

Zbývalo mi jediné: Naučit se pracovat s úplně jinou command-line utilitou pro přenos souborů a celý děj sestávající asi z osmi bodů ručně naskriptovat v Bashi. Začal jsem tedy zkoumat možnosti, kterých je asi osm, jako SFTP, FTPS, Curl, Fish, HFTP, NCFTP, LFTP a co já ještě vím. Většinu z nich odboural můj hosting, že prostě neprošly jeho nastavením. Vylouply se mi akorát tři možnosti: SCP, Ncftp a lftp.

FTP není žádný kanón

Až záhy jsem se dozvěděl, že FTP spadá do začátků moderních počítačů, do nějakého roku 1985, kdy byl definován. Je tedy vlastně jen o dva roky mladší než jsem sám, což je ve světě počítačů sto let za opicemi. Rozstřílel ho můj zásadní požadavek: Uložit do fronty jenom název složky, která má pokaždé jiný počet souborů. A to FTP neumí. FTP musí mít přednastavenou queue jedině jako známý konečný výčet všech souborů, ale uploadovat složku jako proměnnou množinu souborů prostě neumí! Tady mi teprve došlo, že stojím před úplně jiným problémem, než kdy doposud.

A vítězem je lftp

Lftp, bez žádných okolků vždy stylizován jako lftp - sophisticated file transfer program.

K mému zděšení se navíc ukázalo, že lftp je program ruský, nicméně uklidnil jsem se při pomyšlení na jiné ruské programy, jako RAR/Winrar, The Bat! email client, ROSA Linux a hra Chasm the Rift, které byly/jsou přímo božské a patří k mercedesům ve svém oboru.

Odevšad na lftp zaznívala samá chvála a nyní se k ní přidávám i já. Nejdříve jsem si ovšem prošel uličkou 24 hodin pokusů, návodů a omylů, než jsem dal svůj skript s parametry pracujícími na mém hostingu dohromady. Nehledě na to, že samotný bash scripting je záliba pěkně zrádná.

LFTP

Lftp z roku 2009 mi sedl z následujících důvodů: Nevyžaduje SSL. Má single line mode stejně jako interaktivní mód, stejně jako skriptový mód. Dá se použít ve všech případech jako FTP a dovede i higher level příkazy. Dovede pracovat paralelně ve více vláknech. A především: dovede fungovat na bázi složek namísto souborů! Mimo jiné jako zajímavost dovede pracovat s BitTorrent protokolem. Na rozdíl od FTP pracuje spojovaně a spolehlivě, kontroluje tedy každý přijatý paket, v případě poškození požaduje znovu nebo aspoň podá hlášení uživateli. Navíc je přímo stvořený pro mirroring celých stromů složek s dopředu neznámými soubory a umožňuje pokročilou synchronizaci, jako např. výmaz souborů na serveru, pokud se na zdroji nevyskytují. A byl jsem doma! Už to jen nastavit.

Pár rad k Bashi

Co si budeme nalhávat, skriptování pro Bash je taky porod!
Když už jsem měl tělo skriptu vymyšlené a jal jsem se je testovat, vyhazovalo mi to nepochopitelné chyby nedokončených příkazů a rozsekaných slov, takže vše bylo v háji. To jsem po době dalšího hledání vyřešil tím (bavíme se o Linuxu), že jsem v Leafpadu u mého souboru musel nastavit linuxovské mezery LF a soubor s nimi přeuložit. Pokud totiž přenecháte windowsovské mezery v textu CRLF, bash je chápe jako jiné znaky, nikoli mezery, a proto skript nemohl přečíst.

Pár rad k lftp

Lftp sice dokáže řetězit příkazy v jediném řádku příkazu v Bashi, pomocí přepínačů -e a -c,
např.: lftp -e cmd1; cmd2
To je ale v CLI módu. My nejsme ani v příkazovém ani v interaktivním módu, my potřebujeme skript, tedy kaskádu příkazů, které bude vykonávat postupně za sebou.

A to je největší problém! Dle mého dětského skriptování autoexec.BATů kdysi v DOSu bych čekal, že prostě zřetězím příkazy za sebe, každý na řádek a ono je to postupně vykoná. Opět chyba, v Bashi jen tak nelze!

Bash načte jen první příkaz a pak má čekat až se vykoná a poté přeskočit na další, ale to sám neumí, musíte ho k tomu dokopat pomocí linuxovského << následovaného jménem návěští, v mém případě EOF (end of file). Pak teprve dokáže čekat na vykonání jednoho a automaticky mu zadat druhý a další až do konce. Takže celá kaskáda lftp skriptů vypadá podle tohoto schématu:

lftp první příkaz (připojuje se) <<EOF
lftp další příkaz
lftp další příkaz
.
.
.
lftp další příkaz
EOF

Po příkazu <<EOF teprve zpracovává jeden za druhým s čekáním na vykonání až do té doby, než narazí na návěští EOF. Po něm bych mohl případně zadávat další příkazy.

Práce LFTP

Toto je nástin mého skriptu, podle manuálu k lftp si samozřejmě experimentujte po svém.

Po úvodním připojení k serveru, které může vypadat tak:
lftp -u "$user","$heslo" $host <<EOF

nebo tak:
lftp <<EOF
open -u $user,$heslo $remoteServ

nebo ve stylu více příkazů v jednom:
#lftp -e open -u w114359,heslo04687326 114513.w114.wedos.net;ls

Zobrazuji root živého webu:
ls

Pomocí
mirror -R cesta/místní cesta/vzdálená
konečně uploaduju celé složky, to jediné, kvůli čemu jsem se do toho vůbec pouštěl

přepínačem --parallel=18 nastavuji upload 18-ti vlákny vedle sebe, což při obřím množství miniaturních souborů urychlí proces

přepínačem --exclude public/ vyjímám složku /public z příkazu, ta půjde do jiného umístění

přepínačem --delete synchronizuji složku cache na serveru s prázdnou složkou, tedy ji vymazávám.

příkazem exit nebo quit nebo bye končím lftp a vracím se do command promptu tedy Bashe.

Závěr

Nakonec je to tak božské, že si asi jen tak pro radost budu uploadovat navíc i soubory, které mi nevelí povinnost. Bohužel mě to stálo den času, ale výsledek mám zaznamenán, takže už se můj výzkum v tomto směru nikdy opakovat nebude.

Zdroje

Oficiální stránka lftp a manuál:
http://lftp.yar.ru/lftp-man.html

Nejlepší textový návod, který se dá použít jako cheat sheet:
http://mewbies.com/lftp_basic_usage_tutorial.htm

A samozřejmě neobešel bych se bez desítek rad na StackOverflow, jinak bych tu nebyl.

DC home |
Portál vojenských technologií |
Ostatní články |
Organizační

Objev spočívá ve vidění toho, co každý viděl, a uvažování tak, jak to dosud nikoho nenapadlo.
X3 Reunion