Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions api/v1beta2/cloudscalecluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,11 @@ type FloatingIPSpec struct {

// CloudscaleClusterStatus defines the observed state of CloudscaleCluster.
type CloudscaleClusterStatus struct {
// observedGeneration is the latest generation observed by the controller.
// +optional
// +kubebuilder:validation:Minimum=1
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// Initialization contains v1beta2 initialization tracking.
// +optional
Initialization *ClusterInitializationStatus `json:"initialization,omitempty"`
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta2/cloudscalemachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ type MachineInitializationStatus struct {

// CloudscaleMachineStatus defines the observed state of CloudscaleMachine.
type CloudscaleMachineStatus struct {
// observedGeneration is the latest generation observed by the controller.
// +optional
// +kubebuilder:validation:Minimum=1
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// Initialization contains v1beta2 initialization tracking.
// +optional
Initialization *MachineInitializationStatus `json:"initialization,omitempty"`
Expand Down
5 changes: 5 additions & 0 deletions api/v1beta2/cloudscalemachinetemplate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ type CloudscaleMachineTemplateResource struct {

// CloudscaleMachineTemplateStatus defines the observed state of CloudscaleMachineTemplate.
type CloudscaleMachineTemplateStatus struct {
// observedGeneration is the latest generation observed by the controller.
// +optional
// +kubebuilder:validation:Minimum=1
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// Capacity defines the resource capacity for nodes created from this template.
// This value is used for autoscaling from zero operations as defined in:
// https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20210310-opt-in-autoscaling-from-zero.md
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,12 @@ spec:
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
observedGeneration:
description: observedGeneration is the latest generation observed
by the controller.
format: int64
minimum: 1
type: integer
type: object
required:
- spec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ spec:
True when the server is running and ready.
type: boolean
type: object
observedGeneration:
description: observedGeneration is the latest generation observed
by the controller.
format: int64
minimum: 1
type: integer
serverGroupID:
description: ServerGroupID is the cloudscale.ch server group UUID.
type: string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ spec:
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
observedGeneration:
description: observedGeneration is the latest generation observed
by the controller.
format: int64
minimum: 1
type: integer
type: object
required:
- spec
Expand Down
10 changes: 9 additions & 1 deletion internal/controller/cloudscalecluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/cluster-api/util/annotations"
"sigs.k8s.io/cluster-api/util/conditions"
"sigs.k8s.io/cluster-api/util/patch"
"sigs.k8s.io/cluster-api/util/predicates"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
Expand Down Expand Up @@ -135,7 +136,14 @@ func (r *CloudscaleClusterReconciler) Reconcile(ctx context.Context, req ctrl.Re
// when the reconcile context has timed out.
patchCtx, patchCancel := context.WithTimeout(context.Background(), 30*time.Second)
defer patchCancel()
if err := clusterScope.Close(patchCtx); err != nil && reterr == nil {

// Advance status.observedGeneration only on a successful reconcile so
// it lags metadata.generation while reconciliation is failing.
var opts []patch.Option
if reterr == nil {
opts = append(opts, patch.WithStatusObservedGeneration{})
}
if err := clusterScope.Close(patchCtx, opts...); err != nil && reterr == nil {
reterr = err
}
}()
Expand Down
10 changes: 9 additions & 1 deletion internal/controller/cloudscalemachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/cluster-api/util/annotations"
"sigs.k8s.io/cluster-api/util/conditions"
"sigs.k8s.io/cluster-api/util/patch"
"sigs.k8s.io/cluster-api/util/predicates"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
Expand Down Expand Up @@ -161,7 +162,14 @@ func (r *CloudscaleMachineReconciler) Reconcile(ctx context.Context, req ctrl.Re
// when the reconcile context has timed out.
patchCtx, patchCancel := context.WithTimeout(context.Background(), 30*time.Second)
defer patchCancel()
if err := machineScope.Close(patchCtx); err != nil && reterr == nil {

// Advance status.observedGeneration only on a successful reconcile so
// it lags metadata.generation while reconciliation is failing.
var opts []patch.Option
if reterr == nil {
opts = append(opts, patch.WithStatusObservedGeneration{})
}
if err := machineScope.Close(patchCtx, opts...); err != nil && reterr == nil {
reterr = err
}
}()
Expand Down
4 changes: 3 additions & 1 deletion internal/controller/cloudscalemachinetemplate_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ func (r *CloudscaleMachineTemplateReconciler) Reconcile(ctx context.Context, req

template.Status.Capacity = capacity

if err := patchHelper.Patch(ctx, template); err != nil {
// This patch is only reached on the success path, so advance
// status.observedGeneration to the reconciled generation.
if err := patchHelper.Patch(ctx, template, patch.WithStatusObservedGeneration{}); err != nil {
logger.Error(err, "Failed to patch CloudscaleMachineTemplate status")
return ctrl.Result{}, err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/scope/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ func NewClusterScope(params ClusterScopeParams) (*ClusterScope, error) {
}

// Close persists the CloudscaleCluster status and spec changes.
func (s *ClusterScope) Close(ctx context.Context) error {
return s.patchHelper.Patch(ctx, s.CloudscaleCluster)
func (s *ClusterScope) Close(ctx context.Context, opts ...patch.Option) error {
return s.patchHelper.Patch(ctx, s.CloudscaleCluster, opts...)
}

// Name returns the cluster name.
Expand Down
4 changes: 2 additions & 2 deletions internal/scope/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ func NewMachineScope(params MachineScopeParams) (*MachineScope, error) {
}

// Close persists the CloudscaleMachine status and spec changes.
func (s *MachineScope) Close(ctx context.Context) error {
return s.patchHelper.Patch(ctx, s.CloudscaleMachine)
func (s *MachineScope) Close(ctx context.Context, opts ...patch.Option) error {
return s.patchHelper.Patch(ctx, s.CloudscaleMachine, opts...)
}

// Name returns the machine name.
Expand Down