Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
amousset committed Oct 15, 2018
1 parent 0c878a8 commit 8c71954
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 18 deletions.
68 changes: 68 additions & 0 deletions tests/acceptance/20_cfe_basics/flag_lib.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#######################################################
#
# Test flag_lib
#
#######################################################

bundle common acc_path
{
vars:
"root" string => getenv("NCF_TESTS_ACCEPTANCE", 1024);
}

body common control
{
inputs => { "${acc_path.root}/default.cf.sub", "${acc_path.root}/default_ncf.cf.sub", "@{ncf_inputs.default_files}" };
bundlesequence => { configuration, initialization, default("${this.promise_filename}") };
version => "1.0";
}

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

bundle agent init {
methods:
"clean" usebundle => file_absent("/tmp/flags.json");
}

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

bundle agent test
{

methods:
"read before"
usebundle => get_flag("test"),
useresult => "free1";
"reserve"
usebundle => reserve_flag("test");
"read after"
usebundle => get_flag("test"),
useresult => "free2";
# "reserve twice"
# usebundle => reserve_flag("test");
# "read after second"
# usebundle => read_flag("test"),
# useresult => "free3";
"set flag"
usebundle => set_flag("test");
"read after set"
usebundle => get_flag("test"),
useresult => "free4";
}

bundle agent check
{
classes:
"ok_1" expression => strcmp("${test.free1[1]}", "free");
"ok_2" expression => strcmp("${test.free2[1]}", "set");
"ok_4" expression => strcmp("${test.free4[1]}", "set");

"ok" expression => "ok_1.ok_2.ok_4";

reports:
ok::
"$(this.promise_filename) Pass";
!ok::
"$(this.promise_filename) FAIL";
}

