Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cf-agent/cf-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -1601,7 +1601,7 @@ static void AllClassesReport(const EvalContext *ctx)
PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp)
// NB - this function can be called recursively through "methods"
{
if (EvalContextIsClassicOrder(ctx))
if (EvalContextIsClassicOrder(ctx, bp))
{
return ScheduleAgentOperationsNormalOrder(ctx, bp);
}
Expand Down
2 changes: 1 addition & 1 deletion cf-agent/files_editline.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ Bundle *MakeTemporaryBundleFromTemplate(EvalContext *ctx, Policy *policy, const
char bundlename[CF_MAXVARSIZE];
snprintf(bundlename, CF_MAXVARSIZE, "temp_cf_bundle_%s", CanonifyName(a->edit_template));

bp = PolicyAppendBundle(policy, "default", bundlename, "edit_line", NULL, NULL);
bp = PolicyAppendBundle(policy, "default", bundlename, "edit_line", NULL, NULL, EVAL_ORDER_UNDEFINED);
}
assert(bp);

Expand Down
2 changes: 1 addition & 1 deletion cf-monitord/env_monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ void MonitorStartServer(EvalContext *ctx, const Policy *policy)
Policy *monitor_cfengine_policy = PolicyNew();
Promise *pp = NULL;
{
Bundle *bp = PolicyAppendBundle(monitor_cfengine_policy, NamespaceDefault(), "monitor_cfengine_bundle", "agent", NULL, NULL);
Bundle *bp = PolicyAppendBundle(monitor_cfengine_policy, NamespaceDefault(), "monitor_cfengine_bundle", "agent", NULL, NULL, EVAL_ORDER_UNDEFINED);
BundleSection *sp = BundleAppendSection(bp, "monitor_cfengine");

pp = BundleSectionAppendPromise(sp, "the monitor daemon", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, NULL, NULL);
Expand Down
2 changes: 1 addition & 1 deletion cf-monitord/history.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ void HistoryUpdate(EvalContext *ctx, const Averages *const newvals)
Policy *history_db_policy = PolicyNew();
Promise *pp = NULL;
{
Bundle *bp = PolicyAppendBundle(history_db_policy, NamespaceDefault(), "history_db_bundle", "agent", NULL, NULL);
Bundle *bp = PolicyAppendBundle(history_db_policy, NamespaceDefault(), "history_db_bundle", "agent", NULL, NULL, EVAL_ORDER_UNDEFINED);
BundleSection *sp = BundleAppendSection(bp, "history_db");

pp = BundleSectionAppendPromise(sp, "the long term memory", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, NULL, NULL);
Expand Down
2 changes: 1 addition & 1 deletion cf-serverd/cf-serverd-functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ static CfLock AcquireServerLock(EvalContext *ctx,
{
Bundle *bp = PolicyAppendBundle(server_policy, NamespaceDefault(),
"server_cfengine_bundle", "agent",
NULL, NULL);
NULL, NULL, EVAL_ORDER_UNDEFINED);
BundleSection *sp = BundleAppendSection(bp, "server_cfengine");

pp = BundleSectionAppendPromise(sp, config->input_file,
Expand Down
7 changes: 7 additions & 0 deletions libpromises/cf3.defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,13 @@ typedef struct
SyntaxStatus status;
} PromiseTypeSyntax;

typedef enum
{
EVAL_ORDER_UNDEFINED = 0,
EVAL_ORDER_CLASSIC,
EVAL_ORDER_TOP_DOWN
} EvalOrder;

/*************************************************************************/

typedef struct Constraint_ Constraint;
Expand Down
21 changes: 20 additions & 1 deletion libpromises/cf3parse_logic.h
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,24 @@ static inline void ParserHandleBlockAttributeRval()
P.current_namespace = xstrdup(P.rval.item);
}
}
if (StringEqual(P.lval, "evaluation_order"))
{
if (P.rval.type != RVAL_TYPE_SCALAR)
{
yyerror("evaluation_order must be a constant scalar string");
}
else
{
if (StringEqual(P.rval.item, "classic"))
{
P.current_evaluation_order = EVAL_ORDER_CLASSIC;
}
else if (StringEqual(P.rval.item, "top_down"))
{
P.current_evaluation_order = EVAL_ORDER_TOP_DOWN;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be an else with parser error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then the evaluation order stays as EVALUATION_ORDER_UNDEFINED. But the program will error on the wrong value later anyways, so wd don't really need to check for the right value here

}
}
}

RvalDestroy(P.rval);
Expand Down Expand Up @@ -1038,7 +1056,8 @@ static inline void ParserBeginBundleBody()
P.blockid,
P.blocktype,
P.useargs,
P.filename);
P.filename,
P.current_evaluation_order);
P.currentbundle->offset.line = CURRENT_BLOCKID_LINE;
P.currentbundle->offset.start = P.offsets.last_block_id;
}
Expand Down
43 changes: 38 additions & 5 deletions libpromises/eval_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,8 @@ struct EvalContext_
Seq *events;
} profiler;

