From 55022a09960a3a0362aacec3ba46ce7a90e9972e Mon Sep 17 00:00:00 2001 From: Salah Aldeen Al Saleh Date: Fri, 31 Jan 2025 08:59:44 -0800 Subject: [PATCH] use slog --- operator/pkg/cli/migratev2/installation.go | 19 ++--- operator/pkg/cli/migratev2/k0s.go | 11 +-- operator/pkg/cli/migratev2/migrate.go | 21 +++--- operator/pkg/cli/migratev2/operator.go | 9 +-- operator/pkg/cli/upgrade_job.go | 6 +- operator/pkg/upgrade/upgrade.go | 32 +++++---- pkg/addons2/upgrade.go | 56 +++++++-------- pkg/extensions/upgrade.go | 81 +++++++++++----------- 8 files changed, 120 insertions(+), 115 deletions(-) diff --git a/operator/pkg/cli/migratev2/installation.go b/operator/pkg/cli/migratev2/installation.go index 09517be88..b4565dc79 100644 --- a/operator/pkg/cli/migratev2/installation.go +++ b/operator/pkg/cli/migratev2/installation.go @@ -3,6 +3,7 @@ package migratev2 import ( "context" "fmt" + "log/slog" ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -12,43 +13,43 @@ import ( // setV2MigrationInProgress sets the Installation condition to indicate that the v2 migration is in // progress. -func setV2MigrationInProgress(ctx context.Context, logf LogFunc, cli client.Client, in *ecv1beta1.Installation) error { - logf("Setting v2 migration in progress") +func setV2MigrationInProgress(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) error { + slog.Info("Setting v2 migration in progress") err := setV2MigrationInProgressCondition(ctx, cli, in, metav1.ConditionTrue, "MigrationInProgress", "") if err != nil { return fmt.Errorf("set v2 migration in progress condition: %w", err) } - logf("Successfully set v2 migration in progress") + slog.Info("Successfully set v2 migration in progress") return nil } // setV2MigrationComplete sets the Installation condition to indicate that the v2 migration is // complete. -func setV2MigrationComplete(ctx context.Context, logf LogFunc, cli client.Client, in *ecv1beta1.Installation) error { - logf("Setting v2 migration complete") +func setV2MigrationComplete(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) error { + slog.Info("Setting v2 migration complete") err := setV2MigrationInProgressCondition(ctx, cli, in, metav1.ConditionFalse, "MigrationComplete", "") if err != nil { return fmt.Errorf("set v2 migration in progress condition: %w", err) } - logf("Successfully set v2 migration complete") + slog.Info("Successfully set v2 migration complete") return nil } // setV2MigrationFailed sets the Installation condition to indicate that the v2 migration has // failed. -func setV2MigrationFailed(ctx context.Context, logf LogFunc, cli client.Client, in *ecv1beta1.Installation, failure error) error { - logf("Setting v2 migration failed") +func setV2MigrationFailed(ctx context.Context, cli client.Client, in *ecv1beta1.Installation, failure error) error { + slog.Info("Setting v2 migration failed") err := setV2MigrationInProgressCondition(ctx, cli, in, metav1.ConditionFalse, "MigrationFailed", failure.Error()) if err != nil { return fmt.Errorf("set v2 migration in progress condition: %w", err) } - logf("Successfully set v2 migration failed") + slog.Info("Successfully set v2 migration failed") return nil } diff --git a/operator/pkg/cli/migratev2/k0s.go b/operator/pkg/cli/migratev2/k0s.go index cdbaebc4b..c8f17b79f 100644 --- a/operator/pkg/cli/migratev2/k0s.go +++ b/operator/pkg/cli/migratev2/k0s.go @@ -3,6 +3,7 @@ package migratev2 import ( "context" "fmt" + "log/slog" "time" k0shelmv1beta1 "github.com/k0sproject/k0s/pkg/apis/helm/v1beta1" @@ -36,22 +37,22 @@ func needsK0sChartCleanup(ctx context.Context, cli client.Client) (bool, error) } // cleanupK0sCharts removes control of the Helm Charts from the k0s controller. -func cleanupK0sCharts(ctx context.Context, logf LogFunc, cli client.Client) error { - logf("Force deleting Chart custom resources") +func cleanupK0sCharts(ctx context.Context, cli client.Client) error { + slog.Info("Force deleting Chart custom resources") // forceDeleteChartCRs is necessary because the k0s controller will otherwise uninstall the // Helm releases and we don't want that. err := forceDeleteChartCRs(ctx, cli) if err != nil { return fmt.Errorf("delete chart custom resources: %w", err) } - logf("Successfully force deleted Chart custom resources") + slog.Info("Successfully force deleted Chart custom resources") - logf("Removing Helm Charts from ClusterConfig") + slog.Info("Removing Helm Charts from ClusterConfig") err = removeClusterConfigHelmExtensions(ctx, cli) if err != nil { return fmt.Errorf("cleanup cluster config: %w", err) } - logf("Successfully removed Helm Charts from ClusterConfig") + slog.Info("Successfully removed Helm Charts from ClusterConfig") return nil } diff --git a/operator/pkg/cli/migratev2/migrate.go b/operator/pkg/cli/migratev2/migrate.go index b52f2f44f..e36ff6d06 100644 --- a/operator/pkg/cli/migratev2/migrate.go +++ b/operator/pkg/cli/migratev2/migrate.go @@ -3,6 +3,7 @@ package migratev2 import ( "context" "fmt" + "log/slog" ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -14,19 +15,19 @@ type LogFunc func(string, ...any) // Run runs the v1 to v2 migration. It installs the manager service on all nodes, copies the // installations to configmaps, enables the v2 admin console, and finally removes the operator // chart. -func Run(ctx context.Context, logf LogFunc, cli client.Client, in *ecv1beta1.Installation) (err error) { +func Run(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) (err error) { ok, err := needsMigration(ctx, cli) if err != nil { return fmt.Errorf("check if migration is needed: %w", err) } if !ok { - logf("No v2 migration needed") + slog.Info("No v2 migration needed") return nil } - logf("Running v2 migration") + slog.Info("Running v2 migration") - err = setV2MigrationInProgress(ctx, logf, cli, in) + err = setV2MigrationInProgress(ctx, cli, in) if err != nil { return fmt.Errorf("set v2 migration in progress: %w", err) } @@ -34,28 +35,28 @@ func Run(ctx context.Context, logf LogFunc, cli client.Client, in *ecv1beta1.Ins if err == nil { return } - if err := setV2MigrationFailed(ctx, logf, cli, in, err); err != nil { - logf("Failed to set v2 migration failed: %v", err) + if err := setV2MigrationFailed(ctx, cli, in, err); err != nil { + slog.Error("Failed to set v2 migration failed", "error", err) } }() // scale down the operator to ensure that it does not reconcile and revert our changes. - err = scaleDownOperator(ctx, logf, cli) + err = scaleDownOperator(ctx, cli) if err != nil { return fmt.Errorf("disable operator: %w", err) } - err = cleanupK0sCharts(ctx, logf, cli) + err = cleanupK0sCharts(ctx, cli) if err != nil { return fmt.Errorf("cleanup k0s: %w", err) } - err = setV2MigrationComplete(ctx, logf, cli, in) + err = setV2MigrationComplete(ctx, cli, in) if err != nil { return fmt.Errorf("set v2 migration complete: %w", err) } - logf("Successfully migrated from v2") + slog.Info("Successfully migrated from v2") return nil } diff --git a/operator/pkg/cli/migratev2/operator.go b/operator/pkg/cli/migratev2/operator.go index 0151cfcec..7990b369e 100644 --- a/operator/pkg/cli/migratev2/operator.go +++ b/operator/pkg/cli/migratev2/operator.go @@ -3,6 +3,7 @@ package migratev2 import ( "context" "fmt" + "log/slog" "time" appsv1 "k8s.io/api/apps/v1" @@ -20,22 +21,22 @@ const ( // scaleDownOperator scales down the operator deployment to 0 replicas to prevent the operator from // reconciling the installation. -func scaleDownOperator(ctx context.Context, logf LogFunc, cli client.Client) error { - logf("Scaling down operator") +func scaleDownOperator(ctx context.Context, cli client.Client) error { + slog.Info("Scaling down operator") err := setOperatorDeploymentReplicasZero(ctx, cli) if err != nil { return fmt.Errorf("set operator deployment replicas to 0: %w", err) } - logf("Waiting for operator to scale down") + slog.Info("Waiting for operator to scale down") err = waitForOperatorDeployment(ctx, cli) if err != nil { return fmt.Errorf("wait for operator deployment: %w", err) } - logf("Successfully scaled down operator") + slog.Info("Successfully scaled down operator") return nil } diff --git a/operator/pkg/cli/upgrade_job.go b/operator/pkg/cli/upgrade_job.go index 7d1c4bebc..db28412fc 100644 --- a/operator/pkg/cli/upgrade_job.go +++ b/operator/pkg/cli/upgrade_job.go @@ -114,11 +114,7 @@ func attemptUpgrade(ctx context.Context, kcli client.Client, in *ecv1beta1.Insta } }() - logf := func(format string, args ...any) { - fmt.Println(fmt.Sprintf(format, args...)) - } - - if err := migratev2.Run(ctx, logf, kcli, in); err != nil { + if err := migratev2.Run(ctx, kcli, in); err != nil { return fmt.Errorf("failed to run v2 migration: %w", err) } diff --git a/operator/pkg/upgrade/upgrade.go b/operator/pkg/upgrade/upgrade.go index 856fd1b25..2fc6f6fba 100644 --- a/operator/pkg/upgrade/upgrade.go +++ b/operator/pkg/upgrade/upgrade.go @@ -3,6 +3,7 @@ package upgrade import ( "context" "fmt" + "log/slog" "reflect" "time" @@ -28,6 +29,8 @@ import ( // Upgrade upgrades the embedded cluster to the version specified in the installation. // First the k0s cluster is upgraded, then addon charts are upgraded, and finally the installation is unlocked. func Upgrade(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) error { + slog.Info("Upgrading Embedded Cluster", "version", in.Spec.Config.Version) + // Augment the installation with data dirs that may not be present in the previous version. // This is important to do ahead of updating the cluster config. // We still cannot update the installation object as the CRDs are not updated yet. @@ -36,7 +39,6 @@ func Upgrade(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) return fmt.Errorf("override installation data dirs: %w", err) } - fmt.Printf("Upgrading to version %s\n", in.Spec.Config.Version) err = upgradeK0s(ctx, cli, in) if err != nil { return fmt.Errorf("k0s upgrade: %w", err) @@ -50,19 +52,19 @@ func Upgrade(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) return fmt.Errorf("cluster config update: %w", err) } - fmt.Printf("Upgrading addons\n") + slog.Info("Upgrading addons") err = upgradeAddons(ctx, cli, in) if err != nil { return fmt.Errorf("upgrade addons: %w", err) } - fmt.Printf("Upgrading extensions\n") + slog.Info("Upgrading extensions") err = upgradeExtensions(ctx, cli, in) if err != nil { return fmt.Errorf("upgrade extensions: %w", err) } - fmt.Printf("Re-applying installation\n") + slog.Info("Re-applying installation") // re-apply the installation as the CRDs are up-to-date. err = reApplyInstallation(ctx, cli, in) if err != nil { @@ -71,7 +73,7 @@ func Upgrade(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) err = support.CreateHostSupportBundle() if err != nil { - logrus.Warnf("Failed to upgrade host support bundle: %v", err) + logrus.Warnf("upgrade host support bundle: %v", err) } err = k8sutil.SetInstallationState(ctx, cli, in.Name, v1beta1.InstallationStateInstalled, "Installed") @@ -97,7 +99,7 @@ func maybeOverrideInstallationDataDirs(ctx context.Context, cli client.Client, i func upgradeK0s(ctx context.Context, cli client.Client, in *ecv1beta1.Installation) error { meta, err := release.MetadataFor(ctx, in, cli) if err != nil { - return fmt.Errorf("failed to get release metadata: %w", err) + return fmt.Errorf("get release metadata: %w", err) } // check if the k0s version is the same as the current version @@ -112,7 +114,7 @@ func upgradeK0s(ctx context.Context, cli client.Client, in *ecv1beta1.Installati return nil } - fmt.Printf("Upgrading k0s to version %s\n", desiredVersion) + slog.Info("Upgrading k0s", "version", desiredVersion) if err := k8sutil.SetInstallationState(ctx, cli, in.Name, ecv1beta1.InstallationStateInstalling, "Upgrading Kubernetes", ""); err != nil { return fmt.Errorf("update installation status: %w", err) @@ -120,12 +122,12 @@ func upgradeK0s(ctx context.Context, cli client.Client, in *ecv1beta1.Installati // create an autopilot upgrade plan if one does not yet exist if err := createAutopilotPlan(ctx, cli, desiredVersion, in, meta); err != nil { - return fmt.Errorf("failed to create autpilot upgrade plan: %w", err) + return fmt.Errorf("create autpilot upgrade plan: %w", err) } plan, err := waitForAutopilotPlan(ctx, cli) if err != nil { - return fmt.Errorf("failed to wait for autpilot plan: %w", err) + return fmt.Errorf("wait for autpilot plan: %w", err) } if autopilot.HasPlanFailed(plan) { @@ -161,9 +163,9 @@ func upgradeK0s(ctx context.Context, cli client.Client, in *ecv1beta1.Installati } // the plan has been completed, so we can move on - kubernetes is now upgraded - fmt.Printf("Upgrade to %s completed successfully\n", desiredVersion) + slog.Info("Upgrade completed successfully", "version", desiredVersion) if err := cli.Delete(ctx, &plan); err != nil { - return fmt.Errorf("failed to delete successful upgrade plan: %w", err) + return fmt.Errorf("delete successful upgrade plan: %w", err) } err = k8sutil.SetInstallationState(ctx, cli, in.Name, v1beta1.InstallationStateKubernetesInstalled, "Kubernetes upgraded") @@ -200,7 +202,7 @@ func updateClusterConfig(ctx context.Context, cli client.Client) error { if err != nil { return fmt.Errorf("update cluster config: %w", err) } - fmt.Println("Updated cluster config with new images") + slog.Info("Updated cluster config with new images") return nil } @@ -258,16 +260,16 @@ func createAutopilotPlan(ctx context.Context, cli client.Client, desiredVersion var plan apv1b2.Plan okey := client.ObjectKey{Name: "autopilot"} if err := cli.Get(ctx, okey, &plan); err != nil && !errors.IsNotFound(err) { - return fmt.Errorf("failed to get upgrade plan: %w", err) + return fmt.Errorf("get upgrade plan: %w", err) } else if errors.IsNotFound(err) { // if the kubernetes version has changed we create an upgrade command - fmt.Printf("Starting k0s autopilot upgrade plan to version %s\n", desiredVersion) + slog.Info("Starting k0s autopilot upgrade plan", "version", desiredVersion) // there is no autopilot plan in the cluster so we are free to // start our own plan. here we link the plan to the installation // by its name. if err := StartAutopilotUpgrade(ctx, cli, in, meta); err != nil { - return fmt.Errorf("failed to start upgrade: %w", err) + return fmt.Errorf("start upgrade: %w", err) } } return nil diff --git a/pkg/addons2/upgrade.go b/pkg/addons2/upgrade.go index 9198f3542..4618dc4c5 100644 --- a/pkg/addons2/upgrade.go +++ b/pkg/addons2/upgrade.go @@ -3,6 +3,7 @@ package addons2 import ( "context" "fmt" + "log/slog" "runtime/debug" "github.com/pkg/errors" @@ -110,44 +111,34 @@ func upgradeAddOn(ctx context.Context, hcli *helm.Helm, kcli client.Client, in * return errors.Wrap(err, "get condition status") } if conditionStatus == metav1.ConditionTrue { - fmt.Printf("%s is ready\n", addon.Name()) + slog.Info(addon.Name() + " is ready!") return nil } - fmt.Printf("Upgrading %s\n", addon.Name()) + slog.Info("Upgrading", "addon", addon.Name()) // mark as processing - if err := k8sutil.SetConditionStatus(ctx, kcli, in, metav1.Condition{ - Type: conditionName(addon), - Status: metav1.ConditionFalse, - Reason: "Upgrading", - }); err != nil { - return errors.Wrap(err, "set condition status") + if err := setCondition(ctx, kcli, in, conditionName(addon), metav1.ConditionFalse, "Upgrading", ""); err != nil { + return errors.Wrap(err, "failed to set condition status") } defer func() { if r := recover(); r != nil { finalErr = fmt.Errorf("upgrading %s recovered from panic: %v: %s", addon.Name(), r, string(debug.Stack())) } - if finalErr == nil { - // mark as processed successfully - if err := k8sutil.SetConditionStatus(ctx, kcli, in, metav1.Condition{ - Type: conditionName(addon), - Status: metav1.ConditionTrue, - Reason: "Upgraded", - }); err != nil { - fmt.Printf("failed to set condition status: %v", err) - } - } else { - // mark as failed - if err := k8sutil.SetConditionStatus(ctx, kcli, in, metav1.Condition{ - Type: conditionName(addon), - Status: metav1.ConditionFalse, - Reason: "UpgradeFailed", - Message: helpers.CleanErrorMessage(finalErr), - }); err != nil { - fmt.Printf("failed to set condition status: %v", err) - } + + status := metav1.ConditionTrue + reason := "Upgraded" + message := "" + + if finalErr != nil { + status = metav1.ConditionFalse + reason = "UpgradeFailed" + message = helpers.CleanErrorMessage(finalErr) + } + + if err := setCondition(ctx, kcli, in, conditionName(addon), status, reason, message); err != nil { + slog.Error("Failed to set condition status", "error", err) } }() @@ -158,10 +149,19 @@ func upgradeAddOn(ctx context.Context, hcli *helm.Helm, kcli client.Client, in * return errors.Wrap(err, addon.Name()) } - fmt.Printf("%s is ready\n", addon.Name()) + slog.Info(addon.Name() + " is ready!") return nil } func conditionName(addon types.AddOn) string { return fmt.Sprintf("%s-%s", addon.Namespace(), addon.ReleaseName()) } + +func setCondition(ctx context.Context, kcli client.Client, in *ecv1beta1.Installation, conditionType string, status metav1.ConditionStatus, reason, message string) error { + return k8sutil.SetConditionStatus(ctx, kcli, in, metav1.Condition{ + Type: conditionType, + Status: status, + Reason: reason, + Message: message, + }) +} diff --git a/pkg/extensions/upgrade.go b/pkg/extensions/upgrade.go index dff1c60a1..dcef36f02 100644 --- a/pkg/extensions/upgrade.go +++ b/pkg/extensions/upgrade.go @@ -3,6 +3,7 @@ package extensions import ( "context" "fmt" + "log/slog" "runtime/debug" "github.com/pkg/errors" @@ -77,53 +78,35 @@ func handleExtension(ctx context.Context, hcli *helm.Helm, kcli client.Client, i return errors.Wrap(err, "get condition status") } if conditionStatus == metav1.ConditionTrue { - fmt.Printf("%s already %sed\n", ext.Name, action) + slog.Info(fmt.Sprintf("%s already %sed", ext.Name, action)) return nil } - actionIng := "" - actionEd := "" - if action == actionInstall || action == actionUninstall { - actionIng = action + "ing" - actionEd = action + "ed" - } else if action == actionUpgrade { - actionIng = "Upgrading" - actionEd = "Upgraded" - } - fmt.Printf("%s %s\n", actionIng, ext.Name) + actionIng, actionEd := formatAction(action) + slog.Info(actionIng, "extension", ext.Name, "version", ext.Version) // mark as processing - if err := k8sutil.SetConditionStatus(ctx, kcli, in, metav1.Condition{ - Type: conditionName(ext), - Status: metav1.ConditionFalse, - Reason: actionIng, - }); err != nil { - return errors.Wrap(err, "set condition status") + if err := setCondition(ctx, kcli, in, conditionName(ext), metav1.ConditionFalse, actionIng, ""); err != nil { + return errors.Wrap(err, "failed to set condition status") } defer func() { if r := recover(); r != nil { finalErr = fmt.Errorf("%s %s recovered from panic: %v: %s", actionIng, ext.Name, r, string(debug.Stack())) } - if finalErr == nil { - // mark as processed successfully - if err := k8sutil.SetConditionStatus(ctx, kcli, in, metav1.Condition{ - Type: conditionName(ext), - Status: metav1.ConditionTrue, - Reason: actionEd, - }); err != nil { - fmt.Printf("failed to set condition status: %v", err) - } - } else { - // mark as failed - if err := k8sutil.SetConditionStatus(ctx, kcli, in, metav1.Condition{ - Type: conditionName(ext), - Status: metav1.ConditionFalse, - Reason: action + "Failed", - Message: helpers.CleanErrorMessage(finalErr), - }); err != nil { - fmt.Printf("failed to set condition status: %v", err) - } + + status := metav1.ConditionTrue + reason := actionEd + message := "" + + if finalErr != nil { + status = metav1.ConditionFalse + reason = action + "Failed" + message = helpers.CleanErrorMessage(finalErr) + } + + if err := setCondition(ctx, kcli, in, conditionName(ext), status, reason, message); err != nil { + slog.Error("Failed to set condition status", "error", err) } }() @@ -134,7 +117,7 @@ func handleExtension(ctx context.Context, hcli *helm.Helm, kcli client.Client, i return errors.Wrap(err, "check if release exists") } if exists { - fmt.Printf("%s already installed\n", ext.Name) + slog.Info(fmt.Sprintf("%s already installed", ext.Name)) return nil } if err := install(ctx, hcli, ext); err != nil { @@ -152,7 +135,7 @@ func handleExtension(ctx context.Context, hcli *helm.Helm, kcli client.Client, i return errors.Wrap(err, "check if release exists") } if !exists { - fmt.Printf("%s already uninstalled\n", ext.Name) + slog.Info(fmt.Sprintf("%s already uninstalled", ext.Name)) return nil } if err := uninstall(ctx, hcli, ext); err != nil { @@ -160,7 +143,27 @@ func handleExtension(ctx context.Context, hcli *helm.Helm, kcli client.Client, i } } - fmt.Printf("%s %sed successfully\n", ext.Name, actionEd) + slog.Info(fmt.Sprintf("%s %sed successfully", ext.Name, actionEd)) return nil } + +func formatAction(action string) (ing, ed string) { + switch action { + case actionInstall, actionUninstall: + return action + "ing", action + "ed" + case actionUpgrade: + return "Upgrading", "Upgraded" + default: + return "Processing", "Processed" + } +} + +func setCondition(ctx context.Context, kcli client.Client, in *ecv1beta1.Installation, conditionType string, status metav1.ConditionStatus, reason, message string) error { + return k8sutil.SetConditionStatus(ctx, kcli, in, metav1.Condition{ + Type: conditionType, + Status: status, + Reason: reason, + Message: message, + }) +}