2015-07-27 00:30:33

Automatinis diegimas iš VCS (I)

Šį kartą pažvelgsiu į seną, kaip žemė temą, diegimo ir buildinimo automatizacija naudojant Jenkins. Šiame turoriale pamatysite pavyzdį, kaip galima automatizuoti užduotis pasinaudojant Jenkins. Ši sistema yra ko gero plačiausiai naudojamas programuotojų darbų automatizavimo įrankis, taip pat dažniausias karkasas ant kurio yra pakabinama CI (Continous Integration) darbo metodologioja. Vėlesniuose turorialuose pateiksiu pavyzdžių kaip Jenkins galima panaudoti švaraus kodo ir automatinio testavimo procesuose. Jenkins gali atlikti ir tokias užduotis kaip cache valymas, ar duomenų bazės lentelių sukūrimas ir atnaujinimas. 

Pirmoje pamokėlėje bus papraščiausias būdas atlikti automatiniam diegimui, nors tai ir stupid simple ir nelabai efektyvu, ir nešvaru (dirbant su didelio lankomumo ir apkrovos sistemomis) bet pradedantiesiems bus tikrai naudinga ;)

Atsiprašymas: Jenkis keistai sudiegė lietuviškumo paketą, todėl dalis UI elemntų pavadinimų yra Lietuvių, dalis Anglų kalbomis. 

 

1. JENKINS DIEGIMAS.

Jenkins diegsime su APT pagalba. Pirmiausia į APT turime prisidėti repozitoriją, iš kurios diegsime Jenkins:


wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt-get update
sudo apt-get install jenkins

Tada atnaujiname savo APT:

sudo apt-get update

Įdiegiame Jenkins:

sudo apt-get install jenkins

Diegimui pasibaigus, savo interneto naršyklėje einame į URL: http://localhost:8080/ . Turėtų astidaryti Jenkins, jei ne, rašykite į komentarus. 

 

Keletas pastabų:

  • Vartotojas 'jenkins' bus sukurtas Jenkins servisui, jį pakeisime į savajį, paprastumo sumetimais. 
  • Logų žurnalas bus patalpintas: /var/log/jenkins/jenkins.log . 
  • Jenkins veiks po 8080 portu. 

 

Kadangi Jenkins sudiegėme lokaliai, mokymosi tikslams. Patogumo dėlei, norint išvengti papildomų konfigūravimo darbų ar kitų trugdžių, pravartu šį (Jenkins) procesą paleisti savo vartotojovardu (kitaip SSH autorizacijoms reiktų kurti ar perkelinėti raktus Jenkins useriui, o šiuo atveju Jenkins turės priėjimą prie visų Jūsų resursų). 


Tam turime atsidaryti Jenkins konfigūracinį failą, kuris yra /etc/default/jenkins:

sudo nano /etc/default/jenkins


Kintamuosius JENKINS_USER ir JENKINS_GROUP pervadiname savo vartotojo vardu:
Mano atveju pakoreguotos konfigūracinio failo eilutės atrodys taip:

JENKINS_USER=lukasm 
JENKINS_GROUP=lukasm 

 

Pataisome vartotojo teises, dabar prie darbinių Jenkins failų. Mano atveju priėjimą turi turėti vartotojas lukasm:


sudo chown -R lukasm /var/log/jenkins
sudo chown -R lukasm /var/lib/jenkins
sudo chown -R lukasm /var/run/jenkins
sudo chown -R lukasm /var/cache/jenkins


Atlikus šiuos pakeitimus turime perkrauti Jenkins. Jenkins turi perkrovimo URL, todėl paleidžiame URL: http://localhost:8080/restart ir spaudžiame YES.

Jei po kelių akimirkų (30-60 sec.) atsidaro Jenkins, sveikinu, greitai galėsite automatizuoti savo diegimus ar buildus :) 

Galime tęsti toliau.


Dabar turėsime susidiegti priedus ir papildinius. Jenkinse atliekame tokius reikaliukus: 

 

Spaudžiame: Atsiųsti dabar ir įdiegti po perstartavimo

Diegimas gali užtrukti...