EvalContextEvalOrder common_eval_order;
EvalContextEvalOrder agent_eval_order;
EvalOrder common_eval_order;
EvalOrder agent_eval_order;
};

void EvalContextSetConfig(EvalContext *ctx, const GenericAgentConfig *config)
Expand Down Expand Up @@ -4062,21 +4062,54 @@ void EvalContextProfilingEnd(EvalContext *ctx, const Policy *policy)

// ##############################################################

void EvalContextSetCommonEvalOrder(EvalContext *ctx, EvalContextEvalOrder eval_order)
void EvalContextSetCommonEvalOrder(EvalContext *ctx, EvalOrder eval_order)
{
assert(ctx != NULL);
ctx->common_eval_order = eval_order;
}

void EvalContextSetAgentEvalOrder(EvalContext *ctx, EvalContextEvalOrder eval_order)
void EvalContextSetAgentEvalOrder(EvalContext *ctx, EvalOrder eval_order)
{
assert(ctx != NULL);
ctx->agent_eval_order = eval_order;
}

bool EvalContextIsClassicOrder(EvalContext *ctx)
const char *EvalContextEvaluationOrderToString(EvalOrder evaluation_order)
{
if (evaluation_order == EVAL_ORDER_CLASSIC)
{
return "classic";
}
if (evaluation_order == EVAL_ORDER_TOP_DOWN)
{
return "top_down";
}
return "undefined";
}

EvalOrder EvalContextEvaluationOrderFromString(const char *evaluation_order_string)
{
if (StringEqual(evaluation_order_string, "classic"))
{
return EVAL_ORDER_CLASSIC;
}
if (StringEqual(evaluation_order_string, "top_down"))
{
return EVAL_ORDER_TOP_DOWN;
}
return EVAL_ORDER_UNDEFINED;
}

