diff --git a/core/src/main/java/org/jboss/intersmash/IntersmashConfig.java b/core/src/main/java/org/jboss/intersmash/IntersmashConfig.java index 1ed42ac85..107c69c77 100644 --- a/core/src/main/java/org/jboss/intersmash/IntersmashConfig.java +++ b/core/src/main/java/org/jboss/intersmash/IntersmashConfig.java @@ -112,6 +112,14 @@ public class IntersmashConfig { private static final String MYSQL_IMAGE_URL = "intersmash.mysql.image"; private static final String PGSQL_IMAGE_URL = "intersmash.postgresql.image"; + // OpenShift AI (Experimental) + private static final String OPEN_DATA_HUB_INSTALL_MODE = "intersmash.ai.odh.install.mode"; + public static final String OPEN_DATA_HUB_INSTALL_MODE_MANAGED = "managed"; + public static final String OPEN_DATA_HUB_INSTALL_MODE_UNMANAGED = "unmanaged"; + private static final String OPEN_DATA_HUB_INSTALL_MODE_DEFAULT = OPEN_DATA_HUB_INSTALL_MODE_MANAGED; + private static final String OPEN_DATA_HUB_INSTALL_MODE_UNMANAGED_CLASS_FQDN = "intersmash.ai.odh.install.unmanaged.class"; + private static final String OPEN_DATA_HUB_INSTALL_MODE_UNMANAGED_CLASS_FQDN_DEFAULT = "org.jboss.intersmash.provision.ai.OpenDataHubDefaultPrerequisitesProvisioner"; + public static boolean skipDeploy() { return XTFConfig.get(SKIP_DEPLOY, "false").equals("true"); } @@ -402,4 +410,13 @@ public static String keycloakOperatorChannel() { public static String keycloakOperatorPackageManifest() { return XTFConfig.get(KEYCLOAK_OPERATOR_PACKAGE_MANIFEST, DEFAULT_KEYCLOAK_OPERATOR_PACKAGE_MANIFEST); } + + public static String openDataHubInstallMode() { + return XTFConfig.get(OPEN_DATA_HUB_INSTALL_MODE, OPEN_DATA_HUB_INSTALL_MODE_DEFAULT); + } + + public static String openDataHubUnmanagedInstallClass() { + return XTFConfig.get(OPEN_DATA_HUB_INSTALL_MODE_UNMANAGED_CLASS_FQDN, + OPEN_DATA_HUB_INSTALL_MODE_UNMANAGED_CLASS_FQDN_DEFAULT); + } } diff --git a/core/src/main/java/org/jboss/intersmash/junit5/OpenDataHubExtension.java b/core/src/main/java/org/jboss/intersmash/junit5/OpenDataHubExtension.java new file mode 100644 index 000000000..4b2598e07 --- /dev/null +++ b/core/src/main/java/org/jboss/intersmash/junit5/OpenDataHubExtension.java @@ -0,0 +1,79 @@ +/** + * 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.junit5; + +import java.io.IOException; + +import org.jboss.intersmash.IntersmashConfig; +import org.jboss.intersmash.provision.ai.OpenDataHubSetupManager; +import org.junit.platform.launcher.TestExecutionListener; +import org.junit.platform.launcher.TestPlan; + +import cz.xtf.core.config.OpenShiftConfig; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OpenDataHubExtension implements TestExecutionListener { + protected static boolean handleOpenDataHubSetup = IntersmashConfig.OPEN_DATA_HUB_INSTALL_MODE_UNMANAGED.equals( + IntersmashConfig.openDataHubUnmanagedInstallClass()); + + @Override + public void testPlanExecutionStarted(TestPlan testPlan) { + if (handleOpenDataHubSetup) { + // Let the ODH Manager place a subscription to track that this session is handled. + // Note: the configured test namespace is used as identifier, so this might not be reliable in case + // a namespace is reused + try { + OpenDataHubSetupManager.getInstance().subscribe(OpenShiftConfig.namespace()); + } catch (IOException e) { + throw new IllegalStateException("Cannot subscribe to the Intersmash Open Data Hub manager: " + e); + } + // deploy pre-requisites + try { + if (!OpenDataHubSetupManager.getInstance().isReady() && !OpenDataHubSetupManager.getInstance().isInstalling()) { + OpenDataHubSetupManager.getInstance().setup(); + } + } catch (IOException e) { + throw new IllegalStateException("Cannot deploy Open Data Hub prerequisites: " + e); + } + } + } + + @Override + public void testPlanExecutionFinished(TestPlan testPlan) { + if (handleOpenDataHubSetup) { + // Let the ODH Manager remove the subscription that tracks that this session is handled. + // Note: the configured test namespace is used as identifier, so this might not be reliable in case + // a namespace is reused + try { + OpenDataHubSetupManager.getInstance().unsubscribe(OpenShiftConfig.namespace()); + } catch (IOException e) { + throw new IllegalStateException( + "Cannot remove a subscription from the Intersmash the Open Data Hub manager: " + e); + } + // undeploy pre-requisites, as long as there are no more subscribers + try { + if (OpenDataHubSetupManager.getInstance().getSubscribers().isEmpty() + && !OpenDataHubSetupManager.getInstance().isInstalling()) { + OpenDataHubSetupManager.getInstance().tearDown(); + } + } catch (IOException e) { + throw new IllegalStateException("Cannot undeploy Open Data Hub prerequisites: " + e); + } + + } + } +} diff --git a/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubPrerequisitesProvisioner.java b/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubPrerequisitesProvisioner.java new file mode 100644 index 000000000..c2cddb1c9 --- /dev/null +++ b/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubPrerequisitesProvisioner.java @@ -0,0 +1,57 @@ +/** + * 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.provision.ai; + +/** + * Provisioner for deploying and undeploying Open Data Hub prerequisites + */ +public interface OpenDataHubPrerequisitesProvisioner { + /** + * Task which will be performed by a provisioner prior to {@link #deploy()} operation. + */ + default void preDeploy() { + } + + /** + * Deploy the application. + */ + void deploy(); + + /** + * Undeploy the application. + */ + void undeploy(); + + /** + * Task which will be performed by a provisioner after the {@link #undeploy()} operation. + */ + default void postUndeploy() { + } + + /** + * Defines an operation for configuring the provisioner, before any deployment related tasks are executed, e.g.: + * for Operator based provisioners this allows for configuring custom catalog sources etc. + */ + default void configure() { + } + + /** + * Defines an operation for configuring the provisioner, after all deploy related tasks are executed, e.g.: + * for Operator based provisioners this allows for removing custom catalog sources etc. + */ + default void dismiss() { + } +} diff --git a/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubPrerequisitesProvisionerFactory.java b/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubPrerequisitesProvisionerFactory.java new file mode 100644 index 000000000..70d2ccae0 --- /dev/null +++ b/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubPrerequisitesProvisionerFactory.java @@ -0,0 +1,30 @@ +/** + * 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.provision.ai; + +public interface OpenDataHubPrerequisitesProvisionerFactory { + + default Integer getOrder() { + return 0; + } + + /** + * @param fqdn Fully Qualified DOmain Name of the provisioner class that should be looked up and used to + * provision ODH prerequisites + * @return provisioner for the given FQDN or null + */ + T getProvisioner(final String fqdn); +} diff --git a/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubSetupManager.java b/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubSetupManager.java new file mode 100644 index 000000000..0461376fd --- /dev/null +++ b/core/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubSetupManager.java @@ -0,0 +1,220 @@ +package org.jboss.intersmash.provision.ai; + +import java.io.IOException; +import java.util.*; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +import org.jboss.intersmash.IntersmashConfig; +import org.jboss.intersmash.provision.openshift.operator.resources.OperatorGroup; + +import cz.xtf.core.config.OpenShiftConfig; +import cz.xtf.core.openshift.OpenShift; +import cz.xtf.core.openshift.OpenShifts; +import io.fabric8.kubernetes.api.builder.Visitor; +import io.fabric8.kubernetes.api.model.NamespaceBuilder; +import io.fabric8.kubernetes.client.KubernetesClientException; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OpenDataHubSetupManager { + + private static final String GLOBAL_OPERATOR_GROUP_NAMESPACE_DEFAULT = "intersmash-odh-dedicated"; + private static OpenDataHubSetupManager instance; + private final OpenShift openShift; + /** + * A "meta" provisioner that can deploy the components that are needed by Open Data Hub, like Authorino, + * Service Mesh, etc. + * + * @return The {@link OpenDataHubPrerequisitesProvisioner} instance that will handle the provisioning of + * ODH prerequisites, see https://github.com/opendatahub-io/opendatahub-operator#prerequisites + */ + private OpenDataHubPrerequisitesProvisioner requiredComponentsProvisioner = null; + + public static OpenDataHubSetupManager getInstance() throws IOException { + if (instance == null) { + synchronized (OpenDataHubSetupManager.class) { + if (instance == null) { + instance = new OpenDataHubSetupManager(); + } + } + } + return instance; + } + + private OpenDataHubSetupManager() { + // If it does not exist, let's create a dedicated namespace/project for Intersmash to manage the ODH setup + this.openShift = OpenShifts.master(GLOBAL_OPERATOR_GROUP_NAMESPACE_DEFAULT); + if (openShift.getProject(openShift.getNamespace()) == null) { + openShift.createProjectRequest(); + openShift.waiters().isProjectReady().waitFor(); + // and label it as managed by Intersmash ODH + configureNamespaceLabel("intersmash-odh/ready", "false"); + configureNamespaceLabel("intersmash-odh/installing", "false"); + } + // configure a pull secret, which would be used when pulling from secured registries + if (OpenShiftConfig.pullSecret() != null) { + openShift.setupPullSecret(OpenShiftConfig.pullSecret()); + } + openShift.addRoleToGroup("system:image-puller", "ClusterRole", "system:authenticated"); + } + + public OpenDataHubPrerequisitesProvisioner getRequiredComponentsProvisioner() { + if (requiredComponentsProvisioner == null) { + requiredComponentsProvisioner = lookUpProvisioner(); + } + return requiredComponentsProvisioner; + } + + public void setup() throws IOException { + configureNamespaceLabel("intersmash-odh/installing", "true"); + try { + // Create an OperatorGroup resource that will group the global CSVs needed as Open Data Hub required + // components, e.g.: Authorino, Service Mesh etc. They will all be in the project created by this singleton + OpenShifts.adminBinary().execute("apply", "-f", + OperatorGroup.ALL_NAMESPACES.save().getAbsolutePath()); + // use the pluggable provisioner implementation to deploy ODH prerequisites + OpenDataHubPrerequisitesProvisioner provisioner = getRequiredComponentsProvisioner(); + log.info("Deploying ODH prerequisites via: {}", provisioner.getClass().getName()); + provisioner.configure(); + provisioner.preDeploy(); + provisioner.deploy(); + // and label as ready + configureNamespaceLabel("intersmash-odh/ready", "true"); + } catch (Exception e) { + configureNamespaceLabel("intersmash-odh/ready", "false"); + } finally { + configureNamespaceLabel("intersmash-odh/installing", "false"); + } + } + + private void configureNamespaceLabel(final String name, final String value) { + // Adding a label can be only done via 'namespace'. It cannot be set via 'project' API. Thus we do this + // separately. Also, to update namespace label, it's necessary to have 'patch resource "namespaces"' + // permission for current user and updated namespace, e.g. by having 'cluster-admin' role. + // Otherwise you can see: + // $ oc label namespace "label1=foo" + // Error from server (Forbidden): namespaces "" is forbidden: User "" cannot patch resource "namespaces" in API group "" in the namespace "" + try { + OpenShifts.admin(openShift.getNamespace()).namespaces().withName(openShift.getNamespace()) + .edit(new Visitor() { + @Override + public void visit(NamespaceBuilder builder) { + builder.editMetadata() + .addToLabels(name, value); + } + }); + } catch (KubernetesClientException e) { + throw new IllegalArgumentException("Couldn't assign required labels the new project '" + + openShift.getNamespace() + "'. Possible cause are insufficient permissions."); + } + } + + public void tearDown() { + configureNamespaceLabel("intersmash-odh/installing", "true"); + try { + // label as no longer ready + configureNamespaceLabel("intersmash-odh/ready", "false"); + // tear down + OpenDataHubPrerequisitesProvisioner provisioner = getRequiredComponentsProvisioner(); + log.info("Undeploying ODH prerequisites via: {}", provisioner.getClass().getName()); + provisioner.undeploy(); + provisioner.postUndeploy(); + provisioner.dismiss(); + // remove the global operator group related resources + OpenShifts.adminBinary().execute("delete", "subscription", "--all"); + OpenShifts.adminBinary().execute("delete", "csvs", "--all"); + OpenShifts.adminBinary().execute("delete", "operatorgroup", "--all"); + } finally { + configureNamespaceLabel("intersmash-odh/installing", "false"); + } + } + + public void subscribe(final String namespace) { + try { + // Adding a label can be only done via 'namespace'. It cannot be set via 'project' API. Thus we do this + // separately. Also, to update namespace label, it's necessary to have 'patch resource "namespaces"' + // permission for current user and updated namespace, e.g. by having 'cluster-admin' role. + // Otherwise you can see: + // $ oc label namespace "label1=foo" + // Error from server (Forbidden): namespaces "" is forbidden: User "" cannot patch resource "namespaces" in API group "" in the namespace "" + OpenShifts.admin(openShift.getNamespace()).namespaces().withName(openShift.getNamespace()) + .edit(new Visitor() { + @Override + public void visit(NamespaceBuilder builder) { + builder.editMetadata() + .addToLabels(String.format("intersmash-odh-subscriber/%s", namespace), + String.valueOf(System.currentTimeMillis())); + } + }); + } catch (KubernetesClientException e) { + throw new IllegalArgumentException("Couldn't add a subscription label the project '" + + openShift.getNamespace() + "'. Possible cause are insufficient permissions."); + } + } + + public List getSubscribers() { + return OpenShifts.admin(openShift.getNamespace()).namespaces().withName(openShift.getNamespace()).get().getMetadata() + .getLabels().entrySet() + .stream() + .filter(e -> e.getKey().startsWith("intersmash-odh-subscriber/")) + .map(e -> e.getKey().substring("intersmash-odh-subscriber/".length())).collect(Collectors.toList()); + } + + public Boolean isReady() { + return Boolean.valueOf(OpenShifts.admin(openShift.getNamespace()).namespaces().withName(openShift.getNamespace()).get() + .getMetadata().getLabels().entrySet() + .stream() + .filter(e -> "intersmash-odh/ready".equals(e.getKey())) + .findFirst() + .orElseThrow(() -> new IllegalStateException( + "The \"intersmash-odh/ready\" label was not found, cannot determine whether the ODH Manager namespace is ready")) + .getValue()); + } + + public Boolean isInstalling() { + return OpenShifts.admin(openShift.getNamespace()).namespaces().withName(openShift.getNamespace()).get().getMetadata() + .getLabels().entrySet() + .stream() + .anyMatch(e -> "intersmash-odh/installing".equals(e.getKey()) && Boolean.parseBoolean(e.getValue())); + } + + public void unsubscribe(final String namespace) { + try { + // Remove the subscription label + OpenShifts.admin(openShift.getNamespace()).namespaces().withName(openShift.getNamespace()) + .edit(new Visitor() { + @Override + public void visit(NamespaceBuilder builder) { + builder.editMetadata() + .removeFromLabels(String.format("intersmash-odh-subscriber/%s", namespace)); + } + }); + } catch (KubernetesClientException e) { + throw new IllegalArgumentException("Couldn't remove a subscription label from the project '" + + openShift.getNamespace() + "'. Possible cause are insufficient permissions."); + } + } + + private OpenDataHubPrerequisitesProvisioner lookUpProvisioner() { + final String openDataHubUnmanagedInstallClass = IntersmashConfig.openDataHubUnmanagedInstallClass(); + AtomicReference lookedUp = new AtomicReference<>(); + ServiceLoader.load( + OpenDataHubPrerequisitesProvisionerFactory.class) + .stream() + .map(ServiceLoader.Provider::get) + .sorted((p1, p2) -> p2.getOrder().compareTo(p1.getOrder())) + .forEachOrdered(pf -> { + OpenDataHubPrerequisitesProvisioner p = pf.getProvisioner(openDataHubUnmanagedInstallClass); + if (p != null && lookedUp.get() == null) { + lookedUp.set(p); + } + }); + if (lookedUp.get() == null) { + throw new UnsupportedOperationException( + "No suitable Provisioner found for unmanaged Open Data Hub prerequisites installation via class: " + + openDataHubUnmanagedInstallClass); + } + return lookedUp.get(); + } +} diff --git a/core/src/main/java/org/jboss/intersmash/provision/openshift/operator/resources/OperatorGroup.java b/core/src/main/java/org/jboss/intersmash/provision/openshift/operator/resources/OperatorGroup.java index 0101a65cf..e3807ca65 100644 --- a/core/src/main/java/org/jboss/intersmash/provision/openshift/operator/resources/OperatorGroup.java +++ b/core/src/main/java/org/jboss/intersmash/provision/openshift/operator/resources/OperatorGroup.java @@ -15,7 +15,6 @@ */ package org.jboss.intersmash.provision.openshift.operator.resources; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,6 +35,9 @@ @Version("v1") public class OperatorGroup extends CustomResource implements OpenShiftResource { public static final OperatorGroup SINGLE_NAMESPACE = new OperatorGroup(OpenShiftConfig.namespace()); + + public static final OperatorGroup ALL_NAMESPACES = new OperatorGroup(OpenShiftConfig.namespace(), null); + private Map> spec = new HashMap<>(); public OperatorGroup() { @@ -44,12 +46,16 @@ public OperatorGroup() { } public OperatorGroup(String namespace) { + this(namespace, List.of(namespace)); + } + + public OperatorGroup(String namespace, List targetNamespaces) { this(); this.getMetadata().setName(namespace + "-operators"); this.getMetadata().setNamespace(namespace); - List targetNamespaces = new ArrayList<>(); - targetNamespaces.add(namespace); - this.getSpec().put("targetNamespaces", targetNamespaces); + if (targetNamespaces != null && !targetNamespaces.isEmpty()) { + this.getSpec().put("targetNamespaces", targetNamespaces); + } } public Map> getSpec() { diff --git a/provisioners/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubDefaultPrerequisitesProvisioner.java b/provisioners/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubDefaultPrerequisitesProvisioner.java new file mode 100644 index 000000000..038274823 --- /dev/null +++ b/provisioners/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubDefaultPrerequisitesProvisioner.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2023 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.provision.ai; + +import java.util.List; + +import org.jboss.intersmash.application.openshift.AuthorinoOperatorApplication; +import org.jboss.intersmash.provision.Provisioner; +import org.jboss.intersmash.provision.ProvisionerManager; + +import io.kuadrant.authorino.operator.v1beta1.Authorino; +import io.kuadrant.authorino.v1beta2.AuthConfig; + +/** + * + */ +public class OpenDataHubDefaultPrerequisitesProvisioner implements OpenDataHubPrerequisitesProvisioner { + static final String OPENSHIFT_AI_DEFAULT_PREREQUISITES_AUTHORINO_APP_NAME = "intersmash-odh-authorino"; + private static final AuthorinoOperatorApplication authorinoOperatorApplication = new AuthorinoOperatorApplication() { + + @Override + public Authorino getAuthorino() { + return null; + } + + @Override + public List getAuthConfigs() { + return List.of(); + } + + @Override + public String getName() { + return OPENSHIFT_AI_DEFAULT_PREREQUISITES_AUTHORINO_APP_NAME; + } + }; + private final Provisioner authorinoOperatorProvisioner; + + public OpenDataHubDefaultPrerequisitesProvisioner() { + this.authorinoOperatorProvisioner = ProvisionerManager.getProvisioner(authorinoOperatorApplication); + } + + @Override + public void deploy() { + authorinoOperatorProvisioner.deploy(); + } + + @Override + public void undeploy() { + authorinoOperatorProvisioner.undeploy(); + } +} diff --git a/provisioners/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubDefaultPrerequisitesProvisionerFactory.java b/provisioners/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubDefaultPrerequisitesProvisionerFactory.java new file mode 100644 index 000000000..63123cdcc --- /dev/null +++ b/provisioners/src/main/java/org/jboss/intersmash/provision/ai/OpenDataHubDefaultPrerequisitesProvisionerFactory.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2023 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.provision.ai; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OpenDataHubDefaultPrerequisitesProvisionerFactory + implements OpenDataHubPrerequisitesProvisionerFactory { + + @Override + public Integer getOrder() { + return 100; + } + + @Override + public OpenDataHubDefaultPrerequisitesProvisioner getProvisioner(String fqdn) { + if (fqdn.equals(OpenDataHubDefaultPrerequisitesProvisioner.class.getName())) + return new OpenDataHubDefaultPrerequisitesProvisioner(); + return null; + } +} diff --git a/provisioners/src/main/resources/META-INF/services/org.jboss.intersmash.provision.ai.OpenDataHubPrerequisitesProvisionerFactory b/provisioners/src/main/resources/META-INF/services/org.jboss.intersmash.provision.ai.OpenDataHubPrerequisitesProvisionerFactory new file mode 100644 index 000000000..a8bbff3f9 --- /dev/null +++ b/provisioners/src/main/resources/META-INF/services/org.jboss.intersmash.provision.ai.OpenDataHubPrerequisitesProvisionerFactory @@ -0,0 +1 @@ +org.jboss.intersmash.provision.ai.OpenDataHubDefaultPrerequisitesProvisionerFactory diff --git a/testsuite/integration-tests/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener b/testsuite/integration-tests/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener index 63b7383d3..a18aa59e0 100644 --- a/testsuite/integration-tests/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener +++ b/testsuite/integration-tests/src/test/resources/META-INF/services/org.junit.platform.launcher.TestExecutionListener @@ -1,2 +1,3 @@ cz.xtf.junit5.listeners.TestExecutionLogger cz.xtf.junit5.listeners.ProjectCreator +org.jboss.intersmash.junit5.OpenDataHubExtension