Skip to content

Commit 3b6e1db

Browse files
authored
Various fixes (#106)
1 parent 17e2492 commit 3b6e1db

File tree

5 files changed

+81
-65
lines changed

5 files changed

+81
-65
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
workflow_call:
55
push:
66
branches:
7-
- 'main'
7+
- "main"
88
pull_request:
99

1010
# Declare default permissions as read only.
@@ -38,5 +38,5 @@ jobs:
3838
- name: golangci-lint
3939
uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v4.0.0
4040
with:
41-
version: v1.56.2
41+
version: v1.57.2
4242
skip-cache: true

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ test: manifests generate fmt vet envtest ## Run tests.
7272
KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test ./... -coverprofile cover.out
7373

7474
GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint
75-
GOLANGCI_LINT_VERSION ?= v1.54.2
75+
GOLANGCI_LINT_VERSION ?= v1.57.2
7676
golangci-lint:
7777
@[ -f $(GOLANGCI_LINT) ] || { \
7878
set -e ;\

api/v1alpha1/shim_types.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,17 @@ type RuntimeClassSpec struct {
4242
Handler string `json:"handler"`
4343
}
4444

45+
// +kubebuilder:validation:Enum=rolling;recreate
46+
type RolloutStrategyType string
47+
48+
const (
49+
RolloutStrategyTypeRolling RolloutStrategyType = "rolling"
50+
RolloutStrategyTypeRecreate RolloutStrategyType = "recreate"
51+
)
52+
4553
type RolloutStrategy struct {
46-
Type string `json:"type"`
47-
Rolling RollingSpec `json:"rolling,omitempty"`
54+
Type RolloutStrategyType `json:"type"`
55+
Rolling RollingSpec `json:"rolling,omitempty"`
4856
}
4957

5058
type RollingSpec struct {

config/crd/bases/runtime.kwasm.sh_shims.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ spec:
7373
- maxUpdate
7474
type: object
7575
type:
76+
enum:
77+
- rolling
78+
- recreate
7679
type: string
7780
required:
7881
- type

internal/controller/shim_controller.go

Lines changed: 65 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package controller
1818

1919
import (
2020
"context"
21+
"errors"
2122
"fmt"
2223
"math"
2324
"os"
@@ -38,13 +39,15 @@ import (
3839
"sigs.k8s.io/controller-runtime/pkg/predicate"
3940
"sigs.k8s.io/controller-runtime/pkg/reconcile"
4041

41-
kwasmv1 "github.com/spinkube/runtime-class-manager/api/v1alpha1"
42+
rcmv1 "github.com/spinkube/runtime-class-manager/api/v1alpha1"
4243
)
4344

4445
const (
45-
KwasmOperatorFinalizer = "kwasm.sh/finalizer"
46-
INSTALL = "install"
47-
UNINSTALL = "uninstall"
46+
RCMOperatorFinalizer = "rcm.spinkube.dev/finalizer"
47+
INSTALL = "install"
48+
UNINSTALL = "uninstall"
49+
ProvisioningStatusProvisioned = "provisioned"
50+
ProvisioningStatusPending = "pending"
4851
)
4952

5053
// ShimReconciler reconciles a Shim object
@@ -60,7 +63,7 @@ type ShimReconciler struct {
6063
// SetupWithManager sets up the controller with the Manager.
6164
func (sr *ShimReconciler) SetupWithManager(mgr ctrl.Manager) error {
6265
return ctrl.NewControllerManagedBy(mgr).
63-
For(&kwasmv1.Shim{}).
66+
For(&rcmv1.Shim{}).
6467
// As we create and own the created jobs
6568
// Jobs are important for us to update the Shims installation status
6669
// on respective nodes
@@ -91,12 +94,20 @@ func (sr *ShimReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
9194
ctx = log.WithContext(ctx)
9295

9396
// 1. Check if the shim resource exists
94-
var shimResource kwasmv1.Shim
97+
var shimResource rcmv1.Shim
9598
if err := sr.Client.Get(ctx, req.NamespacedName, &shimResource); err != nil {
9699
log.Err(err).Msg("Unable to fetch shimResource")
97100
return ctrl.Result{}, client.IgnoreNotFound(err)
98101
}
99102

103+
// Ensure the finalizer is called even if a return happens before
104+
defer func() {
105+
err := sr.ensureFinalizerForShim(ctx, &shimResource, RCMOperatorFinalizer)
106+
if err != nil {
107+
log.Error().Msgf("Failed to ensure finalizer: %s", err)
108+
}
109+
}()
110+
100111
// 2. Get list of nodes where this shim is supposed to be deployed on
101112
nodes, err := sr.getNodeListFromShimsNodeSelctor(ctx, &shimResource)
102113
if err != nil {
@@ -137,15 +148,11 @@ func (sr *ShimReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
137148
// 4. Deploy job to each node in list
138149
if len(nodes.Items) > 0 {
139150
_, err = sr.handleInstallShim(ctx, &shimResource, nodes)
140-
if err != nil {
141-
return ctrl.Result{}, err
142-
}
143151
} else {
144152
log.Info().Msg("No nodes found")
145153
}
146154

147-
err = sr.ensureFinalizerForShim(ctx, &shimResource, KwasmOperatorFinalizer)
148-
return ctrl.Result{}, client.IgnoreNotFound(err)
155+
return ctrl.Result{}, err
149156
}
150157

151158
// findShimsToReconcile finds all Shims that need to be reconciled.
@@ -154,7 +161,7 @@ func (sr *ShimReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl
154161
// that the shim is deployed on the node if it should be.
155162
func (sr *ShimReconciler) findShimsToReconcile(ctx context.Context, node client.Object) []reconcile.Request {
156163
_ = node
157-
shimList := &kwasmv1.ShimList{}
164+
shimList := &rcmv1.ShimList{}
158165
listOps := &client.ListOptions{
159166
Namespace: "",
160167
}
@@ -175,15 +182,15 @@ func (sr *ShimReconciler) findShimsToReconcile(ctx context.Context, node client.
175182
return requests
176183
}
177184

178-
func (sr *ShimReconciler) updateStatus(ctx context.Context, shim *kwasmv1.Shim, nodes *corev1.NodeList) error {
185+
func (sr *ShimReconciler) updateStatus(ctx context.Context, shim *rcmv1.Shim, nodes *corev1.NodeList) error {
179186
log := log.Ctx(ctx)
180187

181188
shim.Status.NodeCount = len(nodes.Items)
182189
shim.Status.NodeReadyCount = 0
183190

184191
if len(nodes.Items) > 0 {
185192
for _, node := range nodes.Items {
186-
if node.Labels[shim.Name] == "provisioned" {
193+
if node.Labels[shim.Name] == ProvisioningStatusProvisioned {
187194
shim.Status.NodeReadyCount++
188195
}
189196
}
@@ -205,43 +212,50 @@ func (sr *ShimReconciler) updateStatus(ctx context.Context, shim *kwasmv1.Shim,
205212
}
206213

207214
// handleInstallShim deploys a Job to each node in a list.
208-
func (sr *ShimReconciler) handleInstallShim(ctx context.Context, shim *kwasmv1.Shim, nodes *corev1.NodeList) (ctrl.Result, error) {
215+
func (sr *ShimReconciler) handleInstallShim(ctx context.Context, shim *rcmv1.Shim, nodes *corev1.NodeList) (ctrl.Result, error) {
209216
log := log.Ctx(ctx)
210217

211218
switch shim.Spec.RolloutStrategy.Type {
212-
case "rolling":
219+
case rcmv1.RolloutStrategyTypeRolling:
213220
{
214221
log.Debug().Msgf("Rolling strategy selected: maxUpdate=%d", shim.Spec.RolloutStrategy.Rolling.MaxUpdate)
222+
return ctrl.Result{}, errors.New("Rolling strategy not implemented yet")
215223
}
216-
case "recreate":
224+
case rcmv1.RolloutStrategyTypeRecreate:
217225
{
218226
log.Debug().Msgf("Recreate strategy selected")
219-
for i := range nodes.Items {
220-
node := nodes.Items[i]
221-
222-
shimProvisioned := node.Labels[shim.Name] == "provisioned"
223-
shimPending := node.Labels[shim.Name] == "pending"
224-
if !shimProvisioned && !shimPending {
225-
err := sr.deployJobOnNode(ctx, shim, node, INSTALL)
226-
if err != nil {
227-
return ctrl.Result{}, err
228-
}
229-
} else {
230-
log.Info().Msgf("Shim %s already provisioned on Node %s", shim.Name, node.Name)
231-
}
232-
}
227+
return sr.recreateStrategyRollout(ctx, shim, nodes)
233228
}
234229
default:
235230
{
236-
log.Debug().Msgf("No rollout strategy selected; using default: rolling")
231+
log.Debug().Msgf("No rollout strategy selected; using default: recreate")
232+
return sr.recreateStrategyRollout(ctx, shim, nodes)
237233
}
238234
}
235+
}
239236

240-
return ctrl.Result{}, nil
237+
func (sr *ShimReconciler) recreateStrategyRollout(ctx context.Context, shim *rcmv1.Shim, nodes *corev1.NodeList) (ctrl.Result, error) {
238+
log := log.Ctx(ctx)
239+
shimInstallationErrors := []error{}
240+
for i := range nodes.Items {
241+
node := nodes.Items[i]
242+
243+
shimProvisioned := node.Labels[shim.Name] == ProvisioningStatusProvisioned
244+
shimPending := node.Labels[shim.Name] == ProvisioningStatusPending
245+
if !shimProvisioned && !shimPending {
246+
err := sr.deployJobOnNode(ctx, shim, node, INSTALL)
247+
shimInstallationErrors = append(shimInstallationErrors, err)
248+
}
249+
250+
if shimProvisioned {
251+
log.Info().Msgf("Shim %s already provisioned on Node %s", shim.Name, node.Name)
252+
}
253+
}
254+
return ctrl.Result{}, errors.Join(shimInstallationErrors...)
241255
}
242256

243257
// deployUninstallJob deploys an uninstall Job for a Shim.
244-
func (sr *ShimReconciler) deployJobOnNode(ctx context.Context, shim *kwasmv1.Shim, node corev1.Node, jobType string) error {
258+
func (sr *ShimReconciler) deployJobOnNode(ctx context.Context, shim *rcmv1.Shim, node corev1.Node, jobType string) error {
245259
log := log.Ctx(ctx)
246260

247261
if err := sr.Client.Get(ctx, types.NamespacedName{Name: node.Name}, &node); err != nil {
@@ -255,7 +269,7 @@ func (sr *ShimReconciler) deployJobOnNode(ctx context.Context, shim *kwasmv1.Shi
255269

256270
switch jobType {
257271
case INSTALL:
258-
err := sr.updateNodeLabels(ctx, &node, shim, "pending")
272+
err := sr.updateNodeLabels(ctx, &node, shim, ProvisioningStatusPending)
259273
if err != nil {
260274
log.Error().Msgf("Unable to update node label %s: %s", shim.Name, err)
261275
}
@@ -297,7 +311,7 @@ func (sr *ShimReconciler) deployJobOnNode(ctx context.Context, shim *kwasmv1.Shi
297311
return nil
298312
}
299313

300-
func (sr *ShimReconciler) updateNodeLabels(ctx context.Context, node *corev1.Node, shim *kwasmv1.Shim, status string) error {
314+
func (sr *ShimReconciler) updateNodeLabels(ctx context.Context, node *corev1.Node, shim *rcmv1.Shim, status string) error {
301315
node.Labels[shim.Name] = status
302316

303317
if err := sr.Update(ctx, node); err != nil {
@@ -308,16 +322,12 @@ func (sr *ShimReconciler) updateNodeLabels(ctx context.Context, node *corev1.Nod
308322
}
309323

310324
// createJobManifest creates a Job manifest for a Shim.
311-
func (sr *ShimReconciler) createJobManifest(shim *kwasmv1.Shim, node *corev1.Node, operation string) (*batchv1.Job, error) {
325+
func (sr *ShimReconciler) createJobManifest(shim *rcmv1.Shim, node *corev1.Node, operation string) (*batchv1.Job, error) {
312326
priv := true
313327
name := node.Name + "-" + shim.Name + "-" + operation
314328
nameMax := int(math.Min(float64(len(name)), 63))
315329

316330
job := &batchv1.Job{
317-
TypeMeta: metav1.TypeMeta{
318-
Kind: "Job",
319-
APIVersion: "batch/v1",
320-
},
321331
ObjectMeta: metav1.ObjectMeta{
322332
Name: name[:nameMax],
323333
Namespace: os.Getenv("CONTROLLER_NAMESPACE"),
@@ -397,7 +407,7 @@ func (sr *ShimReconciler) createJobManifest(shim *kwasmv1.Shim, node *corev1.Nod
397407
}
398408

399409
// handleDeployRuntimeClass deploys a RuntimeClass for a Shim.
400-
func (sr *ShimReconciler) handleDeployRuntimeClass(ctx context.Context, shim *kwasmv1.Shim) (ctrl.Result, error) {
410+
func (sr *ShimReconciler) handleDeployRuntimeClass(ctx context.Context, shim *rcmv1.Shim) (ctrl.Result, error) {
401411
log := log.Ctx(ctx)
402412

403413
log.Info().Msgf("Deploying RuntimeClass: %s", shim.Spec.RuntimeClass.Name)
@@ -423,7 +433,7 @@ func (sr *ShimReconciler) handleDeployRuntimeClass(ctx context.Context, shim *kw
423433
}
424434

425435
// createRuntimeClassManifest creates a RuntimeClass manifest for a Shim.
426-
func (sr *ShimReconciler) createRuntimeClassManifest(shim *kwasmv1.Shim) (*nodev1.RuntimeClass, error) {
436+
func (sr *ShimReconciler) createRuntimeClassManifest(shim *rcmv1.Shim) (*nodev1.RuntimeClass, error) {
427437
name := shim.Name
428438
nameMax := int(math.Min(float64(len(name)), 63))
429439

@@ -433,14 +443,9 @@ func (sr *ShimReconciler) createRuntimeClassManifest(shim *kwasmv1.Shim) (*nodev
433443
}
434444

435445
runtimeClass := &nodev1.RuntimeClass{
436-
TypeMeta: metav1.TypeMeta{
437-
Kind: "RuntimeClass",
438-
APIVersion: "node.k8s.io/v1",
439-
},
440446
ObjectMeta: metav1.ObjectMeta{
441-
Name: name[:nameMax],
442-
Namespace: os.Getenv("CONTROLLER_NAMESPACE"),
443-
Labels: map[string]string{name[:nameMax]: "true"},
447+
Name: name[:nameMax],
448+
Labels: map[string]string{name[:nameMax]: "true"},
444449
},
445450
Handler: shim.Spec.RuntimeClass.Handler,
446451
Scheduling: &nodev1.Scheduling{
@@ -456,7 +461,7 @@ func (sr *ShimReconciler) createRuntimeClassManifest(shim *kwasmv1.Shim) (*nodev
456461
}
457462

458463
// handleDeleteShim deletes all possible child resources of a Shim. It will ignore NotFound errors.
459-
func (sr *ShimReconciler) handleDeleteShim(ctx context.Context, shim *kwasmv1.Shim, nodes *corev1.NodeList) error {
464+
func (sr *ShimReconciler) handleDeleteShim(ctx context.Context, shim *rcmv1.Shim, nodes *corev1.NodeList) error {
460465
// deploy uninstall job on every node in node list
461466
for i := range nodes.Items {
462467
node := nodes.Items[i]
@@ -473,15 +478,15 @@ func (sr *ShimReconciler) handleDeleteShim(ctx context.Context, shim *kwasmv1.Sh
473478
return nil
474479
}
475480

476-
func (sr *ShimReconciler) getNodeListFromShimsNodeSelctor(ctx context.Context, shim *kwasmv1.Shim) (*corev1.NodeList, error) {
481+
func (sr *ShimReconciler) getNodeListFromShimsNodeSelctor(ctx context.Context, shim *rcmv1.Shim) (*corev1.NodeList, error) {
477482
nodes := &corev1.NodeList{}
478483
if shim.Spec.NodeSelector != nil {
479-
err := sr.List(ctx, nodes, client.InNamespace(shim.Namespace), client.MatchingLabels(shim.Spec.NodeSelector))
484+
err := sr.List(ctx, nodes, client.MatchingLabels(shim.Spec.NodeSelector))
480485
if err != nil {
481486
return &corev1.NodeList{}, fmt.Errorf("failed to get node list: %w", err)
482487
}
483488
} else {
484-
err := sr.List(ctx, nodes, client.InNamespace(shim.Namespace))
489+
err := sr.List(ctx, nodes)
485490
if err != nil {
486491
return &corev1.NodeList{}, fmt.Errorf("failed to get node list: %w", err)
487492
}
@@ -491,7 +496,7 @@ func (sr *ShimReconciler) getNodeListFromShimsNodeSelctor(ctx context.Context, s
491496
}
492497

493498
// runtimeClassExists checks whether a RuntimeClass for a Shim exists.
494-
func (sr *ShimReconciler) runtimeClassExists(ctx context.Context, shim *kwasmv1.Shim) (bool, error) {
499+
func (sr *ShimReconciler) runtimeClassExists(ctx context.Context, shim *rcmv1.Shim) (bool, error) {
495500
log := log.Ctx(ctx)
496501

497502
if shim.Spec.RuntimeClass.Name != "" {
@@ -509,7 +514,7 @@ func (sr *ShimReconciler) runtimeClassExists(ctx context.Context, shim *kwasmv1.
509514
}
510515

511516
// getRuntimeClass finds a RuntimeClass.
512-
func (sr *ShimReconciler) getRuntimeClass(ctx context.Context, shim *kwasmv1.Shim) (*nodev1.RuntimeClass, error) {
517+
func (sr *ShimReconciler) getRuntimeClass(ctx context.Context, shim *rcmv1.Shim) (*nodev1.RuntimeClass, error) {
513518
rc := nodev1.RuntimeClass{}
514519
err := sr.Client.Get(ctx, types.NamespacedName{Name: shim.Spec.RuntimeClass.Name, Namespace: shim.Namespace}, &rc)
515520
if err != nil {
@@ -519,9 +524,9 @@ func (sr *ShimReconciler) getRuntimeClass(ctx context.Context, shim *kwasmv1.Shi
519524
}
520525

521526
// removeFinalizerFromShim removes the finalizer from a Shim.
522-
func (sr *ShimReconciler) removeFinalizerFromShim(ctx context.Context, shim *kwasmv1.Shim) error {
523-
if controllerutil.ContainsFinalizer(shim, KwasmOperatorFinalizer) {
524-
controllerutil.RemoveFinalizer(shim, KwasmOperatorFinalizer)
527+
func (sr *ShimReconciler) removeFinalizerFromShim(ctx context.Context, shim *rcmv1.Shim) error {
528+
if controllerutil.ContainsFinalizer(shim, RCMOperatorFinalizer) {
529+
controllerutil.RemoveFinalizer(shim, RCMOperatorFinalizer)
525530
if err := sr.Client.Update(ctx, shim); err != nil {
526531
return fmt.Errorf("failed to remove finalizer: %w", err)
527532
}
@@ -530,7 +535,7 @@ func (sr *ShimReconciler) removeFinalizerFromShim(ctx context.Context, shim *kwa
530535
}
531536

532537
// ensureFinalizerForShim ensures the finalizer is present on a Shim resource.
533-
func (sr *ShimReconciler) ensureFinalizerForShim(ctx context.Context, shim *kwasmv1.Shim, finalizer string) error {
538+
func (sr *ShimReconciler) ensureFinalizerForShim(ctx context.Context, shim *rcmv1.Shim, finalizer string) error {
534539
if !controllerutil.ContainsFinalizer(shim, finalizer) {
535540
controllerutil.AddFinalizer(shim, finalizer)
536541
if err := sr.Client.Update(ctx, shim); err != nil {

0 commit comments

Comments
 (0)