Toisinaan käy niin, että on tarpeen varmistua siitä aiheuttaako iso kasa Git-committeja jotain sivuvaikutuksia esimerkiksi Puppet-tuotantoympäristössä. Hyvistä commit-viesteistä on aina toki apua, mutta toisinaan commitit eivät ole täysin atomisia, eli tekevät enemmän kuin yhden (dokumentoidun) asian. Lisäksi esimerkiksi Puppet control reposta saattaa löytyä paitsi Puppet-koodia, myös Terraformia ja Ansiblea. Tälläisessä tapauksessa on kätevää näyttää vain muutokset, jotka ovat oikeasti relevantteja. Ensin tarkistetaan, mikä "production"-ympäristön viimeisin commit on:

$ ssh puppet
$ cd /etc/puppetlabs/code/environments/production
$ git rev-parse --short HEAD
86c2152

Tämän jälkeen voidaan tarkista control reposta muutokset Puppetin kannalta oleellisiin kansioihin ja tiedostoihin:

$ cd puppet-control-repo
$ git diff 86c2152…HEAD -- data manifests site Puppetfile

Näin ei tarvitse kahlata läpi myös niitä committeja, jotka eivät mitenkään voi liittyä varsinaiseen Puppet-koodiin ja eivät siten voi aiheuttaa ongelmia tuotantokoneilla.

Puppet-moduulien dokumentaation saa helposti päivitettyä "puppet strings"-työkalulla, jonka käyttö yleisellä tasolla on dokumentoitu varsin hyvin. Kun komento vielä yhdistetään Gitin pre-commit -hookiin, saadaan dokumentaatio päivitettyä automaattisesti joka commitilla. Alla näytetään, miten tämä saadaan toteutettua niin Linuxissa kuin Windowsissa. Oletuksena on, että molemmissa tapauksissa Puppet Agent 5.x on asennettu virallisista Puppetlabsin paketeista.

Aloitan helpommasta eli Linuxista käyttäen esimerkkinä Debian 9:iä: ohjeiden pitäisi kuitenkin toimia myös Ubuntuissa aivan samalla tavoin. Ensin asennetaan Git:

$ sudo -s
 $ apt-get update && apt-get install git

Sen jälkeen asennetaan tarvittavat gemmit käyttäen Puppetin gem-komentoa:

$ /opt/puppetlabs/puppet/bin/gem install yard puppet-strings

Tämän jälkeen mennään dokumentoitavan moduulin juureen:

$ cd ~/opt/puppeteers/puppet-puppetmaster

Tarkistetaan, että "puppet strings" toimii:

$ mkdir docs
 $ /opt/puppetlabs/bin/puppet strings generate --format markdown --out docs/INFO.md
 [warn]: Missing @param tag for parameter 'foreman_db_password' near manifests/lcm.pp:149. 
 
 --- snip ---
 
 manifests/foreman_proxy.pp:87. [0/1899]
 [warn]: Missing @param tag for parameter 'timezone' near manifests/foreman_proxy.pp:87. 
 Files: 8 
 Modules: 0 ( 0 undocumented) 
 Classes: 0 ( 0 undocumented) 
 Constants: 0 ( 0 undocumented) 
 Attributes: 0 ( 0 undocumented) 
 Methods: 0 ( 0 undocumented) 
 Puppet Classes: 7 ( 0 undocumented) 
 Puppet Defined Types: 1 ( 1 undocumented) 
 Puppet Types: 0 ( 0 undocumented) 
 Puppet Providers: 0 ( 0 undocumented) 
 Puppet Functions: 0 ( 0 undocumented) 
 Puppet Tasks: 0 ( 0 undocumented) 
 Puppet Plans: 0 ( 0 undocumented) 
 87.50% documented

Kuten yllä näkyy, puppet-puppetmaster-moduuli voisi olla paremminkin dokumentoitu, ainakin puppet stringsin mielestä. Joka tapauksessa tiedostosta docs/INFO.md löytyy nyt Markdown-muotoinen dokumentaatio moduulista. Jäljellä on siis enää dokumentaation luonnin ja muutosten commitoinnin automatisointi Gitin pre-commit hookilla. Tämä onnistuu luomalla tiedosto .git/hooks/pre-commit seuraavalla sisällöllä:

#!/bin/sh
 #
 # Generate module documentation in markdown format and add it
 # automatically to the commit
 /opt/puppetlabs/puppet/bin/puppet strings generate --format markdown 
 --out docs/INFO.md
 
 git add docs/INFO.md

Määritetään tiedosto käynnistyskelpoiseksi:

$ chmod 755 .git/hooks/pre-commit

Lopuksi tarkistetaan toimiiko pre-commit hook. Muokataan ensin jonkin luokan dokumentaatiota, ajetaan sille "git add" ja sen jälkeen "git commit". Kun commit on tehty, voidaan tarkistaa miten kävi:

