Falling Down the Rabbit Hole: L-istorja ta' żball wieħed ta' reboot tal-verniċ - Parti 1

Ghostinushanka, wara li tħabbat fuq il-buttuni għall-20 minuta ta' qabel bħallikieku ħajtu tiddependi minnu, idur lejja b'espressjoni semi-selvaġġa f'għajnejh u grinn sly - "Raġel, naħseb li nifhem."

"Ħares hawn," jgħid, filwaqt li tipponta lejn wieħed mill-karattri fuq l-iskrin, "Imħatra l-kappell aħmar tiegħi li jekk inżidu hawn dak li għadni bgħattlek" - billi tipponta lejn sezzjoni oħra tal-kodiċi - "l-iżball m'għadux se jintwerew."

Ftit inkwetat u għajjien, nibdel id-dikjarazzjoni tas-sed li ilna naħdmu fuqha, insalva l-fajl, u mexxi systemctl varnish reload. Il-messaġġ ta' żball sparixxa...

"L-emails li skambjt mal-kandidat," kompla l-kollega tiegħi, hekk kif id-daħka tiegħu tinbidel fi tbissima ġenwina mimlija ferħ, "F'daqqa waħda ħarġet fuqi li din hija eżattament l-istess problema!"

Kif beda kollox

L-artikolu jassumi fehim ta 'kif jaħdmu bash, awk, sed u systemd. L-għarfien tal-verniċ huwa preferut iżda mhux meħtieġ.
It-timbri taż-żmien fis-snippets ġew mibdula.
Miktub ma Ghostinushanka.
Dan it-test huwa traduzzjoni tal-oriġinal ippubblikat bl-Ingliż ġimagħtejn ilu; traduzzjoni boyikoden.

Ix-xemx tiddi mit-twieqi panoramiċi f'għodu sħun ieħor tal-ħarifa, tazza ta' xarba tal-kaffeina mħejjija friska tistrieħ mal-ġenb tat-tastiera, sinfonija favorita ta' ħsejjes idoqq fil-headphones fuq il-ħsad ta' tastieri mekkaniċi, u l-ewwel dħul fil- lista ta’ biljetti b’lura fuq il-bord kanban tiddi b’mod ludiku bit-titlu fatali “Investiga varnishreload sh: echo: I/O error in staging” (Investiga “varnishreload sh: echo: I/O error” fl-istadju). Fir-rigward tal-verniċ, m'hemm l-ebda u ma jistax ikun hemm żbalji, anke jekk ma jirriżultawx fi problemi, bħal f'dan il-każ.

Għal dawk li mhumiex familjari magħhom tagħbija tal-verniċ, din hija skript sempliċi tal-qoxra użata biex terġa' tgħabbi l-konfigurazzjoni verniċ - imsejħa wkoll VCL.

Kif jissuġġerixxi t-titlu tal-biljett, l-iżball seħħ fuq wieħed mis-servers fl-istadju, u peress li kont kunfidenti li r-rotot tal-verniċ fl-istadju kien qed jaħdem sew, assumejt li dan kien se jkun żball minuri. Allura, messaġġ biss li daħal fi fluss ta 'output diġà magħluq. Nieħu biljett għalija nnifsi, b'kunfidenza sħiħa li se nimmmarkah lest f'inqas minn 30 minuta, nagħtik fuq l-ispalla biex inaddaf il-bord tal-junk li jmiss u nerġa' lura għal affarijiet aktar importanti.

Jiġġarraf f'ħajt b'200 km/h

Ftuħ fajl varnishreload, fuq wieħed mis-servers li jħaddmu Debian Stretch, rajt script shell inqas minn 200 linja twila.

Tmexxi l-iskrittura, ma rajt xejn li jista 'jikkawża problemi meta tħaddem diversi drabi direttament mit-terminal.

