Cfengine Goodies

To content | To menu | To search

Thursday 28 February 2013

CFEngine 3 :: syslog client

syslog.jpg Simple example to send syslog messages to the policy_hub (errors can be declared in a logdict service error catalog) :

CFEngine code :

Continue reading...

Tuesday 26 February 2013

CFEngine 3 :: From csv to service_catalog

engine.jpg When you have service catalog datas from #1, we can organize then to feed service with this bundle (first field is the name of the array in accordance with meta service definition constraints):

CFEngine code :

Continue reading...

Monday 25 February 2013

CFEngine 3 :: sys_name_resolution service & convergence #2

Instead of using persistence classes like #1 to avoid dangerous deletion and preserve convergence, it is easier to use inheritance of classes.

CFEngine code:

Continue reading...

Friday 15 February 2013

CFEngine 3 :: convergent set of files in a directory

The important parts are :


1) '.*' anchored regexp in the files promise stops at the first '/' encountered, excluding '.' and '..'
2) ex_list body take @() syntax
3) we maintain the files we want in a convergent way with edit_line, and flush the others at the same FS level.

Further reading @cfengine.com


 bundle agent example(prefix,params)
{
vars:
"dest_dir" string => "/tmp";
"filenames" slist => { "file1", "fileN" };

files:
"$(dest_dir)/.*"
file_select => ex_list(@(filenames)),
delete => tidy;

"$(dest_dir)/$(filenames)"
create => "true",
edit_line => edit_whatever_body("$(prefix)","$(catalog)", "$(whatever_params)"),
edit_defaults => empty;

}

bundle edit_line edit_whatever_body(prefix,catalog,name)
{
insert_lines:
"# File Managed by CFEengine $(sys.cf_version)";
"$($(catalog)[$(name)][type]) $($(catalog)[$(name)][url]) $($(catalog)[$(name)][release]) $($(catalog)[$(name)][components])";
}

CFEngine 3 :: csv concatenation

If your service catalog datas are stored in csv files and depend on architecture contexts, you can use this concat function.

bundle agent function_meta(prefix,params)
{

  vars:

    any::
      # variables
      "$(prefix)confidx"       slist   => getindices("$(prefix)_vars.conf");
      "$(prefix)mainfile"      string  => "$(globals.dir_cache)/main/$(prefix)/config.csv";
      "$(prefix)archfile"      string  => "$(globals.dir_cache)/$(architectures_vars.architecture_name)/$(prefix)/config.csv";
      "$(prefix)concatfile"    string  => "$(globals.dir_cache)/main/$(prefix)/concat.csv";
      # readfile
      "$(prefix)len"           int     => readstringarrayidx("$(prefix)meta","$($(prefix)concatfile)","\s*#[^\n]*",";",99,999999);

    architecture_defined::
      "concatlist"    slist   => { "function_meta.$(prefix)mainfile", "function_meta.$(prefix)archfile" };

    !architecture_defined::
      "concatlist"    slist   => { "function_meta.$(prefix)mainfile" };

  files:

        "$($(prefix)mainfile)"
            create      => "true",
            copy_from => u_dcp("$(globals.resources_location)/main/$(prefix)/config.csv");

        "$($(prefix)archfile)"
            create      => "true",
            copy_from   => u_dcp("$(globals.resources_location)/$(architectures_vars.architecture_name)/$(prefix)/config.csv"),
            ifvarclass  => "architecture_defined";

        "$($(prefix)concatfile)"
            create        => "true",
            edit_defaults => empty,
            edit_line     => concatWith(@(this.concatlist));

  reports:

    verbose::
      "$(prefix)::$(this.bundle) csv file :: $(function_meta.$(prefix)concatfile)";
}

bundle edit_line concatWith(file)
{

  insert_lines:

    "$($(file))"
      insert_type    => "file_preserve_block",
      expand_scalars => "false";
}

Wednesday 13 February 2013

CFEngine 3 :: sys_name_resolution service & convergence

You can avoid dangerous deletion by using persistence classes definition and preserve convergence.

Example with comma-separated strings

Continue reading...

Monday 4 February 2013

CFEngine 3 :: delete non managed values

In etc_host sketch, a (regex) list of ips passed to delete_nonmanaged bundle to delete lines do not match ips or are not comments.

caller :

edit_line   => cfdc_etc_hosts:delete_nonmanaged("@(configure.ip)"),

delete_nonmanaged bundle:

bundle edit_line delete_nonmanaged(ips)
{
  vars:
      "regex" string => join ("|", "ips"),
      comment => "Or the escaped ips together so we can delete all others.";

  delete_lines:
      # This is the negative look ahead, and what would need tweaked
      # if you don't like the behavior. Specifically it's identifying
      # our list of ips followed by a space, as well as # comment or
      # localhost and deleting everything else

      "^(?!(\#|127\.0\.0\.1|\:\:1|$(regex))\s.*).*$"
      comment => "Delete lines do not match our ips or are not comments";
}

Friday 1 February 2013

CFEngine 3 :: dynamic bundle parameters #2

instead of using string type #1 to define parameters, you also can use list @() as parameters :

body common control
{
      bundlesequence => {
                          "test_vars",
                          test(@(test_vars.params)),
                        };
}

bundle common test_vars
{

  vars:

   # declare
   "types"
     slist  => { "show", "action" };
   "params"
     slist  => maplist("$(this.bundle).$(this)", "types");

   # define
   "$(types)[version]"
     string => "$(types)_0.1";
   "show[other]"
     string => "other_value";
}

bundle agent test(params)
{

  vars:

   "bundle[$(params)]"
     string => lastnode("$(params)", "\.");

  services:

    "function_$(bundle[$(params)])"
      service_policy => "start",
      service_method => bundle_handler("$(params)");
  reports:

    linux::
      "params : $(params)";
}

body service_method bundle_handler(s)
{
    service_bundle            => $(this.promiser)("$(s)");
}
bundle agent function_show(a)
{

  vars:

    "index"
      slist => getindices("$(a)");

  reports:

    cfengine_3::
      "$(this.bundle) :: $(index) = $($(a)[$(index)])";
}

bundle agent function_action(a)
{

  reports:

    cfengine_3::
      "$(this.bundle) :: version = $($(a)[version])";
}

In action :

# cf-agent -f ./test_listdynparam.cf
R: function_show :: other = other_value
R: function_show :: version = show_0.1
R: function_action :: version = action_0.1
R: params : test_vars.show
R: params : test_vars.action

Wednesday 30 January 2013

CFEngine 3 :: dynamic bundle parameters

Edit : use list __@()__ as parameters

body common control
{
      bundlesequence => {
                          "test_vars",
                          test("$(test_vars.params)"),
                        };
}

bundle common test_vars
{

  vars:

   # declare
   "conflist"
     slist  => { "show", "action" };
   "paramlist"
     slist  => maplist("$(this.bundle).$(this)", "conflist");
   "params"
     string => join(",", "paramlist");

   # define
   "$(conflist)[version]"
     string => "$(conflist)_0.1";
   "show[other]"
     string => "other_value";
}

bundle agent test(params)
{

  vars:

   "str"
     string => "$(params)";
   "paramlist"
     slist  => splitstring("$(str)",",", "10");
   "bundle[$(paramlist)]"
     string => lastnode("$(paramlist)", "\.");

  services:

    "function_$(bundle[$(paramlist)])"
      service_policy => "start",
      service_method => bundle_handler("$(paramlist)");
}
body service_method bundle_handler(s)
{
    service_bundle            => $(this.promiser)("$(s)");
}

bundle agent function_show(a)
{

  vars:

    "index"
      slist => getindices("$(a)");

  reports:

    cfengine_3::
      "$(this.bundle) :: $(index) = $($(a)[$(index)])";
}

bundle agent function_action(a)
{

  reports:

    cfengine_3::
      "$(this.bundle) :: version = $($(a)[version])";
}

In this example, the bundle test_vars declare and define test parameters and test bundle use services promise type to call function bundle with the function specific parameters

# cf-agent -f ./test_dynparam.cf
R: function_show :: other = other_value
R: function_show :: version = show_0.1
R: function_action :: version = action_0.1

Tuesday 29 January 2013

CFEngine 3 :: name of array passed as a parameter

body common control
{
      bundlesequence => {
                          "test_vars", test("test_vars.conf"),
                        };
}

bundle common test_vars
{

  vars:

   "conf[version]"
     string => "0.1";
}

bundle agent test(params)
{

  vars:

   "array_name"
     string  => lastnode("$(params)", "\.");
   "$(array_name)[version]"
     string  => "0.2";

  reports:

    Yr2013::
      "In bundle $(this.bundle) array_name is $(this.array_name) and version is $($(array_name)[version])";

}

In this example, the test bundle receives as argument a variable called params, which (must) contains the name test_vars.conf ( <bundle_name>.<array_name>) lastnode("$(params)", "\.") return the name of array.

