Cfengine Goodies

To content | To menu | To search

Friday 1 March 2013

CFEngine 3 :: satellite mail system with postfix

email_send.jpgBased on the work found at http://www.danstraw.com/ Simply install and configure a ghost postfix without dns MX, only with a external email account.

Continue reading...

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

Markdown to PDF

question.png

How to convert Markdown to PDF ?

answer.png

Install pandoc (you can use your package manager on linux)

Make sure that you have latex2pdf and bibliography packages if required installed (some packages of pandoc don't have these as required)

just run the pandoc command.

pandoc -o output.pdf input1.md input2.md

Add optionals such as

--toc for a Table of Contents
--bibliography mybibliography.bib for a Bibliography
--csl bibliographytemplate.csl for a particular Bibliography style
--template template.tex to use your own particular template

Then just wait a few seconds and you have your finalized PDF

Answered by Jonathan Mifsud

http://jonmifsud.com/blog/writing-in-markdown-and-converting-markdown-to-pdf/

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 -