Wara kollox, dan huwa stadju, anke jekk jinkiser, ħadd ma jilmenta, ukoll ... mhux wisq. Jiena nmexxi l-iskript u nara x'se jinkiteb fit-terminal, iżda l-iżbalji m'għadhomx viżibbli.

Koppja oħra ta 'ġirjiet biex niżgura li ma nistax nirriproduċi l-iżball mingħajr xi sforz żejjed, u nibda nifhem kif nibdel dan l-iskript u nagħmilha xorta tarmi żball.

Jista' l-iskript jimblokka STDOUT (bl-użu > &-)? Jew STDERR? La ħadmu fl-aħħar.

Ovvjament systemd jibdel l-ambjent tal-ġirja b'xi mod, imma kif, u għaliex?
Ixgħel il-vim u neditja varnishreload, żżid set -x dritt taħt il-shebang, bit-tama li debugging l-output ta 'l-iskrittura se jitfa' xi dawl.

Il-fajl huwa ffissat, għalhekk nerġa' niċċarġja l-verniċ u nara li l-bidla kissret kollox kompletament ... L-exhaust huwa mess sħiħ, b'tunnellati ta 'kodiċi bħal C fih. Anke l-iskrolljar fit-terminal mhuwiex biżżejjed biex issib minn fejn jibda. Jien kompletament konfuż. Il-mod ta' debug jista' jaffettwa x-xogħol tal-programmi mmexxija fi skript? Le, bullshit. Bug fil-qoxra? Diversi xenarji possibbli qed itiru f’rasi bħall-wirdien f’direzzjonijiet differenti. Tazza ta' xarba mimlija kaffeina tibattal f'mument, vjaġġ ta' malajr lejn il-kċina għal forniment mill-ġdid u... ejja. Niftaħ l-iskript u nagħti ħarsa aktar mill-qrib lejn ix-shebang: #!/bin/sh.

/bin/sh - dan huwa biss symlink bash, għalhekk l-iskrittura hija interpretata f'mod kompatibbli ma' POSIX, hux? Ma kienx hemm! Il-qoxra default fuq Debian hija dash, li huwa eżattament dak jirreferi /bin/sh.

# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 24  2017 /bin/sh -> dash

Għall-fini tal-prova, biddilt ix-shebang għal #!/bin/bash, imneħħija set -x u ppruvaw mill-ġdid. Fl-aħħarnett, fuq tagħbija mill-ġdid sussegwenti tal-verniċ, deher żball tollerabbli fl-output:

Jan 01 12:00:00 hostname varnishreload[32604]: /usr/sbin/varnishreload: line 124: echo: write error: Broken pipe
Jan 01 12:00:00 hostname varnishreload[32604]: VCL 'reload_20190101_120000_32604' compiled

Linja 124, hawn!

114 find_vcl_file() {
115         VCL_SHOW=$(varnishadm vcl.show -v "$VCL_NAME" 2>&1) || :
116         VCL_FILE=$(
117                 echo "$VCL_SHOW" |
118                 awk '$1 == "//" && $2 == "VCL.SHOW" {print; exit}' | {
119                         # all this ceremony to handle blanks in FILE
120                         read -r DELIM VCL_SHOW INDEX SIZE FILE
121                         echo "$FILE"
122                 }
123         ) || :
124
125         if [ -z "$VCL_FILE" ]
126         then
127                 echo "$VCL_SHOW" >&2
128                 fail "failed to get the VCL file name"
129         fi
130
131         echo "$VCL_FILE"
132 }

Iżda kif irriżulta, linja 124 hija pjuttost vojta u ta 'ebda interess. Stajt nassumi biss li l-iżball seħħ bħala parti minn multiline li tibda fuq il-linja 116.
Dak li huwa finalment miktub lill-varjabbli VCL_FILE bħala riżultat ta 'eżekuzzjoni tas-sub-qoxra ta' hawn fuq?

