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
24 changes: 17 additions & 7 deletions cf-agent/cf-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -1002,12 +1002,6 @@ static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericA
continue;
}

if (CommonControlFromString(cp->lval) != COMMON_CONTROL_MAX)
{
/* Already handled in generic_agent */
continue;
}

VarRef *ref = VarRefParseFromScope(cp->lval, "control_agent");
DataType value_type;
const void *value = EvalContextVariableGet(ctx, ref, &value_type);
Expand Down Expand Up @@ -1353,6 +1347,22 @@ static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericA
config->agent_specific.agent.report_class_log? "true" : "false");
continue;
}

if (StringEqual(cp->lval, CFA_CONTROLBODY[AGENT_CONTROL_EVALUATION_ORDER].lval))
{
assert(value_type == CF_DATA_TYPE_STRING);
const char *evaluation_order = (char *) value;
Comment thread
victormlg marked this conversation as resolved.
Log(LOG_LEVEL_VERBOSE, "SET evaluation %s", evaluation_order);

if (StringEqual(evaluation_order, "top_down"))
{
EvalContextSetAgentEvalOrder(ctx, EVAL_ORDER_TOP_DOWN);
}
else
{
EvalContextSetAgentEvalOrder(ctx, EVAL_ORDER_CLASSIC);
}
}
}
}

Expand Down Expand Up @@ -1569,7 +1579,7 @@ static void AllClassesReport(const EvalContext *ctx)
PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp)
// NB - this function can be called recursively through "methods"
{
if (EvalContextGetEvalOption(ctx, EVAL_OPTION_CLASSIC_EVALUATION))
if (EvalContextIsClassicOrder(ctx))
{
return ScheduleAgentOperationsNormalOrder(ctx, bp);
}
Expand Down
1 change: 1 addition & 0 deletions libpromises/cf3.defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ typedef enum
AGENT_CONTROL_REPORTCLASSLOG,
AGENT_CONTROL_SELECT_END_MATCH_EOF,
AGENT_CONTROL_COPYFROM_RESTRICT_KEYS,
AGENT_CONTROL_EVALUATION_ORDER,
AGENT_CONTROL_NONE
} AgentControl;

Expand Down
43 changes: 43 additions & 0 deletions libpromises/eval_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ struct EvalContext_
int64_t elapsed;
Seq *events;
} profiler;

EvalContextEvalOrder common_eval_order;
EvalContextEvalOrder agent_eval_order;
};

void EvalContextSetConfig(EvalContext *ctx, const GenericAgentConfig *config)
Expand Down Expand Up @@ -1110,6 +1113,10 @@ EvalContext *EvalContextNew(void)
ctx->profiler.events = SeqNew(20, EventFrameDestroy);
ctx->profiler.elapsed = 0;

// evaluation order
ctx->common_eval_order = EVAL_ORDER_UNDEFINED;
ctx->agent_eval_order = EVAL_ORDER_UNDEFINED;

return ctx;
}

Expand Down Expand Up @@ -4047,3 +4054,39 @@ void EvalContextProfilingEnd(EvalContext *ctx, const Policy *policy)

JsonDestroy(profiling);
}

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

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

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

bool EvalContextIsClassicOrder(EvalContext *ctx)
{
assert(ctx != NULL);

if (ctx->config->agent_type != AGENT_TYPE_AGENT)
{
// Not cf-agent, so we ignore body agent control
return (ctx->common_eval_order != EVAL_ORDER_TOP_DOWN);
}

// cf-agent
if (ctx->agent_eval_order != EVAL_ORDER_UNDEFINED)
{
// evaluation_order from body agent control has priority, if defined
return (ctx->agent_eval_order == EVAL_ORDER_CLASSIC);
}

// The fallback is to use what is defined in body common control,
// or if not defined there either, default to true (normal order)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
// or if not defined there either, default to true (normal order)
// or if not defined there either, default to true (classic order)

return (ctx->common_eval_order != EVAL_ORDER_TOP_DOWN);
}
12 changes: 11 additions & 1 deletion libpromises/eval_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,17 @@ typedef enum

EVAL_OPTION_EVAL_FUNCTIONS = 1 << 0,
EVAL_OPTION_CACHE_SYSTEM_FUNCTIONS = 1 << 1,
EVAL_OPTION_CLASSIC_EVALUATION = 1 << 2,

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 @@ -453,4 +459,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);

#endif
10 changes: 8 additions & 2 deletions libpromises/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,8 +1030,14 @@ static void ResolveControlBody(EvalContext *ctx, GenericAgentConfig *config,
Log(LOG_LEVEL_VERBOSE, "SET evaluation %s",
RvalScalarValue(evaluated_rval));

bool is_classic = (StringEqual(RvalScalarValue(evaluated_rval), "classic"));
EvalContextSetEvalOption(ctx, EVAL_OPTION_CLASSIC_EVALUATION, is_classic);
if (StringEqual(RvalScalarValue(evaluated_rval), "top_down"))
{
EvalContextSetCommonEvalOrder(ctx, EVAL_ORDER_TOP_DOWN);
}
else
{
EvalContextSetCommonEvalOrder(ctx, EVAL_ORDER_CLASSIC);
}
}

RvalDestroy(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 @@ -320,6 +320,7 @@ const ConstraintSyntax CFA_CONTROLBODY[] =
ConstraintSyntaxNewBool("report_class_log", "true/false enables logging classes at the end of agent execution. Default value: false", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewBool("select_end_match_eof", "Set the default behavior of select_end_match_eof in edit_line promises. Default: false", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewStringList("copyfrom_restrict_keys", ".*", "A list of key hashes to restrict copy_from to", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewString("evaluation_order", "(classic|top_down)", "Order of evaluation of promises of agent", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewNull()
};

Expand Down
Loading