CFE-4686: Add cancel attribute to classes promises to undefine a class#6175
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
larsewi
left a comment
There was a problem hiding this comment.
When the cancel expression (a class expression — string or a function
returning a boolean) evaluates true...
Please update PR description. It seems to only support boolean.
Will do, yes it got stale, unfortunate byproduct of herman. |
Summary
Adds a
cancelattribute toclassespromises so policy can undefine aclass directly. Until now a classes promise could only define a class;
undefining one required a
cancel_*classes body attached to another promise'soutcome.
cancelis a boolean (cfbool). When it is true and the promise'sclass-context guard is satisfied, the promiser class is undefined.
cancel => "false", an unmet guard, or an already-undefined class are all no-ops.Key detail: the class-skipping exception
ExpandDeRefPromise()normally skips a classes promise whose promiser isalready defined (an optimization). A
cancelpromise must run precisely inthat case, so the skip now makes an exception when
cancelis present. This isthe 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, and rejects the class-modifier attributes (
persistence,scope,timer_policy), which are meaningless alongside it.consistent with the
cancel_*body attributes (ENT-7718 / CFE-3647).cancel_*path: persistent-record removal from thecf_stateLMDB +EvalContextClassRemove+ bundle-frame removal.Tests
New acceptance tests in
tests/acceptance/02_classes/01_basic/:cancel_attribute.cf— core semantics (cfbool true/aliases/false, guard,no-op on an undefined class).
cancel_attribute_hardclass.cf— refuses to cancel a reserved hard class.cancel_attribute_mutex.cf(+.sub) — rejects the class-defining attributes.cancel_attribute_modifier_mutex.cf(+.sub) — rejectspersistence/scope/timer_policy.cancel_attribute_persistent_lmdb.cf(+.sub/.sub2) — verifies thepersistent record is removed from the
cf_stateLMDB, checked at the sourcewith
cf-check dump.All CI checks green.
Docs
Documentation PR: cfengine/documentation (CFE-4686) adds the
cancelreferencesection.
Ticket: https://northerntech.atlassian.net/browse/CFE-4686
🤖 Generated with Claude Code