You can use this name to define a modified test.conf array.

# cf-agent -f ./unit_lastnode.cf
R: In bundle test array_name is conf and version is 0.2

Friday 11 January 2013

CFEngine 3 :: regextract

How to define variables after command extraction :

A command :

"/sbin/ip -4 -o address list"

, a PCRE filter :

"^[^:]*: ([^\s]+).*inet (\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}).*$"

and cfengine (interface) variables definition.

  • CFEngine 3 test:
# cf-agent -I -f ./test_regextract.cf
R: eth0, 192_168_1_1
# cat ./test_regextract.cf
body common control
{
    any::
        bundlesequence  => { test };
}

bundle agent test {

  vars:

   "ifaces"
     string => execresult("/sbin/ip -4 -o address list", "noshell");
   "ifacelist"
     slist  => splitstring( ${ifaces}, "$(const.endl)","100");
   "interface"
     string => canonify("$(device[1])");
   "ip"
     string => canonify("$(device[2])");

  classes:

    "$(ifacelist)"
      expression => regextract("^[^:]*: ([^\s]+).*inet (\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}).*$", "$(ifacelist)", "device");

  reports:

    cfengine_3::
      "$(interface), $(ip)";
}

Becareful, the name is misleading, because PCRE and Perl each have capabilities not shared by the other.

Friday 4 January 2013

CFEngine 3 :: sys.interface variable

https://cfengine.com/manuals/cf3-Reference#Variable-sys_002einterface says:

The assumed (default) name of the main system interface on this host.
# interface = eth0

What is "The assumed (default) name of the main system interface on this host."

CFEngine use traditional ioctl(SIOCGIFCONF) by skipping loopback interface.

  • CFEngine 3 test:
# cat test_sys_interface.cf
body common control
{
    any::
        bundlesequence  => { "test" };
}
bundle agent test
{
 reports:

 cfengine_3::
  "sys.interface is [$(sys.interface)]";
}
# cf-agent -f ./test_sys_interface.cf
R: sys.interface is [eth0]

Continue reading...

Friday 19 October 2012

In cfengine, we trust ;)

ohloh.png

Sunday 24 June 2012

2 new bodies for .INI files

bundle edit_line manage_variable_values_ini(tab, sectionName)

bundle edit_line set_variable_values_ini(tab, sectionName) 

source on github

Monday 5 March 2012

new hard classes [arch]

in order to make a difference between native 32 et 64 architectures :

"32_bit", "64_bit"

from : source trunk
http://source.cfengine.com/websvn/diff.php?repname=Cfengine+core&path=%2Ftrunk%2Fsrc%2Fenv_context.c&rev=4121&peg=4121


Monday 20 February 2012

le port de cfengine

Le client cf-agent utilise /etc/services pour avoir le port tcp cfengine.
Le nom du service est defini dans cf.defs.h:#define CFENGINE_SERVICE "cfengine"
Pour paramétrer un port client different :
. definir CFENGINE_SERVICE "cfengine3"
. definir le port de cfengine3 dans /etc/services

merci a cyril jovet pour la lecture du code.

Monday 13 February 2012

updates and failsafe.cf

question.png Shouldn't the copy go the other way around?

I'm a little confused about the update process for binaries. I'm using the latest svn. It looks like the included failsafe.cf will constantly overwrite any updates I install in /usr/local/sbin because of the following:

  "/usr/local/sbin"                                                            
                                             
          comment => "Ensure cfengine binaries were copied to /usr/local/sbin",
           handle => "update_files_usr_local_sbin",
            perms => u_m("755"),
        copy_from => u_cp_nobck("$(sys.workdir)/bin"),
      file_select => u_cf3_files,
     depth_search => u_recurse("1"),
           action => u_immediate;

Shouldn't the copy go the other way around? Everything else seems so well thought out I thought I'd ask here before fixing it.

Overall though, I love the new bootstrap process.

Asked by elwood

answer.png

Basically it puts a copy of /var/cfengine/bin files to /usr/local/sbin, which is the expected behaviour. A reason behind this is to have all cf-* binaries available in $PATH for the convenience.

One would argue that it would be enough to have a symlinks in /usr/local/sbin pointing back to /var/cfengine/bin. Probably it would, but for the time being it's the full copy.

Answered by Mikhail Gusarov

http://www.mail-archive.com/help-cfengine@cfengine.org/msg08617.html

page 2 of 2 -