Skip to content

Commit

Permalink
Merge pull request #213 from fabiobrz/issues-212.openshift-ai.odh
Browse files Browse the repository at this point in the history
Adding provisioning tooling to deploy Open Data Hub Operator
  • Loading branch information
marekkopecky authored Jan 8, 2025
2 parents c160b26 + 33c9f0a commit 64c2ed8
Show file tree
Hide file tree
Showing 22 changed files with 2,409 additions and 26 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ Feel free to submit an issue in such a case, Intersmash welcomes community contr
| Red Hat JBoss EAP 7 | JBoss EAP 7.4.z (and XP 4.z) | |
| | | |
| Hyperfoil | 0.24.2 | Supports provisioning via the Operator, both on **Kubernetes** and **OpenShift** |
| | | |
| Open Data Hub | 2.22.0 | Supports provisioning on OpenShift via the Operator |

Since multiple deliverables can be bound to a given service version, e.g.: container images, operator CRs, or Helm Charts,
more information can be found in [the provisioners' documentation](./provisioners/README.md), or in the resources there linked.
Expand All @@ -175,7 +177,7 @@ We welcome community contributions to other Kubernetes implementations.


## Future goals
* OpenShift AI provisioning
* Full support for OpenShift AI provisioning
* Documentation and examples enhancements

see the [current milestone](https://github.com/Intersmash/intersmash/milestone/2) for a complete list of issues.
Expand Down
46 changes: 46 additions & 0 deletions core/src/main/java/org/jboss/intersmash/IntersmashConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ public class IntersmashConfig {
private static final String HYPERFOIL_OPERATOR_PACKAGE_MANIFEST = "intersmash.hyperfoil.operators.package_manifest";
private static final String COMMUNITY_HYPERFOIL_OPERATOR_PACKAGE_MANIFEST = "hyperfoil-bundle";
private static final String DEFAULT_HYPERFOIL_OPERATOR_PACKAGE_MANIFEST = COMMUNITY_HYPERFOIL_OPERATOR_PACKAGE_MANIFEST;
private static final String OPEN_DATA_HUB_OPERATOR_CATALOG_SOURCE_NAME = "intersmash.odh.operators.catalog_source";
private static final String OPEN_DATA_HUB_OPERATOR_INDEX_IMAGE = "intersmash.odh.operators.index_image";
private static final String OPEN_DATA_HUB_OPERATOR_CHANNEL = "intersmash.odh.operators.channel";
private static final String OPEN_DATA_HUB_OPERATOR_PACKAGE_MANIFEST = "intersmash.odh.operators.package_manifest";
private static final String COMMUNITY_OPEN_DATA_HUB_OPERATOR_PACKAGE_MANIFEST = "opendatahub-operator";
private static final String DEFAULT_OPEN_DATA_HUB_OPERATOR_PACKAGE_MANIFEST = COMMUNITY_OPEN_DATA_HUB_OPERATOR_PACKAGE_MANIFEST;

// Bootable Jar
private static final String BOOTABLE_JAR_IMAGE_URL = "intersmash.bootable.jar.image";

Expand Down Expand Up @@ -407,4 +414,43 @@ public static String keycloakOperatorChannel() {
public static String keycloakOperatorPackageManifest() {
return XTFConfig.get(KEYCLOAK_OPERATOR_PACKAGE_MANIFEST, DEFAULT_KEYCLOAK_OPERATOR_PACKAGE_MANIFEST);
}

/**
* Read the configuration property for the Open Data Hub Operator catalog source, i.e. {@code intersmash.odh.operators.catalog_source}.
*
* @return The value for the {@code intersmash.odh.operators.catalog_source} property or the default catalog source,
* i.e. the value of {@code intersmash.olm.operators.catalog_source} property.
*/
public static String openDataHubOperatorCatalogSource() {
return XTFConfig.get(OPEN_DATA_HUB_OPERATOR_CATALOG_SOURCE_NAME, defaultOperatorCatalogSourceName());
}

/**
* Read the configuration property for the Open Data Hub Operator index image, i.e. {@code intersmash.odh.operators.index_image}.
*
* @return The value for the {@code intersmash.odh.operators.index_image} property, representing a custom index image.
*/
public static String openDataHubOperatorIndexImage() {
return XTFConfig.get(OPEN_DATA_HUB_OPERATOR_INDEX_IMAGE);
}

/**
* Read the configuration property for the Open Data Hub Operator channel to be used, i.e. {@code intersmash.odh.operators.channel}.
*
* @return The value for the {@code intersmash.odh.operators.channel} property. If not provided the default operator
* channel is used.
*/
public static String openDataHubOperatorChannel() {
return XTFConfig.get(OPEN_DATA_HUB_OPERATOR_CHANNEL);
}

/**
* Read the configuration property for the Open Data Hub Operator channel to be used, i.e. {@code intersmash.odh.operators.package_manifest}.
*
* @return The value for the {@code intersmash.odh.operators.package_manifest} property or the default package manifest
* that should be used for this operator, i.e. {@code opendatahub-operator} property.
*/
public static String openDataHubOperatorPackageManifest() {
return XTFConfig.get(OPEN_DATA_HUB_OPERATOR_PACKAGE_MANIFEST, DEFAULT_OPEN_DATA_HUB_OPERATOR_PACKAGE_MANIFEST);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@
public abstract class OperatorProvisioner<A extends OperatorApplication, C extends NamespacedKubernetesClient>
implements Provisioner<A>, Scalable {
// cache the current csv and list of provided custom resource definitions
static String currentCSV;
final String packageManifestName;
protected static String currentCSV;
protected final String packageManifestName;
private CatalogSource catalogSource;
private final A operatorApplication;
private PackageManifest packageManifest;
Expand Down Expand Up @@ -180,6 +180,16 @@ private String getCatalogSourceNamespace() {
return namespace;
}

/**
* The CatalogSource is in the "openshift-marketplace" namespace by default on OpenShift, in the "olm" one on K8s.
* When a custom operator image must be used, then a custom CatalogSource will be created in the current namespace.
*
* @return namespace where the custom CatalogSource is located
*/
protected String getTargetNamespace() {
return this.client().getNamespace();
}

/**
* Initialize a reference to a proper catalog source which will be used to pull the required operator image.
*
Expand Down Expand Up @@ -350,7 +360,7 @@ public void subscribe(String installPlanApproval, Map<String, String> envVariabl
log.info("Subscribing the {} operator", packageManifestName);
// oc get packagemanifest wildfly -o template --template {{.status.defaultChannel}}
final String catalogSourceNamespace = getCatalogSourceNamespace();
final String targetNamespace = this.client().getNamespace();
final String targetNamespace = getTargetNamespace();
Subscription operatorSubscription = (envVariables == null || envVariables.isEmpty())
? new Subscription(catalogSourceNamespace, targetNamespace, getOperatorCatalogSource(),
packageManifestName,
Expand Down Expand Up @@ -462,7 +472,7 @@ protected void waitForOperatorPod() {
if (operatorSpec.length != 3) {
throw new IllegalStateException("Failed to get operator deployment spec from csvs!");
}
BooleanSupplier bs = () -> this.client().inNamespace(this.client().getNamespace()).pods().list().getItems().stream()
BooleanSupplier bs = () -> this.client().inNamespace(this.getTargetNamespace()).pods().list().getItems().stream()
.filter(p -> !com.google.common.base.Strings.isNullOrEmpty(p.getMetadata().getLabels().get(operatorSpec[1]))
&& p.getMetadata().getLabels().get(operatorSpec[1]).equals(operatorSpec[2])
&& p.getStatus().getContainerStatuses().size() > 0
Expand All @@ -486,8 +496,8 @@ protected FailFastCheck getFailFastCheck() {
* Documentation: https://docs.openshift.com/container-platform/4.4/operators/olm-deleting-operators-from-cluster.html#olm-deleting-operator-from-a-cluster-using-cli_olm-deleting-operators-from-a-cluster
*/
public void unsubscribe() {
this.execute("delete", "subscription", packageManifestName, "--ignore-not-found");
this.execute("delete", "csvs", currentCSV, "--ignore-not-found");
removeSubscription();
removeClusterServiceVersion();
for (String customResource : getCustomResourceDefinitions()) {
final String crds = this.execute("get", "crd", customResource, "--ignore-not-found");
if (crds != null && !crds.isEmpty()) {
Expand All @@ -496,6 +506,14 @@ public void unsubscribe() {
}
}

protected void removeClusterServiceVersion() {
this.execute("delete", "csvs", currentCSV, "--ignore-not-found");
}

protected void removeSubscription() {
this.execute("delete", "subscription", packageManifestName, "--ignore-not-found");
}

public String getCurrentCSV() {
return currentCSV;
}
Expand Down
3 changes: 2 additions & 1 deletion docs/Operator-Based-Provisioning.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ extended easily, since Intersmash _provisioners_ are pluggable components.
| Red Hat Build of keycloak (RHBK) | 24.0.3-opr.1 | stable-v24 | https://github.com/keycloak/keycloak/tree/main/operator | Latest Keycloak, based on Quarkus. |
| Red Hat SSO - **DEPRECATED** | 7.6.8-opr-001 | stable | https://github.com/keycloak/keycloak-operator | Latest Red Hat SSO Operator, based on legacy Keycloak |
| WildFly | 1.0.0 | alpha | https://github.com/wildfly/wildfly-operator | As available on https://operatorhub.io/operator/wildfly |
| Red Hat JBoss EAP | 3.0.0 | stable | https://github.com/wildfly/wildfly-operator | As available on the OpenShift OperatorHub |
| Red Hat JBoss EAP | 3.0.0 | stable | https://github.com/wildfly/wildfly-operator | As available from the OpenShift OperatorHub |
| Hyperfoil | 0.24.2 | alpha | https://github.com/Hyperfoil/hyperfoil-operator | Available for both **Kubernetes** and **OpenShift**. We force the CRs version for the used Hyperfoil runtime to be 0.24.2, see https://github.com/Hyperfoil/hyperfoil-operator/issues/18 |
| Open Data Hub | 2.22.0 | fast | https://github.com/opendatahub-io/opendatahub-operator | As available from the OpenShift OperatorHub |

Intersmash operator-based provisioners implement a common contract and high level behavior which is defined by the
[OperatorProvisioner](../core/src/main/java/org/jboss/intersmash/provision/openshift/operator/OperatorProvisioner.java)
Expand Down
1 change: 1 addition & 0 deletions docs/Provisioner-by-Product.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ The provisioner is selected by a factory, based on the _Application class_ type
| **Keycloak & Red Hat Build of Keycloak Operator** (see KeycloakOperatorApplication) | KeycloakOperatorProvisioner | :heavy_check_mark: | :heavy_check_mark: |
| **Red Hat SSO Operator** (see RhSsoOperatorApplication) - **DEPRECATED** | RhSsoOperatorProvisioner | :x: | :heavy_check_mark: |
| **WildFly & JBoss EAP 8 Operator** (see WildflyOperatorApplication) | WildflyOperatorProvisioner | :heavy_check_mark: | :heavy_check_mark: |
| **Open Data Hub operator** (see OpenDataHubOperatorApplication) | OpenDataHubOpenShiftOperatorProvisioner | :heavy_check_mark: | :x: |
| **Template based services** | | | |
| **JBoss EAP 7 Legacy s2i Build Template** (see Eap7LegacyS2iBuildTemplateApplication) | Eap7LegacyS2iBuildTemplateProvisioner | :x: | :heavy_check_mark: |
| **JBoss EAP 7 Legacy s2i Deployment Template** (see Eap7TemplateOpenShiftApplication) | Eap7TemplateOpenShiftProvisioner | :x: | :heavy_check_mark: |
Expand Down
29 changes: 15 additions & 14 deletions provisioners/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -236,25 +236,26 @@
<artifactId>java-generator-maven-plugin</artifactId>
<executions>
<execution>
<id>default-crd-generation</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<target>target/generated-sources</target>
<source>src/main/resources/crds</source>
<!--
This is needed to force the Java generator from CRD to stick with the original names
for enums, and avoid to uppercase them, since this could generate duplicate names,
as in https://github.com/infinispan/infinispan-operator/blob/2.3.4.Final/config/crd/bases/infinispan.org_infinispans.yaml#L1473-L1477
-->
<enumUppercase>false</enumUppercase>
<!--
The following is required in order to generate Sundrio and Lombok annotations
-->
<extraAnnotations>true</extraAnnotations>
</configuration>
</execution>
</executions>
<configuration>
<target>target/generated-sources</target>
<source>src/main/resources/crds</source>
<!--
This is needed to force the Java generator from CRD to stick with the original names
for enums, and avoid to uppercase them, since this could generate duplicate names,
as in https://github.com/infinispan/infinispan-operator/blob/2.3.4.Final/config/crd/bases/infinispan.org_infinispans.yaml#L1473-L1477
-->
<enumUppercase>false</enumUppercase>
<!--
The following is required in order to generate Sundrio and Lombok annotations
-->
<extraAnnotations>true</extraAnnotations>
</configuration>
</plugin>

<plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright (C) 2024 Red Hat, Inc.
*
* 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.
*/
package org.jboss.intersmash.application.operator;

import io.opendatahub.datasciencecluster.v1.DataScienceCluster;
import io.opendatahub.dscinitialization.v1.DSCInitialization;

/**
* End user Application interface which presents an Open Data Hub/OpenShift AI operator application.
* Only relevant model APIs are currently exposed, more would be added on demand
*
* The application will be deployed by:
* <ul>
* <li>{@link org.jboss.intersmash.provision.operator.OpenDataHubOperatorProvisioner}</li>
* </ul>
*/
public interface OpenDataHubOperatorApplication extends OperatorApplication {

/**
* Provides read access to the deployed {@link DataScienceCluster} instance.
* @return A {@link DataScienceCluster} instance that is deployed.
*/
DataScienceCluster getDataScienceCluster();

/**
* Provides read access to the {@link DSCInitialization} instance that should be used to initialize the
* deployed {@link DataScienceCluster}, represented by {@link #getDataScienceCluster} getter.
* @return A {@link DSCInitialization} instance that configures the deployed {@link DataScienceCluster}
*/
DSCInitialization getDSCInitialization();
}
Loading

0 comments on commit 64c2ed8

Please sign in to comment.