Puppet-moduulit on melko helppo rakentaa siten, että ne saa helposti toimimaan eri käyttöjärjestelmissä ja käyttöjärjestelmäversioissa. Alla ovat itse hyväksi toteamani kolme korkea tason tapaa käyttöjärjestelmäerojen hallintaan kevyimmästä raskaimpaan:
- Params-luokan käyttö
- Käyttöjärjestelmäriippuvaisten aliluokkien käyttö
- Uuden moduulin rakentaminen
Menetelmillä 1 ja 2 pystyy käytännössä hallitsemaan kaikki Unix-tyyppisten käyttöjärjestelmien väliset erot. Menetelmää 3 ei juuri tarvita, paitsi jos jokin käyttöjärjestelmä (lue: Windows) eroa muista käytössä olevista huomattavan paljon.
Pieniin eroihin riittää siis params-luokan käyttö. Otetaan esimerkiksi vaikkapa Puppet-Finlandin ntp-moduuli:
class ntp::params { include ::os::params case $::osfamily { 'RedHat': { $driftfile = '/var/lib/ntp/ntp.drift' $service_name = 'ntpd' } 'Debian': { $driftfile = '/var/lib/ntp/ntp.drift' $service_name = 'ntp' } 'FreeBSD': { $driftfile = '/var/db/ntpd.drift' $service_name = 'ntpd' } default: { fail("Unsupported operating system ${::osfamily}") } } if str2bool($::has_systemd) { $service_start = "${::os::params::systemctl} start ${service_name}" $service_stop = "${::os::params::systemctl} stop ${service_name}" } else { $service_start = "${::os::params::service_cmd} ${service_name} start" $service_stop = "${::os::params::service_cmd} ${service_name} stop" } }
Yllä oleva params-luokka mahdollistaa saman moduulin käytön Debianissa, Ubuntussa, RedHatissa ja FreeBSD:ssä. Lisäksi se huolehtii faktan $::has_systemd avulla myös siitä, etteivät systemd:n ja vanhempien init-järjestelmien erot aiheuta ongelmia. Osa muuttujista, kuten service_cmd ja systemctl, noudetaan moduulista os, koska niiden toistaminen jokaisessa moduulissa erikseen ei olisi järkevää. Yllä default-lohkossa oleva fail()-funktion kutsu varmistaa lisäksi sen, ettei moduulia voi ladata kuin sellaisessa käyttöjärjestelmässä, jossa sen voi olettaa toimivan.
Params-luokassa määritettyjen muuttujien käyttö edellyttää, että params-luokka on ladattu siinä vaiheessa, kun sitä tarvitaan. Tähän on ainakin kaksi tapaa, joista itse suosin perintää (inherits, alla):
class ntp::service inherits ntp::params { service { 'ntp': name => $::ntp::params::service_name, enable => true, require => Class['ntp::config'], } }
Toinen vaihtoehto olisi lisätä rivi
include ::ntp::params
heti luokan alkuun.
Params-luokan muuttujiin on syytä viitata aina koko niiden polulla:
- $::ntp::params::service_name
- $::os::params::service_cmd
Näin vältytään epämääräisiltä ongelmilta, jos vaikkapa saman niminen muuttuja on määritelty sekä params-luokassa, että sitä käyttävässä luokassa.
Blogisarjan seuraavassa osassa käsitellään käyttöjärjestelmäkohtaisia aliluokkia.