CFE-4686: Add cancel attribute to classes promises to undefine a class#6175
CFE-4686: Add cancel attribute to classes promises to undefine a class#6175nickanderson wants to merge 2 commits into
Conversation
|
@cf-bottom jenkins please |
|
Alright, I triggered a build: Jenkins: https://ci.cfengine.com/job/pr-pipeline/13945/ Packages: http://buildcache.cfengine.com/packages/testing-pr/jenkins-pr-pipeline-13945/ |
|
Thanks nice addition!! Much needed |
d9151e2 to
bf85569
Compare
olehermanse
left a comment
There was a problem hiding this comment.
It looks a bit backwards that cancel has a class expression. To me it reads as if what you put as the value to the cancel attribute should be the class you want to cancel. With the proposed behavior I guess something like cancel_if would be a better name.
But why should it have a class expression? We already have conditions (class expressions) in many places: class guard, if, unless, and expression for classes promises. Why do we need one more?
Some other proposals;
bundle agent example
{
classes:
some_condition.linux::
"my_class"
# true / false, default to false:
cancel => true;
}
bundle agent example
{
classes:
"my_class"
# define / undefine, default to define:
do => "undefine",
if => "some_condition.linux";
}
On the naming, yeah right after I pushed it I was thinking to mysefl that maintenance cancel blah read quite poorly. I was thinking a bit about That leaves if/unless still available for further compound constraint. or maybe invalidated_by ? we already have if/ifvarclass so cancel_if just seemed a bit yeuck. @basvandervlies @ncharles opinions on language here?
Most class-defining attributes accepts full class expressions:
|
|
Another idea, expire_when |
|
expire is growing on me (I don't need the _when suffix, but im ok with it or even _if I guess.) |
|
I like what @olehermanse suggested as syntax: Only I suggest If we got for the |
An attribute that specifies define/undefined would change how all classes promises are processed instead of adding a new canceling expression. What would be un-defined?. What about the distribution and selected class? Yes, the attribute could be made mutually exclusive. The attributes that are currently involved in determining if the class should be defined (and, dist, expression, or, not, select_class, and xorg are already mutually exclusive. I don't know if that is that is cleaner. it feels like more to remember. Persistent classes were on my mind when I suggested expire. It doesn't fit as well with non-persistent classes. So I am back to preferring |
|
@nickanderson the exact same problems exist with your suggestion. We should make all those other attributes mutually exclusive with the new cancel attribute regardless. It's not at all clear what should happen here or how
|
ugh, true.
I still don't like it and I still think it's wrong. We use expressions all over the place, it's weird to not take an expression. |
bf85569 to
df85b19
Compare
|
Updated the branch (force-pushed, rebased onto current
Docs PR cfengine/documentation#3683 updated to match. |
df85b19 to
fc390a9
Compare
Covers the cfbool true/false semantics, the class-guard trigger, the no-op for an undefined class, refusal to cancel reserved hard classes, mutual exclusion with the class-defining and class-modifier attributes, and removal of the persistent-class record from the cf_state LMDB. These fail until the following commit adds the 'cancel' attribute. Ticket: CFE-4686 Changelog: None Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
'cancel => "true"' (a cfbool) undefines the promiser class; the trigger is the promise's own class guard. The skip in ExpandDeRefPromise() makes an exception so the promise runs when the class is already defined. 'cancel' is mutually exclusive with the class-defining attributes (Irreconcilable constraints) and with persistence/scope/timer_policy. Undefining clears the persistent record from the cf_state LMDB; reserved hard classes are left in place with a warning. Ticket: CFE-4686 Changelog: Title Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fc390a9 to
eda330f
Compare
|
@cf-bottom jenkins, please. |
|
@cf-bottom jenkins please |
|
Alright, I triggered a build: Jenkins: https://ci.cfengine.com/job/pr-pipeline/13955/ Packages: http://buildcache.cfengine.com/packages/testing-pr/jenkins-pr-pipeline-13955/ |
addressed and implemented your bad idea
Summary
Adds a
cancelattribute toclassespromises so policy can undefine aclass. Until now a classes promise could only define a class; the only way
to undefine one from policy was a
cancel_*classes body attached to anotherpromise's outcome. With
cancel, the classes promise can undefine its ownpromiser directly:
When the cancel expression (a class expression — string or a function
returning a boolean) evaluates true, the promiser class is undefined if it is
currently defined. False trigger, or an already-undefined class, is a no-op.
Key detail: the class-skipping exception
ExpandDeRefPromise()normally excludes a classes promise whose promiser isalready defined (an optimization). A
cancelpromise must run precisely inthat case, so the skip now makes an exception when the
cancelattribute ispresent. This is the crux of the change — without it the promise would never
actuate.
Behaviour
expression,and,or,xor,not,dist,select_class) via the existing "Irreconcilableconstraints" check —
cancelis counted like any other class-body attribute.consistent with the
cancel_*classes body attributes (ENT-7718 / CFE-3647).cancel_*classes body(
DeleteAllClasses): persistent removal +EvalContextClassRemove+bundle-frame removal.
Tests
New acceptance tests in
tests/acceptance/02_classes/01_basic/:cancel_attribute.cf,cancel_attribute_hardclass.cf,cancel_attribute_mutex.cf(+.sub).Full
02_classessuite: 117 passed, 0 failed (3 staging-skipped, 3pre-existing soft failures).
Docs
Documentation PR: cfengine/documentation (CFE-4686) adds the
cancelreferencesection.
Ticket: https://northerntech.atlassian.net/browse/CFE-4686
🤖 Generated with Claude Code