diff --git a/pkg/embeddedcluster/monitor.go b/pkg/embeddedcluster/monitor.go index 4cb5d9f0ad..3d0e1d0eca 100644 --- a/pkg/embeddedcluster/monitor.go +++ b/pkg/embeddedcluster/monitor.go @@ -2,6 +2,7 @@ package embeddedcluster import ( "context" + "errors" "fmt" "sync" "time" @@ -18,6 +19,7 @@ var stateMut = sync.Mutex{} // it starts the upgrade process. We only start an upgrade if the following conditions are met: // - The app has an embedded cluster configuration. // - The app embedded cluster configuration differs from the current embedded cluster config. +// - The current cluster config (as part of the Installation object) already exists in the cluster. func MaybeStartClusterUpgrade(ctx context.Context, client kubernetes.Interface, store store.Store, conf *v1beta1.Config) error { if conf == nil { return nil @@ -33,6 +35,13 @@ func MaybeStartClusterUpgrade(ctx context.Context, client kubernetes.Interface, spec := conf.Spec if upgrade, err := RequiresUpgrade(ctx, spec); err != nil { + // if there is no installation object we can't start an upgrade. this is a valid + // scenario specially during cluster bootstrap. as we do not need to upgrade the + // cluster just after its installation we can return nil here. + // (the cluster in the first kots version will match the cluster installed during bootstrap) + if errors.Is(err, ErrNoInstallations) { + return nil + } return fmt.Errorf("failed to check if upgrade is required: %w", err) } else if !upgrade { return nil diff --git a/pkg/embeddedcluster/util.go b/pkg/embeddedcluster/util.go index ffcaacee0e..6487ee3601 100644 --- a/pkg/embeddedcluster/util.go +++ b/pkg/embeddedcluster/util.go @@ -21,6 +21,9 @@ import ( const configMapName = "embedded-cluster-config" const configMapNamespace = "embedded-cluster" +// ErrNoInstallations is returned when no installation object is found in the cluster. +var ErrNoInstallations = fmt.Errorf("no installations found") + // ReadConfigMap will read the Kurl config from a configmap func ReadConfigMap(client kubernetes.Interface) (*corev1.ConfigMap, error) { return client.CoreV1().ConfigMaps(configMapNamespace).Get(context.TODO(), configMapName, metav1.GetOptions{}) @@ -96,7 +99,7 @@ func GetCurrentInstallation(ctx context.Context) (*embeddedclusterv1beta1.Instal return nil, fmt.Errorf("failed to list installations: %w", err) } if len(installationList.Items) == 0 { - return nil, fmt.Errorf("no installations found") + return nil, ErrNoInstallations } items := installationList.Items sort.SliceStable(items, func(i, j int) bool {