Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 12 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,28 @@ 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)
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
13 changes: 3 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,8 @@ 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);
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
3 changes: 2 additions & 1 deletion libpromises/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,8 +1025,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
4 changes: 4 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 @@ -106,6 +108,8 @@ static void ParserStateClean(ParserState *p)
{
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
5 changes: 3 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 @@ -2312,7 +2313,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, EVAL_ORDER_UNDEFINED);

{
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
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
2 changes: 1 addition & 1 deletion tests/unit/iteration_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ static void IteratorPrepare_TestHelper(
EvalContext *evalctx = EvalContextNew();
Policy *policy = PolicyNew();
Bundle *bundle = PolicyAppendBundle(policy, "ns1", "bundle1", "agent",
NULL, NULL);
NULL, NULL, EVAL_ORDER_UNDEFINED);
BundleSection *section = BundleAppendSection(bundle, "dummy");
Promise *promise = BundleSectionAppendPromise(section, promiser,
(Rval) { NULL, RVAL_TYPE_NOPROMISEE },
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/var_expressions_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static void test_array_with_dot_colon_in_index(void)
static void test_special_scope(void)
{
Policy *p = PolicyNew();
Bundle *bp = PolicyAppendBundle(p, "ns", "b", "agent", NULL, NULL);
Bundle *bp = PolicyAppendBundle(p, "ns", "b", "agent", NULL, NULL, EVAL_ORDER_UNDEFINED);

{
VarRef *ref = VarRefParseFromBundle("c.lval", bp);
Expand Down