LPS:CFEngine3/hands-on

Z HelpDesk

Instalace

echo "deb http://cfengine.com/pub/apt stable main" >> /etc/apt/sources.list
echo "deb http://download.zcu.cz/public/software/linux/debian stable main" >> /etc/apt/sources.list
apt-get update
apt-get install cfengine-community vim-syntax-cfengine3

Struktura .cf

Co lze v souboru potkat:

  • bundle: sbirka promises (slibu)
  • typ bundle: podle toho co chci delat, lisi se povolenymi atributy a cilem (definice promennych, trid, sprava souboru, sprava baliku, reporty, ...)
  • body: sbirka atributu (mozno parametrizovat)
  • funkce: nekdy vraci hodnotu, jindy tridu, nekdy delaji neco jineho, pouzivaji se v atributech slibu

Common:

  • body common control: odrazovy mustek pro programy
  • bundle common *: globalni (pro vsechny programy), promenne a tridy v nem nastavene jsou globalni, v jinych bundlech pouze lokalni, ale lze se na ne odkazat pres nazev bundle

bundlesequence vs. usebundle:

  • bundlesequence je pevne dane v 'body common control', nelze uz menit, je to dobry start pro inicializaci
  • usebundle je dynamicky a lze predavat parametry, navratove hodnoty lze, ale je to problematicke, je mozne na zaklade trid prorezavat a tim zrychlit beh

Ukázkové bundly

Spousta příkladů:

/var/cfengine/share/doc/examples/

Hello world: test1.cf

body common control {
  bundlesequence => {"main"};
}

bundle agent main {
reports:
  verbose::
    "Hello World";
}
cf-agent -Kf ./test1.cf 
cf-agent -Kf ./test1.cf -D verbose
2014-03-18T17:11:18+0100   notice: R: Hello World

Soubor: test2.cf

body common control {
  bundlesequence => { "main" };
}

bundle agent main {
vars:
  any::
    "file"
      string => "/tmp/cftest.txt";

classes:
  any::
    "file_exists"
      expression => fileexists("$(file)");

files:
  any::
    "/tmp/cftest.txt"
      create => "true",
      classes => if_repaired("file_created");

reports:
  file_exists::
    "Soubor existuje";

  file_created::
    "Soubor byl vytvoren";
}

cf-promises -cf ./test2.cf
./test2.cf:20:0: error: Undefined body if_repaired with type classes

Ukradneme z /var/cfengine/share/CoreBase/lib/3.5/common.cf

body classes if_repaired(x)
{
  promise_repaired => { "$(x)" };
}
cf-promises -cf ./test2.cf
cf-agent -KInf ./test2.cf
cf-agent -KInf ./test2.cf


Implicitní cyklus: test3.cf

body common control{
  bundlesequence  => { "example" };   
}

bundle agent example {
vars:
  any::
    "v[index_1]" string => "value_1";
    "v[index_2]" string => "value_2";

    "x" slist => getindices("v");
    "y" slist => getvalues("v");

reports:
  any::
    "All indices:";
    "  Found index: $(x) with value \"$(v[$(x)])\"";
    "All values:";
    "  Found value: $(y)";
    "Kombinace $(x) $(y)";
}

Proměnné třídy: test4.cf

body common control {
  bundlesequence => { "example" };
}

bundle agent example {
vars:
  any::
    "distro" slist => { "redhat", "debian", "suse", "leopard" };
    "os"     slist => { "linux", "solaris", "windows" };

reports:
  any::
    "Tento system je na operacnim systemu ${os} s distribuci ${distro}."
      ifvarclass => "${distro}.${os}";

    "Toto NENI ${os} na distribuci ${distro}"
      ifvarclass => "!(${distro}.${os})";
}

První kontakt

cf-agent --bootstrap cf.civ.zcu.cz

Co jsme získali?

ls /var/cfengine/inputs
ls /var/cfengine/masterfiles

Jak udělat změnu

Příprava gitu

apt-get install git
git config -l
git config --global user.name "Tvoje Jmeno"
git config --global user.email tvuj_login@civ.zcu.cz

Klon

cd /root
git clone file:///afs/zcu.cz/project/software/git/cfengine.git cf
cd cf
git checkout production
git branch --set-upstream production origin/production

Změna v gitu a propagace

cd /root/cf
git checkout -b zmena
git branch
vim file.cf
cf-promises -cf ./promises.cf
cf-agent -KnIf ./promises.cf 
git status
git commit file.cf
git checkout master
git merge zmena 
git push
git checkout production
git merge zmena 
git push

Struktura masterfiles

Vychází se z předpokladu, že nejnovější je vždy vývojová větev, proto by neměl být problém "upgradnout" z production do master:

  1. Stroj si stáhne minimální konfiguraci z cf:/var/lib/cfengine/masterfiles/*
  2. Spustí update.cf, který stáhne cf:/var/lib/cfengine/masterfiles_branches/production/*
  3. Spusti update.cf, pokud zjistí, že má používat testovací větev, stáhne cf:/var/lib/cfengine/masterfiles_branches/master/*

Jak budou řešeny učebny ještě není úplně rozhodnuto, ale budou mít samostatný GIT repozitář.

Kořen

ls /root/cf/
  • update.cf: samostatný, nezávislý kód (vyjma def.cf), pouští se před promises.cf a má za úkol aktualizovat úložiště
  • promises.cf: 'main" odkud se řídí zpracování (def.cf, lib, inventory, services, ...)
  • def.cf: definuje větev, defaultně 'production', vyjmenované stroje mají 'master'
  • hosts.cf: definuje skupiny převážně dle hostname
  • services.cf: rozstřel pro služby na základě tříd definovaných z inventáře, def.cf a hosts.cf
  • ...

lib vs. zculib

Standardní a naše funkce. Děleny podle typu promise (files, packages, ...) nebo logiky. Zpracovávají se jako jedny z prvních.

inventory vs. zcuinventory

Spouští se před začátkem služeb, mají za úkol nastavit globální třídy na základě stavu stroje a jeho HW.

services

Sbírka politik podle služeb a skupin, které provozujeme. Používá se jednotné pojmenování:

services/SLUZBA/SLUZBA.cf => z promises.cf volá 'bundle agent SLUZBA'
services/SLUZBA/PODSLUZBA.cf => bundle agent SLUZBA_PODSLUZBA, bundle agent SLUZBA_PODSLUZBA_DETAIL

Například v services/kerberos/kerberos.cf:

bundle agent kerberos
{
methods:
  any::
    "any" usebundle => kerberos_config,
      comment => "Spravuje /etc/krb5.conf";

    "any" usebundle => kerberos_k5login,
      comment => "Spravuje /root/.k5login soubor";

}

Bundl 'kerberos_k5login' je v souboru services/kerberos/k5login.cf, zde se volají již specifické bundly 'kerberos_k5login_allow' (možno dát i do samostatného souboru k5login_allow.cf).

files

Obdobná struktura jako ve FAI pro fcopy. Definováno v zculib/fcopy.cf, lze volat

fcopy(cesta, verze) => vždy aktualizuje z repozitáře
fcopy_add(cesta, verze) => jen pokud neexistuje cílový soubor

Log o kopírování je vždy generován.

Použití např. v services/kerberos/config.cf:

bundle agent krb_config
{
methods:
  any::
    "any" usebundle => fcopy("/etc/krb5.conf", "default");

}


modules, templates

Zatím nebylo potřeba použít.