dcsimg

Intro to Automating System Administration with Cfengine 3

Take some of the headaches out of managing sever farms with Cfengine 3. Use this automation introduction to save time, money and spare yourself crippling manual mistakes.

Here we see that the Perl Compatible Regular Expression (PCRE) library is being used. Success.

At this point you could do a make install, as root of course, and the binaries and support files will be installed into the default prefix of /usr/local unless you’ve change it. There is however another option.

Instead of using ‘make install’ you could manually install the files and have Cfengine keep them up to date for you. For example we often manually install the binaries into /var/cfengine/bin and the man pages into standard /usr/share/ man. We also keep copies of these files in our masterfiles repository. Then we configure promises in Cfengine to ensure that the files on client hosts match the files in the masterfiles repository. Using this method we are able to build new binaries once, copy them to masterfiles and Cfengine will automatically distribute them to all of our client hosts.

The basic grammar of Cfengine 3 looks like this:

type:
	classes::

	 "promiser" -> { "promisee1", "promisee2", ... }

		attribute_1 => value_1,
		attribute_2 => value_2,
		...
		attribute_n => value_n;

A class is a built-in if/then test, and if it is specified, the rule will hold only if that class is true for that machine. Examples of built-in classes can be: “Linux”, “Solaris”, “CentOS”, “Thursday”, “2:00am-3:00am”, a particular IP address on the host, etc. Examples of user-defined classes can be “database server” or all machines administered by our department.

Example: Hello World. 

commands:

        "/bin/echo hello world";

The promise type is “commands”, the promiser is the command string.

List of promise types

  • commands – Run external commands
  • files – Handle files (permissions, copying, etc.)
  • edit_line – Handle files (content)
  • interfaces – Network configuration
  • methods – Methods are compound promises that refer to whole bundles of promises.
  • packages – Package management
  • processes – Process management
  • storage – Disk and filesystem management

Another simple example: 

files:

"/tmp/test_plain" -> "John Smith",

	comment => "Make sure John's /tmp/test_plain exists",
	create  => "true";

Here we have the promisee on the right of the -> sign.

The promisee is “the abstract object to whom the promise is made”. This is for documentation. The commercial version of cfengine uses promisees to generate automated knowledge maps. The object can be the handle of another promise, recognizing an interest in the outcome, or an affected person who you might want to contact in case of emergency.

Example of a handle (id tag): 

files:

   "/tmp/test_plain" -> "John Smith",

		handle => "file_check",
		comment => "Make sure John's /tmp/test_plain exists",
		create  => "true";

Documenting a dependency with a handle: 

files:

  "/tmp/testcopy"

    depends_on    => { "file_check" },
    copy_from     => mycopy("/tmp/test_plain");

These are contrived examples; they document John Smith as somehow involved in this activity and show how handles can be used to document dependencies.

The above are not working examples. But this is, and you can run it to get familiar with Cfengine 3:

Make sure /tmp/test_plain exists. 

########################################################
body common control

{
version => "1.0";
bundlesequence  => { "test1"  };
}

########################################################

bundle agent test1

{

    files:

       "/tmp/test_plain" -> "John Smith",

            comment => "Make sure /tmp/test_plain exists",
            create  => "true";

}

First is the mandatory control section, where you can set certain values, and specify which promise bundles to run.

The next section is a promise bundle, which means a group of one or more promises. The bundle type is “agent” which means it will result in action on the part of Cfengine, or will be picked up by the Cfengine agent when it runs (cf-agent).

Each promise bundle has a name, and that name is referenced in bundlesequence in control.

Thus the above promise bundle is a promise that /tmp/test_plain exists; and specifies John Smith as an involved party.

Put the above in test.cf and run it with

cf-agent -f test.cf

If the file does not exist, Cfengine will create it.

Promise that ntpd and portmap are running. 

body common control

{
version => "1.0";
bundlesequence  => { "check_service_running"  };
}

bundle agent check_service_running

{
    vars:
        "service" slist => {"ntpd", "portmap"};
        "daemon_path" string => "/etc/init.d";

    processes:

            "${service}"
                comment => "Check processes running for '${service}'",
                restart_class => "restart_$(service)";

    commands:

        "${daemon_path}/${service} start"
            comment => "Execute the start command for the service",
            ifvarclass => "restart_${service}";

}

This uses variables (lists and strings); and when cf-agent hits the ${service} variable, which is a list, it loops over the list. This implicit looping is part of the power of Cfengine.

