Open zmerlynn opened 2 months ago
I like the approach. But you would want to ApplyDefaults()
here:
https://github.com/googleforgames/agones/blob/4bb673186b2ee8431de00c5c564bd1daa1a356df/pkg/gameservers/controller.go#L389-L396
Rather than where you specified, as enqueing only enque's the namespace/name
of the object, not the object itself - giving the best opportunity to get the latest Object at the time of syncronisation.
LGTM! I like the approach 👍🏻
Apply Default
I like the approach. But you would want to
ApplyDefaults()
here:
You're right. It might be nice if we had a helper function here that's basically "Get and Default" (for the case of inline changes like you just did for the migration controller), but agreed on the placement.
Storage Compatibility
Defaulting
Right now, Agones defaults values in the webhook, e.g. GameServer defaulting is the only real thing the GameServer mutation webhook does. Defaulting serves a couple of purposes:
kubectl describe
. This increases discoverability for new API elements, asdescribe
is a common UI element.The problem is that defaulting in the webhook alone is not safe across configuration changes. Example using
eviction.safe
:SafeToEvict
disabled.foo
created.eviction.safe
is not defaulted because the feature gate was not enabled.SafeToEvict
enabled.eviction.safe
is defaulted on new objects.The reason for the failure is that the hook blindly assumes the value was defaulted by the webhook, but the webhook never had a chance to run. Note that for this particular case, the gap here is very narrow in time - in particular t1 and t2 need to occur such that defaulting of the GameServer occurs on a 1.29
agones-extensions
container, but a 1.30agones-controller
container attempts to create the Pod. That said, this condition could easily occur during rollout of 1.30, though, and cause a multi-second hiccup.To solve this problem, I propose we:
Get
in the controller - probably via helper function). This effectively ensures defaulting on creation and on subsequent update, but it relies on idempotent defaulting.Unknown or Disabled Fields
A similar problem exists for API fields that should not be present but have already been set, which typically only occurs if a feature gate has been disabled (either due to downgrade or explicit disablement). This takes a couple of forms:
eviction.safe
, imagine downgrading from 1.30 (where the feature gate is Beta and therefore the API is defaulted) to 1.28 (prior toeviction.safe
even existing).In either of these cases, we need to ensure that on "first touch", the controller drops the unknown fields, rather than preserving them. In general, this is a safer handling of latent unknown fields - otherwise when the feature gate is reenabled, a preserved field could surprise the user. (Note that the first case, where the field is not present at all in the CRD, is generally covered by field pruning, so mostly this is figuring out logic for the latter case.)
Update vs Patch for controllers
Note that controllers have a similar problem to the SDK of using
Update
vsPatch
, mentioned here - different controller versions may drop fields. However:sdk-server
, which requires a full rollout.