Fil-bidu, tibgħat il-kontenut tal-varjabbli VLC_SHOW, maħluqa fuq il-linja 115, għall-kmand li jmiss permezz tal-pajp. U allura x'jiġri hemmhekk?

L-ewwel, juża varnishadm, li hija parti mill-pakkett ta 'installazzjoni tal-verniċ, biex tikkonfigura l-verniċ mingħajr ma terġa' tibda.

sottokmand vcl.show -v jintuża biex joħroġ il-konfigurazzjoni VCL kollha speċifikata fi ${VCL_NAME}, lil STDOUT.

Biex turi l-konfigurazzjoni VCL attiva bħalissa kif ukoll bosta verżjonijiet preċedenti tal-konfigurazzjonijiet tar-routing tal-verniċ li għadhom fil-memorja, tista 'tuża l-kmand varnishadm vcl.list, li l-output tiegħu se jkun simili għal dan li ġej:

discarded   cold/busy       1 reload_20190101_120000_11903
discarded   cold/busy       2 reload_20190101_120000_12068
discarded   cold/busy       16 reload_20190101_120000_12259
discarded   cold/busy       16 reload_20190101_120000_12299
discarded   cold/busy       28 reload_20190101_120000_12357
active      auto/warm       32 reload_20190101_120000_12397
available   auto/warm       0 reload_20190101_120000_12587

Valur varjabbli ${VCL_NAME} issettjat f’parti oħra tal-iskrittura varnishreload għall-isem tal-VCL attiv bħalissa, jekk ikun hemm. F'dan il-każ ikun "reload_20190101_120000_12397".

Okay, varjabbli. ${VCL_SHOW} fih il-konfigurazzjoni sħiħa għall-verniċ, s'issa ċara. Issa fl-aħħar nifhem għaliex sing output ma set -x irriżulta li kien tant miksur - kien jinkludi l-kontenut tal-konfigurazzjoni li tirriżulta.

Huwa importanti li wieħed jifhem li konfigurazzjoni VCL kompluta spiss tista 'tiġi cobbled flimkien minn fajls multipli. Kummenti ta 'stil C jintużaw biex jiddefinixxu fejn fajl ta' konfigurazzjoni wieħed ġie inkluż f'ieħor, u dan huwa eżattament dwar il-linja kollha ta 'snippet ta' kodiċi hawn taħt.
Is-sintassi għall-kummenti li jiddeskrivu l-fajls inklużi għandha l-format li ġej:

// VCL.SHOW <NUM> <NUM> <FILENAME>

In-numri f'dan il-kuntest mhumiex importanti, aħna interessati fl-isem tal-fajl.

Allura x'jiġri fil-swamp ta 'kmandi li jibda fuq il-linja 116?
Ejja niftakruha.
Il-kmand jikkonsisti f'erba' partijiet:

  1. Sempliċi echo, li juri l-valur tal-varjabbli ${VCL_SHOW}
    echo "$VCL_SHOW"
  2. awk, li tfittex linja (rekord), fejn l-ewwel qasam, wara li jinqasam it-test, se jkun "//", u t-tieni wieħed ikun "VCL.SHOW".
    Awk se jikteb l-ewwel linja li taqbel ma' dawn il-mudelli u mbagħad tieqaf mill-ipproċessar immedjatament.

    awk '$1 == "//" && $2 == "VCL.SHOW" {print; exit}'
  3. Blokk ta’ kodiċi li jaħżen il-valuri tal-kamp separati bi spazji f’ħames varjabbli. Il-ħames varjabbli FILE jirċievi l-bqija tal-linja. Fl-aħħarnett, l-aħħar eku jikteb il-kontenut tal-varjabbli ${FILE}.
    { read -r DELIM VCL_SHOW INDEX SIZE FILE; echo "$FILE" }
  4. Peress li l-passi kollha 1 sa 3 huma magħluqa f'sub-qoxra, l-output tal-valur $FILE se jinkiteb għal varjabbli VCL_FILE.