Kol diegiasi pluginai, pažymime varnelę ties restart. Jei varnelės nepažymėjote, po diegimo įveskite URL: http://localhost:8080/restart .

 

2. KURIAME NAUJĄ JENKINS PROJEKTĄ/UŽDUOTĮ.

Dabar galėsi išsibandyti prisijungimą prie BitBucket Git repositorijos.


Kaip minėjau, Jūs turite turėti aktyvią BitBucket (arba GitHub) Git repositoriją ir joje registruotą SSH raktą.

 

Norėdami sukurti naują diegimų užduotį. Šiam reikalui spaudžiame:

 



Pirmasis mūsų žingsnis bus pridėti Jenkins'ui darbą, kurio metu jis gaus pakeitimus iš Git serverio. Vėliau su šiuo kodu galėsime atlikinėti kitas operacija, ar tiesiog juo pasigrožėti :)

 

Ne, darbo dar nepridėsime, pirmiausiai sukonfigūruosime Jenkis, taip kad jis galėtų pasiekti Git repositoriją.

Taigi, naujai atsidariusiame lange, norėdami sokonfigūruoti prisijungimą prie Git leidžamės (scroliname) iki skyriaus Source Code Management (Išeities kodo valdymas) ir pažymime Git.
Repository URL laukelyje įvedame savo Git repo linką: git@bitbucket.org:xyxyxyx/repo_pavadinimas.git


Dabar turime kelis pasirinkimus: jungtis prie Git pasinaudojant SSH raktu ar panaudojant savo prisijungimo vardą ir slaptažodį. Rekomenduočiau pirmajį variantą. Bloga praktika laikoma įvedinėti savo slaptažodį, kai galima to nedaryti ;)

Git su SSH (rekomenduojama tik tada kai Jenkins veikia jūsų vartotojo vardu)

 

Palaukiame kelias sekundes, jei yra klaidų, pasirodys raudoni pikti pranešimai.

Kaip jau minėjau, kadangi Jenkins veikia Jūsų vartotojo vardu, jis turės priėjimą, prie Jums įprastų resursų, tokių kaip SSH raktai.

Git be SSH

  • Šį variantą siūlyčiau naudoti tik tuomet, jei žemiau jums nepavyks prisijungti su SSH.
  • Tiesiog įvesti savo BitBucket vartotojo detales, vartotojo vardą ir slaptažodį.
  • Pasirenkame ir spaudžiame Add.

 

Palaukiame kelias sekundes, jei yra klaidų, pasirodys raudoni pikti pranešimai.


Kol kas, daugiau jokių kitų pakeitimų nustatymuose neatliekame.


Jei klaidų pranešimų neatsirado, prisijungimas prie Git serverio repositorijos veiks sklandžiai.

Todėl vėl, apačioj kairėje spaudžiam Apply.


Dabar turime pridėti darbo žingsnį, kuris paims pakeitimus iš Git ir paruoš juos perkėlimui į testinį serverį.

Šis žingsnis gali būti atliktas keliais skirtingais būdais.


Šiuo atveju peržiūrėsime: a) Visų pakeitimų iš Git repo diegimas ir b) Vieno tag'o diegimas. a) varianto diegimas yra tinkamesnis diegiant į LIVE (production) aplinkas.

Šiuo būdu mes gauname failus, kurie buvo pakeisti tarp dviejų commit'ų. Tai yra speciali "Git release/stability branch" strategija. Pagal šią strategiją, Git šakoje (branch'e) kiekvienas commitas, turi būti pakeitimų visuma, kuri bus diegiama to releas'e metu. T.y. jūsų Jenkins paleidimo metu. Naudojant šią strategija, reikia turėti omenyje, kad šakoje iš kurios yra vykdomi diegimai, neturi būti šiukšlių, o vienas commit'as (tag'as) turi būti lygus vienam diegimui. b) versija yra tinkama projektų diegimui į TST aplinkas. Jos metu yra paimami visi pakeitimai esantys Git serveryje ir perkeliami į serverį.


Abiem atvejais, šakose turi būti kokybiškas kodas, kuriame nėra kritinių klaidų.


Plačiau apie Git versijavimo strategijas gali paskaityti čia http://git-scm.com/book/be/v2/Git-Branching-Branching-Workflows arba čia https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow

a) Visų pakeitimų iš Git repo diegimas.

