commit e4a19e5926c853132a3c6e6b302d5e121ba167faf0beec209d52ecc048651334
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2026-04-23T18:51:02Z |
| subject | Migrate to generated clients |
commit e4a19e5926c853132a3c6e6b302d5e121ba167faf0beec209d52ecc048651334
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2026-04-23T18:51:02Z
Migrate to generated clients
---
clitools/pkg/cmd/agent/agent.go | 4 +
clitools/pkg/controller/osupgrade/progress.go | 127 ++++-------
clitools/pkg/node/agent.go | 5 +
clitools/pkg/node/{admission.go => controller.go} | 27 ++-
devtools/build-all.sh | 248 ++++++++++++++++++++++
devtools/test-upgrade.sh | 2 +-
makefile | 2 +-
7 files changed, 312 insertions(+), 103 deletions(-)
diff --git a/clitools/pkg/cmd/agent/agent.go b/clitools/pkg/cmd/agent/agent.go
index dfc8148..e3c5420 100644
--- a/clitools/pkg/cmd/agent/agent.go
+++ b/clitools/pkg/cmd/agent/agent.go
@@ -265,6 +265,10 @@ func shouldHandle(osup *monov1alpha1.OSUpgradeProgress) bool {
return false
}
+ if osup.Status == nil {
+ return false
+ }
+
switch osup.Status.Phase {
case "",
monov1alpha1.OSUpgradeProgressPhasePending:
diff --git a/clitools/pkg/controller/osupgrade/progress.go b/clitools/pkg/controller/osupgrade/progress.go
index 4932a2b..587d111 100644
--- a/clitools/pkg/controller/osupgrade/progress.go
+++ b/clitools/pkg/controller/osupgrade/progress.go
@@ -7,9 +7,6 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
@@ -17,16 +14,6 @@ import (
"example.com/monok8s/pkg/kube"
)
-var (
- unstructuredConverter = runtime.DefaultUnstructuredConverter
-
- osup_gvr = schema.GroupVersionResource{
- Group: monov1alpha1.Group,
- Version: monov1alpha1.Version,
- Resource: "osupgradeprogresses",
- }
-)
-
func EnsureOSUpgradeProgressForNode(
ctx context.Context,
clients *kube.Clients,
@@ -39,6 +26,7 @@ func EnsureOSUpgradeProgressForNode(
}
name := fmt.Sprintf("%s-%s", osu.Name, nodeName)
+ now := metav1.Now()
progress := &monov1alpha1.OSUpgradeProgress{
TypeMeta: metav1.TypeMeta{
@@ -55,9 +43,13 @@ func EnsureOSUpgradeProgressForNode(
Name: osu.Name,
},
},
+ Status: &monov1alpha1.OSUpgradeProgressStatus{
+ Phase: monov1alpha1.OSUpgradeProgressPhasePending,
+ LastUpdatedAt: &now,
+ },
}
- created, err := createProgress(ctx, clients, osup_gvr, progress)
+ created, err := createProgress(ctx, clients, progress)
if err == nil {
klog.InfoS("created osupgradeprogress", "name", created.Name, "namespace", created.Namespace)
return nil
@@ -66,7 +58,7 @@ func EnsureOSUpgradeProgressForNode(
return fmt.Errorf("create OSUpgradeProgress %s/%s: %w", namespace, name, err)
}
- existing, err := getProgress(ctx, clients, osup_gvr, namespace, name)
+ existing, err := getProgress(ctx, clients, namespace, name)
if err != nil {
return fmt.Errorf("get existing OSUpgradeProgress %s/%s: %w", namespace, name, err)
}
@@ -96,7 +88,7 @@ func updateProgressRobust(
var out *monov1alpha1.OSUpgradeProgress
err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
- current, err := getProgress(ctx, clients, osup_gvr, namespace, name)
+ current, err := getProgress(ctx, clients, namespace, name)
if err != nil {
return err
}
@@ -107,10 +99,10 @@ func updateProgressRobust(
mutate(current)
- updated, err := updateProgressStatus(ctx, clients, osup_gvr, current)
+ updated, err := updateProgressStatus(ctx, clients, current)
if err != nil {
if isUnknownUpdateResult(err) {
- latest, getErr := getProgress(ctx, clients, osup_gvr, namespace, name)
+ latest, getErr := getProgress(ctx, clients, namespace, name)
if getErr == nil {
out = latest
}
@@ -152,84 +144,55 @@ func isUnknownUpdateResult(err error) bool {
func createProgress(
ctx context.Context,
clients *kube.Clients,
- gvr schema.GroupVersionResource,
progress *monov1alpha1.OSUpgradeProgress,
) (*monov1alpha1.OSUpgradeProgress, error) {
- obj, err := toUnstructured(progress)
- if err != nil {
- return nil, err
- }
+ toCreate := progress.DeepCopy()
+ toCreate.Status = nil
- created, err := clients.Dynamic.
- Resource(gvr).
- Namespace(progress.Namespace).
- Create(ctx, obj, metav1.CreateOptions{})
+ created, err := clients.MonoKS.
+ Monok8sV1alpha1().
+ OSUpgradeProgresses(toCreate.Namespace).
+ Create(ctx, toCreate, metav1.CreateOptions{})
if err != nil {
return nil, err
}
- return fromUnstructuredProgress(created)
-}
-
-func getProgress(
- ctx context.Context,
- clients *kube.Clients,
- gvr schema.GroupVersionResource,
- namespace, name string,
-) (*monov1alpha1.OSUpgradeProgress, error) {
- got, err := clients.Dynamic.
- Resource(gvr).
- Namespace(namespace).
- Get(ctx, name, metav1.GetOptions{})
- if err != nil {
- return nil, err
+ if progress.Status != nil {
+ toUpdate := created.DeepCopy()
+ toUpdate.Status = progress.Status
+ return updateProgressStatus(ctx, clients, toUpdate)
}
- return fromUnstructuredProgress(got)
+ return created, nil
}
-func updateProgressSpec(
+func updateProgressStatus(
ctx context.Context,
clients *kube.Clients,
- gvr schema.GroupVersionResource,
progress *monov1alpha1.OSUpgradeProgress,
) (*monov1alpha1.OSUpgradeProgress, error) {
- obj, err := toUnstructured(progress)
- if err != nil {
- return nil, err
- }
-
- updated, err := clients.Dynamic.
- Resource(gvr).
- Namespace(progress.Namespace).
- Update(ctx, obj, metav1.UpdateOptions{})
+ updated, err := clients.MonoKS.
+ Monok8sV1alpha1().
+ OSUpgradeProgresses(progress.Namespace).
+ UpdateStatus(ctx, progress, metav1.UpdateOptions{})
if err != nil {
- return nil, err
+ return nil, fmt.Errorf(
+ "update status for OSUpgradeProgress %s/%s: %w",
+ progress.Namespace, progress.Name, err,
+ )
}
-
- return fromUnstructuredProgress(updated)
+ return updated, nil
}
-func updateProgressStatus(
+func getProgress(
ctx context.Context,
clients *kube.Clients,
- gvr schema.GroupVersionResource,
- progress *monov1alpha1.OSUpgradeProgress,
+ namespace, name string,
) (*monov1alpha1.OSUpgradeProgress, error) {
- obj, err := toUnstructured(progress)
- if err != nil {
- return nil, err
- }
-
- updated, err := clients.Dynamic.
- Resource(gvr).
- Namespace(progress.Namespace).
- UpdateStatus(ctx, obj, metav1.UpdateOptions{})
- if err != nil {
- return nil, err
- }
-
- return fromUnstructuredProgress(updated)
+ return clients.MonoKS.
+ Monok8sV1alpha1().
+ OSUpgradeProgresses(namespace).
+ Get(ctx, name, metav1.GetOptions{})
}
func failProgress(
@@ -287,19 +250,3 @@ func markProgressCompleted(
return nil
}
-
-func toUnstructured(progress *monov1alpha1.OSUpgradeProgress) (*unstructured.Unstructured, error) {
- m, err := unstructuredConverter.ToUnstructured(progress)
- if err != nil {
- return nil, fmt.Errorf("convert OSUpgradeProgress to unstructured: %w", err)
- }
- return &unstructured.Unstructured{Object: m}, nil
-}
-
-func fromUnstructuredProgress(obj *unstructured.Unstructured) (*monov1alpha1.OSUpgradeProgress, error) {
- var progress monov1alpha1.OSUpgradeProgress
- if err := unstructuredConverter.FromUnstructured(obj.Object, &progress); err != nil {
- return nil, fmt.Errorf("convert unstructured to OSUpgradeProgress: %w", err)
- }
- return &progress, nil
-}
diff --git a/clitools/pkg/node/agent.go b/clitools/pkg/node/agent.go
index 13c42d8..1f54c5f 100644
--- a/clitools/pkg/node/agent.go
+++ b/clitools/pkg/node/agent.go
@@ -151,6 +151,11 @@ func applyControlAgentServiceAccount(ctx context.Context, kubeClient kubernetes.
func applyControlAgentClusterRole(ctx context.Context, kubeClient kubernetes.Interface, labels map[string]string) error {
wantRules := []rbacv1.PolicyRule{
+ {
+ APIGroups: []string{monov1alpha1.Group},
+ Resources: []string{"osupgrades"},
+ Verbs: []string{"get"},
+ },
{
APIGroups: []string{monov1alpha1.Group},
Resources: []string{"osupgradeprogresses"},
diff --git a/clitools/pkg/node/admission.go b/clitools/pkg/node/controller.go
similarity index 88%
rename from clitools/pkg/node/admission.go
rename to clitools/pkg/node/controller.go
index 61b36a4..9e4c7dd 100644
--- a/clitools/pkg/node/admission.go
+++ b/clitools/pkg/node/controller.go
@@ -21,9 +21,9 @@ import (
templates "example.com/monok8s/pkg/templates"
)
-func applyAdmissionControllerDeploymentResources(ctx context.Context, n *NodeContext) error {
+func applyControllerDeploymentResources(ctx context.Context, n *NodeContext) error {
if strings.TrimSpace(n.Config.Spec.ClusterRole) != "control-plane" || !n.Config.Spec.EnableControlAgent {
- klog.InfoS("skipped admission controller deployment",
+ klog.InfoS("skipped controller deployment",
"clusterRole", n.Config.Spec.ClusterRole,
"enableControlAgent", n.Config.Spec.EnableControlAgent,
)
@@ -56,23 +56,23 @@ func applyAdmissionControllerDeploymentResources(ctx context.Context, n *NodeCon
if err := ensureNamespace(ctx, kubeClient, namespace, labels); err != nil {
return fmt.Errorf("ensure namespace %q: %w", namespace, err)
}
- if err := applyAdmissionControllerServiceAccount(ctx, kubeClient, namespace, labels); err != nil {
+ if err := applyControllerServiceAccount(ctx, kubeClient, namespace, labels); err != nil {
return fmt.Errorf("apply serviceaccount: %w", err)
}
- if err := applyAdmissionControllerClusterRole(ctx, kubeClient, labels); err != nil {
+ if err := applyControllerClusterRole(ctx, kubeClient, labels); err != nil {
return fmt.Errorf("apply clusterrole: %w", err)
}
- if err := applyAdmissionControllerClusterRoleBinding(ctx, kubeClient, namespace, labels); err != nil {
+ if err := applyControllerClusterRoleBinding(ctx, kubeClient, namespace, labels); err != nil {
return fmt.Errorf("apply clusterrolebinding: %w", err)
}
- if err := applyAdmissionControllerDeployment(ctx, kubeClient, namespace, labels); err != nil {
+ if err := applyControllerDeployment(ctx, kubeClient, namespace, labels); err != nil {
return fmt.Errorf("apply deployment: %w", err)
}
return nil
}
-func applyAdmissionControllerServiceAccount(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error {
+func applyControllerServiceAccount(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error {
automount := true
want := &corev1.ServiceAccount{
@@ -111,7 +111,7 @@ func applyAdmissionControllerServiceAccount(ctx context.Context, kubeClient kube
return err
}
-func applyAdmissionControllerClusterRole(ctx context.Context, kubeClient kubernetes.Interface, labels map[string]string) error {
+func applyControllerClusterRole(ctx context.Context, kubeClient kubernetes.Interface, labels map[string]string) error {
wantRules := []rbacv1.PolicyRule{
{
APIGroups: []string{monov1alpha1.Group},
@@ -126,7 +126,12 @@ func applyAdmissionControllerClusterRole(ctx context.Context, kubeClient kuberne
{
APIGroups: []string{monov1alpha1.Group},
Resources: []string{"osupgradeprogresses"},
- Verbs: []string{"get", "list", "watch", "create", "patch", "update"},
+ Verbs: []string{"get", "list", "create"},
+ },
+ {
+ APIGroups: []string{monov1alpha1.Group},
+ Resources: []string{"osupgradeprogresses/status"},
+ Verbs: []string{"create"},
},
{
APIGroups: []string{""},
@@ -170,7 +175,7 @@ func applyAdmissionControllerClusterRole(ctx context.Context, kubeClient kuberne
return err
}
-func applyAdmissionControllerClusterRoleBinding(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error {
+func applyControllerClusterRoleBinding(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error {
wantSubjects := []rbacv1.Subject{
{
Kind: "ServiceAccount",
@@ -225,7 +230,7 @@ func applyAdmissionControllerClusterRoleBinding(ctx context.Context, kubeClient
return err
}
-func applyAdmissionControllerDeployment(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error {
+func applyControllerDeployment(ctx context.Context, kubeClient kubernetes.Interface, namespace string, labels map[string]string) error {
replicas := int32(1)
selectorLabels := map[string]string{
diff --git a/devtools/build-all.sh b/devtools/build-all.sh
new file mode 100755
index 0000000..df8860c
--- /dev/null
+++ b/devtools/build-all.sh
@@ -0,0 +1,248 @@
+#!/bin/bash
+set -euo pipefail
+
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+OUT_DIR="$(realpath "$SCRIPT_DIR/../out/")"
+
+cd "$SCRIPT_DIR/../"
+
+# ===== CONFIG TABLE =====
+# Add supported concrete builds here.
+# format: kube=crio
+CONFIGS=(
+ "v1.33.3=cri-o.arm64.v1.33.3"
+ "v1.34.1=cri-o.arm64.v1.34.1"
+ "v1.35.3=cri-o.arm64.v1.35.2"
+)
+
+# ===== HELPERS =====
+
+strip_v() {
+ echo "${1#v}"
+}
+
+minor_of_version() {
+ # input: 1.35.3 or v1.35.3
+ local v="${1#v}"
+ IFS='.' read -r major minor patch <<< "$v"
+ echo "$major.$minor"
+}
+
+version_sort() {
+ sort -t. -k1,1n -k2,2n -k3,3n
+}
+
+list_configs() {
+ echo "Available build targets:"
+ for c in "${CONFIGS[@]}"; do
+ local kube="${c%%=*}"
+ local crio="${c##*=}"
+ echo " ${kube#v} (CRI-O: $crio)"
+ done
+}
+
+list_minors() {
+ echo "Latest supported target per minor:"
+ latest_per_minor | while read -r kube crio; do
+ echo " ${kube#v} (CRI-O: $crio)"
+ done
+}
+
+latest_per_minor() {
+ # Output lines: <kube> <crio>
+ local minors
+ minors="$(
+ for c in "${CONFIGS[@]}"; do
+ kube="${c%%=*}"
+ minor_of_version "$kube"
+ done | sort -uV
+ )"
+
+ while read -r minor; do
+ [ -n "$minor" ] || continue
+ resolve_minor "$minor"
+ done <<< "$minors"
+}
+
+resolve_exact() {
+ local target="$1"
+ local target_v="v${target#v}"
+
+ for c in "${CONFIGS[@]}"; do
+ local kube="${c%%=*}"
+ local crio="${c##*=}"
+ if [[ "$kube" == "$target_v" ]]; then
+ echo "$kube $crio"
+ return 0
+ fi
+ done
+
+ return 1
+}
+
+resolve_minor() {
+ # input: 1.35 or v1.35
+ local want_minor
+ want_minor="$(minor_of_version "${1#v}.0")"
+
+ local matches=()
+ local c kube crio
+ for c in "${CONFIGS[@]}"; do
+ kube="${c%%=*}"
+ crio="${c##*=}"
+ if [[ "$(minor_of_version "$kube")" == "$want_minor" ]]; then
+ matches+=("${kube}=${crio}")
+ fi
+ done
+
+ if [[ ${#matches[@]} -eq 0 ]]; then
+ return 1
+ fi
+
+ local latest_kube
+ latest_kube="$(
+ for c in "${matches[@]}"; do
+ echo "${c%%=*#}" | sed 's/^v//'
+ done | version_sort | tail -n1
+ )"
+
+ resolve_exact "$latest_kube"
+}
+
+build_exact() {
+ local target="$1"
+ local resolved
+ if ! resolved="$(resolve_exact "$target")"; then
+ echo "❌ Unknown exact target: $target" >&2
+ echo >&2
+ list_configs >&2
+ exit 1
+ fi
+
+ local kube crio
+ read -r kube crio <<< "$resolved"
+
+ echo ">>> Building Kubernetes $kube with $crio"
+ make release CRIO_VERSION="$crio" KUBE_VERSION="$kube"
+}
+
+build_minor() {
+ local minor="$1"
+ local resolved
+ if ! resolved="$(resolve_minor "$minor")"; then
+ echo "❌ No supported target found for minor: $minor" >&2
+ echo >&2
+ list_minors >&2
+ exit 1
+ fi
+
+ local kube crio
+ read -r kube crio <<< "$resolved"
+
+ echo ">>> Minor $minor resolved to latest supported target ${kube#v}"
+ echo ">>> Building Kubernetes $kube with $crio"
+ make release CRIO_VERSION="$crio" KUBE_VERSION="$kube"
+}
+
+build_range() {
+ # input like 1.33-1.35
+ local range="$1"
+ local start="${range%-*}"
+ local end="${range#*-}"
+
+ local start_minor="${start#v}"
+ local end_minor="${end#v}"
+
+ local any=0
+ while read -r minor; do
+ [ -n "$minor" ] || continue
+
+ # simple lexical-safe because format is N.N and sort -V was used
+ if [[ "$(printf '%s\n%s\n' "$start_minor" "$minor" | sort -V | head -n1)" != "$start_minor" ]]; then
+ continue
+ fi
+ if [[ "$(printf '%s\n%s\n' "$minor" "$end_minor" | sort -V | head -n1)" != "$minor" ]]; then
+ continue
+ fi
+
+ any=1
+ build_minor "$minor"
+ done < <(
+ for c in "${CONFIGS[@]}"; do
+ kube="${c%%=*}"
+ minor_of_version "$kube"
+ done | sort -uV
+ )
+
+ if [[ $any -eq 0 ]]; then
+ echo "❌ No supported minors found in range: $range" >&2
+ echo >&2
+ list_minors >&2
+ exit 1
+ fi
+}
+
+build_all() {
+ local c kube crio
+ for c in "${CONFIGS[@]}"; do
+ kube="${c%%=*}"
+ crio="${c##*=}"
+ echo ">>> Building Kubernetes $kube with $crio"
+ make release CRIO_VERSION="$crio" KUBE_VERSION="$kube"
+ done
+}
+
+usage() {
+ cat <<'EOF'
+Usage:
+ ./devtools/build-all.sh
+ ./devtools/build-all.sh list
+ ./devtools/build-all.sh list-minors
+ ./devtools/build-all.sh 1.35.3
+ ./devtools/build-all.sh 1.35
+ ./devtools/build-all.sh 1.33-1.35
+
+Behavior:
+ no args Build all configured targets
+ list List all exact configured targets
+ list-minors List latest supported target per minor
+ X.Y.Z Build exact version
+ X.Y Build latest supported patch in that minor
+ X.Y-A.B Build latest supported patch for each minor in range
+EOF
+}
+
+# ===== ENTRY =====
+
+if [[ $# -eq 0 ]]; then
+ echo "No target specified -> building all configured targets"
+ build_all
+ exit 0
+fi
+
+case "$1" in
+ list)
+ list_configs
+ ;;
+ list-minors)
+ list_minors
+ ;;
+ -*|--help|help)
+ usage
+ ;;
+ *-*)
+ build_range "$1"
+ ;;
+ *.*.*)
+ build_exact "$1"
+ ;;
+ *.*)
+ build_minor "$1"
+ ;;
+ *)
+ echo "❌ Unrecognized target: $1" >&2
+ echo >&2
+ usage >&2
+ exit 1
+ ;;
+esac
diff --git a/devtools/test-upgrade.sh b/devtools/test-upgrade.sh
index 4e5ae4d..b4b6452 100755
--- a/devtools/test-upgrade.sh
+++ b/devtools/test-upgrade.sh
@@ -6,7 +6,7 @@ OUT_DIR="$( realpath "$SCRIPT_DIR"/../out/ )"
set -e
BASE_URL="http://localhost:8000"
-TARGET_VERSION="v1.34.6"
+TARGET_VERSION="v$1"
STABLE_VERSION="v1.34.6"
NAME="my-upgrade-1"
diff --git a/makefile b/makefile
index b3667a8..21d0fb2 100644
--- a/makefile
+++ b/makefile
@@ -38,7 +38,7 @@ PART_IMAGE := $(OUT_DIR)/monok8s-$(KUBE_VERSION)-$(TAG).ext4.zst
KERNEL_IMAGE := $(OUT_DIR)/Image.gz
BUILD_BASE_STAMP := $(OUT_DIR)/.build-base-$(TAG).stamp
-DOWNLOAD_PACKAGES_STAMP := $(PACKAGES_DIR)/.download-packages.stamp
+DOWNLOAD_PACKAGES_STAMP := $(PACKAGES_DIR)/.stamp-$(KUBE_VERSION)-$(CRIO_VERSION)
ALPINE_SERIES := $(word 1,$(subst ., ,$(ALPINE_VER))).$(word 2,$(subst ., ,$(ALPINE_VER)))