Skip to content

Commit

Permalink
Merge pull request wildfly-extras#680 from parsharma/204
Browse files Browse the repository at this point in the history
Introduce command that would list available profiles#204
  • Loading branch information
spyrkob authored Jun 6, 2024
2 parents 57043a2 + 7b08308 commit ad70fe7
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.wildfly.prospero.actions.ApplyCandidateAction;
import org.wildfly.prospero.cli.commands.CliConstants;
import org.wildfly.prospero.metadata.ProsperoMetadataUtils;
import picocli.CommandLine;

import java.io.File;
import java.nio.file.Path;
Expand Down Expand Up @@ -115,15 +116,15 @@ default String changesFound() {
}

default String continueWithUpdate() {
return bundle.getString("prospero.updates.prompt") + " ";
return bundle.getString("prospero.updates.prompt") + " ";
}

default String continueWithRevert() {
return bundle.getString("prospero.revert.prompt") + " ";
return bundle.getString("prospero.revert.prompt") + " ";
}

default String continueWithBuildUpdate() {
return bundle.getString("prospero.updates.build.prompt") + " ";
return bundle.getString("prospero.updates.build.prompt") + " ";
}

default String updateCancelled() {
Expand Down Expand Up @@ -368,9 +369,11 @@ default String attemptedRepositories() {
default String missing() {
return bundle.getString("prospero.general.error.resolve.missing");
}

default String checksumFailed() {
return bundle.getString("prospero.general.error.resolve.checksum_failed");
}

default String offline() {
return bundle.getString("prospero.general.error.resolve.offline");
}
Expand Down Expand Up @@ -611,25 +614,31 @@ default String diffFeaturesChanges() {
default String productAndVersionNotNull() {
return bundle.getString("prospero.update.subscribe.product.version.required");
}

default String unknownProduct(String product) {
return format(bundle.getString("prospero.update.subscribe.unknown.product"), product);
}

default String writeManifest(Path manifestPath) {
return format(bundle.getString("prospero.update.subscribe.write.manifest"), manifestPath);
}

default String writeChannelsConfiguration(Path channelsPath) {
return format(bundle.getString("prospero.update.subscribe.write.channels"), channelsPath);
}

default String conflictsWhenGenerating(String diff) {
return format(bundle.getString("prospero.update.subscribe.conflict.prompt"), diff);
}

default String continueGenerating() {
return bundle.getString("prospero.update.subscribe.conflict.prompt.continue");
}

default String quitGenerating() {
return bundle.getString("prospero.update.subscribe.conflict.prompt.cancel");
}

default String metadataExistsAlready(Path path, String distName) {
return format(bundle.getString("prospero.update.subscribe.meta.exists"), path, distName);
}
Expand All @@ -638,18 +647,44 @@ default String serverVersionsHeader() {
return bundle.getString("prospero.channels.versions.header");
}

default IllegalArgumentException unknownStabilityLevel(String stabilityLevel, List<String> supportedStabilityLevels) {
default IllegalArgumentException unknownStabilityLevel(String stabilityLevel, List<String> supportedStabilityLevels) {
return new IllegalArgumentException(format(bundle.getString("prospero.install.unknown_stability_level"),
stabilityLevel, String.join(",", supportedStabilityLevels)));
}

default String featurePackRequiresLayers(String featurePackName) {
return format(bundle.getString("prospero.features.add.validation.layers_required"), featurePackName, CliConstants.LAYERS);
}

default String featurePackDoesNotSupportCustomization(String featurePackName) {
return format(bundle.getString("prospero.features.add.validation.customization_not_supported"), featurePackName,
String.join(",", List.of(CliConstants.LAYERS, CliConstants.TARGET_CONFIG)));
}

default String featurePackRequiresLicense(String featurePackName) {
return format(bundle.getString("prospero.features.add.required_licences"), featurePackName);
}

default CommandLine.ParameterException missingRequiredParameter(CommandLine spec, String param) {
return new CommandLine.ParameterException(spec, format(bundle.getString("prospero.general.error.missing.parameter"), param));
}

default String availableProfiles() {
return bundle.getString("prospero.install.list.profile.header");
}
default String noAvailableProfiles() {
return bundle.getString("prospero.install.list.profile.no_profiles.header");
}

default String subscribedChannels() {
return bundle.getString("prospero.install.list.profile.subscribe.channels");
}
default String includedFeaturePacks() {
return bundle.getString("prospero.install.list.profile.featurePacks");
}

default String getProfile() {
return bundle.getString("prospero.install.list.profile");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ private Commands() {
public static final String H = "-h";
public static final String HELP = "--help";
public static final String LAYERS = "--layers";
public static final String LIST_PROFILES = "--list-profiles";
public static final String LOCAL_CACHE = "--local-cache";
public static final String OFFLINE = "--offline";
public static final String PACKAGE_STABILITY_LEVEL = "--package-stability-level";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.jboss.galleon.Constants;
import org.jboss.galleon.ProvisioningException;
import org.jboss.galleon.api.config.GalleonFeaturePackConfig;
import org.jboss.galleon.api.config.GalleonProvisioningConfig;

import org.jboss.galleon.universe.FeaturePackLocation;
import org.wildfly.channel.Channel;
import org.wildfly.channel.ChannelManifestCoordinate;
import org.wildfly.channel.Repository;
Expand All @@ -51,18 +56,28 @@
import org.wildfly.prospero.api.TemporaryFilesManager;
import org.wildfly.prospero.cli.commands.options.FeaturePackCandidates;
import org.wildfly.prospero.cli.printers.ChannelPrinter;
import org.wildfly.prospero.galleon.GalleonUtils;
import org.wildfly.prospero.licenses.License;
import org.wildfly.prospero.model.KnownFeaturePack;
import picocli.CommandLine;

import javax.xml.stream.XMLStreamException;


@CommandLine.Command(
name = CliConstants.Commands.INSTALL,
sortOptions = false
)
public class InstallCommand extends AbstractInstallCommand {

protected static final int PROFILES_INDENT = 4;
protected static final String PROFILE_SUBHEADERS_INDENT = " ";
@CommandLine.Spec
CommandLine.Model.CommandSpec spec;

@CommandLine.Option(
names = CliConstants.DIR,
required = true,
required = false,
order = 2
)
Path directory;
Expand Down Expand Up @@ -117,6 +132,13 @@ static class FeaturePackOrDefinition {
order = 3
)
Optional<Path> definition;

@CommandLine.Option(
names = CliConstants.LIST_PROFILES,
order = 4
)
boolean listProfiles;

}

public InstallCommand(CliConsole console, ActionFactory actionFactory) {
Expand All @@ -127,6 +149,13 @@ public InstallCommand(CliConsole console, ActionFactory actionFactory) {
public Integer call() throws Exception {
final long startTime = System.currentTimeMillis();

if (featurePackOrDefinition.listProfiles) {
return displayListOfProfiles();
}
if (directory == null) {
throw CliMessages.MESSAGES.missingRequiredParameter(spec.commandLine(), CliConstants.DIR);
}

// following is checked by picocli, adding this to avoid IDE warnings
assert featurePackOrDefinition.definition.isPresent() || featurePackOrDefinition.fpl.isPresent() || featurePackOrDefinition.profile.isPresent();

Expand Down Expand Up @@ -162,7 +191,6 @@ public Integer call() throws Exception {
}

verifyTargetDirectoryIsEmpty(directory);

final ProvisioningDefinition provisioningDefinition = buildDefinition()
.setStabilityLevel(stabilityLevels.stabilityLevel==null?null:stabilityLevels.stabilityLevel.toLowerCase(Locale.ROOT))
.setPackageStabilityLevel(stabilityLevels.packageStabilityLevel==null?null:stabilityLevels.packageStabilityLevel.toLowerCase(Locale.ROOT))
Expand Down Expand Up @@ -285,4 +313,49 @@ public void verify() {
}
}
}

private int displayListOfProfiles() throws ProvisioningException {
final Set<String> profiles = KnownFeaturePacks.getNames();
if (profiles.isEmpty()) {
console.println(CliMessages.MESSAGES.noAvailableProfiles() + "\n");
} else {
console.println(CliMessages.MESSAGES.availableProfiles() + "\n");
}

final ChannelPrinter channelPrinter = new ChannelPrinter(console, PROFILES_INDENT);
for (String profileName : profiles){
console.println("----------");
console.println(CliMessages.MESSAGES.getProfile() + profileName);

final KnownFeaturePack profile = KnownFeaturePacks.getByName(profileName);

console.println(PROFILE_SUBHEADERS_INDENT + CliMessages.MESSAGES.subscribedChannels());
for(Channel channel: profile.getChannels()){
channelPrinter.print(channel);
}

console.println(PROFILE_SUBHEADERS_INDENT + CliMessages.MESSAGES.includedFeaturePacks());
for (FeaturePackLocation featurePackLocation: getFeaturePacks(profile)) {
console.println(" ".repeat(PROFILES_INDENT) + featurePackLocation.toString());
}
}

return ReturnCodes.SUCCESS;
}

private List<FeaturePackLocation> getFeaturePacks(KnownFeaturePack profile) throws ProvisioningException {
try {
final GalleonProvisioningConfig config = GalleonUtils.loadProvisioningConfig(profile.getGalleonConfiguration());
if (config.getFeaturePackDeps().isEmpty()) {
throw new ProvisioningException("At least one feature pack location must be specified in the provisioning configuration");
}

return config.getFeaturePackDeps().stream()
.map(GalleonFeaturePackConfig::getLocation)
.collect(Collectors.toList());
} catch (XMLStreamException e) {
throw new ProvisioningException("Unable to parse provisioning configuration", e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,37 @@
public class ChannelPrinter {

private final Console console;
private final int indentSize;

public ChannelPrinter(Console console) {
this(console, 0);
}

public ChannelPrinter(Console console, int indentSize) {
this.console = console;
this.indentSize = indentSize;
}

public void print(Channel channel) {
String startMarker = "# ";
if (channel.getName() != null && !channel.getName().isEmpty()) {
console.println(startMarker + channel.getName());
printLine(startMarker + channel.getName());
startMarker = " ";
}
final String manifest = channel.getManifestCoordinate().getMaven() == null
?channel.getManifestCoordinate().getUrl().toExternalForm():toGav(channel.getManifestCoordinate().getMaven());
console.println(startMarker + "manifest: " + manifest);
console.println(" " + "repositories:");
printLine(startMarker + "manifest: " + manifest);
printLine(" " + "repositories:");
for (Repository repository : channel.getRepositories()) {
console.println(" " + " " + "id: " + repository.getId());
console.println(" " + " " + "url: " + repository.getUrl());
printLine(" " + " " + "id: " + repository.getId());
printLine(" " + " " + "url: " + repository.getUrl());
}
}

private void printLine(String text) {
console.println(" ".repeat(indentSize) + text);
}

private static String toGav(MavenCoordinate coord) {
final String ga = coord.getGroupId() + ":" + coord.getArtifactId();
if (coord.getVersion() != null && !coord.getVersion().isEmpty()) {
Expand Down
12 changes: 12 additions & 0 deletions prospero-cli/src/main/resources/UsageMessages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ ${prospero.dist.name}.install.usage.customSynopsis.3 = \u0020 or: @|bold ${pros
${prospero.dist.name}.install.usage.customSynopsis.4 = \u0020 (to install a feature pack)
${prospero.dist.name}.install.usage.customSynopsis.5 = \u0020 or: @|bold ${prospero.dist.name} install|@ @|fg(yellow) --definition|@=@|italic <path>|@ @|fg(yellow) --dir|@=@|italic <target-directory>|@ [@|fg(yellow) OPTION|@]...
${prospero.dist.name}.install.usage.customSynopsis.6 = \u0020 (to install from a Galleon `@|bold provisioning.xml|@` file)
${prospero.dist.name}.install.usage.customSynopsis.7 = \u0020 or: @|bold ${prospero.dist.name} install|@ @|fg(yellow) --list-profiles|@
${prospero.dist.name}.install.usage.customSynopsis.8 = \u0020 (to list available installation profiles)


${prospero.dist.name}.update.usage.header = Updates a server instance with the latest patches.
${prospero.dist.name}.update.usage.description.0 = Update operation can be run either as a one-step (@|bold perform|@) or two-step (@|bold prepare|@+@|bold apply|@) operation.
Expand Down Expand Up @@ -139,6 +142,7 @@ channel-name = Name of the new channel. Channel names should be unique for the s
${prospero.dist.name}.channel.remove.channel-name = Name of the channel.
customization-repository = URL to repository containing custom artifacts.
definition = Path to the Galleon `@|bold provisioning.xml|@` file.
list-profiles = Displays the available installation profiles. The profiles contain complete provisioning configurations required to install a server.

# General description for the --dir option, applies to all commands unless a command specifies different description:
dir = Location of the existing application server. If not specified, current working directory is used.
Expand Down Expand Up @@ -390,3 +394,11 @@ prospero.changes.diff.channel=channel
prospero.changes.diff.features_changes=Installed features changes

prospero.changes.conflict.header=Conflicting changes detected in the update:
prospero.general.error.missing.parameter=Error: Missing required argument: (%s)
prospero.install.list.profile.header=Available installation profiles
prospero.install.list.profile.no_profiles.header=No installation profiles available. \n \
You can use the feature pack location (--fpl) argument to install the server.
prospero.install.list.profile=Profile:\u0020
prospero.install.list.profile.subscribe.channels=Subscribed channels:\u0020
prospero.install.list.profile.featurePacks=Installed feature packs:\u0020

Loading

0 comments on commit ad70fe7

Please sign in to comment.