34 changes: 18 additions & 16 deletions tree/10_ncf_internals/configuration.cf
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,18 @@ bundle agent configuration
{

vars:
# We expand the template in the agent folder, so that it is not
# overwritten by the policy server expanded version, and if there are multiple
# agents on the node, each conf file does not compete
"ncf_configuration_file" string => "${sys.workdir}/ncf.conf.cache";

pass1.!ncf_override_conf_file_defined::
"ncf_configuration_basedir" string => dirname("${this.promise_filename}");

"ncf_configuration_file_source" string => "${ncf_configuration_basedir}/../ncf.conf";

pass1.ncf_override_conf_file_defined::
"ncf_configuration_file_source" string => "${ncf_configuration.ncf_configuration_file}";

pass1::
# We expand the template in the agent folder, so that it is not
# overwritten by the policy server expanded version, and if there are multiple
# agents on the node, each conf file does not compete
"ncf_configuration_file" string => "${sys.workdir}/ncf.conf.cache";
"ncf_configuration_file_source" string => "${ncf_configuration.ncf_configuration_file}";

pass2::
# Read all entries from the configuration file
Expand All @@ -47,18 +45,21 @@ bundle agent configuration
"enabled_loggers" slist => splitstring("${ncf_config[loggers][1]}",",","10");
"enabled_abort_handlers" slist => splitstring("${ncf_config[abort_handlers][1]}",",","10");
"cfengine_port" string => "${ncf_config[cfengine_port][1]}";
"flag_file" string => "${ncf_config[flag_file][1]}";

# Add a default empty list to allow skipping those handlers
pass3.enabled_loggers_empty::
pass2.enabled_loggers_empty::
"enabled_loggers" slist => {};
pass3.enabled_abort_handlers_empty::
pass2.enabled_abort_handlers_empty::
"enabled_abort_handlers" slist => {};
pass3.!enabled_loggers_defined::
pass2.!enabled_loggers_defined::
"enabled_loggers" slist => { "_log_default" };
pass3.!enabled_abort_handlers_defined::
pass2.!enabled_abort_handlers_defined::
"enabled_abort_handlers" slist => { "_abort_default" };
pass3.!cfengine_port_defined::
pass2.!cfengine_port_defined::
"cfengine_port" string => "5308";
pass2.!flag_file_defined::
"flag_file" string => "/var/rudder/agent-data/flags.json";

any::
# Constants
Expand All @@ -69,12 +70,12 @@ bundle agent configuration
"trace" string => "[TRACE]";

classes:
"ncf_override_conf_file_defined" expression => fileexists("${ncf_configuration.ncf_configuration_file}");

"pass3" expression => "pass1";
"pass3" expression => "pass2";
"pass2" expression => "pass1";
"pass1" expression => "any";

"ncf_override_conf_file_defined" expression => fileexists("${ncf_configuration.ncf_configuration_file}");

# Define ncf verbosity classes according to classes
# defined by the agent after verbosity options (-I, -v, -d)
"info" expression => "inform_mode",
Expand All @@ -90,7 +91,7 @@ bundle agent configuration
"info" expression => "debug",
scope => "namespace";

pass3::
pass2::
# this line will not be evaluated by cfengine if destination_prefix contains a variable that does not exist
# and it will always be evaluated to true otherwise
# Using the source variable for empty check to allow trailing comma
Expand All @@ -99,6 +100,7 @@ bundle agent configuration
"enabled_abort_handlers_defined" expression => strcmp("${enabled_abort_handlers}", "${enabled_abort_handlers}");
"enabled_abort_handlers_empty" expression => strcmp("${ncf_config[abort_handlers][1]}", "");
"cfengine_port_defined" not => strcmp("${cfengine_port}", "${ncf_config[cfengine_port][1]}");
"flag_file_defined" not => strcmp("${flag_file}", "${ncf_config[flag_file][1]}");

# We cannot use the generic method to expand template, as it relies on the logger,
# which is not yet defined
Expand Down
1 change: 1 addition & 0 deletions tree/10_ncf_internals/initialization.cf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ bundle agent initialization
# the ncf_init_* classes can be used to get the agregated result of ncf intialization
"copy classes for reporting" usebundle => _classes_copy("ncf_internals_modules_update", "ncf_init");
"init dry_run context" usebundle => dry_run_initialization;
"init flag context" usebundle => flag_initialization;

reports:
info::
Expand Down
140 changes: 140 additions & 0 deletions tree/20_cfe_basics/flag_lib.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#####################################################################################
# Copyright 2018 Normation SAS
#####################################################################################
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#####################################################################################

# Flag library

# Flags variable is stored in the ncf_flags bundle

# This bundle initializes the context for push/pop
# It is called in 10_ncf_internals/initialization.cf
bundle agent flag_initialization {
vars:
# designed to be incremented when a global unique ID is needed
"flag_unique.value" string => "1";
}

bundle agent reserve_flag(name) {
vars:
"cname" string => canonify("${name}");

"flag_unique.value" string => eval("${flag_unique.value}+1", "math", "infix");

classes:
"flag_reserved_${cname}" expression => "any",
# 1 day
persistence => "1440";

"pass1" expression => "any";

methods:
"${flag_unique.value}" usebundle => read_flags;


# Read flags
# Check if flag is defined
# Check if persistent class is defined

# Define persistent class
}

bundle agent get_flag(name) {
vars:
"cname" string => canonify("${name}");
"flag_unique.value" string => eval("${flag_unique.value}+1", "math", "infix");

classes:
"is_set" expression => isvariable("ncf_flags.data[${cname}]");
"pass1" expression => "any";

methods:
"${flag_unique.value}" usebundle => read_flags;

reports:
"set"
bundle_return_value_index => "1",
comment => "${flag_unique.value}",
if => "is_set|flag_reserved_${cname}";

"free"
bundle_return_value_index => "1",
comment => "${flag_unique.value}",
if => "!is_set.!flag_reserved_${cname}";
info::
"Flag '${name}' is set"
comment => "${flag_unique.value}",
if => "is_set";

"Flag '${name}' is reserved"
comment => "${flag_unique.value}",
if => "!is_set.flag_reserved_${cname}";

"Flag '${name}' is free"
comment => "${flag_unique.value}",
if => "!is_set.!flag_reserved_${cname}";
}

bundle agent set_flag(name) {
vars:
"cname" string => canonify("${name}");
"time" string => strftime("localtime", "%FT%T%z", "${sys.systime}");
"flag" data => '{ "${cname}": { "created": "${time}" } }';
pass2::
"output" data => mergedata("ncf_flags.data", "flag");

classes:
"pass3" expression => "pass2";
"pass2" expression => "pass1";
"pass1" expression => "any";

files:
pass3::
"${configuration.flag_file}"
create => "true",
template_method => "mustache",
edit_template => "${sys.workdir}/modules/templates/datastate.json.tpl",
template_data => "@{set_flag.output}",
edit_defaults => no_backup;
# TODO handle errors

methods:
"${flag_unique.value}" usebundle => read_flags;

reports:
info::
"Setting flag '${cname}' (created ${time})";
}

bundle agent read_flags {
vars:
"flag_unique.value" string => eval("${flag_unique.value}+1", "math", "infix");

# Pass3 to avoid reading the json at each pass...
pass3.file_exists::
"ncf_flags.data" data => readjson("${configuration.flag_file}"),
comment => "${flag_unique.value}";
pass3.!file_exists::
"ncf_flags.data" data => '{}';

classes:
"file_exists" expression => fileexists("${configuration.flag_file}");

"pass3" expression => "pass2";
"pass2" expression => "pass1";
"pass1" expression => "any";
}

4 changes: 2 additions & 2 deletions tree/ncf.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# and https://docs.cfengine.com/docs/3.6/reference-promise-types-files.html for
# CFEngine implementation
#
{{#classes.any}}
# Which logger(s) should be used in ncf?
# Comma separated list, default is '_log_default', use '' to disable all loggers
loggers=_log_default
Expand All @@ -16,4 +15,5 @@ abort_handlers=_abort_default
# Which port should be for CFEngine connections/data transfers
# default is 5308
cfengine_port=5308
{{/classes.any}}
# Where to store persistent flags, default is '/var/rudder/agent-data/flags.json'
flag_file=/tmp/flags.json

0 comments on commit 8c71954

Please sign in to comment.