Šiuo atveju šiame žingsnyje papildomų nustatymų daryti nereikia.

b) Vieno tag'o diegimas.

Toks diegimas yra tinkamesnis diegiant į LIVE (production) aplinkas.
Šiuo būdu mes gauname failus, kurie buvo pakeisti tarp dviejų commit. Tai yra speciali "Git release/stability branch" strategija. Plačiau apie Git versijavimo strategijas gali paskaityti čia http://git-scm.com/book/be/v2/Git-Branching-Branching-Workflows arba čia https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow

Taigi, pirmas darbas, kurį turime pridėti yra, pakeitimų iš Git gavimas.

 

Build(Darbas) > Add build step (Pridėti darbo žingsnį) > Execute shell


Laukelyje command įrašome: 

ls -a
mkdir keliaus_i_srv
cp -pv --parents `git diff --name-only HEAD~2..HEAD~1` keliaus_i_srv

Kiek plačiau apie užduotis kurias duodime Jenkins'ui:

  • Eilutė: ls -a , tiesiog parodys, kas buvo parsiųsta iš Git repo.
  • Eilutė: mkdir keliaus_i_srv , sukuria naują direktoriją jūsų builde.
  • Eilutė: cp -pv --parents `git diff --name-only HEAD~2..HEAD~1` keliaus_i_srv , atlieka patikrinimą, tarp dviejų paskutinių pakeitimų ir failus perkelia į folderį keliaus_i_srv

 

Apačioj kairėj spaudžiam Apply.

 

Skiltyje Veiksmai po darbo pasirenkame Delete workspace when build is done.
Ši komanda po kiekvieno diegimo išvalys virtualų Jenkins darbalaukį. Išbandome savo naujuosius nustatymus. Spaudžiame: Jenkins > Testas 001 > Build Now Kairėje atsiras progress baras su greta mirksinčiu pilku skrituliuku. 

Galite paspausti ant skrituliuko, tada Console Output. Šiame lange galėsite matyti kaip vyksta Jūsų diegimas realiu laiku.
Tai gali užtrukti.... Pasidaryk kavos ;)


Jei gausite klaidą, panašią į :
stderr: Permission denied (publickey).
fatal: Could not read from remote repository.


Siūlau susikonfigūruoti be SSH raktų ir pabandyti paleisti diegimą iš naujo, kaip aprašyta aukščiau.
Jei gavote pranešimą panašų į:
Finished: SUCCESS


Sveikinu pirmoji dalis baigta sėkmingai.


Jei nepavyko, googlinkit :D Arba rašykite į komentarus.

Sekantis žingsnis yra duomenų perkėlimas į serverį.

Šį kart vėl pasiūlysiu du variantus, kiekvienam pagal galimybes ir poreikius, kaip sakant ;)


Pirmasis, kodo perkėlimas į serverį per SSH. Antrasis į FTP. Taip FTP yra nykstanti rūšis tokiuose reikaluose, bet manau, kad gali pasitaikyti kažkas, kas neturi serverio su SSH, o naudojasi senu geru sharde hosting'u, kur paprastai SSH nebūna... :(

a) Perkėlimas per SSH:

Tam panaudosime įskiepį: “Publish over SSH”.

Pirmiausiai sukuriame prisijungimą prie serverio per SSH:


Jenkins >  Testas 001 > Nustatyti > Skyrius Publish over SSH > Add server
Pridedame aukščiau sukurtą serverį.
Jei diegiame pagal Visų pakeitimų iš Git repo diegimo startegiją. Source files skiltyje įrašome: *, */*, /*, */, **

Jei digiame pagal Vieno tag'o diegimas Source files skiltyje įrašome: keliaus_i_srv/**.

Spaudžiame: Add transfer set.

Ir užpildome:

Exec command: chmod 0775 ~/laravel/blogas/deploy.sh

Exec command: ~/laravel/blogas/deploy.sh


