Skip to content

Commit 6070af7

Browse files
authored
install operator with no custom values in install2 (#1756)
* install operator with no custom values in install2 * check installation state is installed in install2 tests * use CRD based installation type * use correct CRD kind, apply multiple CRDs, wait for right condition * recreate crd object for second loop * add loading spinner, decrease wait times, remove debug logs * allow crd to be taken over by helm * remove prefix from installation name * formatting * set installation status after upgrade * Revert "set installation status after upgrade" This reverts commit 1b6cd62. * Revert "remove prefix from installation name" This reverts commit 226950b.
1 parent 5fc0962 commit 6070af7

File tree

12 files changed

+217
-95
lines changed

12 files changed

+217
-95
lines changed

cmd/installer/cli/install2.go

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import (
55
"errors"
66
"fmt"
77
"os"
8+
"strings"
89
"time"
910

1011
k0sconfig "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
1112
k0sv1beta1 "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
1213
"github.com/replicatedhq/embedded-cluster/cmd/installer/kotscli"
1314
ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
15+
"github.com/replicatedhq/embedded-cluster/operator/charts"
1416
"github.com/replicatedhq/embedded-cluster/pkg/addons2"
1517
"github.com/replicatedhq/embedded-cluster/pkg/configutils"
1618
"github.com/replicatedhq/embedded-cluster/pkg/extensions"
@@ -29,9 +31,12 @@ import (
2931
"github.com/sirupsen/logrus"
3032
"github.com/spf13/cobra"
3133
corev1 "k8s.io/api/core/v1"
34+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3235
k8serrors "k8s.io/apimachinery/pkg/api/errors"
3336
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
37+
"k8s.io/apimachinery/pkg/util/wait"
3438
"sigs.k8s.io/controller-runtime/pkg/client"
39+
"sigs.k8s.io/yaml"
3540
)
3641

3742
type Install2CmdFlags struct {
@@ -478,15 +483,25 @@ func installAndStartCluster(ctx context.Context, networkInterface string, airgap
478483
}
479484

480485
func recordInstallation(ctx context.Context, flags Install2CmdFlags, k0sCfg *k0sv1beta1.ClusterConfig, disasterRecoveryEnabled bool) (*ecv1beta1.Installation, error) {
486+
loading := spinner.Start()
487+
defer loading.Close()
488+
loading.Infof("Creating types")
489+
481490
kcli, err := kubeutils.KubeClient()
482491
if err != nil {
483492
return nil, fmt.Errorf("create kube client: %w", err)
484493
}
485494

495+
// ensure that the embedded-cluster namespace exists
486496
if err := createECNamespace(ctx, kcli); err != nil {
487497
return nil, fmt.Errorf("create embedded-cluster namespace: %w", err)
488498
}
489499

500+
// ensure that the installation CRD exists
501+
if err := createInstallationCRD(ctx, kcli); err != nil {
502+
return nil, fmt.Errorf("create installation CRD: %w", err)
503+
}
504+
490505
cfg, err := release.GetEmbeddedClusterConfig()
491506
if err != nil {
492507
return nil, err
@@ -525,7 +540,7 @@ func recordInstallation(ctx context.Context, flags Install2CmdFlags, k0sCfg *k0s
525540
RuntimeConfig: runtimeconfig.Get(),
526541
EndUserK0sConfigOverrides: euOverrides,
527542
BinaryName: runtimeconfig.BinaryName(),
528-
SourceType: ecv1beta1.InstallationSourceTypeConfigMap,
543+
SourceType: ecv1beta1.InstallationSourceTypeCRD,
529544
LicenseInfo: &ecv1beta1.LicenseInfo{
530545
IsDisasterRecoverySupported: disasterRecoveryEnabled,
531546
},
@@ -538,6 +553,11 @@ func recordInstallation(ctx context.Context, flags Install2CmdFlags, k0sCfg *k0s
538553
return nil, fmt.Errorf("create installation: %w", err)
539554
}
540555

556+
if err := kubeutils.UpdateInstallationStatus(ctx, kcli, &installation); err != nil {
557+
return nil, fmt.Errorf("update installation status: %w", err)
558+
}
559+
560+
loading.Infof("Types created!")
541561
return &installation, nil
542562
}
543563

@@ -547,7 +567,7 @@ func updateInstallation(ctx context.Context, install *ecv1beta1.Installation) er
547567
return fmt.Errorf("create kube client: %w", err)
548568
}
549569

550-
if err := kubeutils.UpdateInstallation(ctx, kcli, install); err != nil {
570+
if err := kubeutils.UpdateInstallationStatus(ctx, kcli, install); err != nil {
551571
return fmt.Errorf("update installation")
552572
}
553573
return nil
@@ -565,6 +585,54 @@ func createECNamespace(ctx context.Context, kcli client.Client) error {
565585
return nil
566586
}
567587

588+
func createInstallationCRD(ctx context.Context, kcli client.Client) error {
589+
// decode the CRD file
590+
crds := strings.Split(charts.InstallationCRDFile, "\n---\n")
591+
592+
for _, crdYaml := range crds {
593+
var crd apiextensionsv1.CustomResourceDefinition
594+
if err := yaml.Unmarshal([]byte(crdYaml), &crd); err != nil {
595+
return fmt.Errorf("unmarshal installation CRD: %w", err)
596+
}
597+
598+
// apply labels and annotations so that the CRD can be taken over by helm shortly
599+
if crd.Labels == nil {
600+
crd.Labels = map[string]string{}
601+
}
602+
crd.Labels["app.kubernetes.io/managed-by"] = "Helm"
603+
if crd.Annotations == nil {
604+
crd.Annotations = map[string]string{}
605+
}
606+
crd.Annotations["meta.helm.sh/release-name"] = "embedded-cluster-operator"
607+
crd.Annotations["meta.helm.sh/release-namespace"] = "embedded-cluster"
608+
609+
// apply the CRD
610+
if err := kcli.Create(ctx, &crd); err != nil {
611+
return fmt.Errorf("apply installation CRD: %w", err)
612+
}
613+
614+
// wait for the CRD to be ready
615+
backoff := wait.Backoff{Steps: 600, Duration: 100 * time.Millisecond, Factor: 1.0, Jitter: 0.1}
616+
if err := wait.ExponentialBackoffWithContext(ctx, backoff, func(ctx context.Context) (bool, error) {
617+
newCrd := apiextensionsv1.CustomResourceDefinition{}
618+
err := kcli.Get(ctx, client.ObjectKey{Name: crd.Name}, &newCrd)
619+
if err != nil {
620+
return false, nil // not ready yet
621+
}
622+
for _, cond := range newCrd.Status.Conditions {
623+
if cond.Type == apiextensionsv1.Established && cond.Status == apiextensionsv1.ConditionTrue {
624+
return true, nil
625+
}
626+
}
627+
return false, nil
628+
}); err != nil {
629+
return fmt.Errorf("wait for installation CRD to be ready: %w", err)
630+
}
631+
}
632+
633+
return nil
634+
}
635+
568636
func networkSpecFromK0sConfig(k0sCfg *k0sv1beta1.ClusterConfig) *ecv1beta1.NetworkSpec {
569637
network := &ecv1beta1.NetworkSpec{}
570638

e2e/scripts/check-installation-state2.sh

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,15 @@ main() {
1919
echo "pods"
2020
kubectl get pods -A
2121

22-
echo "TODO: check installation configmap state"
22+
echo "ensure that installation is installed"
23+
if echo "$version" | grep "pre-minio-removal"; then
24+
echo "waiting for installation as this is a pre-minio-removal embedded-cluster version (and so the installer doesn't wait for the installation to be ready itself)"
25+
wait_for_installation
26+
fi
27+
if ! ensure_installation_is_installed; then
28+
echo "installation is not installed"
29+
exit 1
30+
fi
2331

2432
if ! wait_for_nginx_pods; then
2533
echo "Failed waiting for the application's nginx pods"

kinds/apis/v1beta1/installation_types.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ const (
4545

4646
// Valid installation source types
4747
const (
48-
InstallationSourceTypeCRD string = "CRD"
49-
InstallationSourceTypeConfigMap string = "ConfigMap"
48+
InstallationSourceTypeCRD string = "CRD"
5049
)
5150

5251
const (

operator/charts/crd.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package charts
2+
3+
// this package is used to embed the installation CRD file into the binary
4+
5+
import _ "embed"
6+
7+
//go:embed embedded-cluster-operator/charts/crds/templates/resources.yaml
8+
var InstallationCRDFile string

pkg/addons2/addons.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/pkg/errors"
77
ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
88
"github.com/replicatedhq/embedded-cluster/pkg/addons2/adminconsole"
9+
"github.com/replicatedhq/embedded-cluster/pkg/addons2/embeddedclusteroperator"
910
"github.com/replicatedhq/embedded-cluster/pkg/addons2/openebs"
1011
"github.com/replicatedhq/embedded-cluster/pkg/addons2/registry"
1112
"github.com/replicatedhq/embedded-cluster/pkg/addons2/types"
@@ -69,6 +70,7 @@ func Install(ctx context.Context, opts InstallOptions) error {
6970
func getAddOns(opts InstallOptions) []types.AddOn {
7071
addOns := []types.AddOn{
7172
&openebs.OpenEBS{},
73+
&embeddedclusteroperator.EmbeddedClusterOperator{},
7274
}
7375

7476
if opts.AirgapBundle != "" {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package embeddedclusteroperator
2+
3+
import (
4+
_ "embed"
5+
6+
"github.com/pkg/errors"
7+
"github.com/replicatedhq/embedded-cluster/pkg/release"
8+
"gopkg.in/yaml.v2"
9+
)
10+
11+
type EmbeddedClusterOperator struct{}
12+
13+
const (
14+
releaseName = "embedded-cluster-operator"
15+
namespace = "embedded-cluster"
16+
)
17+
18+
var (
19+
//go:embed static/values.tpl.yaml
20+
rawvalues []byte
21+
// helmValues is the unmarshal version of rawvalues.
22+
helmValues map[string]interface{}
23+
//go:embed static/metadata.yaml
24+
rawmetadata []byte
25+
// Metadata is the unmarshal version of rawmetadata.
26+
Metadata release.AddonMetadata
27+
)
28+
29+
func init() {
30+
if err := yaml.Unmarshal(rawmetadata, &Metadata); err != nil {
31+
panic(errors.Wrap(err, "unable to unmarshal metadata"))
32+
}
33+
hv, err := release.RenderHelmValues(rawvalues, Metadata)
34+
if err != nil {
35+
panic(errors.Wrap(err, "unable to unmarshal values"))
36+
}
37+
helmValues = hv
38+
}
39+
40+
func (a *EmbeddedClusterOperator) Name() string {
41+
return "Embedded Cluster Operator"
42+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package embeddedclusteroperator
2+
3+
import (
4+
"context"
5+
6+
"github.com/pkg/errors"
7+
"github.com/replicatedhq/embedded-cluster/pkg/helm"
8+
"github.com/replicatedhq/embedded-cluster/pkg/spinner"
9+
"sigs.k8s.io/controller-runtime/pkg/client"
10+
)
11+
12+
func (o *EmbeddedClusterOperator) Install(ctx context.Context, kcli client.Client, hcli *helm.Helm, writer *spinner.MessageWriter) error {
13+
if err := o.prepare(); err != nil {
14+
return errors.Wrap(err, "prepare metrics operator")
15+
}
16+
17+
_, err := hcli.Install(ctx, helm.InstallOptions{
18+
ReleaseName: releaseName,
19+
ChartPath: Metadata.Location,
20+
ChartVersion: Metadata.Version,
21+
Values: helmValues,
22+
Namespace: namespace,
23+
})
24+
if err != nil {
25+
return errors.Wrap(err, "install metrics operator")
26+
}
27+
28+
return nil
29+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package embeddedclusteroperator
2+
3+
import (
4+
"github.com/pkg/errors"
5+
)
6+
7+
func (a *EmbeddedClusterOperator) prepare() error {
8+
if err := a.generateHelmValues(); err != nil {
9+
return errors.Wrap(err, "generate helm values")
10+
}
11+
12+
return nil
13+
}
14+
15+
func (a *EmbeddedClusterOperator) generateHelmValues() error {
16+
return nil
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#
2+
# this file is automatically generated by buildtools. manual edits are not recommended.
3+
# to regenerate this file, run the following commands:
4+
#
5+
# $ make buildtools
6+
# $ output/bin/buildtools update addon <addon name>
7+
#
8+
version: 1.19.0+k8s-1.30
9+
location: oci://proxy.replicated.com/anonymous/registry.replicated.com/library/embedded-cluster-operator
10+
images:
11+
embedded-cluster-operator:
12+
repo: proxy.replicated.com/anonymous/replicated/embedded-cluster-operator-image
13+
tag:
14+
amd64: v1.19.0-k8s-1.30
15+
arm64: v1.19.0-k8s-1.30
16+
utils:
17+
repo: proxy.replicated.com/anonymous/replicated/ec-utils
18+
tag:
19+
amd64: latest
20+
arm64: latest
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
global:
2+
labels:
3+
replicated.com/disaster-recovery: infra
4+
replicated.com/disaster-recovery-chart: embedded-cluster-operator
5+
{{- if .ReplaceImages }}
6+
image:
7+
repository: '{{ (index .Images "embedded-cluster-operator").Repo }}'
8+
tag: '{{ index (index .Images "embedded-cluster-operator").Tag .GOARCH }}'
9+
utilsImage: '{{ ImageString (index .Images "utils") }}'
10+
{{- end }}

0 commit comments

Comments
 (0)