Skip to content

Commit 599311a

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 599311a

File tree

7 files changed

+99
-0
lines changed

7 files changed

+99
-0
lines changed

cf-agent/cf-agent.c

Lines changed: 84 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,81 @@ PromiseResult ScheduleAgentOperations(EvalContext *ctx, const Bundle *bp)
16521661
return result;
16531662
}
16541663

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

16571741
#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)