Včera (ano, myslím, že to bylo včera) jsem se rozhodl, že tady na blog přihodím ještě RSS pro komentáře. Bylo to jednoduché, přidat routu do jednoho souboru, upravit model v jiném souboru, přidat další kontrolér a šablonu – celkově pár základních operací nad několika soubory. Na „lokále“ všechno chodí, říkám si: „Super!“ teď to hodím na „ostrý“ server. Teď přišlo avšak na řadu to horší – právě ono „házení“.
Možná, že kdybych používal nějakého hezkého a přítulného grafického FTP manažera, tak by takové problémy nikdy nenastaly, ale já prostě mám řádku rád, takže veškeré nahrávání na FTP provádím pomocí ní. Používám utilitku nesoucí název curlftpfs. Je to prográmek napsaný pomocí FUSE, který dokáže připojit FTP jako lokální složku, takže nahrání souborů je prosté zkopírování z jedné složky do druhé. Problém nastává právě tehdy, když se upraví pár souborů v různých složkách – nahrání všeho naráz (tzn. celého projektu) je pomalé a přenáší se při tom zbytečně mnoho dat (i když je pravda, že je to velice pohodlné :o)); a pořád skákat jako kamzík ze složky do složky a nahrávat jeden soubor za druhým zase moc pohodlné není (přeci to musí jít nějak lépe… :o)). Navíc, když člověk na nějaký soubor zapomene tak ho neočekává nějaká zpráva ve stylu „hej, ještě tohle“. V lepším případě aplikace nebude fungovat vůbec a napíše se nějaká hezká chybová hláška typu „tohle chybí, tohle přebývá“, v horším bude aplikace fungovat a člověk něpozná, že na něco zapomněl a v tom nejhorším se načte a stránka a tam nic, bíloprázdno (zajímalo, kdo začal jako první používat termín „bílá obrazovka smrti“ :o)).
Spusťte famfáry :o), s řešením přichází můj deployovací skript. Cíl byl jednoduchý – nahrávat vždy jenom ty soubory, u kterých došlo k nějakým změnám. Vymyslet návrh netrvalo o moc déle. Na FTP je umístěn soubor, který obsahuje názvy souborů a údaje o nich. Nejdříve jsem chtěl rozlišovat to, jestli byl soubor nějak upraven, podle data poslední změny, ale pak jsme si řekl, že to asi nebude to pravé ořechové. A jelikož chci sledovat obsah souboru, tak rozlišovacím znakem bude jeho „otisk“ (hash) – když se hash lokálního souboru a toho na FTP liší, byly provedeny změny, což znamená, že je potřeba soubor nahrát. Princip je jednoduchý a léty ověřený i na jiných systémech (kupř. takový Git myslím sleduje taky otisky souborů, ne nějaké časy).
Takže zkráceně celá operace nahrávání probíhá takto:
-
stáhne se „soubor objektů“ z FTP, z něj se získají páry typu soubor-hash (prostě asociativní pole, kde klíči jsou soubory a hodnotami hashe)
-
získají se hashe lokálních souborů, porovnají se s těmi z FTP a pokud jsou jiné, proběhla v souboru nějaká změna – je potřeba ho nahrát
-
nahrají se změněné soubory
Myslím, že je to jednoduché a přímočaré. Hned jsem to začal používat (ještě aby ne :o)). Včera jsem měl funkční prototyp a dneska jsem si hrál s výstupy a hlavně s konfigurací (předtím byla „hard-coded“ přímo v PHP). Nechtěl jsem tahat XML, či podobné molochy, INI se mi taky vůbec nelíbí a podle mě se na tohle moc nehodí atd. Takže nakonec používám něco na styl HTTP :o) Celý konfigurační soubor sestává ze dvou částí – hlaviček určujících parametry připojení k FTP, chování skriptu, a pokud by bylo potřeba, mohou být v budoucnu přidány další věci; a těla, kde jsou na každém řádku jeden soubor, který se má nahrát. Obě části jsou odděleny tečkou, která musí na řádku stát samostaně. Takhle jsem ten konfigurák sestavil hlavně proto, aby se mohly soubory jednoduše vyhledávat pomocí find.
Volby v „hlavičkách“ jsou zatím takovéto:
host(string)- Adresa FTP serveru (defaultně
localhost). port(integer)- Číslo portu FTP serveru (defaultně
21). timeout(integer)- Čekání na připojení k FTP serveru (defaultně
10). username(string)- Uživatelské jméno (defaultně prázdné).
password(string)- Heslo uživatele (defaultně prázdné).
root(string)- Kořenový adresář na FTP serveru, kam půjdou soubory (defaultně prázdné).
force(boolean)- Pokud je nastaveno na
true, na všechny otázky se odpovídá ano (defaultnětrue). verbose(boolean)- Pokud je
true, skript se bude hodně vykecávat (defaultněfalse). objects_file(string)- Název pro soubor s objekty na FTP (defaultně
.objects). config_file(string)- Název konfiguračního souboru (defaultně
.dy). Tento soubor se vždycky otevře a přečte se z něj konfigurace.
U logických hodnot místo toho, aby se musely vypisovat stylem název: hodnota, kde hodnota je buď true nebo false, lze používat zkrácený zápis, kdy pokud se jen uvede název (nikde na řádku nesmí být :), je nastaveno true, pokud je na začátku vykřičník, je hodnota false. Pro lepší pochopení bude asi lepší ukázka:
host: bukaj.netuje.cz port: 21 username: xxx password: xxx root: / verbose !force . index.php foo.png bar.css …
Mám ověřenu funkčnost na PHP 5.2.6 na Linuxu. Zkoušel jsem taky na PHP 4.4.9 ve virtuální mašině na Windows. Ale tam jsem neměl možnost, jak vyzkoušet, jestli funguje odesílání na FTP – nemám tam totiž zprovozněné připojení. Takže tady lze jen doufat :o) Podle mě by to však fungovat prakticky kdekoli, kde je PHP. Jediné, čeho se bojím je to, že Windowsí „kománd lajna“ nerozumí shellovým escape sekvencím, takže tam bude místo hezkého postupu nahrávání zobrazovat bůhvíjaké paznaky. Nicméně hlavní funkčnost (tj. nahrávání) by měla být zachována.
Abych se jen tak blbě nevykecával, nejlepší bude ukázat zdrojový kód, že?
Doposud žádný komentář
Přidat komentář