bool EvalContextIsClassicOrder(EvalContext *ctx, const Bundle *bp)
{
assert(ctx != NULL);
assert(bp != NULL);

if (bp->evaluation_order != EVAL_ORDER_UNDEFINED)
{
// bundle evaluation order overrides common or agent control
return bp->evaluation_order == EVAL_ORDER_CLASSIC;
}

if (ctx->config->agent_type != AGENT_TYPE_AGENT)
{
Expand Down
15 changes: 5 additions & 10 deletions libpromises/eval_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,6 @@ typedef enum
EVAL_OPTION_FULL = 0xFFFFFFFF
} EvalContextOption;

typedef enum
{
EVAL_ORDER_UNDEFINED = 0,
EVAL_ORDER_CLASSIC,
EVAL_ORDER_TOP_DOWN
} EvalContextEvalOrder;

EvalContext *EvalContextNew(void);
void EvalContextDestroy(EvalContext *ctx);

Expand Down Expand Up @@ -459,8 +452,10 @@ void EvalContextSetProfiling(EvalContext *ctx, bool profiling);
void EvalContextProfilingStart(EvalContext *ctx);
void EvalContextProfilingEnd(EvalContext *ctx, const Policy *policy);

void EvalContextSetCommonEvalOrder(EvalContext *ctx, EvalContextEvalOrder eval_order);
void EvalContextSetAgentEvalOrder(EvalContext *ctx, EvalContextEvalOrder eval_order);
bool EvalContextIsClassicOrder(EvalContext *ctx);
void EvalContextSetCommonEvalOrder(EvalContext *ctx, EvalOrder eval_order);
void EvalContextSetAgentEvalOrder(EvalContext *ctx, EvalOrder eval_order);
const char *EvalContextEvaluationOrderToString(EvalOrder evaluation_order);
EvalOrder EvalContextEvaluationOrderFromString(const char *evaluation_order_string);
bool EvalContextIsClassicOrder(EvalContext *ctx, const Bundle *bp);

#endif
2 changes: 1 addition & 1 deletion libpromises/evalfunction.c
Original file line number Diff line number Diff line change
Expand Up @@ -4883,7 +4883,7 @@ static FnCallResult FnCallSelectServers(EvalContext *ctx,
Policy *select_server_policy = PolicyNew();
{
Bundle *bp = PolicyAppendBundle(select_server_policy, NamespaceDefault(),
"select_server_bundle", "agent", NULL, NULL);
"select_server_bundle", "agent", NULL, NULL, EVAL_ORDER_UNDEFINED);
BundleSection *sp = BundleAppendSection(bp, "select_server");

BundleSectionAppendPromise(sp, "function", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, NULL, NULL);
Expand Down
4 changes: 3 additions & 1 deletion libpromises/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ void BundleResolve(EvalContext *ctx, const Bundle *bundle)
static void ResolveControlBody(EvalContext *ctx, GenericAgentConfig *config,
const Body *control_body)
{
assert(control_body != NULL);
const char *filename = control_body->source_path;

assert(CFG_CONTROLBODY[COMMON_CONTROL_MAX].lval == NULL);
Expand Down Expand Up @@ -1025,8 +1026,9 @@ static void ResolveControlBody(EvalContext *ctx, GenericAgentConfig *config,
/* Ignored */
}

if (StringEqual(lval, CFG_CONTROLBODY[COMMON_CONTROL_EVALUATION_ORDER].lval))
if (StringEqual(lval, CFG_CONTROLBODY[COMMON_CONTROL_EVALUATION_ORDER].lval) && !StringEqual(control_body->type, "file"))
{
/* evaluation_order in file control is already handled in the parser */
Log(LOG_LEVEL_VERBOSE, "SET evaluation %s",
RvalScalarValue(evaluated_rval));

Expand Down
1 change: 1 addition & 0 deletions libpromises/mod_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ const ConstraintSyntax file_control_constraints[] = /* enum cfh_control */
{
ConstraintSyntaxNewString("namespace", "[a-zA-Z_][a-zA-Z0-9_]*", "Switch to a private namespace to protect current file from duplicate definitions", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewStringList("inputs", ".*", "List of additional filenames to parse for promises", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewString("evaluation_order", "(classic|top_down)", "Order of evaluation of promises", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewNull()
};

Expand Down
6 changes: 6 additions & 0 deletions libpromises/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ static void ParserStateReset(ParserState *p, bool discard)
free(p->current_namespace);
p->current_namespace = xstrdup("default");

p->current_evaluation_order = EVAL_ORDER_UNDEFINED;

p->currentid[0] = '\0';
if (p->currentstring)
{
Expand Down Expand Up @@ -104,8 +106,12 @@ static void ParserStateReset(ParserState *p, bool discard)

static void ParserStateClean(ParserState *p)
{
assert(p != NULL);

free(p->current_namespace);
p->current_namespace = NULL;

p->current_evaluation_order = EVAL_ORDER_UNDEFINED;
}

Policy *ParserParseFile(AgentType agent_type, const char *path, unsigned int warnings, unsigned int warnings_error)
Expand Down
1 change: 1 addition & 0 deletions libpromises/parser_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ typedef struct
char *promiser;
void *promisee;

EvalOrder current_evaluation_order;
char *current_namespace;
char currentid[CF_MAXVARSIZE];
char currenttype[CF_MAXVARSIZE];
Expand Down
8 changes: 6 additions & 2 deletions libpromises/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,7 @@ void BundleSectionDestroy(BundleSection *section)

Bundle *PolicyAppendBundle(Policy *policy,
const char *ns, const char *name, const char *type,
const Rlist *args, const char *source_path)
const Rlist *args, const char *source_path, const EvalOrder evaluation_order)
{
Bundle *bundle = xcalloc(1, sizeof(Bundle));

Expand All @@ -1323,6 +1323,7 @@ Bundle *PolicyAppendBundle(Policy *policy,
bundle->sections = SeqNew(10, BundleSectionDestroy);
bundle->custom_sections = SeqNew(10, BundleSectionDestroy);
bundle->all_promises = SeqNew(10, NULL);
bundle->evaluation_order = evaluation_order;

return bundle;
}
Expand Down Expand Up @@ -1907,6 +1908,7 @@ static JsonElement *BundleContextsToJson(const Seq *promises)
*/
JsonElement *BundleToJson(const Bundle *bundle)
{
assert(bundle != NULL);
JsonElement *json_bundle = JsonObjectCreate(10);

if (bundle->source_path)
Expand All @@ -1918,6 +1920,7 @@ JsonElement *BundleToJson(const Bundle *bundle)
JsonObjectAppendString(json_bundle, "namespace", bundle->ns);
JsonObjectAppendString(json_bundle, "name", bundle->name);
JsonObjectAppendString(json_bundle, "bundleType", bundle->type);
JsonObjectAppendString(json_bundle, "evaluation_order", EvalContextEvaluationOrderToString(bundle->evaluation_order));

{
JsonElement *json_args = JsonArrayCreate(10);
Expand Down Expand Up @@ -2302,6 +2305,7 @@ static Bundle *PolicyAppendBundleJson(Policy *policy, JsonElement *json_bundle)
const char *name = JsonObjectGetAsString(json_bundle, "name");
const char *type = JsonObjectGetAsString(json_bundle, "bundleType");
const char *source_path = JsonObjectGetAsString(json_bundle, "sourcePath");
const char *evaluation_order_string = JsonObjectGetAsString(json_bundle, "evaluation_order");

Rlist *args = NULL;
{
Expand All @@ -2312,7 +2316,7 @@ static Bundle *PolicyAppendBundleJson(Policy *policy, JsonElement *json_bundle)
}
}

Bundle *bundle = PolicyAppendBundle(policy, ns, name, type, args, source_path);
Bundle *bundle = PolicyAppendBundle(policy, ns, name, type, args, source_path, EvalContextEvaluationOrderFromString(evaluation_order_string));

{
JsonElement *json_promise_types = JsonObjectGetAsArray(json_bundle, "promiseTypes");
Expand Down
3 changes: 2 additions & 1 deletion libpromises/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct Bundle_
char *type;
char *name;
char *ns;
EvalOrder evaluation_order;
Rlist *args;

Seq *sections;
Expand Down Expand Up @@ -179,7 +180,7 @@ void PolicyErrorWrite(Writer *writer, const PolicyError *error);
bool PolicyCheckPartial(const Policy *policy, Seq *errors);
bool PolicyCheckRunnable(const EvalContext *ctx, const Policy *policy, Seq *errors);

Bundle *PolicyAppendBundle(Policy *policy, const char *ns, const char *name, const char *type, const Rlist *args, const char *source_path);
Bundle *PolicyAppendBundle(Policy *policy, const char *ns, const char *name, const char *type, const Rlist *args, const char *source_path, const EvalOrder evaluation_order);
Body *PolicyAppendBody(Policy *policy, const char *ns, const char *name,
const char *type, Rlist *args, const char *source_path,
bool is_custom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ body common control()
{
"arguments": [],
"bundleType": "agent",
"evaluation_order": "undefined",
"line": 7,
"name": "test",
"namespace": "default",
Expand Down Expand Up @@ -189,6 +190,7 @@ body common control()
{
"arguments": [],
"bundleType": "agent",
"evaluation_order": "undefined",
"line": 7,
"name": "test",
"namespace": "default",
Expand Down Expand Up @@ -243,6 +245,7 @@ body common control()
{
"arguments": [],
"bundleType": "common",
"evaluation_order": "undefined",
"line": 1,
"name": "extra",
"namespace": "default",
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/eval_context_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ static void test_class_persistence(void)
// e.g. by a class promise in a bundle with a namespace
{
Policy *p = PolicyNew();
Bundle *bp = PolicyAppendBundle(p, "ns1", "bundle1", "agent", NULL, NULL);
Bundle *bp = PolicyAppendBundle(p, "ns1", "bundle1", "agent", NULL, NULL, EVAL_ORDER_UNDEFINED);

EvalContextStackPushBundleFrame(ctx, bp, NULL, false);
EvalContextHeapPersistentSave(ctx, "class2", 5, CONTEXT_STATE_POLICY_PRESERVE, "x");
Expand Down
Loading
Loading