commit 1ce00aa38fcc13471390a25c83f7c6ea2d59c430
 Author: Samuli Seppänen <[email protected]>
 Date: Tue Nov 20 10:09:58 2018 +0200
 
 Test pre-commit hook
 
 diff --git a/docs/INFO.md b/docs/INFO.md
 index da94769..4115ffd 100644
 --- a/docs/INFO.md
 +++ b/docs/INFO.md
 @@ -5,7 +5,7 @@
 
 **Classes**
 
 -* [`puppetmaster::common`](#puppetmastercommon): Common configurations for all scenarios as you see
 +* [`puppetmaster::common`](#puppetmastercommon): Common configurations for all scenarios as you see foobar
 * [`puppetmaster::common::r10k`](#puppetmastercommonr10k): r10k install and configure, but not run
 * [`puppetmaster::foreman_proxy`](#puppetmasterforeman_proxy): Class to setup Foreman smart proxy == Parameters: $foreman_proxy_foreman_base_url:: XXX $foreman_proxy_templates:: XXX $foreman_proxy_tem
 * [`puppetmaster::lcm`](#puppetmasterlcm): Class to setup Foreman with a Smart Proxy == Parameters: $foreman_db_password:: The password for the foreman database. $foreman_admin_firs
 @@ -21,7 +21,7 @@
 
 ### puppetmaster::common
 
 -Common configurations for all scenarios as you see
 +This class includes common configurations for all scenarios
 
 #### Parameters
 
 diff --git a/manifests/common.pp b/manifests/common.pp
 index df99c02..3c4bd9a 100644
 --- a/manifests/common.pp
 +++ b/manifests/common.pp
 @@ -1,4 +1,4 @@
 -# Common configurations for all scenarios
 +# This class includes common configurations for all scenarios 
 class puppetmaster::common
 (
 Array[String] $primary_names,

Stringsin luomaan markdown-tiedosto on helpointa pitää täysin erillään README.md:stä ja viitata siihen tähän tyyliin:

 Module documentation is available in [docs/INFO.md](docs/INFO.md).

Windowsin tapauksessa homma toimii lähes identtisesti muutamaa lisäkikkaa lukuun ottamatta. Alla oletetaan, että pakettien asennukseen on käytettävissä Chocolatey. Ensin käynnistetään Powershell admin-oikeuksin ja asennetaan Git:

PS> choco install -y git

Haluattaessa voidaan asentaa jokin järkevä tekstieditorikin, esim. Notepad++:

PS> choco install -y notepadplusplus

Seuraavaksi asennetaan puppet-strings Puppetin gemmillä:

PS> cd 'C:Program FilesPuppet LabsPuppetsysrubybin'
 PS> .gem install yard puppet-strings
 Fetching: yard-0.9.16.gem (100%)
 --- snip ---
 Successfully installed yard-0.9.16
 Parsing documentation for yard-0.9.16
 Installing ri documentation for yard-0.9.16
 Done installing documentation for yard after 12 seconds
 Fetching: rgen-0.8.2.gem (100%)
 Successfully installed rgen-0.8.2
 Fetching: puppet-strings-2.1.0.gem (100%)
 Successfully installed puppet-strings-2.1.0
 Parsing documentation for rgen-0.8.2
 Installing ri documentation for rgen-0.8.2
 Parsing documentation for puppet-strings-2.1.0
 Installing ri documentation for puppet-strings-2.1.0
 Done installing documentation for rgen, puppet-strings after 8 seconds
 3 gems installed

Sitten käynnistetään admin Powershell uudelleen, jotta saadaan järjestelmän polku päivitettyä ja siirrytään dokumentoitavan moduulin juureen:

PS> cd C:UsersSamulipuppet-puppetmaster

Seuraavaksi kirjoitetaan pre-commit skripti (".githookspre-commit.ps1") Powershellillä:

# Place this script to
 #
 # <module-dir>.githookspre-commit.ps1
 #
 puppet strings generate --format markdown --out docsINFO.md
 git add docs/INFO.md

Koska Git ei suoraan tue mitään muita kuin Bash-skriptejä, ei se aja em. skriptiä ilman ohutta Bash-wrapperiä (".githookspre-commit"):

#!C:/Program Files/Git/usr/bin/sh.exe
 #
 # This script goes to
 #
 # <module-dir>.githookspre-commit
 #
 exec powershell.exe -NoProfile -ExecutionPolicy Bypass -File "..githookspre-commit.ps1"

Bash-wrapper käyttää Gitin Windows-paketin mukana tulevaa Bashia, jonka voi yleensä olettaa olevan asennettuna jos Windowissa on ylipäätään Git.

Tämän jälkeen pre-commit hook toimii aivan samoin kuin Linuxissakin.

Edellisissä artikkeleissa käsiteltiin hallintarepoa ja r10k:ta. Vaikka mikään ei estäkään hallintarepon pitämistä Puppetmaster-koneella ja r10k.yaml:n osoittamista siihen, menetettäisiin silloin monta työvaihetta eikä ratkaisu siten sopisi tämän artikkelisarjan teemaan. Viimeinen puuttuva komponentti työnkulun läskiyttämisessä onkin GitLab tai vastaava, kuten GitHub tai Bitbucket. Näistä ensimmäinen soveltuu parhaiten tilanteeseen, jossa halutaan luoda paljon yksityisiä Git-repoja, joista ei haluta maksaa, eikä GitLabin edistyneemmille ominaisuuksille ole käyttöä. GitHubissa jokainen yksityinen repository maksaa, joten se on kallis ratkaisu yksityisten puppet-moduulien säilömiseen. Bitbucket sallii GitLabin tavoin rajoittamattomasti yksityisiä repositoryjä, mutta rajoittaa käyttäjien määrän tällä hetkellä viiteen, eikä tarjoa merkittävästi etuja, paitsi ehkä Trello-integraation, jos Kanbania haluaa käytellä. GitLabilla on puolellaan vielä se etu, että se on avointa lähdekoodia, joten sen voi asentaa myös omaan sisäverkkoon ja käyttää sieltä.

Työnkulku on GitLabin ja sen kaltaisten järjestelmien kanssa jokseenkin sama. Lisäksi valmisteluvaihe on jokseenkin identtinen:

Edellisessä artikkelissa kerrottiin, miten r10k konfiguroidaan käyttämään GitLabin kanssa oikeaa SSH-avainta eli "deploy keytä". Kun kaikki yllä mainitut valmistelut on tehty, voidaankin siirtyä varsinaiseen työnkulkuun, joka menee tyypillisesti näin.

Ensin käyttäjä päivättä oman hallintarepo-klooninsa production-haaran:

$ git branch
 * production
 $ git pull

luo paikalliseen hallintarepon klooniinsa uuden haaran (ns. "feature branch"):

$ git branch feature_a
 $ git checkout feature_a

Seuraavaksi hän tekee tarvittavat muokkaukset ja commitoi ("commit") muutokset:

$ git add <file>
 $ git commit -m "Add feature a"

Sitten hän julkaisee muutokset GitLabissa:

$ git push origin feature_a

Muutokset siis löytyvät nyt GitLab-reposityn haarasta feature_a.

Seuraavaksi käyttäjä tekee "Merge requestin" GitLabin käyttöliittymällä. Yleensä GitLab osaa valita oikean lähdehaaran automaattisesti, mutta jos näin ei ole, voi sen valita myös käsin. Merge requestin kohteeksi valitaan tyypillisesti production-haara, mutta mikään ei estä erillisen, pitkäikäisen testing tai staging-haaran käyttöä ennen production-haaraan siirtämistä.

Jonkun toisen käyttäjän olisi hyvä seuraavaksi tarkistaa Merge requestin sisältämät muutokset niiden laadun varmistamiseksi. Tässä vaiheessa on myös mahdollista ja jopa järkevää ajaa r10k Puppetmasterilla, jolloin se luo Puppet environmentin feature_a:

$ r10k deploy environment
 

Nyt uutta ominaisuutta ("feature_a") voi testata oikeilla Puppetiin liitetyillä koneilla tähän tapaan:

$ puppet agent -tv --environment=feature_a --noop

Testikoneilla komento voidaan turvallisesti ajaa myös ilman --noop -vipua.

Jos muutokset näyttävät hyviltä ja toimivat odotetulla tavalla, voi tarkistava käyttäjä liittää ("merge") ne hallintarepoon, jolloin ne päätyvät sen production-haaraan.

Seuraava ja viimeinen vaihe on uuden production-haaran sisällön vienti oikeasti tuotantoon r10k:lla:

$ r10k deploy environment
 

Sama prosessi toistetaan aina muutoksia tehdessä.

Jos (ja vain jos) Puppetia käyttää ainostaan yksi henkilö, voi merge requestit halutessaan unohtaa ja tarkistaa muutokset pelkästään Gitin omilla työkaluilla eli lähinnä "git diff"-komennolla. Erillisten feature-haarojen käyttö on kuitenkin perusteltua, koska se helpottaa uuden koodin testausta r10k:lla. Testien jälkeen muutokset voi liittää ("merge") production-haaraan ja julkaista suoraan:

$ git branch
 * feature_a
 production
 $ git push origin feature_a
 $ r10k deploy environment
 --- testaus ---
 $ git checkout production
 $ git merge feature_a
 $ git push

Artikkelisarjan muut osat:

menucross-circle