Skip to content

Commit f9a9ac0

Browse files
committed
Allow top-down evaluation of promises
Ticket: ENT-10184 Signed-off-by: Victor Moene <victor.moene@northern.tech>
1 parent b8e4c70 commit f9a9ac0

File tree

7 files changed

+96
-0
lines changed

7 files changed

+96
-0
lines changed

cf-agent/cf-agent.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,6 +1559,15 @@ static void AllClassesReport(const EvalContext *ctx)
15591559

15601560
PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp)
15611561
// NB - this function can be called recursively through "methods"
1562+
{
1563+
if (EvalContextGetEvalOption(ctx, EVAL_OPTION_NORMAL_EVALUATION))
1564+
{
1565+
return ScheduleAgentOperationsNormalOrder(ctx, bp);
1566+
}
1567+
return ScheduleAgentOperationsTopDownOrder(ctx, bp);
1568+
}
1569+
1570+
PromiseResult ScheduleAgentOperationsNormalOrder(EvalContext *ctx, const Bundle *bp)
15621571
{
15631572
assert(bp != NULL);
15641573

@@ -1652,6 +1661,78 @@ PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp)
16521661
return result;
16531662
}
16541663

1664+
int PromiseCmpWrapper(const Promise *p1, const Promise *p2, void *user_data)
1665+
{
1666+
UNUSED(user_data);
1667+
if (p1->offset.start < p2->offset.start)
1668+
{
1669+
return -1;
1670+
}
1671+
else if (p1->offset.start > p2->offset.start)
1672+
{
1673+
return 1;
1674+
}
1675+
return 0;
1676+
}
1677+
1678+
PromiseResult ScheduleAgentOperationsTopDownOrder(EvalContext *ctx, const Bundle *bp)
1679+
{
1680+
assert(bp != NULL);
1681+
1682+
int save_pr_kept = PR_KEPT;
1683+
int save_pr_repaired = PR_REPAIRED;
1684+
int save_pr_notkept = PR_NOTKEPT;
1685+
struct timespec start = BeginMeasure();
1686+
1687+
if (PROCESSREFRESH == NULL || (PROCESSREFRESH && IsRegexItemIn(ctx, PROCESSREFRESH, bp->name)))
1688+
{
1689+
ClearProcessTable();
1690+
}
1691+
1692+
Seq *promise_sequence = SeqNew(10, NULL);
1693+
1694+
const size_t sections = SeqLength(bp->sections);
1695+
for (size_t i = 0; i < sections; i++)
1696+
{
1697+
BundleSection *section = SeqAt(bp->sections, i);
1698+
const size_t promises = SeqLength(section->promises);
1699+
1700+
for (size_t j = 0; j < promises; j++)
1701+
{
1702+
SeqAppend(promise_sequence, SeqAt(section->promises, j));
1703+
}
1704+
}
1705+
1706+
SeqSort(promise_sequence, PromiseCmpWrapper, NULL);
1707+
1708+
PromiseResult result = PROMISE_RESULT_SKIPPED;
1709+
for (int pass = 1; pass < CF_DONEPASSES; pass++)
1710+
{
1711+
for (size_t ppi = 0; ppi < SeqLength(promise_sequence); ppi++)
1712+
{
1713+
Promise *pp = SeqAt(promise_sequence, ppi);
1714+
BundleSection *parent_section = pp->parent_section;
1715+
1716+
EvalContextStackPushBundleSectionFrame(ctx, parent_section);
1717+
1718+
PromiseResult promise_result = ExpandPromise(ctx, pp, KeepAgentPromise, NULL);
1719+
result = PromiseResultUpdate(result, promise_result);
1720+
if (EvalAborted(ctx) || BundleAbort(ctx))
1721+
{
1722+
EvalContextStackPopFrame(ctx);
1723+
NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start);
1724+
SeqDestroy(promise_sequence);
1725+
return result;
1726+
}
1727+
EvalContextStackPopFrame(ctx);
1728+
}
1729+
}
1730+
1731+
NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept, start);
1732+
SeqDestroy(promise_sequence);
1733+
return result;
1734+
}
1735+
16551736
/*********************************************************************/
16561737

16571738
#ifdef __MINGW32__

libpromises/cf3.defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ typedef enum
441441
COMMON_CONTROL_TLS_MIN_VERSION,
442442
COMMON_CONTROL_PACKAGE_INVENTORY,
443443
COMMON_CONTROL_PACKAGE_MODULE,
444+
COMMON_CONTROL_EVALUATION_ORDER,
444445
COMMON_CONTROL_MAX
445446
} CommonControl;
446447

libpromises/eval_context.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ typedef enum
108108

109109
EVAL_OPTION_EVAL_FUNCTIONS = 1 << 0,
110110
EVAL_OPTION_CACHE_SYSTEM_FUNCTIONS = 1 << 1,
111+
EVAL_OPTION_NORMAL_EVALUATION = 1 << 2,
111112

112113
EVAL_OPTION_FULL = 0xFFFFFFFF
113114
} EvalContextOption;

libpromises/expand.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,15 @@ static void ResolveControlBody(EvalContext *ctx, GenericAgentConfig *config,
10251025
/* Ignored */
10261026
}
10271027

1028+
if (strcmp(lval, CFG_CONTROLBODY[COMMON_CONTROL_EVALUATION_ORDER].lval) == 0)
1029+
{
1030+
Log(LOG_LEVEL_VERBOSE, "SET evaluation %s",
1031+
RvalScalarValue(evaluated_rval));
1032+
1033+
bool is_normal = (StringEqual(RvalScalarValue(evaluated_rval), "normal"));
1034+
EvalContextSetEvalOption(ctx, EVAL_OPTION_NORMAL_EVALUATION, is_normal);
1035+
}
1036+
10281037
RvalDestroy(evaluated_rval);
10291038
}
10301039

libpromises/mod_common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ const ConstraintSyntax CFG_CONTROLBODY[COMMON_CONTROL_MAX + 1] =
268268
ConstraintSyntaxNewString("tls_min_version", "", "Minimum acceptable TLS version for outgoing connections, defaults to OpenSSL's default", SYNTAX_STATUS_NORMAL),
269269
ConstraintSyntaxNewStringList("package_inventory", ".*", "Name of the package manager used for software inventory management", SYNTAX_STATUS_NORMAL),
270270
ConstraintSyntaxNewString("package_module", ".*", "Name of the default package manager", SYNTAX_STATUS_NORMAL),
271+
ConstraintSyntaxNewString("evaluation_order", "(normal|top_down)", "Order of evaluation of promises", SYNTAX_STATUS_NORMAL),
271272
ConstraintSyntaxNewNull()
272273
};
273274

libpromises/policy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,7 @@ Promise *BundleSectionAppendPromise(BundleSection *section, const char *promiser
14371437
{
14381438
assert(promiser && "Missing promiser");
14391439
assert(section != NULL && "Missing promise type");
1440+
assert(section->parent_bundle != NULL);
14401441

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

libpromises/prototypes3.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ void yyerror(const char *s);
4444
/* agent.c */
4545

4646
PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp);
47+
PromiseResult ScheduleAgentOperationsNormalOrder(EvalContext *ctx, const Bundle *bp);
48+
PromiseResult ScheduleAgentOperationsTopDownOrder(EvalContext *ctx, const Bundle *bp);
4749

4850
/* Only for agent.c */
4951

0 commit comments

Comments
 (0)