Kif jissuġġerixxi l-kumment fuq il-linja 119, dan iservi l-iskop uniku li jiġu mmaniġġjati b'mod affidabbli każijiet fejn il-VCL se jirreferi għal fajls b'karattri ta' spazju abjad fl-ismijiet tagħhom.

Kkummentajt il-loġika tal-ipproċessar oriġinali għal ${VCL_FILE} u ppruvaw jibdlu s-sekwenza tal-kmandi, iżda ma wassal għal xejn. Kollox ħadem tajjeb għalija, u fil-każ li nibda s-servizz, ta żball.

Jidher li l-iżball sempliċement mhux riproduċibbli meta tħaddem l-iskript manwalment, filwaqt li t-30 minuta stmati diġà spiċċaw sitt darbiet u, barra minn hekk, deher kompitu ta 'prijorità ogħla, li twarrab affarijiet oħra. Il-kumplament tal-ġimgħa kien mimli b'varjetà ta' kompiti u kien dilwit ftit biss b'taħdita fuq sed u intervista mal-kandidat. Problema ta’ żball fi varnishreload mitlufa irrimedjabbli fir-ramel taż-żmien.

L-hekk imsejjaħ sed-fu tiegħek... fil-fatt... żibel

Il-ġimgħa ta' wara kellha ġurnata waħda pjuttost ħielsa, għalhekk iddeċidejt li nerġa' nieħu dan il-biljett. Jien nittama li f’moħħi, xi proċess fl-isfond dan iż-żmien kollu kien qed ifittex soluzzjoni għal din il-problema, u din id-darba żgur li se nifhem x’inhu ħażin.

Peress li l-aħħar darba li tbiddel il-kodiċi ma għenitx, iddeċidejt li nikteb mill-ġdid billi tibda mill-116-il linja. Fi kwalunkwe każ, il-kodiċi eżistenti kien iblah. U m'hemm assolutament l-ebda ħtieġa li tuża read.

Erġa nħares lejn l-iżball:
sh: echo: broken pipe - f'dan il-kmand, l-eku jinsab f'żewġ postijiet, imma nissuspetta li l-ewwel huwa l-iktar ħati probabbli (sewwa, jew għall-inqas kompliċi). Awk lanqas ma jispira kunfidenza. U fil-każ li verament hu awk | {read; echo} id-disinn iwassal għal dawn il-problemi kollha, għaliex ma tibdilha? Dan il-kmand ta 'linja waħda ma jużax il-karatteristiċi kollha ta' awk, u anke dan żejjed read fl-appendiċi.

Mill-ġimgħa li għaddiet kien hemm rapport dwar sedXtaqt nipprova l-ħiliet ġodda tiegħi u nissimplifika echo | awk | { read; echo} f'mod aktar li jinftiehem echo | sed. Filwaqt li dan żgur mhuwiex l-aħjar approċċ biex taqbad il-bug, ħsibt li tal-inqas nipprova s-sed-fu tiegħi u forsi nitgħallem xi ħaġa ġdida dwar il-problema. Tul it-triq, staqsejt lill-kollega tiegħi, il-kittieb tat-taħdita sed, biex jgħinni noħroġ b'kitba sed aktar effiċjenti.

Waqqa l-kontenut varnishadm vcl.show -v "$VCL_NAME" għal fajl sabiex nista' niffoka fuq il-kitba tal-iskrittura sed mingħajr l-ebda battikata ta 'restartjar tas-servizz.

Deskrizzjoni qasira ta 'eżattament kif sed mankijiet input tista' tinstab fi il-manwal GNU tiegħu. Fis-sorsi sed, is-simbolu n speċifikat b'mod espliċitu bħala separatur tal-linja.

F’diversi passes, u bil-parir tal-kollega tiegħi, ktibna sed script li tat l-istess riżultat tal-linja oriġinali kollha 116.

Hawn taħt hemm kampjun ta' fajl b'dejta tal-input:

> cat vcl-example.vcl
Text
// VCL.SHOW 0 1578 file with 3 spaces.vcl
More text
// VCL.SHOW 0 1578 file.vcl
Even more text
// VCL.SHOW 0 1578 file with TWOspaces.vcl
Final text

Jista 'ma jkunx ovvju mid-deskrizzjoni ta' hawn fuq, iżda aħna interessati biss fl-ewwel kumment // VCL.SHOW, u jista 'jkun hemm diversi minnhom fid-dejta tal-input. Huwa għalhekk li l-awk oriġinali jintemm wara l-ewwel logħba.

# шаг первый, вывести только строки с комментариями
# используя возможности sed, определяется символ-разделитель с помощью конструкции '#' вместо обычно используемого '/', за счёт этого не придётся экранировать косые в искомом комментарии
# определяется регулярное выражение “// VCL.SHOW”, для поиска строк с определенным шаблоном
# флаг -n позаботится о том, чтобы sed не выводил все входные данные, как он это делает по умолчанию (см. ссылку выше)
# -E позволяет использовать расширенные регулярные выражения
> cat vcl-processor-1.sed
#// VCL.SHOW#p
> sed -En -f vcl-processor-1.sed vcl-example.vcl
// VCL.SHOW 0 1578 file with 3 spaces.vcl
// VCL.SHOW 0 1578 file.vcl
// VCL.SHOW 0 1578 file with TWOspaces.vcl

# шаг второй, вывести только имя файла
# используя команду “substitute”, с группами внутри регулярных выражений, отображается только нужная группa
# и это делается только для совпадений, ранее описанного поиска
> cat vcl-processor-2.sed
#// VCL.SHOW# {
    s#.* [0-9]+ [0-9]+ (.*)$#1#
    p
}
> sed -En -f vcl-processor-2.sed vcl-example.vcl
file with 3 spaces.vcl
file.vcl
file with TWOspaces.vcl

# шаг третий, получить только первый из результатов
# как и в случае с awk, добавляется немедленное завершения после печати первого найденного совпадения
> cat vcl-processor-3.sed
#// VCL.SHOW# {
    s#.* [0-9]+ [0-9]+ (.*)$#1#
    p
    q
}
> sed -En -f vcl-processor-3.sed vcl-example.vcl
file with 3 spaces.vcl

# шаг четвертый, схлопнуть всё в однострочник, используя двоеточия для разделения команд
> sed -En -e '#// VCL.SHOW#{s#.* [0-9]+ [0-9]+ (.*)$#1#p;q;}' vcl-example.vcl
file with 3 spaces.vcl

Allura l-kontenut tal-iskrittura varnishreload ikun jidher xi ħaġa bħal din:

VCL_FILE="$(echo "$VCL_SHOW" | sed -En '#// VCL.SHOW#{s#.*[0-9]+ [0-9]+ (.*)$#1#p;q;};')"

Il-loġika ta’ hawn fuq tista’ tiġi mqassra kif ġej:
Jekk is-sekwenza taqbel ma' espressjoni regolari // VCL.SHOW, imbagħad greedily devour it-test li jinkludi ż-żewġ numri f'dik il-linja, u ssalva dak kollu li jkun fadal wara din l-operazzjoni. Ħruġ il-valur maħżun u tmiem il-programm.

Sempliċi, hux?

Konna kuntenti bl-iskrittura sed u l-fatt li tissostitwixxi l-kodiċi oriġinali kollu. It-testijiet kollha tiegħi taw ir-riżultati mixtieqa, għalhekk biddilt il-"varnishreload" fuq is-server u erġajt ġrajt systemctl reload varnish. Żball filthy echo: write error: Broken pipe reġgħet daħqet f’wiċċna. Cursor li jteptep kien qed jistenna li jiddaħħal kmand ġdid fil-vojt mudlam tat-terminal...

Sors: www.habr.com

Żid kumment