Promise content of /etc/resolv.conf. 

body common control
{
    version => "1.0";
    bundlesequence  => { "checkresolver" };
}

bundle agent checkresolver
{
    vars:

          "resolvers" slist => { "128.39.89.10", "158.36.85.10", "129.241.1.99" };

    files:

          "${sys.resolv}"

               edit_line => resolvconf("iu.hio.no cfengine.com",@{checkresolver.resolvers});
}

bundle edit_line resolvconf(search,list)
{
    delete_lines:

        "search.*";

    insert_lines:

         "search ${search}";
         "${list}";
}

“body common control{}” is the control promise body, which affects the operational behavior of Cfengine. In it, we define a version string, used in errors and reports.

Next we have a promise bundle “checkresolver{}” which uses:

  • An “slist”, a list of scalar strings,
  • “${sys.resolv}”, a system variable (built in to Cfengine) that containes the path to our resolv.conf file.
  • checkresolver{} calls the promise bundle “resolvconf{}” which is of the editline promise type. Cfengine has built-in functionality for editing files, as this is a common system administration task, and editlines promises handle that. For example:
    • “delete_lines promise” will make sure we don’t end up with duplicate “search” lines which would be invalid for /etc/resolv.conf.
    • The “insert_lines” promise will make sure the file contains the specified data, which are a string (the search path) and an array (list of resolvers).

Note: we have to reference the @resolvers array using its full name, @checkresolver.resolvers, otherwise resolvconf will fail to find a @resolvers array within its own scope. The @resolvers array is in the scope of “checkresolver{}”.

You may have noticed the above Cfengine configuration is in two kinds of parts: a body or a bundle. What are they?

Bundle: A promise bundle is a collection of promises.

Body: A promise body is the part of a promise which details and constrains its nature. The body of a promise explains what it is about. Think of the body of a contract, or the body of a document. Cfengine “body” declarations divide up these details into standardized, paramaterizable, library units, so we can just write:

Snippet example of cf-agent client copying a file from cf-serverd (not a full working example). 

body copy_from my_secure_cp(from,server)
{
source      => "$(from)";
servers     => { "$(server)" };
compare     => "digest";
encrypt     => "true";
verify      => "true";
force_ipv4  => "false";
collapse_destination_dir => "false";
copy_size => irange("0","50000");
findertype => "MacOSX";
# etc etc
}

Think of the declarations in the promise as:

(cfengine-word) ⇒ (user-data-pattern)
body cfengine-word user-data-pattern
{
details
}

Working example of copying a file with cfengine, call it test_copy.cf. 

body common control
{
bundlesequence ⇒ { "testcopy" };
version ⇒ "1.2.3";
inputs ⇒ { "library.cf" };
}

bundle agent testcopy
{
files:
"/home/aleksey/testcopy1"
copy_from ⇒
my_copy_body_with_options("/home/aleksey/testcopy2","192.168.1.10");
}
body copy_from my_copy_body_with_options(sourcefile,sourceserver)
{
source ⇒ "$(sourcefile)";
servers ⇒ { "$(sourceserver)" };
copy_backup ⇒ "true";
purge ⇒ "true";
trustkey        ⇒ "true";
compare     ⇒ "digest";
encrypt     ⇒ "true";
verify      ⇒ "true";
force_ipv4  ⇒ "false";
collapse_destination_dir ⇒ "false";
copy_size ⇒ irange("0","50000");
# etc. etc.
}

Note: In order to get this example to work, we had to:

Modify “runagent control{}” and “server control{}” in promises.cf to remove mention of localhost (127.0.0.1 and ::1), replacing them with the IP address of the primary interface of 192.168.1.10.

Modify “server control{}” in promises.cf to add a non-root user to “allowusers” because we were running cf-serverd as a non-root user.

Here is the part of promises.cf we modified: 

body runagent control
{
hosts => {
          "192.168.1.10"
          # , "myhost.example.com:5308", ...
         };

}

#######################################################

body server control

{
allowconnects         => { "192.168.1.10" };
allowallconnects      => { "192.168.1.10" };
trustkeysfrom         => { "192.168.1.10" };

# make updates and runs happen in one

cfruncommand          => "$(sys.workdir)/bin/cf-agent -f failsafe.cf &&
$(sys.workdir)/bin/cf-agent";
allowusers            => { "root" , "aleksey" };
}

