Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Status.Version for KThreesControlPlane #127

Merged
merged 1 commit into from
Jun 4, 2024
Merged
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 controlplane/api/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ func Convert_v1beta2_KThreesConfigSpec_To_v1beta1_KThreesConfigSpec(in *bootstra
return bootstrapv1beta1.Convert_v1beta2_KThreesConfigSpec_To_v1beta1_KThreesConfigSpec(in, out, s)
}

func Convert_v1beta2_KThreesControlPlaneStatus_To_v1beta1_KThreesControlPlaneStatus(in *controlplanev1beta2.KThreesControlPlaneStatus, out *KThreesControlPlaneStatus, s conversion.Scope) error { //nolint: stylecheck
return autoConvert_v1beta2_KThreesControlPlaneStatus_To_v1beta1_KThreesControlPlaneStatus(in, out, s)
}

// ConvertTo converts the v1beta1 KThreesControlPlane receiver to a v1beta2 KThreesControlPlane.
func (in *KThreesControlPlane) ConvertTo(dstRaw ctrlconversion.Hub) error {
dst := dstRaw.(*controlplanev1beta2.KThreesControlPlane)
Expand All @@ -91,6 +95,7 @@ func (in *KThreesControlPlane) ConvertTo(dstRaw ctrlconversion.Hub) error {
dst.Spec.KThreesConfigSpec.ServerConfig.DisableCloudController = restored.Spec.KThreesConfigSpec.ServerConfig.DisableCloudController
dst.Spec.MachineTemplate.NodeVolumeDetachTimeout = restored.Spec.MachineTemplate.NodeVolumeDetachTimeout
dst.Spec.MachineTemplate.NodeDeletionTimeout = restored.Spec.MachineTemplate.NodeDeletionTimeout
dst.Status.Version = restored.Status.Version
return nil
}

Expand Down
16 changes: 6 additions & 10 deletions controlplane/api/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions controlplane/api/v1beta2/kthreescontrolplane_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ type KThreesControlPlaneStatus struct {
// +optional
Replicas int32 `json:"replicas,omitempty"`

// Version represents the minimum Kubernetes version for the control plane machines
// in the cluster.
// +optional
Version *string `json:"version,omitempty"`

// Total number of non-terminated machines targeted by this control plane
// that have the desired template spec.
// +optional
Expand Down
5 changes: 5 additions & 0 deletions controlplane/api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,11 @@ spec:
that have the desired template spec.
format: int32
type: integer
version:
description: |-
Version represents the minimum Kubernetes version for the control plane machines
in the cluster.
type: string
type: object
type: object
served: true
Expand Down
25 changes: 21 additions & 4 deletions controlplane/controllers/kthreescontrolplane_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import (
controlplanev1 "github.com/k3s-io/cluster-api-k3s/controlplane/api/v1beta2"
k3s "github.com/k3s-io/cluster-api-k3s/pkg/k3s"
"github.com/k3s-io/cluster-api-k3s/pkg/kubeconfig"
"github.com/k3s-io/cluster-api-k3s/pkg/machinefilters"
"github.com/k3s-io/cluster-api-k3s/pkg/secret"
"github.com/k3s-io/cluster-api-k3s/pkg/token"
)
Expand Down Expand Up @@ -159,13 +160,23 @@ func (r *KThreesControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.
err = kerrors.NewAggregate([]error{err, patchErr})
}

// TODO: remove this as soon as we have a proper remote cluster cache in place.
// Make KCP to requeue in case status is not ready, so we can check for node status without waiting for a full resync (by default 10 minutes).
// Only requeue if we are not going in exponential backoff due to error, or if we are not already re-queueing, or if the object has a deletion timestamp.
if err == nil && !res.Requeue && !(res.RequeueAfter > 0) && kcp.ObjectMeta.DeletionTimestamp.IsZero() {
// Only requeue if there is no error, Requeue or RequeueAfter and the object does not have a deletion timestamp.
if err == nil && res.IsZero() && kcp.ObjectMeta.DeletionTimestamp.IsZero() {
// Make KCP requeue in case node status is not ready, so we can check for node status without waiting for a full
// resync (by default 10 minutes).
// The alternative solution would be to watch the control plane nodes in the Cluster - similar to how the
// MachineSet and MachineHealthCheck controllers watch the nodes under their control.
if !kcp.Status.Ready {
res = ctrl.Result{RequeueAfter: 20 * time.Second}
}

// Make KCP requeue if ControlPlaneComponentsHealthyCondition is false so we can check for control plane component
// status without waiting for a full resync (by default 10 minutes).
// Otherwise this condition can lead to a delay in provisioning MachineDeployments when MachineSet preflight checks are enabled.
// The alternative solution to this requeue would be watching the relevant pods inside each workload cluster which would be very expensive.
if conditions.IsFalse(kcp, controlplanev1.ControlPlaneComponentsHealthyCondition) {
res = ctrl.Result{RequeueAfter: 20 * time.Second}
}
}

return res, err
Expand Down Expand Up @@ -364,6 +375,12 @@ func (r *KThreesControlPlaneReconciler) updateStatus(ctx context.Context, kcp *c
return nil
}

machinesWithAgentHealthy := controlPlane.Machines.Filter(machinefilters.AgentHealthy())
lowestVersion := machinesWithAgentHealthy.LowestVersion()
if lowestVersion != nil {
controlPlane.KCP.Status.Version = lowestVersion
}

switch {
// We are scaling up
case replicas < desiredReplicas:
Expand Down
12 changes: 12 additions & 0 deletions pkg/machinefilters/machine_filters.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
"sigs.k8s.io/cluster-api/util/collections"
"sigs.k8s.io/cluster-api/util/conditions"

bootstrapv1 "github.com/k3s-io/cluster-api-k3s/bootstrap/api/v1beta2"
controlplanev1 "github.com/k3s-io/cluster-api-k3s/controlplane/api/v1beta2"
Expand Down Expand Up @@ -112,3 +113,14 @@ func MatchesKThreesBootstrapConfig(machineConfigs map[string]*bootstrapv1.KThree
return reflect.DeepEqual(&machineConfig.Spec, kcpConfig)
}
}

// AgentHealthy returns a filter to find all machines that have an AgentHealthy
// set to true.
func AgentHealthy() Func {
return func(machine *clusterv1.Machine) bool {
if machine == nil {
return false
}
return conditions.IsTrue(machine, controlplanev1.MachineAgentHealthyCondition)
}
}
Loading