Skip to content

ENT-10184: Top down evaluation #5834

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
57 changes: 57 additions & 0 deletions cf-agent/cf-agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,15 @@ 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))
{
return ScheduleAgentOperationsNormalOrder(ctx, bp);
}
return ScheduleAgentOperationsTopDownOrder(ctx, bp);
}

PromiseResult ScheduleAgentOperationsNormalOrder(EvalContext *ctx, const Bundle *bp)
{
assert(bp != NULL);

Expand Down Expand Up @@ -1652,6 +1661,54 @@ PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp)
return result;
}

PromiseResult ScheduleAgentOperationsTopDownOrder(EvalContext *ctx, const Bundle *bp)
{
assert(bp != NULL);

int save_pr_kept = PR_KEPT;
int save_pr_repaired = PR_REPAIRED;
int save_pr_notkept = PR_NOTKEPT;
struct timespec start = BeginMeasure();

if (PROCESSREFRESH == NULL || (PROCESSREFRESH && IsRegexItemIn(ctx, PROCESSREFRESH, bp->name)))
{
ClearProcessTable();
}

PromiseResult result = PROMISE_RESULT_SKIPPED;
for (int pass = 1; pass < CF_DONEPASSES; pass++)
{
char *last_promise_type = "";
for (size_t ppi = 0; ppi < SeqLength(bp->all_promises); ppi++)
{
EvalContextSetPass(ctx, pass);
Promise *pp = SeqAt(bp->all_promises, ppi);
BundleSection *parent_section = pp->parent_section;

if (!StringEqual(last_promise_type, parent_section->promise_type))
{
SpecialTypeBannerFromString(parent_section->promise_type, pass);
}
last_promise_type = parent_section->promise_type;

EvalContextStackPushBundleSectionFrame(ctx, parent_section);

PromiseResult promise_result = ExpandPromise(ctx, pp, KeepAgentPromise, NULL);
result = PromiseResultUpdate(result, promise_result);
if (EvalAborted(ctx) || BundleAbort(ctx))
{
EvalContextStackPopFrame(ctx);
NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start);
return result;
}
EvalContextStackPopFrame(ctx);
}
}

NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start);
return result;
}

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

#ifdef __MINGW32__
Expand Down
1 change: 1 addition & 0 deletions libpromises/cf3.defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ typedef enum
COMMON_CONTROL_TLS_MIN_VERSION,
COMMON_CONTROL_PACKAGE_INVENTORY,
COMMON_CONTROL_PACKAGE_MODULE,
COMMON_CONTROL_EVALUATION_ORDER,
COMMON_CONTROL_MAX
} CommonControl;

Expand Down
1 change: 1 addition & 0 deletions libpromises/eval_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ 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;
Expand Down
9 changes: 9 additions & 0 deletions libpromises/expand.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,15 @@ static void ResolveControlBody(EvalContext *ctx, GenericAgentConfig *config,
/* Ignored */
}

if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_EVALUATION_ORDER].lval) == 0)
{
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);
}

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 @@ -268,6 +268,7 @@ const ConstraintSyntax CFG_CONTROLBODY[COMMON_CONTROL_MAX + 1] =
ConstraintSyntaxNewString("tls_min_version", "", "Minimum acceptable TLS version for outgoing connections, defaults to OpenSSL's default", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewStringList("package_inventory", ".*", "Name of the package manager used for software inventory management", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewString("package_module", ".*", "Name of the default package manager", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewString("evaluation_order", "(classic|top_down)", "Order of evaluation of promises", SYNTAX_STATUS_NORMAL),
ConstraintSyntaxNewNull()
};

Expand Down
14 changes: 14 additions & 0 deletions libpromises/ornaments.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,20 @@ void SpecialTypeBanner(TypeSequence type, int pass)
}
}

void SpecialTypeBannerFromString(char *type, int pass)
{
if (StringEqual(type, "classes"))
{
Log(LOG_LEVEL_VERBOSE, "C: .........................................................");
Log(LOG_LEVEL_VERBOSE, "C: BEGIN classes / conditions (pass %d)", pass);
}
if (StringEqual(type, "vars"))
{
Log(LOG_LEVEL_VERBOSE, "V: .........................................................");
Log(LOG_LEVEL_VERBOSE, "V: BEGIN variables (pass %d)", pass);
}
}

void PromiseBanner(EvalContext *ctx, const Promise *pp)
{
char handle[CF_MAXVARSIZE];
Expand Down
1 change: 1 addition & 0 deletions libpromises/ornaments.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <eval_context.h>

void SpecialTypeBanner(TypeSequence type, int pass);
void SpecialTypeBannerFromString(char *type, int pass);
void PromiseBanner(EvalContext *ctx, const Promise *pp);
void Banner(const char *s);
void Legend();
Expand Down
4 changes: 4 additions & 0 deletions libpromises/policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,7 @@
bundle->source_path = SafeStringDuplicate(source_path);
bundle->sections = SeqNew(10, BundleSectionDestroy);
bundle->custom_sections = SeqNew(10, BundleSectionDestroy);
bundle->all_promises = SeqNew(10, NULL);

return bundle;
}
Expand Down Expand Up @@ -1437,6 +1438,7 @@
{
assert(promiser && "Missing promiser");
assert(section != NULL && "Missing promise type");
assert(section->parent_bundle != NULL);

Promise *pp = xcalloc(1, sizeof(Promise));

Expand All @@ -1452,6 +1454,7 @@
}

SeqAppend(section->promises, pp);
SeqAppend(section->parent_bundle->all_promises, pp);

Check notice

Code scanning / CodeQL

Pointer argument is dereferenced without checking for NULL Note

Parameter section in BundleSectionAppendPromise() is dereferenced without an explicit null-check

pp->parent_section = section;

Expand Down Expand Up @@ -1479,6 +1482,7 @@
RlistDestroy(bundle->args);
SeqDestroy(bundle->sections);
SeqDestroy(bundle->custom_sections);
SeqDestroy(bundle->all_promises);

free(bundle);
}
Expand Down
1 change: 1 addition & 0 deletions libpromises/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ struct Bundle_

Seq *sections;
Seq *custom_sections;
Seq *all_promises;

char *source_path;
SourceOffset offset;
Expand Down
2 changes: 2 additions & 0 deletions libpromises/prototypes3.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ void yyerror(const char *s);
/* agent.c */

PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp);
PromiseResult ScheduleAgentOperationsNormalOrder(EvalContext *ctx, const Bundle *bp);
PromiseResult ScheduleAgentOperationsTopDownOrder(EvalContext *ctx, const Bundle *bp);

/* Only for agent.c */

Expand Down
Loading
Loading