Šios komandus suteiks priėjimo teises diegimo scriptui ir jį paleis.


Dėmesio Dėmesio: žemiau yra failo deploy.sh turinys, jį turite įsidėti į projektą, tik mokymosi tikslais ir paprastumo dėlei. Realiose situacijose diegimo scriptai būna laikomi ne su projektu o į diegimą įtraukiami jau diegimo metu.

Taigi žemiau aprašytas scriptas, kuris atliks juodą diegimo darbą. T.y. iš git iščekoutintus projekto failus, perkels į laikiną (temp) direktoriją. Ten įkopijuos konfigus (konfigai taip pat negali būti komitinami į git, nes juose gali būti slaptažodžiai ir kita jautri informacija), paleis composer install ir galiausiai perkels failus į darbinę nginx direktoriją, t.y. jūsu virtualų hostą.

#!/bin/bash

# Sugeneruoja dabartinę datą ir laiką, tam kad atsargoje liktų senų diegimų kopijos.
DATE=$(date +%F-%T) ;
echo $DATE ;

# Sukuriame naujos versijos direktorija.
mkdir /home/lukasm/laravel/deploy/$DATE ;

# Nukopijuojame projekta i naujos versijos direktorija.
cp -a /home/lukasm/laravel/deploy/tmp/* /home/lukasm/laravel/deploy/$DATE ;
cd /home/lukasm/laravel/deploy/$DATE

# Suteikiame prieigos teises prie bendru darbiniu direktoriju.
chmod -R 0777 /home/lukasm/laravel/deploy/$DATE/storage
chmod -R 0777 /home/lukasm/laravel/deploy/$DATE/bootstrap/cache

# Sudiegiame projekto 3iuju saliu bibliotekas su composer.
composer install

# Nukopijuojame configus.
cp /home/lukasm/laravel/deploy/production.env /home/lukasm/laravel/deploy/$DATE/production.env

# Sukeiciame direktorijas. Butent sioje vietoje musu nauja projekto versija tampa LIVE versija.
rm ~/laravel/blogas ;
ln -s /home/lukasm/laravel/deploy/$DATE ~/laravel/blogas ;

# Isivalome
rm -rf /home/lukasm/laravel/deploy/tmp*;

b) Perkėlimas į FTP:

Tai labai supaprastintas aukščiau aprašyto darbo variantas. Jame nebus diegimo scripto paleidžiančio composer, kadangi per FTP protokolą, apie tokį dalyką, tik pasvajoti galime...
Kadangi galima gauti savo failus iš Git. Susikonfigūruosime paskutinį žingsnį leisiantį įkelti savo nauju pakeitimus atliktus tarp git commitų.
Tam panaudosime įskiepį: “Publish over FTP”.



Remote Directory įrašome direktoriją nutolusiame FTP serveryje, jei yra poreikis. Pvz.:/public_html .
Spaudžiame Test Configuration.
Jei pasirodo Success skaitykite toliau, jei klaida, pasitikrinkite savo prisijungimo duomenis.
Apačioje dešinėje spauskite Save.
Tada scroliname iki skyriaus: Send files over FTP
Transfers > Source files įrašome - keliaus_i_srv/**
Ši eilutė nurodo, kad Jenkins FTP klientas nukopijuos vis failus (**) iš direktorijos keliaus_i_srv.
Galimos ir sudetingesnės variacijos su failų plėtiniais ar vardasi, sakykim *.css.
Remote directory: public_html 

Spaudžiame Save.

Pabandymui paleidžiame Buildą:


Jei gauname kažką panašaus į:

FTP: Connecting from host [lukasm-UX32]
FTP: Connecting with configuration [Testas_001] ...
FTP: Disconnecting configuration [Testas_001] ...
FTP: Transferred 18 file(s)
Build step 'Send files over FTP' changed build result to SUCCESS
Finished: SUCCES

Būname labai laimingi ir keliaujame į savo puslapio URL ir tikriname kaip atrodo projektas su atnaujintais failais.

Jei kažkas neveikia, radote klaidų, turite komentarų ar pastabų, rašykite į komentarus.