We also had to modify “server access_rules{}” in site.cf to set up the ACL to allow the file transfer. Running cf-serverd in verbose mode with debugging set to 1 will show more information about how the server handles requests.

Here are our changes to site.cf: . 

#######################################################
# server configuration
#######################################################

bundle server access_rules()
{
access:

  "/home/aleksey/testcopy2"

    admit   => { "192.168.1.10" };

roles:

  ".*"  authorize => { "aleksey" };
}

Generate a keypair for our cf-serverd:

cf-key

Start cf-serverd in verbose (non-forked) mode, debug level 1:

cf-serverd -v -d 1

Run our example code to copy the file from cf-serverd:

cf-agent -v test_copy.cf -k

More Information

cfengine contains far more features that we can touch upon in just this one introduction. To learn more about cfengine and how you can put it to use, check out the following resources:

Learning More

There will be a full day of Cfengine training at the LISA system administration conference in Boston in December 2011 http://www.usenix.org/event/lisa11/

Comments on "Intro to Automating System Administration with Cfengine 3"

We like to honor several other web internet sites around the internet, even if they aren?t linked to us, by linking to them. Underneath are some webpages worth checking out.

Desmoxan obrobiony na bazie cytozyny zwalcza niedosyt nikotynowy, przeciwdzia?a materialnej potrzebie zawleczenia dymkiem, od której ekstremalnie uwalnia w toku 25 dni. Tak p?ytki period zmaga? z na?ogiem istnieje mo?ebny,dzi?ki zdobyciu w?a?ciwego rz?du dopaminy, lub przydatnego neuroprzeka?nika w rozumu. Ju? pi?tego dnia terapii kapsu?kami Desmoxan wykluczamy wnikliwie blanty ze swojego menu.O mule po zwyci?stwu z na?ogiem onemu b?dziemy nu?e wypala?, skutek powinien zosta? wytrzyma?y.Odr?bnym zagadnieniem s? sprawiania niewarto?ciowe spojone ze stosowaniem preparatu, które najci??ej mog? przynosi? si? we ?lady na ta? starciu wojny z nikotyn?. Jak odczytujemy w ulotce, Desmoxan zdo?a przysporzy? si? do m?czliwo?ci, ?zawienia oczach,wacht nastroju, k?opotów ze spaniem, post?pu apetytu oraz rang.Nie powinni?my tak?e istnie? zaskoczeni w kazusie bólu lub zawrotów ?epetyny, bólu mi??ni, zaburze? szwungu serca, ?upie?y ci?nienie farby, dolegliwo?ci ze strony rozk?adu ?ywno?ciowego, spadku libido, obni?enia elastyczno?ci ?upiny, b?d? pojawienia si? nasilonej potliwo?ci, lub odczynów futbolówki, gdy np.wysypka. Z medykamentem Desmoxan zdo?aj? tak?e zwi?zywa? si? zaburzenia gustu, duszno??, odkrztuszanie b?d? pieczenie j?zyka.

When I origina?ly commented I clicked the “Notify me when new comments are added” checkbo? and no? each time a comment is added I get several mail? with the same comment.Is there aany way y?u can remove me f?dom that serv?ce?Many thanks!My web-s?te: ??? ??????? ? ??????

Forstres Produkt wyznaczony istnieje figurom o ciemnym sposobie mieszkania, zadziwiaj?co nara?onych na stres.Forstres niesie kompozycj? stosownie zharmonizowanych wyci?gów ro?linnych, który wspomaga ustrój w kondycjach stresowych, udokumentowany w magnez za? wit.B6 , które s? bardzo poka?ne w klasach zm?czenia i znu?enia.

Leczenie nak?onienia dzi?se? otacza kardynalnie przechowywanie higieny jamy ustnej, s?uszny dobór ?rodków sanitarnych (faringosept) , przemywanie ust pomyœlnymi naparami natomiast p?dzlowanie olejkami duchowymi.Gdy cho? pojawi si? zanieczyszczenie, to cz?sto poradzi? wolno sobie z nim we krajowym charakterze. Dokona? owego wolno, chocia?by poprzez wykorzystanie z preparatu odka?aj?cego, jakim istnieje faringosept. Hamuje on rozwój bakterii, które cz?sto s? powa?ne za zanieczyszczenia jamy ustnej natomiast gard?a.Also visit my web blog … http://flora-bakteryjna.pl/faringosept-zapalenie-dziasel/

Leave a Reply