From 438f4c26cb4e6c31831aed9a338a86f50a9cc2a9 Mon Sep 17 00:00:00 2001 From: Wen Zhou Date: Tue, 2 Jul 2024 16:56:25 +0200 Subject: [PATCH] refactor: dashboard with new manifests structure (#1065) * refactor: dashboard with new manifests structure - change type of platform, skip convert to string - add more support for ApplyParam() to not only take ENV but also anything from ExtraParamMaps * update: simplify override function * update: add value for Unknown platform --------- Signed-off-by: Wen Zhou --- components/README.md | 2 +- components/codeflare/codeflare.go | 4 +- components/component.go | 2 +- components/dashboard/dashboard.go | 226 ++++++------------ .../datasciencepipelines.go | 4 +- components/kserve/kserve.go | 4 +- components/kueue/kueue.go | 4 +- .../modelmeshserving/modelmeshserving.go | 4 +- components/modelregistry/modelregistry.go | 4 +- components/ray/ray.go | 4 +- .../trainingoperator/trainingoperator.go | 4 +- components/trustyai/trustyai.go | 4 +- components/workbenches/workbenches.go | 6 +- pkg/deploy/deploy.go | 72 +++--- pkg/plugins/addLabelsplugin.go | 2 +- 15 files changed, 141 insertions(+), 205 deletions(-) diff --git a/components/README.md b/components/README.md index 986bceaafaa..28c888e9b16 100644 --- a/components/README.md +++ b/components/README.md @@ -35,7 +35,7 @@ can be found [here](https://github.com/opendatahub-io/opendatahub-operator/tree/ Cleanup(cli client.Client, DSCISpec *dsciv1.DSCInitializationSpec) error GetComponentName() string GetManagementState() operatorv1.ManagementState - OverrideManifests(platform string) error + OverrideManifests(platform cluster.Platform) error UpdatePrometheusConfig(cli client.Client, enable bool, component string) error ConfigComponentLogger(logger logr.Logger, component string, dscispec *dsciv1.DSCInitializationSpec) logr.Logger } diff --git a/components/codeflare/codeflare.go b/components/codeflare/codeflare.go index 353c7609b21..f40d3f648ef 100644 --- a/components/codeflare/codeflare.go +++ b/components/codeflare/codeflare.go @@ -35,7 +35,7 @@ type CodeFlare struct { components.Component `json:""` } -func (c *CodeFlare) OverrideManifests(ctx context.Context, _ string) error { +func (c *CodeFlare) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // If devflags are set, update default manifests path if len(c.DevFlags.Manifests) != 0 { manifestConfig := c.DevFlags.Manifests[0] @@ -76,7 +76,7 @@ func (c *CodeFlare) ReconcileComponent(ctx context.Context, if enabled { if c.DevFlags != nil { // Download manifests and update paths - if err := c.OverrideManifests(ctx, string(platform)); err != nil { + if err := c.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/component.go b/components/component.go index c796e9483d0..d8cf1b240e8 100644 --- a/components/component.go +++ b/components/component.go @@ -84,7 +84,7 @@ type ComponentInterface interface { Cleanup(ctx context.Context, cli client.Client, DSCISpec *dsciv1.DSCInitializationSpec) error GetComponentName() string GetManagementState() operatorv1.ManagementState - OverrideManifests(ctx context.Context, platform string) error + OverrideManifests(ctx context.Context, platform cluster.Platform) error UpdatePrometheusConfig(cli client.Client, enable bool, component string) error ConfigComponentLogger(logger logr.Logger, component string, dscispec *dsciv1.DSCInitializationSpec) logr.Logger } diff --git a/components/dashboard/dashboard.go b/components/dashboard/dashboard.go index 7042b8050a0..aea2d4f55ef 100644 --- a/components/dashboard/dashboard.go +++ b/components/dashboard/dashboard.go @@ -5,13 +5,12 @@ package dashboard import ( "context" + "errors" "fmt" "path/filepath" - "strings" "github.com/go-logr/logr" operatorv1 "github.com/openshift/api/operator/v1" - routev1 "github.com/openshift/api/route/v1" corev1 "k8s.io/api/core/v1" k8serr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -20,26 +19,18 @@ import ( dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1" "github.com/opendatahub-io/opendatahub-operator/v2/components" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" - "github.com/opendatahub-io/opendatahub-operator/v2/pkg/common" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) var ( - ComponentName = "dashboard" - Path = deploy.DefaultManifestPath + "/" + ComponentName + "/base" // ODH - PathISV = deploy.DefaultManifestPath + "/" + ComponentName + "/apps" // ODH APPS - PathCRDs = deploy.DefaultManifestPath + "/" + ComponentName + "/crd" // ODH + RHOAI - PathConsoleLink = deploy.DefaultManifestPath + "/" + ComponentName + "/consolelink" // ODH consolelink - - ComponentNameSupported = "rhods-dashboard" - PathSupported = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/rhoai" // RHOAI - PathISVSM = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/apps/apps-onprem" // RHOAI APPS - PathISVAddOn = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/apps/apps-addon" // RHOAI APPS - PathConsoleLinkSupported = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/consolelink" // RHOAI - PathODHDashboardConfig = deploy.DefaultManifestPath + "/" + ComponentName + "/overlays/odhdashboardconfig" // RHOAI odhdashboardconfig - - NameConsoleLink = "console" - NamespaceConsoleLink = "openshift-console" + ComponentNameUpstream = "dashboard" + PathUpstream = deploy.DefaultManifestPath + "/" + ComponentNameUpstream + "/odh" + + ComponentNameDownstream = "rhods-dashboard" + PathDownstream = deploy.DefaultManifestPath + "/" + ComponentNameUpstream + "/rhoai" + PathSelfDownstream = PathDownstream + "/onprem" + PathManagedDownstream = PathDownstream + "/addon" + OverridePath = "" ) // Verifies that Dashboard implements ComponentInterface. @@ -51,37 +42,24 @@ type Dashboard struct { components.Component `json:""` } -func (d *Dashboard) OverrideManifests(ctx context.Context, platform string) error { +func (d *Dashboard) OverrideManifests(ctx context.Context, platform cluster.Platform) error { // If devflags are set, update default manifests path if len(d.DevFlags.Manifests) != 0 { manifestConfig := d.DevFlags.Manifests[0] - if err := deploy.DownloadManifests(ctx, ComponentName, manifestConfig); err != nil { + if err := deploy.DownloadManifests(ctx, ComponentNameUpstream, manifestConfig); err != nil { return err } - // If overlay is defined, update paths - if platform == string(cluster.ManagedRhods) || platform == string(cluster.SelfManagedRhods) { - defaultKustomizePath := "overlays/rhoai" - if manifestConfig.SourcePath != "" { - defaultKustomizePath = manifestConfig.SourcePath - } - PathSupported = filepath.Join(deploy.DefaultManifestPath, ComponentName, defaultKustomizePath) - } else { - defaultKustomizePath := "base" - if manifestConfig.SourcePath != "" { - defaultKustomizePath = manifestConfig.SourcePath - } - Path = filepath.Join(deploy.DefaultManifestPath, ComponentName, defaultKustomizePath) + if manifestConfig.SourcePath != "" { + OverridePath = filepath.Join(deploy.DefaultManifestPath, ComponentNameUpstream, manifestConfig.SourcePath) } } - return nil } func (d *Dashboard) GetComponentName() string { - return ComponentName + return ComponentNameUpstream } -//nolint:gocyclo func (d *Dashboard) ReconcileComponent(ctx context.Context, cli client.Client, logger logr.Logger, @@ -93,54 +71,62 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, var l logr.Logger if platform == cluster.SelfManagedRhods || platform == cluster.ManagedRhods { - l = d.ConfigComponentLogger(logger, ComponentNameSupported, dscispec) + l = d.ConfigComponentLogger(logger, ComponentNameDownstream, dscispec) } else { - l = d.ConfigComponentLogger(logger, ComponentName, dscispec) + l = d.ConfigComponentLogger(logger, ComponentNameUpstream, dscispec) } - var imageParamMap = map[string]string{ - "odh-dashboard-image": "RELATED_IMAGE_ODH_DASHBOARD_IMAGE", - } + entryPath := map[cluster.Platform]string{ + cluster.SelfManagedRhods: PathDownstream + "/onprem", + cluster.ManagedRhods: PathDownstream + "/addon", + cluster.OpenDataHub: PathUpstream, + cluster.Unknown: PathUpstream, + }[platform] + enabled := d.GetManagementState() == operatorv1.Managed monitoringEnabled := dscispec.Monitoring.ManagementState == operatorv1.Managed - // Update Default rolebinding if enabled { - // Update Default rolebinding - // cleanup OAuth client related secret and CR if dashboard is in 'installed false' status + // 1. cleanup OAuth client related secret and CR if dashboard is in 'installed false' status if err := d.cleanOauthClient(ctx, cli, dscispec, currentComponentExist, l); err != nil { return err } if d.DevFlags != nil { // Download manifests and update paths - if err := d.OverrideManifests(ctx, string(platform)); err != nil { + if err := d.OverrideManifests(ctx, platform); err != nil { return err } - } - // 1. Deploy CRDs - if err := d.deployCRDsForPlatform(ctx, cli, owner, dscispec.ApplicationsNamespace, platform); err != nil { - return fmt.Errorf("failed to deploy Dashboard CRD: %w", err) + if OverridePath != "" { + entryPath = OverridePath + } } // 2. platform specific RBAC if platform == cluster.OpenDataHub || platform == "" { - err := cluster.UpdatePodSecurityRolebinding(ctx, cli, dscispec.ApplicationsNamespace, "odh-dashboard") - if err != nil { + if err := cluster.UpdatePodSecurityRolebinding(ctx, cli, dscispec.ApplicationsNamespace, "odh-dashboard"); err != nil { return err } - } - - if platform == cluster.SelfManagedRhods || platform == cluster.ManagedRhods { - err := cluster.UpdatePodSecurityRolebinding(ctx, cli, dscispec.ApplicationsNamespace, "rhods-dashboard") - if err != nil { + } else { + if err := cluster.UpdatePodSecurityRolebinding(ctx, cli, dscispec.ApplicationsNamespace, "rhods-dashboard"); err != nil { return err } } // 3. Update image parameters + var imageParamMap = map[string]string{ + "odh-dashboard-image": "RELATED_IMAGE_ODH_DASHBOARD_IMAGE", + } + + // 4. Append or Update variable for component to consume + extraParamsMap, err := updateKustomizeVariable(ctx, cli, platform, dscispec) + if err != nil { + return errors.New("failed to set variable for extraParamsMap") + } + + // 5. update params.env if (dscispec.DevFlags == nil || dscispec.DevFlags.ManifestsUri == "") && (d.DevFlags == nil || len(d.DevFlags.Manifests) == 0) { - if err := deploy.ApplyParams(PathSupported, imageParamMap, false); err != nil { - return fmt.Errorf("failed to update image from %s : %w", PathSupported, err) + if err := deploy.ApplyParams(entryPath, imageParamMap, false, extraParamsMap); err != nil { + return fmt.Errorf("failed to update params.env from %s : %w", entryPath, err) } } } @@ -153,18 +139,9 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, if err := cluster.CreateSecret(ctx, cli, "anaconda-ce-access", dscispec.ApplicationsNamespace); err != nil { return fmt.Errorf("failed to create access-secret for anaconda: %w", err) } - // overlay which including ../../base + anaconda-ce-validator - if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathSupported, dscispec.ApplicationsNamespace, ComponentNameSupported, enabled); err != nil { - return fmt.Errorf("failed to apply manifests from %s: %w", PathSupported, err) - } - - // Apply RHOAI specific configs, e.g anaconda screct and cronjob and ISV - if err := d.applyRHOAISpecificConfigs(ctx, cli, owner, dscispec.ApplicationsNamespace, platform); err != nil { - return err - } - // consolelink - if err := d.deployConsoleLink(ctx, cli, owner, platform, dscispec.ApplicationsNamespace, ComponentNameSupported); err != nil { - return err + // Deploy RHOAI manifests + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, entryPath, dscispec.ApplicationsNamespace, ComponentNameDownstream, enabled); err != nil { + return fmt.Errorf("failed to apply manifests from %s: %w", PathDownstream, err) } l.Info("apply manifests done") @@ -172,13 +149,13 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, if platform == cluster.ManagedRhods { if enabled { // first check if the service is up, so prometheus won't fire alerts when it is just startup - if err := cluster.WaitForDeploymentAvailable(ctx, cli, ComponentNameSupported, dscispec.ApplicationsNamespace, 20, 3); err != nil { - return fmt.Errorf("deployment for %s is not ready to server: %w", ComponentName, err) + if err := cluster.WaitForDeploymentAvailable(ctx, cli, ComponentNameDownstream, dscispec.ApplicationsNamespace, 20, 3); err != nil { + return fmt.Errorf("deployment for %s is not ready to server: %w", ComponentNameDownstream, err) } l.Info("deployment is done, updating monitoring rules") } - if err := d.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentNameSupported); err != nil { + if err := d.UpdatePrometheusConfig(cli, enabled && monitoringEnabled, ComponentNameDownstream); err != nil { return err } if err := deploy.DeployManifestsFromPath(ctx, cli, owner, @@ -190,17 +167,10 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, l.Info("updating SRE monitoring done") } return nil + default: - // base - if err := deploy.DeployManifestsFromPath(ctx, cli, owner, Path, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { - return err - } - // ISV - if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathISV, dscispec.ApplicationsNamespace, ComponentName, enabled); err != nil { - return err - } - // consolelink - if err := d.deployConsoleLink(ctx, cli, owner, platform, dscispec.ApplicationsNamespace, ComponentName); err != nil { + // Deploy ODH manifests + if err := deploy.DeployManifestsFromPath(ctx, cli, owner, entryPath, dscispec.ApplicationsNamespace, ComponentNameUpstream, enabled); err != nil { return err } l.Info("apply manifests done") @@ -208,81 +178,37 @@ func (d *Dashboard) ReconcileComponent(ctx context.Context, } } -func (d *Dashboard) deployCRDsForPlatform(ctx context.Context, cli client.Client, owner metav1.Object, namespace string, platform cluster.Platform) error { - componentName := ComponentName - if platform == cluster.SelfManagedRhods || platform == cluster.ManagedRhods { - componentName = ComponentNameSupported - } - // we only deploy CRD, we do not remove CRD - return deploy.DeployManifestsFromPath(ctx, cli, owner, PathCRDs, namespace, componentName, true) -} - -func (d *Dashboard) applyRHOAISpecificConfigs(ctx context.Context, cli client.Client, owner metav1.Object, namespace string, platform cluster.Platform) error { - enabled := d.ManagementState == operatorv1.Managed - - // set proper group name - dashboardConfig := filepath.Join(PathODHDashboardConfig, "odhdashboardconfig.yaml") +func updateKustomizeVariable(ctx context.Context, cli client.Client, platform cluster.Platform, dscispec *dsciv1.DSCInitializationSpec) (map[string]string, error) { adminGroups := map[cluster.Platform]string{ cluster.SelfManagedRhods: "rhods-admins", cluster.ManagedRhods: "dedicated-admins", + cluster.OpenDataHub: "odh-admins", + cluster.Unknown: "odh-admins", }[platform] - if err := common.ReplaceStringsInFile(dashboardConfig, map[string]string{"": adminGroups}); err != nil { - return err - } - if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathODHDashboardConfig, namespace, ComponentNameSupported, enabled); err != nil { - return fmt.Errorf("failed to create OdhDashboardConfig from %s: %w", PathODHDashboardConfig, err) - } - // ISV - path := PathISVSM - if platform == cluster.ManagedRhods { - path = PathISVAddOn - } - if err := deploy.DeployManifestsFromPath(ctx, cli, owner, path, namespace, ComponentNameSupported, enabled); err != nil { - return fmt.Errorf("failed to set dashboard ISV from %s : %w", Path, err) - } - return nil -} - -func (d *Dashboard) deployConsoleLink(ctx context.Context, cli client.Client, owner metav1.Object, platform cluster.Platform, namespace, componentName string) error { - var manifestsPath, sectionTitle, routeName string - switch platform { - case cluster.SelfManagedRhods: - sectionTitle = "OpenShift Self Managed Services" - manifestsPath = PathConsoleLinkSupported - routeName = componentName - case cluster.ManagedRhods: - sectionTitle = "OpenShift Managed Services" - manifestsPath = PathConsoleLinkSupported - routeName = componentName - default: - sectionTitle = "OpenShift Open Data Hub" - manifestsPath = PathConsoleLink - routeName = "odh-dashboard" - } - - pathConsoleLink := filepath.Join(manifestsPath, "consolelink.yaml") - - consoleRoute := &routev1.Route{} - if err := cli.Get(ctx, client.ObjectKey{Name: NameConsoleLink, Namespace: NamespaceConsoleLink}, consoleRoute); err != nil { - return fmt.Errorf("error getting console route URL %s : %w", NameConsoleLink, err) - } - - domainIndex := strings.Index(consoleRoute.Spec.Host, ".") - consoleLinkDomain := consoleRoute.Spec.Host[domainIndex+1:] - if err := common.ReplaceStringsInFile(pathConsoleLink, map[string]string{ - "": "https://" + routeName + "-" + namespace + "." + consoleLinkDomain, - "": sectionTitle, - }); err != nil { - return fmt.Errorf("error replacing with correct dashboard URL for consolelink : %w", err) - } + sectionTitle := map[cluster.Platform]string{ + cluster.SelfManagedRhods: "OpenShift Self Managed Services", + cluster.ManagedRhods: "OpenShift Managed Services", + cluster.OpenDataHub: "OpenShift Open Data Hub", + cluster.Unknown: "OpenShift Open Data Hub", + }[platform] - enabled := d.ManagementState == operatorv1.Managed - if err := deploy.DeployManifestsFromPath(ctx, cli, owner, PathConsoleLink, namespace, componentName, enabled); err != nil { - return fmt.Errorf("failed to set dashboard consolelink %s : %w", pathConsoleLink, err) + consoleLinkDomain, err := cluster.GetDomain(ctx, cli) + if err != nil { + return nil, fmt.Errorf("error getting console route URL %s : %w", consoleLinkDomain, err) } + consoleURL := map[cluster.Platform]string{ + cluster.SelfManagedRhods: "https://rhods-dashboard-" + dscispec.ApplicationsNamespace + "." + consoleLinkDomain, + cluster.ManagedRhods: "https://rhods-dashboard-" + dscispec.ApplicationsNamespace + "." + consoleLinkDomain, + cluster.OpenDataHub: "https://odh-dashboard-" + dscispec.ApplicationsNamespace + "." + consoleLinkDomain, + cluster.Unknown: "https://odh-dashboard-" + dscispec.ApplicationsNamespace + "." + consoleLinkDomain, + }[platform] - return nil + return map[string]string{ + "admin_groups": adminGroups, + "dashboard-url": consoleURL, + "section-title": sectionTitle, + }, nil } func (d *Dashboard) cleanOauthClient(ctx context.Context, cli client.Client, dscispec *dsciv1.DSCInitializationSpec, currentComponentExist bool, l logr.Logger) error { diff --git a/components/datasciencepipelines/datasciencepipelines.go b/components/datasciencepipelines/datasciencepipelines.go index 14f68ed64a0..578c15614de 100644 --- a/components/datasciencepipelines/datasciencepipelines.go +++ b/components/datasciencepipelines/datasciencepipelines.go @@ -41,7 +41,7 @@ type DataSciencePipelines struct { components.Component `json:""` } -func (d *DataSciencePipelines) OverrideManifests(ctx context.Context, _ string) error { +func (d *DataSciencePipelines) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // If devflags are set, update default manifests path if len(d.DevFlags.Manifests) != 0 { manifestConfig := d.DevFlags.Manifests[0] @@ -97,7 +97,7 @@ func (d *DataSciencePipelines) ReconcileComponent(ctx context.Context, if enabled { if d.DevFlags != nil { // Download manifests and update paths - if err := d.OverrideManifests(ctx, string(platform)); err != nil { + if err := d.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/kserve/kserve.go b/components/kserve/kserve.go index 7265f647c99..ace508b8074 100644 --- a/components/kserve/kserve.go +++ b/components/kserve/kserve.go @@ -56,7 +56,7 @@ type Kserve struct { DefaultDeploymentMode DefaultDeploymentMode `json:"defaultDeploymentMode,omitempty"` } -func (k *Kserve) OverrideManifests(ctx context.Context, _ string) error { +func (k *Kserve) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // Download manifests if defined by devflags // Go through each manifest and set the overlays if defined for _, subcomponent := range k.DevFlags.Manifests { @@ -119,7 +119,7 @@ func (k *Kserve) ReconcileComponent(ctx context.Context, cli client.Client, } if k.DevFlags != nil { // Download manifests and update paths - if err := k.OverrideManifests(ctx, string(platform)); err != nil { + if err := k.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/kueue/kueue.go b/components/kueue/kueue.go index e6e3807d2b9..339a5c33d4f 100644 --- a/components/kueue/kueue.go +++ b/components/kueue/kueue.go @@ -31,7 +31,7 @@ type Kueue struct { components.Component `json:""` } -func (k *Kueue) OverrideManifests(ctx context.Context, _ string) error { +func (k *Kueue) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // If devflags are set, update default manifests path if len(k.DevFlags.Manifests) != 0 { manifestConfig := k.DevFlags.Manifests[0] @@ -65,7 +65,7 @@ func (k *Kueue) ReconcileComponent(ctx context.Context, cli client.Client, logge if enabled { if k.DevFlags != nil { // Download manifests and update paths - if err := k.OverrideManifests(ctx, string(platform)); err != nil { + if err := k.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/modelmeshserving/modelmeshserving.go b/components/modelmeshserving/modelmeshserving.go index ce094172740..31d7befcf0f 100644 --- a/components/modelmeshserving/modelmeshserving.go +++ b/components/modelmeshserving/modelmeshserving.go @@ -35,7 +35,7 @@ type ModelMeshServing struct { components.Component `json:""` } -func (m *ModelMeshServing) OverrideManifests(ctx context.Context, _ string) error { +func (m *ModelMeshServing) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // Go through each manifest and set the overlays if defined for _, subcomponent := range m.DevFlags.Manifests { if strings.Contains(subcomponent.URI, DependentComponentName) { @@ -100,7 +100,7 @@ func (m *ModelMeshServing) ReconcileComponent(ctx context.Context, if enabled { if m.DevFlags != nil { // Download manifests and update paths - if err := m.OverrideManifests(ctx, string(platform)); err != nil { + if err := m.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/modelregistry/modelregistry.go b/components/modelregistry/modelregistry.go index b20a7a97582..4e70cbf79bb 100644 --- a/components/modelregistry/modelregistry.go +++ b/components/modelregistry/modelregistry.go @@ -36,7 +36,7 @@ type ModelRegistry struct { components.Component `json:""` } -func (m *ModelRegistry) OverrideManifests(ctx context.Context, _ string) error { +func (m *ModelRegistry) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // If devflags are set, update default manifests path if len(m.DevFlags.Manifests) != 0 { manifestConfig := m.DevFlags.Manifests[0] @@ -71,7 +71,7 @@ func (m *ModelRegistry) ReconcileComponent(ctx context.Context, cli client.Clien if enabled { if m.DevFlags != nil { // Download manifests and update paths - if err := m.OverrideManifests(ctx, string(platform)); err != nil { + if err := m.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/ray/ray.go b/components/ray/ray.go index 8e582f7711e..f5fd468ae53 100644 --- a/components/ray/ray.go +++ b/components/ray/ray.go @@ -33,7 +33,7 @@ type Ray struct { components.Component `json:""` } -func (r *Ray) OverrideManifests(ctx context.Context, _ string) error { +func (r *Ray) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // If devflags are set, update default manifests path if len(r.DevFlags.Manifests) != 0 { manifestConfig := r.DevFlags.Manifests[0] @@ -70,7 +70,7 @@ func (r *Ray) ReconcileComponent(ctx context.Context, cli client.Client, logger if enabled { if r.DevFlags != nil { // Download manifests and update paths - if err := r.OverrideManifests(ctx, string(platform)); err != nil { + if err := r.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/trainingoperator/trainingoperator.go b/components/trainingoperator/trainingoperator.go index b7e68e243c2..fed2bb10ef3 100644 --- a/components/trainingoperator/trainingoperator.go +++ b/components/trainingoperator/trainingoperator.go @@ -33,7 +33,7 @@ type TrainingOperator struct { components.Component `json:""` } -func (r *TrainingOperator) OverrideManifests(ctx context.Context, _ string) error { +func (r *TrainingOperator) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // If devflags are set, update default manifests path if len(r.DevFlags.Manifests) != 0 { manifestConfig := r.DevFlags.Manifests[0] @@ -70,7 +70,7 @@ func (r *TrainingOperator) ReconcileComponent(ctx context.Context, cli client.Cl if enabled { if r.DevFlags != nil { // Download manifests and update paths - if err := r.OverrideManifests(ctx, string(platform)); err != nil { + if err := r.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/trustyai/trustyai.go b/components/trustyai/trustyai.go index 7bd452541cf..0bcf312eddc 100644 --- a/components/trustyai/trustyai.go +++ b/components/trustyai/trustyai.go @@ -33,7 +33,7 @@ type TrustyAI struct { components.Component `json:""` } -func (t *TrustyAI) OverrideManifests(ctx context.Context, _ string) error { +func (t *TrustyAI) OverrideManifests(ctx context.Context, _ cluster.Platform) error { // If devflags are set, update default manifests path if len(t.DevFlags.Manifests) != 0 { manifestConfig := t.DevFlags.Manifests[0] @@ -68,7 +68,7 @@ func (t *TrustyAI) ReconcileComponent(ctx context.Context, cli client.Client, lo if enabled { if t.DevFlags != nil { // Download manifests and update paths - if err := t.OverrideManifests(ctx, string(platform)); err != nil { + if err := t.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/components/workbenches/workbenches.go b/components/workbenches/workbenches.go index 4fd154532aa..0f3e55efe17 100644 --- a/components/workbenches/workbenches.go +++ b/components/workbenches/workbenches.go @@ -40,7 +40,7 @@ type Workbenches struct { components.Component `json:""` } -func (w *Workbenches) OverrideManifests(ctx context.Context, platform string) error { +func (w *Workbenches) OverrideManifests(ctx context.Context, platform cluster.Platform) error { // Download manifests if defined by devflags // Go through each manifest and set the overlays if defined for _, subcomponent := range w.DevFlags.Manifests { @@ -56,7 +56,7 @@ func (w *Workbenches) OverrideManifests(ctx context.Context, platform string) er defaultKustomizePath = subcomponent.SourcePath defaultKustomizePathSupported = subcomponent.SourcePath } - if platform == string(cluster.ManagedRhods) || platform == string(cluster.SelfManagedRhods) { + if platform == cluster.ManagedRhods || platform == cluster.SelfManagedRhods { notebookImagesPathSupported = filepath.Join(deploy.DefaultManifestPath, "jupyterhub", defaultKustomizePathSupported) } else { notebookImagesPath = filepath.Join(deploy.DefaultManifestPath, DependentComponentName, defaultKustomizePath) @@ -113,7 +113,7 @@ func (w *Workbenches) ReconcileComponent(ctx context.Context, cli client.Client, if enabled { if w.DevFlags != nil { // Download manifests and update paths - if err := w.OverrideManifests(ctx, string(platform)); err != nil { + if err := w.OverrideManifests(ctx, platform); err != nil { return err } } diff --git a/pkg/deploy/deploy.go b/pkg/deploy/deploy.go index 87dbfd95ebc..a5344082b81 100644 --- a/pkg/deploy/deploy.go +++ b/pkg/deploy/deploy.go @@ -240,92 +240,102 @@ func manageResource(ctx context.Context, cli client.Client, obj *unstructured.Un } /* -User env variable passed from CSV (if it is set) to overwrite values from manifests' params.env file +overwrite values in components' manifests params.env file This is useful for air gapped cluster priority of image values (from high to low): - image values set in manifests params.env if manifestsURI is set -- RELATED_IMAGE_* values from CSV +- RELATED_IMAGE_* values from CSV (if it is set) - image values set in manifests params.env if manifestsURI is not set. -parameter isUpdateNamespace is used to set if should update namespace with dsci applicationnamespace. +parameter isUpdateNamespace is used to set if should update namespace with DSCI CR's applicationnamespace. +extraParamsMaps is used to set extra parameters which are not carried from ENV variable. this can be passed per component. */ -func ApplyParams(componentPath string, imageParamsMap map[string]string, isUpdateNamespace bool) error { - envFilePath := filepath.Join(componentPath, "params.env") +func ApplyParams(componentPath string, imageParamsMap map[string]string, isUpdateNamespace bool, extraParamsMaps ...map[string]string) error { + paramsFile := filepath.Join(componentPath, "params.env") // Require params.env at the root folder - file, err := os.Open(envFilePath) + paramsEnv, err := os.Open(paramsFile) if err != nil { if os.IsNotExist(err) { // params.env doesn't exist, do not apply any changes return nil } - return err } - backupPath := envFilePath + ".bak" - defer file.Close() - envMap := make(map[string]string) - scanner := bufio.NewScanner(file) + defer paramsEnv.Close() + + paramsEnvMap := make(map[string]string) + scanner := bufio.NewScanner(paramsEnv) for scanner.Scan() { line := scanner.Text() parts := strings.SplitN(line, "=", 2) if len(parts) == 2 { - envMap[parts[0]] = parts[1] + paramsEnvMap[parts[0]] = parts[1] } } - if err := scanner.Err(); err != nil { return err } - // Update images with env variables + // 1. Update images with env variables // e.g "odh-kuberay-operator-controller-image": "RELATED_IMAGE_ODH_KUBERAY_OPERATOR_CONTROLLER_IMAGE", - for i := range envMap { + for i := range paramsEnvMap { relatedImageValue := os.Getenv(imageParamsMap[i]) if relatedImageValue != "" { - envMap[i] = relatedImageValue + paramsEnvMap[i] = relatedImageValue } } - // Update namespace variable with applicationNamepsace + // 2. Update namespace variable with applicationNamepsace if isUpdateNamespace { - envMap["namespace"] = imageParamsMap["namespace"] + paramsEnvMap["namespace"] = imageParamsMap["namespace"] + } + + // 3. Update other fileds with extraParamsMap which are not carried from component + for _, extraParamsMap := range extraParamsMaps { + for eKey, eValue := range extraParamsMap { + paramsEnvMap[eKey] = eValue + } } // Move the existing file to a backup file and create empty file - if err := os.Rename(envFilePath, backupPath); err != nil { + paramsBackupFile := paramsFile + ".bak" + if err := os.Rename(paramsFile, paramsBackupFile); err != nil { return err } - file, err = os.Create(envFilePath) + file, err := os.Create(paramsFile) if err != nil { // If create fails, try to restore the backup file - _ = os.Rename(backupPath, envFilePath) - + _ = os.Rename(paramsBackupFile, paramsFile) return err } defer file.Close() - // Now, write the map back to the file + // Now, write the new map back to params.env writer := bufio.NewWriter(file) - for key, value := range envMap { + for key, value := range paramsEnvMap { if _, fErr := fmt.Fprintf(writer, "%s=%s\n", key, value); fErr != nil { return fErr } } if err := writer.Flush(); err != nil { - if removeErr := os.Remove(envFilePath); removeErr != nil { - return removeErr + if removeErr := os.Remove(paramsFile); removeErr != nil { + fmt.Printf("Failed to remove file: %v", removeErr) } - if renameErr := os.Rename(backupPath, envFilePath); renameErr != nil { - return renameErr + if renameErr := os.Rename(paramsBackupFile, paramsFile); renameErr != nil { + fmt.Printf("Failed to restore file from backup: %v", renameErr) } + fmt.Printf("Failed to write to file: %v", err) return err } - // cleanup backup file - err = os.Remove(backupPath) + // cleanup backup file params.env.bak + if err := os.Remove(paramsBackupFile); err != nil { + fmt.Printf("Failed to remove backup file: %v", err) + return err + } - return err + return nil } // removeResourcesFromDeployment checks if the provided resource is a Deployment, diff --git a/pkg/plugins/addLabelsplugin.go b/pkg/plugins/addLabelsplugin.go index 5991c157d4c..13ecada5a93 100644 --- a/pkg/plugins/addLabelsplugin.go +++ b/pkg/plugins/addLabelsplugin.go @@ -1,7 +1,7 @@ package plugins import ( - "sigs.k8s.io/kustomize/api/builtins" //nolint:staticcheck //Remove after package update + "sigs.k8s.io/kustomize/api/builtins" //nolint:staticcheck // Remove after package update "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/kyaml/resid"