From 75cd6bd3836f873987c4ea424e6ff626400c1ec9 Mon Sep 17 00:00:00 2001 From: Jean-Francois Denise Date: Tue, 15 Oct 2024 16:22:08 +0200 Subject: [PATCH] Fix for Issue #87, Introduce the notion of discovery space for discovered feature-packs --- .../wildfly/glow/cli/support/Constants.java | 3 + .../org/wildfly/glow/cli/support/Utils.java | 51 -------- .../glow/cli/commands/GoOfflineCommand.java | 8 ++ .../glow/cli/commands/ScanCommand.java | 6 + .../glow/cli/commands/ShowAddOnsCommand.java | 113 +++++++++++++++++- .../commands/ShowConfigurationCommand.java | 65 ++++++++-- .../commands/ShowServerVersionsCommand.java | 11 ++ .../main/resources/UsageMessages.properties | 1 + .../main/java/org/wildfly/glow/Arguments.java | 13 +- .../wildfly/glow/BaseArgumentsBuilder.java | 4 +- .../org/wildfly/glow/DeploymentScanner.java | 1 + .../java/org/wildfly/glow/FeaturePacks.java | 77 +++++++++++- .../java/org/wildfly/glow/GlowSession.java | 30 ++++- .../org/wildfly/glow/ProvisioningUtils.java | 8 +- .../java/org/wildfly/glow/ScanArguments.java | 6 +- .../src/main/java/org/wildfly/glow/Space.java | 56 +++++++++ .../wildfly/glow/plugin/doc/ScanDocMojo.java | 112 +++++++++++++---- docs/guide/intro/index.adoc | 9 ++ docs/guide/wildfly-maven-plugin/index.adoc | 14 +++ 19 files changed, 490 insertions(+), 98 deletions(-) create mode 100644 core/src/main/java/org/wildfly/glow/Space.java diff --git a/cli-support/src/main/java/org/wildfly/glow/cli/support/Constants.java b/cli-support/src/main/java/org/wildfly/glow/cli/support/Constants.java index 6b9e03a0..5e274902 100644 --- a/cli-support/src/main/java/org/wildfly/glow/cli/support/Constants.java +++ b/cli-support/src/main/java/org/wildfly/glow/cli/support/Constants.java @@ -90,6 +90,9 @@ public interface Constants { String SHOW_ADD_ONS_COMMAND = "show-add-ons"; String SHOW_CONFIGURATION_COMMAND = "show-configuration"; String SHOW_SERVER_VERSIONS_COMMAND = "show-server-versions"; + String SPACES_OPTION = "--spaces"; + String SPACES_OPTION_SHORT = "-sp"; + String SPACES_OPTION_LABEL = ""; String STABILITY_LABEL = ""; String STABILITY_OPTION = "--stability-level"; String STABILITY_OPTION_SHORT = "-sl"; diff --git a/cli-support/src/main/java/org/wildfly/glow/cli/support/Utils.java b/cli-support/src/main/java/org/wildfly/glow/cli/support/Utils.java index 681e6b7e..171a1fd2 100644 --- a/cli-support/src/main/java/org/wildfly/glow/cli/support/Utils.java +++ b/cli-support/src/main/java/org/wildfly/glow/cli/support/Utils.java @@ -20,21 +20,8 @@ import java.nio.file.Path; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Set; -import org.jboss.galleon.api.config.GalleonProvisioningConfig; -import org.jboss.galleon.universe.FeaturePackLocation; -import org.jboss.galleon.universe.maven.repo.MavenRepoManager; -import org.wildfly.channel.Channel; -import org.wildfly.channel.ChannelMapper; -import org.wildfly.glow.AddOn; -import org.wildfly.glow.Arguments; -import org.wildfly.glow.Layer; -import org.wildfly.glow.LayerMapping; -import org.wildfly.glow.ProvisioningUtils; -import org.wildfly.glow.ScanArguments; -import org.wildfly.glow.maven.MavenResolver; /** * @@ -42,44 +29,6 @@ */ public class Utils { - public static void showAddOns(AbstractCommand cmd, String context, Path provisioningXml, boolean isLatest, - String serverVersion, boolean isPreview, Path channelsFile) throws Exception { - CLIConfigurationResolver resolver = new CLIConfigurationResolver(); - ProvisioningUtils.ProvisioningConsumer consumer = new ProvisioningUtils.ProvisioningConsumer() { - @Override - public void consume(GalleonProvisioningConfig provisioning, Map all, - LayerMapping mapping, Map> fpDependencies) throws Exception { - StringBuilder builder = new StringBuilder(); - for (Map.Entry> entry : mapping.getAddOnFamilyMembers().entrySet()) { - builder.append("* @|bold ").append(entry.getKey()).append("|@ add-ons:%n"); - for (AddOn member : mapping.getAddOnFamilyMembers().get(entry.getKey())) { - if (!member.getName().endsWith(":default")) { - String deployer = resolver.getPossibleDeployer(member.getLayers()); - builder.append(" - ").append(member.getName()).append((deployer == null ? "" : " @|bold (supported by " + deployer + " deployer)|@")).append(member.getDescription() == null ? "" : ": " + member.getDescription()).append("%n"); - } - } - } - cmd.print(builder.toString()); - cmd.print("@|bold Add-ons can be set using the|@ @|fg(yellow) %s=|@ @|bold option of the|@ @|fg(yellow) %s|@ @|bold command|@", Constants.ADD_ONS_OPTION, Constants.SCAN_COMMAND); - - } - - }; - ScanArguments.Builder builder = Arguments.scanBuilder(); - MavenRepoManager repoManager; - List channels = Collections.emptyList(); - if (channelsFile != null) { - String content = Files.readString(channelsFile); - channels = ChannelMapper.fromString(content); - builder.setChannels(channels); - repoManager = MavenResolver.newMavenResolver(channels); - } else { - repoManager = MavenResolver.newMavenResolver(); - } - ProvisioningUtils.traverseProvisioning(consumer, context, provisioningXml, isLatest, serverVersion, - isPreview, channels, repoManager); - } - public static void setSystemProperties(Set systemProperties) throws Exception { if (!systemProperties.isEmpty()) { for (String p : systemProperties) { diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/GoOfflineCommand.java b/cli/src/main/java/org/wildfly/glow/cli/commands/GoOfflineCommand.java index 03d054d4..a96a0cc1 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/GoOfflineCommand.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/GoOfflineCommand.java @@ -19,7 +19,9 @@ import org.wildfly.glow.cli.support.AbstractCommand; import org.wildfly.glow.cli.support.Constants; import java.nio.file.Path; +import java.util.LinkedHashSet; import java.util.Optional; +import java.util.Set; import org.wildfly.glow.Arguments; import static org.wildfly.glow.Arguments.CLOUD_EXECUTION_CONTEXT; import org.wildfly.glow.GlowMessageWriter; @@ -48,6 +50,9 @@ public class GoOfflineCommand extends AbstractCommand { @CommandLine.Option(names = Constants.INPUT_FEATURE_PACKS_FILE_OPTION, paramLabel = "") Optional provisioningXml; + @CommandLine.Option(names = {Constants.SPACES_OPTION_SHORT, Constants.SPACES_OPTION}, split = ",", paramLabel = Constants.SPACES_OPTION_LABEL) + Set spaces = new LinkedHashSet<>(); + @Override public Integer call() throws Exception { print("Wildfly Glow is assembling offline content..."); @@ -65,6 +70,9 @@ public Integer call() throws Exception { if (provisioningXml.isPresent()) { builder.setProvisoningXML(provisioningXml.get()); } + if (!spaces.isEmpty()) { + builder.setSpaces(spaces); + } GlowSession.goOffline(MavenResolver.newMavenResolver(), builder.build(), GlowMessageWriter.DEFAULT); print("Offline zip file %s generated", OFFLINE_ZIP); return 0; diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java b/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java index bc8a49e9..37c450ce 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/ScanCommand.java @@ -164,6 +164,9 @@ public OutputFormat convert(String value) throws Exception { @CommandLine.Option(names = Constants.DRY_RUN_OPTION) Optional dryRun; + @CommandLine.Option(names = {Constants.SPACES_OPTION_SHORT, Constants.SPACES_OPTION}, split = ",", paramLabel = Constants.SPACES_OPTION_LABEL) + Set spaces = new LinkedHashSet<>(); + @Override public Integer call() throws Exception { Utils.setSystemProperties(systemProperties); @@ -188,6 +191,9 @@ public Integer call() throws Exception { if (!layersForJndi.isEmpty()) { builder.setJndiLayers(layersForJndi); } + if (!spaces.isEmpty()) { + builder.setSpaces(spaces); + } if (suggest.orElse(false)) { builder.setSuggest(true); } diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/ShowAddOnsCommand.java b/cli/src/main/java/org/wildfly/glow/cli/commands/ShowAddOnsCommand.java index f322ebbc..92a89409 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/ShowAddOnsCommand.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/ShowAddOnsCommand.java @@ -16,12 +16,32 @@ */ package org.wildfly.glow.cli.commands; +import java.nio.file.Files; import org.wildfly.glow.cli.support.AbstractCommand; -import org.wildfly.glow.cli.support.Utils; import org.wildfly.glow.cli.support.Constants; import java.nio.file.Path; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.Set; +import org.jboss.galleon.api.config.GalleonProvisioningConfig; +import org.jboss.galleon.universe.FeaturePackLocation; +import org.jboss.galleon.universe.FeaturePackLocation.FPID; +import org.jboss.galleon.universe.maven.repo.MavenRepoManager; +import org.wildfly.channel.Channel; +import org.wildfly.channel.ChannelMapper; +import org.wildfly.glow.AddOn; import org.wildfly.glow.Arguments; +import org.wildfly.glow.FeaturePacks; +import org.wildfly.glow.Layer; +import org.wildfly.glow.LayerMapping; +import org.wildfly.glow.ProvisioningUtils; +import org.wildfly.glow.ScanArguments; +import org.wildfly.glow.Space; +import org.wildfly.glow.cli.support.CLIConfigurationResolver; +import org.wildfly.glow.maven.MavenResolver; import picocli.CommandLine; @CommandLine.Command( @@ -45,6 +65,11 @@ public class ShowAddOnsCommand extends AbstractCommand { @CommandLine.Option(names = {Constants.CHANNELS_OPTION_SHORT, Constants.CHANNELS_OPTION}, paramLabel = Constants.CHANNELS_OPTION_LABEL) Optional channelsFile; + @CommandLine.Option(names = {Constants.SPACES_OPTION_SHORT, Constants.SPACES_OPTION}, split = ",", paramLabel = Constants.SPACES_OPTION_LABEL) + Set spaces = new LinkedHashSet<>(); + + private Map> defaultSpaceFpDependencies; + @Override public Integer call() throws Exception { print("Wildfly Glow is retrieving add-ons..."); @@ -62,8 +87,92 @@ public Integer call() throws Exception { throw new Exception(Constants.SERVER_VERSION_OPTION + "can't be set when " + Constants.CHANNELS_OPTION + " is set."); } } - Utils.showAddOns(this, context, provisioningXml.orElse(null), wildflyServerVersion.isEmpty(), wildflyServerVersion.orElse(null), + showAddOns(Space.DEFAULT, context, provisioningXml.orElse(null), wildflyServerVersion.isEmpty(), wildflyServerVersion.orElse(null), wildflyPreview.orElse(false), channelsFile.orElse(null)); + String vers = wildflyServerVersion.isPresent() ? wildflyServerVersion.get() : FeaturePacks.getLatestVersion(); + for(String spaceName : spaces) { + Set versions = FeaturePacks.getAllVersions(spaceName); + if (versions.contains(vers)) { + Space space = FeaturePacks.getSpace(spaceName); + showAddOns(space, context, provisioningXml.orElse(null), wildflyServerVersion.isEmpty(), wildflyServerVersion.orElse(null), + wildflyPreview.orElse(false), channelsFile.orElse(null)); + } + } + print("@|bold Add-ons can be set using the|@ @|fg(yellow) %s=|@ @|bold option of the|@ @|fg(yellow) %s|@ @|bold command|@", Constants.ADD_ONS_OPTION, Constants.SCAN_COMMAND); + return 0; } + + public void showAddOns(Space space, String context, Path provisioningXml, boolean isLatest, + String serverVersion, boolean isPreview, Path channelsFile) throws Exception { + CLIConfigurationResolver resolver = new CLIConfigurationResolver(); + ProvisioningUtils.ProvisioningConsumer consumer = new ProvisioningUtils.ProvisioningConsumer() { + @Override + public void consume(Space space, GalleonProvisioningConfig provisioning, Map all, + LayerMapping mapping, Map> fpDependencies) throws Exception { + if (Space.DEFAULT.equals(space)) { + defaultSpaceFpDependencies = fpDependencies; + } + StringBuilder builder = new StringBuilder(); + builder.append("\nAdd-ons found in the @|bold ").append(space.getName()).append("|@ space:\n"); + if (provisioning == null) { + builder.append("- No Add-ons."); + } else { + boolean foundAddOns = false; + for (Map.Entry> entry : mapping.getAddOnFamilyMembers().entrySet()) { + StringBuilder addOnFamilyBuilder = new StringBuilder(); + for (AddOn member : mapping.getAddOnFamilyMembers().get(entry.getKey())) { + boolean ignore = false; + if (!Space.DEFAULT.equals(space)) { + // Only keep addOns that are not defined in feature-packs from the default space. + for(Layer l : member.getLayers()) { + for(FPID fpid : l.getFeaturePacks()) { + for (FPID dfpid : defaultSpaceFpDependencies.keySet()) { + if (dfpid.getProducer().equals(fpid.getProducer())) { + ignore = true; + break; + } + } + if (ignore) { + break; + } + } + if(ignore) { + break; + } + } + } + if (!member.getName().endsWith(":default") && !ignore) { + foundAddOns = true; + String deployer = resolver.getPossibleDeployer(member.getLayers()); + addOnFamilyBuilder.append(" - ").append(member.getName()).append((deployer == null ? "" : " @|bold (supported by " + deployer + " deployer)|@")).append(member.getDescription() == null ? "" : ": " + member.getDescription()).append("%n"); + } + } + if (!addOnFamilyBuilder.isEmpty()) { + builder.append("* @|bold ").append(entry.getKey()).append("|@ add-ons:%n"); + builder.append(addOnFamilyBuilder.toString()); + } + } + if (!foundAddOns) { + builder.append("- No Add-ons."); + } + } + print(builder.toString()); + } + + }; + ScanArguments.Builder builder = Arguments.scanBuilder(); + MavenRepoManager repoManager; + List channels = Collections.emptyList(); + if (channelsFile != null) { + String content = Files.readString(channelsFile); + channels = ChannelMapper.fromString(content); + builder.setChannels(channels); + repoManager = MavenResolver.newMavenResolver(channels); + } else { + repoManager = MavenResolver.newMavenResolver(); + } + ProvisioningUtils.traverseProvisioning(space, consumer, context, provisioningXml, isLatest, serverVersion, + isPreview, channels, repoManager); + } } diff --git a/cli/src/main/java/org/wildfly/glow/cli/commands/ShowConfigurationCommand.java b/cli/src/main/java/org/wildfly/glow/cli/commands/ShowConfigurationCommand.java index 8da3d325..020b9bba 100644 --- a/cli/src/main/java/org/wildfly/glow/cli/commands/ShowConfigurationCommand.java +++ b/cli/src/main/java/org/wildfly/glow/cli/commands/ShowConfigurationCommand.java @@ -44,6 +44,7 @@ import org.wildfly.glow.Layer; import org.wildfly.glow.LayerMapping; import org.wildfly.glow.ScanArguments; +import org.wildfly.glow.Space; import org.wildfly.glow.deployment.openshift.api.Deployer; import picocli.CommandLine; @@ -69,6 +70,11 @@ public class ShowConfigurationCommand extends AbstractCommand { @CommandLine.Option(names = {Constants.CHANNELS_OPTION_SHORT, Constants.CHANNELS_OPTION}, paramLabel = Constants.CHANNELS_OPTION_LABEL) Optional channelsFile; + @CommandLine.Option(names = {Constants.SPACES_OPTION_SHORT, Constants.SPACES_OPTION}, split = ",", paramLabel = Constants.SPACES_OPTION_LABEL) + Set spaces = new LinkedHashSet<>(); + + private Map> defaultSpaceFpDependencies; + @Override public Integer call() throws Exception { print("Wildfly Glow is retrieving known provisioning configuration..."); @@ -78,6 +84,12 @@ public Integer call() throws Exception { ocBuilder.append("* @|bold " + d.getName() + "|@. Enabled when the layer(s) " + d.getSupportedLayers() + " is/are discovered.\n"); } print(ocBuilder.toString()); + StringBuilder spacesBuilder = new StringBuilder(); + spacesBuilder.append("\nSpaces from which more feature-packs can be used when scanning deployments (use the " + Constants.SPACES_OPTION + " option to enable the space(s):\n"); + for(Space space : FeaturePacks.getAllSpaces()) { + spacesBuilder.append("* @|bold " + space.getName() + "|@. " + space.getDescription() + "\n"); + } + print(spacesBuilder.toString()); String context = Arguments.BARE_METAL_EXECUTION_CONTEXT; if (cloud.orElse(false)) { @@ -98,9 +110,12 @@ public Integer call() throws Exception { String vers = wildflyServerVersion.isPresent() ? wildflyServerVersion.get() : FeaturePacks.getLatestVersion(); ProvisioningUtils.ProvisioningConsumer consumer = new ProvisioningUtils.ProvisioningConsumer() { @Override - public void consume(GalleonProvisioningConfig provisioning, Map all, + public void consume(Space space, GalleonProvisioningConfig provisioning, Map all, LayerMapping mapping, Map> fpDependencies) throws Exception { - String configStr = dumpConfiguration(fpDependencies, finalContext, vers, all, + if (Space.DEFAULT.equals(space)) { + defaultSpaceFpDependencies = fpDependencies; + } + String configStr = dumpConfiguration(space, fpDependencies, finalContext, vers, all, mapping, provisioning, isLatest, wildflyPreview.orElse(false), provisioningXml.orElse(null)); print(configStr); } @@ -116,24 +131,39 @@ public void consume(GalleonProvisioningConfig provisioning, Map a } else { repoManager = MavenResolver.newMavenResolver(); } - ProvisioningUtils.traverseProvisioning(consumer, context, provisioningXml.orElse(null), wildflyServerVersion.isEmpty(), vers, wildflyPreview.orElse(false), channels, repoManager); - + ProvisioningUtils.traverseProvisioning(Space.DEFAULT, consumer, context, provisioningXml.orElse(null), wildflyServerVersion.isEmpty(), vers, wildflyPreview.orElse(false), channels, repoManager); + for(String spaceName : spaces) { + Set versions = FeaturePacks.getAllVersions(spaceName); + if (versions.contains(vers)) { + Space space = FeaturePacks.getSpace(spaceName); + ProvisioningUtils.traverseProvisioning(space, consumer, context, provisioningXml.orElse(null), wildflyServerVersion.isEmpty(), vers, wildflyPreview.orElse(false), channels, repoManager); + } + } return 0; } - private static String dumpConfiguration(Map> fpDependencies, + private String dumpConfiguration(Space space, Map> fpDependencies, String context, String serverVersion, Map allLayers, LayerMapping mapping, GalleonProvisioningConfig config, boolean isLatest, boolean techPreview, Path provisioningXml) throws Exception { StringBuilder builder = new StringBuilder(); - if (provisioningXml == null) { - builder.append("Execution context: ").append(context).append("\n"); - builder.append("Server version: ").append(serverVersion).append(isLatest ? " (latest)" : "").append("\n"); - builder.append("Tech Preview: ").append(techPreview).append("\n"); - } else { - builder.append("Input provisioning.xml file: ").append(provisioningXml).append("\n"); + if (config == null) { + builder.append("\nFeature-packs in the @|bold ").append(space.getName()).append("|@ space:\n"); + builder.append("No feature-packs found in the " + space.getName() + " space for context " + context + ", server version " +serverVersion + "."); + return builder.toString(); } + + if (Space.DEFAULT.equals(space)) { + if (provisioningXml == null) { + builder.append("Execution context: ").append(context).append("\n"); + builder.append("Server version: ").append(serverVersion).append(isLatest ? " (latest)" : "").append("\n"); + builder.append("Tech Preview: ").append(techPreview).append("\n"); + } else { + builder.append("Input provisioning.xml file: ").append(provisioningXml).append("\n"); + } + } + builder.append("\nFeature-packs in the @|bold ").append(space.getName()).append("|@ space:\n"); Set topLevel = new LinkedHashSet<>(); - Map featurepacks = new LinkedHashMap<>(); + Map featurepacks = new LinkedHashMap<>(); for(GalleonFeaturePackConfig fp : config.getFeaturePackDeps()) { topLevel.add(fp.getLocation().getProducer()); for(FPID fpid : fpDependencies.keySet()) { @@ -155,7 +185,16 @@ private static String dumpConfiguration(Map spaces = new LinkedHashSet<>(); + @Override public Integer call() throws Exception { + print("WildFly server versions in the " + Space.DEFAULT.getName() + " space:"); print(FeaturePacks.getAllVersions()); + for(String space : spaces) { + print("WildFly server versions in the " + space + " space:"); + print(FeaturePacks.getAllVersions(space)); + } print("@|bold WildFly server version can be set using the|@ @|fg(yellow) %s=|@ @|bold option of the|@ @|fg(yellow) %s|@ @|bold command|@", Constants.SERVER_VERSION_OPTION, Constants.SCAN_COMMAND); return 0; } diff --git a/cli/src/main/resources/UsageMessages.properties b/cli/src/main/resources/UsageMessages.properties index 6100ea93..ba7eea77 100644 --- a/cli/src/main/resources/UsageMessages.properties +++ b/cli/src/main/resources/UsageMessages.properties @@ -34,6 +34,7 @@ package-stability-level = Specify a stability to be used when provisioning serve properties = A space separated list of Java system properties. When multiple system properties are set, the list must be enclosed in double quotes. For example: "-Dfoo=bar -DmyProp" provision = The kind of provisioning to produce based on what has been discovered. Can be @|fg(yellow) SERVER|@: a provisioned WildFly server, @|fg(yellow) BOOTABLE_JAR|@: a WildFly Bootable JAR, @|fg(yellow) DOCKER_IMAGE|@: a Docker image, @|fg(yellow) OPENSHIFT|@: a server built and deploy on OpenShift, you must be logged to a cluster, or @|fg(yellow) PROVISIONING_XML|@: a Galleon provisioning.xml file. server-version = The WildFly server version to deploy the deployment to. By default the latest WildFly version is used. +spaces= The additional spaces to look for Galleon feature-packs when scanning deployments. By default only the "default" space is used. To list known spaces call the @|fg(yellow) show-configuration|@ command. stability-level = Specify a stability to be used when provisioning a server. This is an option to set both config-stability-level and package-stability-level options with a single option. The stability can be @|fg(yellow) default|@, @|fg(yellow) community|@, @|fg(yellow) preview|@, @|fg(yellow) experimental|@. suggest = WildFly Glow will suggest additional add-ons and environment variables that are usable with your deployment. usage.commandListHeading = %nCommands:%n diff --git a/core/src/main/java/org/wildfly/glow/Arguments.java b/core/src/main/java/org/wildfly/glow/Arguments.java index a89b51e0..a6cd2061 100644 --- a/core/src/main/java/org/wildfly/glow/Arguments.java +++ b/core/src/main/java/org/wildfly/glow/Arguments.java @@ -38,6 +38,7 @@ public class Arguments implements GoOfflineArguments, ScanArguments { private final String defaultConfigStability; private final boolean isCli; private final List channels; + private final Set spaces; protected Arguments( String executionContext, @@ -57,7 +58,8 @@ protected Arguments( String packageStability, String defaultConfigStability, boolean isCli, - List channels) { + List channels, + Set spaces) { this.executionProfiles = executionProfiles; this.userEnabledAddOns = userEnabledAddOns; this.binaries = binaries; @@ -84,6 +86,7 @@ protected Arguments( } this.isCli = isCli; this.channels = channels; + this.spaces = spaces == null ? Collections.emptySet() : spaces; } /** @@ -220,6 +223,14 @@ public List getChannels() { return channels; } + /** + * @return the set of spaces + */ + @Override + public Set getSpaces() { + return spaces; + } + static GoOfflineArguments.Builder goOfflineBuilder() { return new GoOfflineArguments.Builder(); } diff --git a/core/src/main/java/org/wildfly/glow/BaseArgumentsBuilder.java b/core/src/main/java/org/wildfly/glow/BaseArgumentsBuilder.java index 37e5d83a..f9ffe62b 100644 --- a/core/src/main/java/org/wildfly/glow/BaseArgumentsBuilder.java +++ b/core/src/main/java/org/wildfly/glow/BaseArgumentsBuilder.java @@ -45,6 +45,7 @@ public class BaseArgumentsBuilder { protected String defaultConfigStability; protected boolean isCli; protected List channels; + protected Set spaces; protected BaseArgumentsBuilder() { @@ -73,6 +74,7 @@ public Arguments build() { packageStability, defaultConfigStability, isCli, - channels); + channels, + spaces); } } diff --git a/core/src/main/java/org/wildfly/glow/DeploymentScanner.java b/core/src/main/java/org/wildfly/glow/DeploymentScanner.java index f7168633..697fc928 100644 --- a/core/src/main/java/org/wildfly/glow/DeploymentScanner.java +++ b/core/src/main/java/org/wildfly/glow/DeploymentScanner.java @@ -634,6 +634,7 @@ private Set lookup(String className, DeploymentScanContext ctx) { } if (l != null) { LayerMapping.addRule(LayerMapping.RULE.JAVA_TYPE,l, s); + break; } } } diff --git a/core/src/main/java/org/wildfly/glow/FeaturePacks.java b/core/src/main/java/org/wildfly/glow/FeaturePacks.java index 11099d6f..a1eb384b 100644 --- a/core/src/main/java/org/wildfly/glow/FeaturePacks.java +++ b/core/src/main/java/org/wildfly/glow/FeaturePacks.java @@ -25,7 +25,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; @@ -37,18 +39,35 @@ public class FeaturePacks { private static final String VERSIONS = "versions.yaml"; + private static final String SPACES = "spaces/spaces.yaml"; private static final String PROVISIONING_FILE_RADICAL = "/provisioning-"; private static final String TECH_PREVIEW = "/tech-preview/"; public static final String URL_PROPERTY = "wildfly-glow-galleon-feature-packs-url"; public static Path getFeaturePacks(String version, String context, boolean techPreview) throws Exception { + return getFeaturePacks(Space.DEFAULT, version, context, techPreview); + } + + public static Path getFeaturePacks(Space space, String version, String context, boolean techPreview) throws Exception { try { - String rootURL = getFeaturePacksURL(); + String rootURL = getFeaturePacksURL(space); Yaml yaml = new Yaml(); + Map map = yaml.load(new URI(getFeaturePacksURL() + VERSIONS).toURL().openStream()); if (version == null) { - Map map = yaml.load(new URI(rootURL + VERSIONS).toURL().openStream()); version = map.get("latest"); + } else { + String[] versions = map.get("versions").split(","); + boolean found = false; + for (String v : versions) { + if (v.trim().equals(version)) { + found = true; + break; + } + } + if (!found) { + throw new Exception("The server version " + version + " doesn't exist."); + } } Path p = Files.createTempFile("glow-provisioning-", context); try (InputStream in = new URL(rootURL + version + (techPreview ? TECH_PREVIEW : "") + PROVISIONING_FILE_RADICAL + context + ".xml").openStream()) { @@ -63,6 +82,10 @@ public static Path getFeaturePacks(String version, String context, boolean techP } public static String getFeaturePacksURL() throws Exception { + return getFeaturePacksURL(Space.DEFAULT); + } + + public static String getFeaturePacksURL(Space space) throws Exception { String rootURL = Utils.getConfigEntry(URL_PROPERTY); if (rootURL == null) { throw new Exception("No " + URL_PROPERTY + " entry found"); @@ -70,6 +93,9 @@ public static String getFeaturePacksURL() throws Exception { if (!rootURL.endsWith("/")) { rootURL = rootURL + "/"; } + if (Space.DEFAULT != space) { + rootURL = rootURL + "/spaces/"+space.getName()+"/"; + } return rootURL; } @@ -78,10 +104,55 @@ public static Set getAllVersions() throws Exception { Set set = new TreeSet<>(); Yaml yaml = new Yaml(); Map map = yaml.load(new URI(rootURL + VERSIONS).toURL().openStream()); - set.addAll(Arrays.asList(map.get("versions").split(","))); + for(String v : Arrays.asList(map.get("versions").split(","))) { + set.add(v.trim()); + } + return set; + } + + public static Set getAllVersions(String spaceName) throws Exception { + Space space = getSpace(spaceName); + String rootURL = getFeaturePacksURL(space); + Set set = new TreeSet<>(); + Yaml yaml = new Yaml(); + Map map = yaml.load(new URI(rootURL + VERSIONS).toURL().openStream()); + for (String v : Arrays.asList(map.get("versions").split(","))) { + set.add(v.trim()); + } return set; } + public static List getAllSpaces() throws Exception { + String rootURL = getFeaturePacksURL(); + List lst = new ArrayList<>(); + Yaml yaml = new Yaml(); + Map>> map = yaml.load(new URI(rootURL + SPACES).toURL().openStream()); + List> spaces = map.get("spaces"); + for(Map space : spaces) { + lst.add(new Space(space.get("name"), space.get("description"))); + } + return lst; + } + + public static Space getSpace(String spaceName) throws Exception { + String rootURL = getFeaturePacksURL(); + List lst = new ArrayList<>(); + Yaml yaml = new Yaml(); + Map>> map = yaml.load(new URI(rootURL + SPACES).toURL().openStream()); + List> spaces = map.get("spaces"); + for(Map space : spaces) { + if(space.get("name").equals(spaceName)) { + return new Space(space.get("name"), space.get("description")); + } + } + List knownSpaces = getAllSpaces(); + StringBuilder builder = new StringBuilder(); + for(Space space : knownSpaces) { + builder.append(space.getName() + " "); + } + throw new Exception("Space " + spaceName + " doesn't exist. Known spaces are: " + builder.toString()); + } + public static String getLatestVersion() throws Exception { String rootURL = getFeaturePacksURL(); Yaml yaml = new Yaml(); diff --git a/core/src/main/java/org/wildfly/glow/GlowSession.java b/core/src/main/java/org/wildfly/glow/GlowSession.java index e2929895..d13e8b02 100644 --- a/core/src/main/java/org/wildfly/glow/GlowSession.java +++ b/core/src/main/java/org/wildfly/glow/GlowSession.java @@ -111,6 +111,7 @@ private void goOffline() throws Exception { GalleonBuilder provider = new GalleonBuilder(); provider.addArtifactResolver(resolver); Provisioning provisioning = null; + Path fakeHome = Files.createTempDirectory("wildfly-glow"); try { GalleonProvisioningConfig config = Utils.buildOfflineProvisioningConfig(provider, writer); if (config == null) { @@ -118,8 +119,10 @@ private void goOffline() throws Exception { if (provisioningXML == null) { provisioningXML = FeaturePacks.getFeaturePacks(arguments.getVersion(), arguments.getExecutionContext(), arguments.isTechPreview()); } - provisioning = provider.newProvisioningBuilder(provisioningXML).build(); + provisioning = provider.newProvisioningBuilder(provisioningXML).setInstallationHome(fakeHome).build(); config = provisioning.loadProvisioningConfig(provisioningXML); + // Compute extra config from configured spaces + config = mergeSpaces(provider, config); } else { provisioning = provider.newProvisioningBuilder(config).build(); } @@ -128,6 +131,7 @@ private void goOffline() throws Exception { if (provisioning != null) { provisioning.close(); } + IoUtils.recursiveDelete(fakeHome); } Files.deleteIfExists(OFFLINE_ZIP); ZipUtils.zip(OFFLINE_CONTENT, OFFLINE_ZIP); @@ -142,6 +146,28 @@ public static ScanResults scan(MavenRepoManager resolver, ScanArguments argument return session.scan(); } + private GalleonProvisioningConfig mergeSpaces(GalleonBuilder provider, GalleonProvisioningConfig defaultConfig) throws Exception { + if (!arguments.getSpaces().isEmpty()) { + GalleonProvisioningConfig.Builder mergedConfigBuilder = GalleonProvisioningConfig.builder(defaultConfig); + for (String spaceName : arguments.getSpaces()) { + Space space = FeaturePacks.getSpace(spaceName); + Set versions = FeaturePacks.getAllVersions(spaceName); + String vers = arguments.getVersion() == null ? FeaturePacks.getLatestVersion() : arguments.getVersion(); + if (versions.contains(vers)) { + Path spaceProvisioningXML = FeaturePacks.getFeaturePacks(space, + arguments.getVersion(), arguments.getExecutionContext(), arguments.isTechPreview()); + try (Provisioning spaceProvisioning = provider.newProvisioningBuilder(spaceProvisioningXML).build()) { + GalleonProvisioningConfig spaceConfig = spaceProvisioning.loadProvisioningConfig(spaceProvisioningXML); + for (GalleonFeaturePackConfig fpSpaceConfig : spaceConfig.getFeaturePackDeps()) { + mergedConfigBuilder.addFeaturePackDep(fpSpaceConfig); + } + } + } + } + defaultConfig = mergedConfigBuilder.build(); + } + return defaultConfig; + } public ScanResults scan() throws Exception { Set layers = new LinkedHashSet<>(); Set possibleAddOns = new TreeSet<>(); @@ -167,6 +193,8 @@ public ScanResults scan() throws Exception { } provisioning = provider.newProvisioningBuilder(provisioningXML).setInstallationHome(fakeHome).build(); config = provisioning.loadProvisioningConfig(provisioningXML); + // Compute extra config from configured spaces + config = mergeSpaces(provider, config); } else { provisioning = provider.newProvisioningBuilder(config).setInstallationHome(fakeHome).build(); } diff --git a/core/src/main/java/org/wildfly/glow/ProvisioningUtils.java b/core/src/main/java/org/wildfly/glow/ProvisioningUtils.java index 60ab5e4d..2d17e91f 100644 --- a/core/src/main/java/org/wildfly/glow/ProvisioningUtils.java +++ b/core/src/main/java/org/wildfly/glow/ProvisioningUtils.java @@ -40,11 +40,11 @@ public class ProvisioningUtils { public interface ProvisioningConsumer { - void consume(GalleonProvisioningConfig provisioning, Map all, + void consume(Space space, GalleonProvisioningConfig provisioning, Map all, LayerMapping mapping, Map> fpDependencies) throws Exception; } - public static void traverseProvisioning(ProvisioningConsumer consumer, + public static void traverseProvisioning(Space space, ProvisioningConsumer consumer, String executionContext, Path provisioningXML, boolean isLatest, String wildflyServerVersion, boolean wildflyPreview, List channels, MavenRepoManager resolver) throws Exception { UniverseResolver universeResolver = UniverseResolver.builder().addArtifactResolver(resolver).build(); GalleonBuilder provider = new GalleonBuilder(); @@ -55,7 +55,7 @@ public static void traverseProvisioning(ProvisioningConsumer consumer, GalleonProvisioningConfig config = Utils.buildOfflineProvisioningConfig(provider, GlowMessageWriter.DEFAULT); if (config == null) { if (provisioningXML == null) { - provisioningXML = FeaturePacks.getFeaturePacks(vers, executionContext, wildflyPreview); + provisioningXML = FeaturePacks.getFeaturePacks(space, vers, executionContext, wildflyPreview); } provisioning = provider.newProvisioningBuilder(provisioningXML).build(); config = provisioning.loadProvisioningConfig(provisioningXML); @@ -65,7 +65,7 @@ public static void traverseProvisioning(ProvisioningConsumer consumer, Map> fpDependencies = new HashMap<>(); Map all = Utils.getAllLayers(config, universeResolver, provisioning, fpDependencies); LayerMapping mapping = org.wildfly.glow.Utils.buildMapping(all, Collections.emptySet()); - consumer.consume(config, all, mapping, fpDependencies); + consumer.consume(space, config, all, mapping, fpDependencies); } finally { IoUtils.recursiveDelete(OFFLINE_CONTENT); if (provisioning != null) { diff --git a/core/src/main/java/org/wildfly/glow/ScanArguments.java b/core/src/main/java/org/wildfly/glow/ScanArguments.java index 6c4bd616..00c1088c 100644 --- a/core/src/main/java/org/wildfly/glow/ScanArguments.java +++ b/core/src/main/java/org/wildfly/glow/ScanArguments.java @@ -80,7 +80,7 @@ public interface ScanArguments { boolean isCli(); List getChannels(); - + Set getSpaces(); default Builder createScanArgumentsBuilder() { return new Builder(); } @@ -179,5 +179,9 @@ public Builder setChannels(List channels) { this.channels = channels; return this; } + public Builder setSpaces(Set spaces) { + this.spaces = spaces; + return this; + } } } diff --git a/core/src/main/java/org/wildfly/glow/Space.java b/core/src/main/java/org/wildfly/glow/Space.java new file mode 100644 index 00000000..b6e8a956 --- /dev/null +++ b/core/src/main/java/org/wildfly/glow/Space.java @@ -0,0 +1,56 @@ +/* + * Copyright The WildFly Authors + * SPDX-License-Identifier: Apache-2.0 + */ +package org.wildfly.glow; + +import java.util.Objects; + +/** + * + * @author jdenise + */ +public final class Space { + public static final Space DEFAULT = new Space("default", "Default space"); + private final String name; + private final String description; + + Space(String name, String description) { + Objects.requireNonNull(name); + Objects.requireNonNull(description); + this.name = name; + this.description = description; + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + @Override + public boolean equals(Object obj) { + if (! (obj instanceof Space)) { + return false; + } + Space other = (Space) obj; + return this.name.equals(other.name) && this.description.equals(other.description); + } + + @Override + public int hashCode() { + int hash = 3; + hash = 47 * hash + Objects.hashCode(this.name); + hash = 47 * hash + Objects.hashCode(this.description); + return hash; + } + +} diff --git a/doc-plugin/src/main/java/org/wildfly/glow/plugin/doc/ScanDocMojo.java b/doc-plugin/src/main/java/org/wildfly/glow/plugin/doc/ScanDocMojo.java index c5d116ee..c7efe6e5 100644 --- a/doc-plugin/src/main/java/org/wildfly/glow/plugin/doc/ScanDocMojo.java +++ b/doc-plugin/src/main/java/org/wildfly/glow/plugin/doc/ScanDocMojo.java @@ -42,6 +42,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.TreeMap; @@ -49,6 +50,7 @@ import org.jboss.galleon.api.Provisioning; import org.jboss.galleon.api.config.GalleonFeaturePackConfig; import org.jboss.galleon.api.config.GalleonProvisioningConfig; +import org.jboss.galleon.universe.FeaturePackLocation.FPID; import org.jboss.galleon.universe.UniverseResolver; import org.jboss.galleon.universe.maven.repo.MavenRepoManager; import org.wildfly.channel.Channel; @@ -56,6 +58,7 @@ import org.wildfly.glow.FeaturePacks; import org.wildfly.glow.LayerMapping; import org.wildfly.glow.LayerMetadata; +import org.wildfly.glow.Space; import org.wildfly.glow.Utils; /** @@ -128,6 +131,9 @@ public class ScanDocMojo extends AbstractMojo { @Parameter(required = false, defaultValue = "WildFly") String serverType; + @Parameter(required = false, defaultValue = "true") + boolean spaces; + @Override public void execute() throws MojoExecutionException, MojoFailureException { try { @@ -183,16 +189,56 @@ public void execute() throws MojoExecutionException, MojoFailureException { provider.addArtifactResolver(artifactResolver); Map> rules = new TreeMap<>(); - getRules(provider, "bare-metal", universeResolver, rules); + getRules(Space.DEFAULT, provider, "bare-metal", universeResolver, rules, false); Map> cloudRules = new TreeMap<>(); - getRules(provider,"cloud", universeResolver, cloudRules); + getRules(Space.DEFAULT, provider,"cloud", universeResolver, cloudRules, false); rulesBuilder.append("## Support for " + serverType + " " + FeaturePacks.getLatestVersion() + "\n\n"); - rulesBuilder.append(buildTable(provider,"bare-metal", rules, false)); - rulesBuilder.append(buildTable(provider,"cloud", cloudRules, false)); + rulesBuilder.append(buildTable(Space.DEFAULT, provider,"bare-metal", rules, false)); + rulesBuilder.append(buildTable(Space.DEFAULT, provider,"cloud", cloudRules, false)); if (preview) { + Map> previewRules = new TreeMap<>(); + getRules(Space.DEFAULT, provider, "bare-metal", universeResolver, previewRules, true); + Map> previewCloudRules = new TreeMap<>(); + getRules(Space.DEFAULT, provider,"cloud", universeResolver, previewCloudRules, true); rulesBuilder.append("## Support for WildFly Preview " + FeaturePacks.getLatestVersion() + "\n\n"); - rulesBuilder.append(buildTable(provider, "bare-metal", rules, true)); - rulesBuilder.append(buildTable(provider, "cloud", cloudRules, true)); + rulesBuilder.append(buildTable(Space.DEFAULT, provider, "bare-metal", previewRules, true)); + rulesBuilder.append(buildTable(Space.DEFAULT, provider, "cloud", previewCloudRules, true)); + } + if (spaces) { + for (Space space : FeaturePacks.getAllSpaces()) { + if (FeaturePacks.getAllVersions(space.getName()).contains(FeaturePacks.getLatestVersion())) { + Map> spaceRules = new TreeMap<>(); + getRules(space, provider, "bare-metal", universeResolver, spaceRules, false); + Map> spaceCloudRules = new TreeMap<>(); + getRules(space, provider, "cloud", universeResolver, spaceCloudRules, false); + if (!spaceRules.isEmpty() || !spaceCloudRules.isEmpty()) { + rulesBuilder.append("## Additional '" + space.getName() + "' space\n\n"); + rulesBuilder.append(space.getDescription() + "\n\n"); + rulesBuilder.append("### Support for " + serverType + " " + FeaturePacks.getLatestVersion() + "\n\n"); + } + if (!spaceRules.isEmpty()) { + rulesBuilder.append(buildTable(space, provider, "bare-metal", spaceRules, false)); + } + if (!spaceCloudRules.isEmpty()) { + rulesBuilder.append(buildTable(space, provider, "cloud", spaceCloudRules, false)); + } + if (preview) { + Map> spacePreviewRules = new TreeMap<>(); + getRules(space, provider, "bare-metal", universeResolver, spacePreviewRules, true); + Map> spacePreviewCloudRules = new TreeMap<>(); + getRules(space, provider, "cloud", universeResolver, spacePreviewCloudRules, true); + if (!spacePreviewRules.isEmpty() || !spacePreviewCloudRules.isEmpty()) { + rulesBuilder.append("### Support for WildFly Preview " + FeaturePacks.getLatestVersion() + "\n\n"); + if (!spacePreviewRules.isEmpty()) { + rulesBuilder.append(buildTable(space, provider, "bare-metal", spacePreviewRules, true)); + } + if (!spacePreviewCloudRules.isEmpty()) { + rulesBuilder.append(buildTable(space, provider, "cloud", spacePreviewCloudRules, true)); + } + } + } + } + } } } finally { System.clearProperty(FeaturePacks.URL_PROPERTY); @@ -206,12 +252,12 @@ public void execute() throws MojoExecutionException, MojoFailureException { } } - private String buildTable(GalleonBuilder provider, String context, Map> rules, boolean preview) throws Exception { + private String buildTable(Space space, GalleonBuilder provider, String context, Map> rules, boolean preview) throws Exception { StringBuilder rulesBuilder = new StringBuilder(); rulesBuilder.append("\n### " + context + "\n"); rulesBuilder.append("\n#### Supported Galleon feature-packs \n"); - Path provisioningXML = FeaturePacks.getFeaturePacks(null, context, preview); + Path provisioningXML = FeaturePacks.getFeaturePacks(space, null, context, preview); try (Provisioning p = provider.newProvisioningBuilder(provisioningXML).build()) { GalleonProvisioningConfig pConfig = p.loadProvisioningConfig(provisioningXML); for (GalleonFeaturePackConfig c : pConfig.getFeaturePackDeps()) { @@ -240,35 +286,59 @@ private String buildTable(GalleonBuilder provider, String context, Map addOns = new TreeMap<>(); for (Layer l : rules.keySet()) { if (l.getAddOn() != null) { addOns.put(l.getAddOn().getName(), l.getAddOn()); } } - for (String a : addOns.keySet()) { - AddOn addon = addOns.get(a); - rulesBuilder.append("|" + addon.getName() + "\n"); - rulesBuilder.append("|" + addon.getFamily() + "\n"); - rulesBuilder.append("|" + addon.getDescription() + "\n"); + if (!addOns.isEmpty()) { + rulesBuilder.append("\n#### [[glow.table.addons." + context + "]]Add-ons\n"); + rulesBuilder.append("[cols=\"25%,25%,50%\"]\n"); + rulesBuilder.append("|===\n"); + rulesBuilder.append("|Add-on |Family |Description\n"); + + for (String a : addOns.keySet()) { + AddOn addon = addOns.get(a); + rulesBuilder.append("|" + addon.getName() + "\n"); + rulesBuilder.append("|" + addon.getFamily() + "\n"); + rulesBuilder.append("|" + addon.getDescription() + "\n"); + } + rulesBuilder.append("|===\n"); } - rulesBuilder.append("|===\n"); return rulesBuilder.toString(); } - private LayerMapping getRules(GalleonBuilder provider, String context, UniverseResolver universeResolver, - Map> rules) throws Exception { - Path provisioningXML = FeaturePacks.getFeaturePacks(null, context, false); + private LayerMapping getRules(Space space, GalleonBuilder provider, String context, UniverseResolver universeResolver, + Map> rules, boolean preview) throws Exception { + Path provisioningXML = FeaturePacks.getFeaturePacks(space, null, context, preview); Map all; try (Provisioning p = provider.newProvisioningBuilder(provisioningXML).build()) { GalleonProvisioningConfig config = p.loadProvisioningConfig(provisioningXML); Map> fpDependencies = new HashMap<>(); all = Utils.getAllLayers(config, universeResolver, p, fpDependencies); + // Filter-out the layers that are not in the additional space + if (!Space.DEFAULT.equals(space)) { + Set toRemove = new HashSet<>(); + for(Entry entry : all.entrySet()) { + Layer l = entry.getValue(); + boolean toInclude = false; + for(FPID fpid : l.getFeaturePacks()) { + if (config.getFeaturePackDep(fpid.getProducer()) != null) { + toInclude = true; + break; + } + } + if (!toInclude) { + toRemove.add(entry.getKey()); + } + } + for(String k : toRemove) { + all.remove(k); + } + } } + LayerMapping mapping = Utils.buildMapping(all, new HashSet<>()); for (Layer l : all.values()) { if (!l.getProperties().isEmpty()) { diff --git a/docs/guide/intro/index.adoc b/docs/guide/intro/index.adoc index e93cde6c..957abe6b 100644 --- a/docs/guide/intro/index.adoc +++ b/docs/guide/intro/index.adoc @@ -28,6 +28,15 @@ link:https://github.com/wildfly/wildfly-galleon-feature-packs/tree/release[this] In order for these extras Feature-packs to be recognized by WildFly Glow, they must have their defined Layers annotated with rules. +### Incubating feature-packs. + +Feature-packs that are developed outside of the WildFly feature process can be registered in the "incubating" space. +This space can be explicitly enabled when discovering provisioning configuration. +WildFly Glow has, per WildFly version, the knowledge of 'incubating' compatible Galleon Feature-packs (this information is stored in +link:https://github.com/wildfly/wildfly-galleon-feature-packs/tree/main/spaces/incubating[this] directory). + +In order for these extras feature-packs to be recognized by WildFly Glow, they must have their defined Layers annotated with rules. + ### Going beyond discovered Galleon Layers WildFly Glow does more than identifying Galleon Feature-packs and Layers. diff --git a/docs/guide/wildfly-maven-plugin/index.adoc b/docs/guide/wildfly-maven-plugin/index.adoc index f6311fba..dc6344b4 100644 --- a/docs/guide/wildfly-maven-plugin/index.adoc +++ b/docs/guide/wildfly-maven-plugin/index.adoc @@ -244,6 +244,20 @@ In case your application packages some jars, you can exclude such jars from the ---- +### Enabling spaces + +In case you want to have access to feature-packs registered in some additional spaces (e.g.: in the 'incubating' space), +you can provide the list of spaces to enable. To do so evolve the `discover-provisioning-info`: + +[source,xml,subs=attributes+] +---- + + + incubating + + +---- + ### Printing matching rules You can print the rules that selected the Galleon Layers. To do so set the `` argument.