diff --git a/apis/datasciencecluster/v1/datasciencecluster_types.go b/apis/datasciencecluster/v1/datasciencecluster_types.go index 39166651ac1..5bc85631502 100644 --- a/apis/datasciencecluster/v1/datasciencecluster_types.go +++ b/apis/datasciencecluster/v1/datasciencecluster_types.go @@ -87,12 +87,6 @@ type Components struct { TrainingOperator trainingoperator.TrainingOperator `json:"trainingoperator,omitempty"` } -// ComponentsStatus defines the custom status of DataScienceCluster components. -type ComponentsStatus struct { - // ModelRegistry component status - ModelRegistry *status.ModelRegistryStatus `json:"modelregistry,omitempty"` -} - // DataScienceClusterStatus defines the observed state of DataScienceCluster. type DataScienceClusterStatus struct { // Phase describes the Phase of DataScienceCluster reconciliation state @@ -114,7 +108,7 @@ type DataScienceClusterStatus struct { // Expose component's specific status // +optional - Components ComponentsStatus `json:"components,omitempty"` + Components map[string]status.ReleaseStatus `json:"components,omitempty"` // Version and release type Release cluster.Release `json:"release,omitempty"` diff --git a/apis/datasciencecluster/v1/zz_generated.deepcopy.go b/apis/datasciencecluster/v1/zz_generated.deepcopy.go index f089d70e9ee..6eb35cd409f 100644 --- a/apis/datasciencecluster/v1/zz_generated.deepcopy.go +++ b/apis/datasciencecluster/v1/zz_generated.deepcopy.go @@ -53,26 +53,6 @@ func (in *Components) DeepCopy() *Components { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ComponentsStatus) DeepCopyInto(out *ComponentsStatus) { - *out = *in - if in.ModelRegistry != nil { - in, out := &in.ModelRegistry, &out.ModelRegistry - *out = new(status.ModelRegistryStatus) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentsStatus. -func (in *ComponentsStatus) DeepCopy() *ComponentsStatus { - if in == nil { - return nil - } - out := new(ComponentsStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DataScienceCluster) DeepCopyInto(out *DataScienceCluster) { *out = *in @@ -170,7 +150,13 @@ func (in *DataScienceClusterStatus) DeepCopyInto(out *DataScienceClusterStatus) (*out)[key] = val } } - in.Components.DeepCopyInto(&out.Components) + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = make(map[string]status.ReleaseStatus, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } in.Release.DeepCopyInto(&out.Release) } diff --git a/components/codeflare/codeflare.go b/components/codeflare/codeflare.go index 5e731c28ba4..213acefe050 100644 --- a/components/codeflare/codeflare.go +++ b/components/codeflare/codeflare.go @@ -8,7 +8,9 @@ import ( "fmt" "path/filepath" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -16,6 +18,7 @@ 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/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) @@ -72,6 +75,37 @@ func (c *CodeFlare) GetComponentName() string { return ComponentName } +func (c *CodeFlare) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: CodeflareOperator, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (c *CodeFlare) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, diff --git a/components/component.go b/components/component.go index c43cef7ac92..fc0508c5c4a 100644 --- a/components/component.go +++ b/components/component.go @@ -14,6 +14,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1" + "github.com/opendatahub-io/opendatahub-operator/v2/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" ) @@ -86,6 +87,7 @@ type ComponentInterface interface { owner metav1.Object, DSCISpec *dsciv1.DSCInitializationSpec, platform cluster.Platform, currentComponentStatus bool) error Cleanup(ctx context.Context, cli client.Client, owner metav1.Object, DSCISpec *dsciv1.DSCInitializationSpec) error GetComponentName() string + GetComponentStatus() ([]status.ComponentReleaseStatus, error) GetManagementState() operatorv1.ManagementState OverrideManifests(ctx context.Context, platform cluster.Platform) error UpdatePrometheusConfig(cli client.Client, logger logr.Logger, enable bool, component string) error diff --git a/components/dashboard/dashboard.go b/components/dashboard/dashboard.go index d2ed096b3bd..ff3afb342ef 100644 --- a/components/dashboard/dashboard.go +++ b/components/dashboard/dashboard.go @@ -9,7 +9,9 @@ import ( "fmt" "path/filepath" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" corev1 "k8s.io/api/core/v1" k8serr "k8s.io/apimachinery/pkg/api/errors" @@ -19,6 +21,7 @@ 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/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) @@ -82,6 +85,35 @@ func (d *Dashboard) GetComponentName() string { return ComponentNameUpstream } +func (d *Dashboard) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + fmt.Print("manifest path", d.DevFlags.Manifests) + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentNameUpstream, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["INTERNAL_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + } + releaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentNameUpstream), + DisplayName: ComponentNameDownstream, + Version: componentVersion, + RepoURL: d.DevFlags.Manifests[0].URI} + fmt.Print("release object", releaseStatus) + // returnDetails.UpstreamReleases = upstreamReleases + upstreamReleases = append(upstreamReleases, releaseStatus) + return upstreamReleases, nil +} + func (d *Dashboard) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, diff --git a/components/datasciencepipelines/datasciencepipelines.go b/components/datasciencepipelines/datasciencepipelines.go index f0066a6c544..6dd3cd0768b 100644 --- a/components/datasciencepipelines/datasciencepipelines.go +++ b/components/datasciencepipelines/datasciencepipelines.go @@ -8,7 +8,9 @@ import ( "fmt" "path/filepath" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1" corev1 "k8s.io/api/core/v1" @@ -93,6 +95,37 @@ func (d *DataSciencePipelines) GetComponentName() string { return ComponentName } +func (d *DataSciencePipelines) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentName, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (d *DataSciencePipelines) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, diff --git a/components/kserve/kserve.go b/components/kserve/kserve.go index 85b739285ea..6b15b5c8ca2 100644 --- a/components/kserve/kserve.go +++ b/components/kserve/kserve.go @@ -8,7 +8,9 @@ import ( "path/filepath" "strings" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -17,6 +19,7 @@ import ( dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1" infrav1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/infrastructure/v1" "github.com/opendatahub-io/opendatahub-operator/v2/components" + "github.com/opendatahub-io/opendatahub-operator/v2/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) @@ -111,6 +114,37 @@ func (k *Kserve) GetComponentName() string { return ComponentName } +func (k *Kserve) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentName, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (k *Kserve) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, platform cluster.Platform, _ bool) error { enabled := k.GetManagementState() == operatorv1.Managed diff --git a/components/kueue/kueue.go b/components/kueue/kueue.go index ec609317092..b04a121a413 100644 --- a/components/kueue/kueue.go +++ b/components/kueue/kueue.go @@ -6,7 +6,9 @@ import ( "fmt" "path/filepath" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -14,6 +16,7 @@ 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/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) @@ -68,6 +71,37 @@ func (k *Kueue) GetComponentName() string { return ComponentName } +func (k *Kueue) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentName, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (k *Kueue) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, platform cluster.Platform, _ bool) error { enabled := k.GetManagementState() == operatorv1.Managed diff --git a/components/modelmeshserving/modelmeshserving.go b/components/modelmeshserving/modelmeshserving.go index cb1d07b7838..16ea2b2e088 100644 --- a/components/modelmeshserving/modelmeshserving.go +++ b/components/modelmeshserving/modelmeshserving.go @@ -8,7 +8,9 @@ import ( "path/filepath" "strings" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -16,6 +18,7 @@ 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/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) @@ -101,6 +104,37 @@ func (m *ModelMeshServing) GetComponentName() string { return ComponentName } +func (m *ModelMeshServing) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentName, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (m *ModelMeshServing) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, diff --git a/components/modelregistry/modelregistry.go b/components/modelregistry/modelregistry.go index dbf577ec8f8..337e9b42f56 100644 --- a/components/modelregistry/modelregistry.go +++ b/components/modelregistry/modelregistry.go @@ -10,7 +10,9 @@ import ( "strings" "text/template" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -20,6 +22,7 @@ import ( dsciv1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/dscinitialization/v1" infrav1 "github.com/opendatahub-io/opendatahub-operator/v2/apis/infrastructure/v1" "github.com/opendatahub-io/opendatahub-operator/v2/components" + "github.com/opendatahub-io/opendatahub-operator/v2/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/conversion" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" @@ -97,6 +100,37 @@ func (m *ModelRegistry) GetComponentName() string { return ComponentName } +func (m *ModelRegistry) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentName, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (m *ModelRegistry) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, platform cluster.Platform, _ bool) error { enabled := m.GetManagementState() == operatorv1.Managed diff --git a/components/ray/ray.go b/components/ray/ray.go index c8fa30edbd4..ad9584c02ee 100644 --- a/components/ray/ray.go +++ b/components/ray/ray.go @@ -8,7 +8,9 @@ import ( "fmt" "path/filepath" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -16,13 +18,15 @@ 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/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) var ( - ComponentName = "ray" - RayPath = deploy.DefaultManifestPath + "/" + ComponentName + "/openshift" + ComponentName = "ray" + RayPath = deploy.DefaultManifestPath + "/" + ComponentName + "/openshift" + ComponentNameUpstream = "ray-project" ) // Verifies that Ray implements ComponentInterface. @@ -69,6 +73,34 @@ func (r *Ray) GetComponentName() string { return ComponentName } +func (r *Ray) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["RHOAI_RELEASE_VERSION"]) + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentNameUpstream, + Version: componentVersion, + RepoURL: repositoryURL} + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (r *Ray) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, platform cluster.Platform, _ bool) error { enabled := r.GetManagementState() == operatorv1.Managed diff --git a/components/trainingoperator/trainingoperator.go b/components/trainingoperator/trainingoperator.go index a6a7c8f87e7..a096ef72bd8 100644 --- a/components/trainingoperator/trainingoperator.go +++ b/components/trainingoperator/trainingoperator.go @@ -8,7 +8,9 @@ import ( "fmt" "path/filepath" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -16,6 +18,7 @@ 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/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) @@ -70,6 +73,37 @@ func (r *TrainingOperator) GetComponentName() string { return ComponentName } +func (r *TrainingOperator) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentName, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (r *TrainingOperator) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, platform cluster.Platform, _ bool) error { enabled := r.GetManagementState() == operatorv1.Managed diff --git a/components/trustyai/trustyai.go b/components/trustyai/trustyai.go index 45a211e79c0..e7050dfe2c8 100644 --- a/components/trustyai/trustyai.go +++ b/components/trustyai/trustyai.go @@ -7,7 +7,9 @@ import ( "fmt" "path/filepath" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -15,6 +17,7 @@ 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/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" ) @@ -79,6 +82,37 @@ func (t *TrustyAI) GetComponentName() string { return ComponentName } +func (t *TrustyAI) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentName, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (t *TrustyAI) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, platform cluster.Platform, _ bool) error { enabled := t.GetManagementState() == operatorv1.Managed diff --git a/components/workbenches/workbenches.go b/components/workbenches/workbenches.go index c11f1e24297..904b349b968 100644 --- a/components/workbenches/workbenches.go +++ b/components/workbenches/workbenches.go @@ -8,7 +8,9 @@ import ( "path/filepath" "strings" + "github.com/blang/semver/v4" "github.com/go-logr/logr" + "github.com/joho/godotenv" operatorv1 "github.com/openshift/api/operator/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" @@ -16,6 +18,7 @@ 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/controllers/status" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/cluster" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/deploy" "github.com/opendatahub-io/opendatahub-operator/v2/pkg/metadata/labels" @@ -111,6 +114,37 @@ func (w *Workbenches) GetComponentName() string { return ComponentName } +func (w *Workbenches) GetComponentStatus() ([]status.ComponentReleaseStatus, error) { + var componentVersion semver.Version + var repositoryURL string + var upstreamReleases = make([]status.ComponentReleaseStatus, 0) + + env, err := godotenv.Read(filepath.Join(deploy.DefaultManifestPath, ComponentName, ".env")) + + if err != nil { + fmt.Print("godotenv", err) + return nil, err + } + if env != nil { + componentVersion, err = semver.Parse(env["UPSTREAM_RELEASE_VERSION"]) + + if err != nil { + fmt.Print("getEnv error", err) + return nil, err + } + repositoryURL = env["REPOSITORY_URL"] + } + componentReleaseStatus := status.ComponentReleaseStatus{ + Name: status.Platform(ComponentName), + DisplayName: ComponentName, + Version: componentVersion, + RepoURL: repositoryURL} + + fmt.Print("release object", componentReleaseStatus) + upstreamReleases = append(upstreamReleases, componentReleaseStatus) + return upstreamReleases, nil +} + func (w *Workbenches) ReconcileComponent(ctx context.Context, cli client.Client, l logr.Logger, owner metav1.Object, dscispec *dsciv1.DSCInitializationSpec, platform cluster.Platform, _ bool) error { // Set default notebooks namespace diff --git a/config/crd/bases/datasciencecluster.opendatahub.io_datascienceclusters.yaml b/config/crd/bases/datasciencecluster.opendatahub.io_datascienceclusters.yaml index 41d1c76d658..618beaee665 100644 --- a/config/crd/bases/datasciencecluster.opendatahub.io_datascienceclusters.yaml +++ b/config/crd/bases/datasciencecluster.opendatahub.io_datascienceclusters.yaml @@ -648,14 +648,28 @@ spec: description: DataScienceClusterStatus defines the observed state of DataScienceCluster. properties: components: + additionalProperties: + properties: + registriesNamespace: + type: string + upstreamReleases: + items: + description: |- + Condition represents the state of the operator's + reconciliation functionality. + properties: + displayname: + type: string + name: + type: string + repourl: + type: string + version: + type: string + type: object + type: array + type: object description: Expose component's specific status - properties: - modelregistry: - description: ModelRegistry component status - properties: - registriesNamespace: - type: string - type: object type: object conditions: description: Conditions describes the state of the DataScienceCluster @@ -750,8 +764,12 @@ spec: release: description: Version and release type properties: + displayname: + type: string name: type: string + repourl: + type: string version: type: string type: object diff --git a/config/crd/bases/dscinitialization.opendatahub.io_dscinitializations.yaml b/config/crd/bases/dscinitialization.opendatahub.io_dscinitializations.yaml index dd381696bb1..adbefa1f9f3 100644 --- a/config/crd/bases/dscinitialization.opendatahub.io_dscinitializations.yaml +++ b/config/crd/bases/dscinitialization.opendatahub.io_dscinitializations.yaml @@ -293,8 +293,12 @@ spec: release: description: Version and release type properties: + displayname: + type: string name: type: string + repourl: + type: string version: type: string type: object diff --git a/controllers/datasciencecluster/datasciencecluster_controller.go b/controllers/datasciencecluster/datasciencecluster_controller.go index af00a344e73..bcc5f958fdb 100644 --- a/controllers/datasciencecluster/datasciencecluster_controller.go +++ b/controllers/datasciencecluster/datasciencecluster_controller.go @@ -293,6 +293,8 @@ func (r *DataScienceClusterReconciler) reconcileSubComponent(ctx context.Context log := r.Log componentName := component.GetComponentName() + componentStatus := make(map[string]status.ReleaseStatus) + enabled := component.GetManagementState() == operatorv1.Managed installedComponentValue, isExistStatus := instance.Status.InstalledComponents[componentName] @@ -333,6 +335,29 @@ func (r *DataScienceClusterReconciler) reconcileSubComponent(ctx context.Context }) return instance, err } + + details, err := component.GetComponentStatus() + + if err != nil { + fmt.Print("fetch details error", err) + } else { + fmt.Print("before marshal/unmarshal", details) + fmt.Print("ComponentStatus", componentStatus) + + instance, err = status.UpdateWithRetry(ctx, r.Client, instance, func(saved *dscv1.DataScienceCluster) { + if saved.Status.Components == nil { + saved.Status.Components = make(map[string]status.ReleaseStatus) + } + fmt.Print("after setProperty simply called") + saved.Status.Components[componentName] = status.ReleaseStatus{UpstreamReleases: details} + }) + if err != nil { + instance = r.reportError(err, instance, "failed to update Component status after reconciling ") + + return instance, err + } + } + // reconciliation succeeded: update status accordingly instance, err = status.UpdateWithRetry(ctx, r.Client, instance, func(saved *dscv1.DataScienceCluster) { if saved.Status.InstalledComponents == nil { @@ -348,9 +373,9 @@ func (r *DataScienceClusterReconciler) reconcileSubComponent(ctx context.Context // TODO: replace this hack with a full refactor of component status in the future if mr, isMR := component.(*modelregistry.ModelRegistry); isMR { if enabled { - saved.Status.Components.ModelRegistry = &status.ModelRegistryStatus{RegistriesNamespace: mr.RegistriesNamespace} + saved.Status.Components["ModelRegistry"] = status.ReleaseStatus{RegistriesNamespace: mr.RegistriesNamespace} } else { - saved.Status.Components.ModelRegistry = nil + saved.Status.Components["ModelRegistry"] = status.ReleaseStatus{} } } }) diff --git a/controllers/status/status.go b/controllers/status/status.go index 808cfee2f7b..4f5d5d071bc 100644 --- a/controllers/status/status.go +++ b/controllers/status/status.go @@ -19,6 +19,7 @@ limitations under the License. package status import ( + "github.com/blang/semver/v4" conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1" corev1 "k8s.io/api/core/v1" ) @@ -210,7 +211,20 @@ func RemoveComponentCondition(conditions *[]conditionsv1.Condition, component st conditionsv1.RemoveStatusCondition(conditions, conditionsv1.ConditionType(component+ReadySuffix)) } -// ModelRegistryStatus struct holds the status for the ModelRegistry component. -type ModelRegistryStatus struct { - RegistriesNamespace string `json:"registriesNamespace,omitempty"` +type Platform string + +// Condition represents the state of the operator's +// reconciliation functionality. +// +k8s:deepcopy-gen=true +type ComponentReleaseStatus struct { + Name Platform `json:"name,omitempty"` + DisplayName string `json:"displayname,omitempty"` + Version semver.Version `json:"version,omitempty"` + RepoURL string `json:"repourl,omitempty"` +} + +// +k8s:deepcopy-gen=true +type ReleaseStatus struct { + RegistriesNamespace string `json:"registriesNamespace,omitempty"` + UpstreamReleases []ComponentReleaseStatus `json:"upstreamReleases,omitempty"` } diff --git a/controllers/status/zz_generated.deepcopy.go b/controllers/status/zz_generated.deepcopy.go new file mode 100644 index 00000000000..2f01ae932e3 --- /dev/null +++ b/controllers/status/zz_generated.deepcopy.go @@ -0,0 +1,61 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package status + +import () + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentReleaseStatus) DeepCopyInto(out *ComponentReleaseStatus) { + *out = *in + in.Version.DeepCopyInto(&out.Version) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentReleaseStatus. +func (in *ComponentReleaseStatus) DeepCopy() *ComponentReleaseStatus { + if in == nil { + return nil + } + out := new(ComponentReleaseStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReleaseStatus) DeepCopyInto(out *ReleaseStatus) { + *out = *in + if in.UpstreamReleases != nil { + in, out := &in.UpstreamReleases, &out.UpstreamReleases + *out = make([]ComponentReleaseStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReleaseStatus. +func (in *ReleaseStatus) DeepCopy() *ReleaseStatus { + if in == nil { + return nil + } + out := new(ReleaseStatus) + in.DeepCopyInto(out) + return out +} diff --git a/go.mod b/go.mod index 9b86d8e92c2..1ea03118201 100644 --- a/go.mod +++ b/go.mod @@ -55,14 +55,17 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/imdario/mergo v0.3.13 // indirect + github.com/joho/godotenv v1.5.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/ompluscator/dynamic-struct v1.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect diff --git a/go.sum b/go.sum index 3b193384846..0718da71d92 100644 --- a/go.sum +++ b/go.sum @@ -219,6 +219,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -246,6 +248,8 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -262,6 +266,8 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/ompluscator/dynamic-struct v1.4.0 h1:I/Si9LZtItSwiTMe7vosEuIu2TKdOvWbE3R/lokpN4Q= +github.com/ompluscator/dynamic-struct v1.4.0/go.mod h1:ADQ1+6Ox1D+ntuNwTHyl1NvpAqY2lBXPSPbcO4CJdeA= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= diff --git a/manager b/manager new file mode 100755 index 00000000000..021c17cfe68 Binary files /dev/null and b/manager differ