From 89028613d82f953e60bf666c60d1154488ff026c Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Fri, 15 Jul 2022 08:26:50 -0300 Subject: [PATCH] Introducing --optimise option Closes #10737 --- .../guides/src/main/server/configuration.adoc | 36 +- docs/guides/src/main/server/containers.adoc | 7 +- .../controllers/KeycloakDeployment.java | 5 +- .../integration/KeycloakDeploymentTest.java | 3 +- quarkus/dist/src/main/content/bin/kc.bat | 9 +- quarkus/dist/src/main/content/bin/kc.sh | 7 +- .../keycloak/quarkus/runtime/Environment.java | 6 +- .../quarkus/runtime/KeycloakMain.java | 8 +- .../keycloak/quarkus/runtime/cli/Picocli.java | 40 ++- .../cli/command/AbstractStartCommand.java | 3 + .../quarkus/runtime/cli/command/Build.java | 5 +- .../quarkus/runtime/cli/command/Start.java | 14 +- .../it/junit5/extension/CLIResult.java | 12 +- .../org/keycloak/it/cli/HelpCommandTest.java | 4 +- .../org/keycloak/it/cli/StartCommandTest.java | 3 +- .../it/cli/dist/BuildAndStartDistTest.java | 6 +- .../it/cli/dist/ClusterConfigDistTest.java | 4 +- .../it/cli/dist/FeaturesDistTest.java | 3 +- .../keycloak/it/cli/dist/LoggingDistTest.java | 1 + .../QuarkusPropertiesAutoBuildDistTest.java | 16 +- .../cli/dist/QuarkusPropertiesDistTest.java | 3 +- .../it/cli/dist/StartAutoBuildDistTest.java | 48 ++- .../it/cli/dist/StartCommandDistTest.java | 7 +- .../it/cli/dist/StartDevCommandDistTest.java | 36 +- .../storage/database/BasicDatabaseTest.java | 7 +- .../it/storage/map/ChmStorageDistTest.java | 2 +- .../it/storage/map/JPAStoreDistTest.java | 2 +- ...ommandTest.testBuildHelp.unix.approved.txt | 9 +- ...Test.testStartDevHelp.windows.approved.txt | 319 ++++++++--------- ...ommandTest.testStartHelp.unix.approved.txt | 23 +- ...andTest.testStartHelp.windows.approved.txt | 333 +++++++++--------- ...cloakQuarkusServerDeployableContainer.java | 5 +- 32 files changed, 545 insertions(+), 441 deletions(-) diff --git a/docs/guides/src/main/server/configuration.adoc b/docs/guides/src/main/server/configuration.adoc index 8571551a27..7f9024eb81 100644 --- a/docs/guides/src/main/server/configuration.adoc +++ b/docs/guides/src/main/server/configuration.adoc @@ -53,6 +53,19 @@ db-url-host=mykeycloakdb The configuration source and the corresponding format you should use is use-case specific. That decision depends on the platform where the server is deployed and the runtime optimizations you are seeking. For instance, if you deploy the server into Kubernetes, you would probably rely on environment variables to configure the server. However, you are not limited to a single configuration source or format. +== Starting the server + +You start the server by entering the following command: + +.Starting the server +<@kc.start parameters="--db postgres --db-url-host keycloak-postgres --db-username keycloak --db-password change_me --hostname mykeycloak.acme.com"/> + +Under certain circumstances, you might prefer to allow a longer startup time in favor of updating the values of build options when starting the server, hence performing the two configuration stages +when starting the server. + +By default, running the `start` command is going to automatically run the `build` command prior to starting the server. While this is a handy way to start the server with any available option, +including **build options** that otherwise are only available to the `build` command, it introduces an additional overhead in the server startup time. For most environments, this approach is not optimal. + == Configuration commands and stages The server options are narrowed to a specific command or configuration stage. The goal is to perform a series of optimizations in a specific order to achieve optimal startup and runtime performance. This configuration occurs in two stages: @@ -84,18 +97,20 @@ The following are some optimizations performed by the `build` command: Once you run the `build` command, you do not need to set the same **build options** when you start the server. -=== Second stage: Starting Keycloak +=== Second stage: Starting an optimized server instance -The second stage involves starting the server by using the `start` command and including **configuration options** with the appropriate values. +In order to achieve an optimal startup time when the server was previously built with any **build option**, you should run the `start` command together with the `--optimise` option and including any **configuration option** you want to set. .Run the `start` command to start the server while setting various database options -<@kc.start parameters="--db-url-host=keycloak-postgres --db-username=keycloak --db-password=change_me --hostname mykeycloak.acme.com"/> +<@kc.start parameters="--optimise --db-url-host=keycloak-postgres --db-username=keycloak --db-password=change_me --hostname mykeycloak.acme.com"/> + +The `--optimise` indicates that the server was previously configured with any build option so that it no longer need to run the `build` command prior to start the server. Note that if you invoke commands containing special shell characters such as `;` using the CLI, you need to escape those characters. In that situation, you might choose to use the `keycloak.conf` file to set configuration options instead. == Optimization by using a configuration file -Most optimizations to startup and memory footprint can be achieved by using the `build` command. Additionally, you can use the `conf/keycloak.conf` file to set configuration options. Using this file avoids some necessary parsing steps when providing configuration options using the CLI or environment variables. +Most optimizations to startup and memory footprint can be achieved by using the `build` command. Additionally, you can use the `conf/keycloak.conf` file to set configuration options. Using this file avoids some necessary parsing steps when providing configuration options using the CLI. .Set any build option <@kc.build parameters="--db=postgres"/> @@ -109,21 +124,10 @@ hostname=mykeycloak.acme.com ``` .Start the server -<@kc.start/> +<@kc.start parameters="--optimise"/> By using the `keycloak.conf` file, the server can omit some steps at startup. As a result, the server starts faster. -== The auto-build option: automatic detection when the server needs a build - -Under certain circumstances, you might prefer to allow a longer startup time in favor of updating the values of build options when starting the server. Using the `auto-build` option, you can perform the two configuration stages by using a single command. Note that using `auto-build` is very likely to double the startup time for Keycloak. For most environments, this approach is not optimal. - -You start the server by entering the following command: - -.Using the `auto-build` option -<@kc.start parameters="--auto-build --db postgres --db-url-host keycloak-postgres --db-username keycloak --db-password change_me --hostname mykeycloak.acme.com"/> - -By including the `auto-build` option, the server calculates the build options that have changed and runs the `build` command, if necessary, before starting the server. - == Configuring the server by using configuration files By default, the server always fetches configuration options from the `conf/keycloak.conf` file. For a new installation, diff --git a/docs/guides/src/main/server/containers.adoc b/docs/guides/src/main/server/containers.adoc index 1c34551943..17b7df7907 100644 --- a/docs/guides/src/main/server/containers.adoc +++ b/docs/guides/src/main/server/containers.adoc @@ -74,7 +74,7 @@ To start the image, run: podman|docker run --name optimized_keycloak -p 8443:8443 \ -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=change_me \ prebuilt_keycloak \ - start + start --optimised ---- Keycloak starts in production mode, using only secured HTTPS communication, and is available on `https://localhost:8443`. Notice that the startup log contains the following line: @@ -105,10 +105,10 @@ Invoking this command starts the Keycloak server in development mode. This mode should be strictly avoided in production environments because it has insecure defaults. For more information about running Keycloak in production, take a look at the <@links.server id="configuration-production"/> guide. -== Use auto-build to run a standard keycloak container +== Running a standard keycloak container In keeping with concepts such as immutable infrastructure, containers need to be re-provisioned routinely. In these environments, you need containers that start fast, therefore you need to create an optimized image as described in the preceding section. -However, if your environment has different requirements, you can run a standard Keycloak image using the `--auto-build` flag. +However, if your environment has different requirements, you can run a standard Keycloak image by just running the `start` command. For example: [source, bash] @@ -117,7 +117,6 @@ podman|docker run --name keycloak_auto_build -p 8080:8080 \ -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=change_me \ quay.io/keycloak/keycloak:latest \ start \ - --auto-build \ --db=postgres --features=token-exchange \ --db-url= --db-username= --db-password= \ --https-key-store-file= --https-key-store-password= diff --git a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDeployment.java b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDeployment.java index b3ec993c31..53eeb7a860 100644 --- a/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDeployment.java +++ b/operator/src/main/java/org/keycloak/operator/controllers/KeycloakDeployment.java @@ -513,8 +513,9 @@ public class KeycloakDeployment extends OperatorManagedResource implements Statu Container container = baseDeployment.getSpec().getTemplate().getSpec().getContainers().get(0); var customImage = Optional.ofNullable(keycloakCR.getSpec().getImage()); container.setImage(customImage.orElse(config.keycloak().image())); - if (customImage.isEmpty()) { - container.getArgs().add("--auto-build"); + + if (customImage.isPresent()) { + container.getArgs().add("--optimised"); } container.setImagePullPolicy(config.keycloak().imagePullPolicy()); diff --git a/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakDeploymentTest.java b/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakDeploymentTest.java index 2207dedcf3..b3d12fd211 100644 --- a/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakDeploymentTest.java +++ b/operator/src/test/java/org/keycloak/operator/testsuite/integration/KeycloakDeploymentTest.java @@ -388,8 +388,7 @@ public class KeycloakDeploymentTest extends BaseOperatorTest { .list() .getItems(); - assertEquals(1, pods.get(0).getSpec().getContainers().get(0).getArgs().size()); - assertEquals("start", pods.get(0).getSpec().getContainers().get(0).getArgs().get(0)); + assertThat(pods.get(0).getSpec().getContainers().get(0).getArgs()).containsExactly("start", "--optimised"); } catch (Exception e) { savePodLogs(); throw e; diff --git a/quarkus/dist/src/main/content/bin/kc.bat b/quarkus/dist/src/main/content/bin/kc.bat index ba3a3c2c33..05c24b5c3a 100644 --- a/quarkus/dist/src/main/content/bin/kc.bat +++ b/quarkus/dist/src/main/content/bin/kc.bat @@ -24,6 +24,7 @@ set "SERVER_OPTS=-Djava.util.logging.manager=org.jboss.logmanager.LogManager -Dq set DEBUG_MODE=false set DEBUG_PORT_VAR=8787 set DEBUG_SUSPEND_VAR=n +set CONFIG_ARGS= rem Read command-line args, the ~ removes the quotes from the parameter :READ-ARGS @@ -128,10 +129,12 @@ set "JAVA_RUN_OPTS=%JAVA_OPTS% -Dkc.home.dir="%DIRNAME%.." -Djboss.server.config SetLocal EnableDelayedExpansion -set "AUTO_BUILD_OPTION=auto-build" +set "ONLY_BUILD_OPTION= build" +set "NO_AUTO_BUILD_OPTION=optimised" -if not "!CONFIG_ARGS:%AUTO_BUILD_OPTION%=!"=="!CONFIG_ARGS!" ( - "%JAVA%" -Dkc.config.rebuild-and-exit=true %JAVA_RUN_OPTS% +if "!CONFIG_ARGS:%NO_AUTO_BUILD_OPTION%=!"=="!CONFIG_ARGS!" if "!CONFIG_ARGS:%ONLY_BUILD_OPTION%=!"=="!CONFIG_ARGS!" ( + "%JAVA%" -Dkc.config.build-and-exit=true %JAVA_RUN_OPTS% + set "JAVA_RUN_OPTS=-Dkc.config.built=true %JAVA_RUN_OPTS%" ) "%JAVA%" %JAVA_RUN_OPTS% diff --git a/quarkus/dist/src/main/content/bin/kc.sh b/quarkus/dist/src/main/content/bin/kc.sh index fd28d5b2be..625d5b26e5 100644 --- a/quarkus/dist/src/main/content/bin/kc.sh +++ b/quarkus/dist/src/main/content/bin/kc.sh @@ -48,7 +48,7 @@ do *) if [[ $1 = --* || ! $1 =~ ^-D.* ]]; then if [[ "$1" = "start-dev" ]]; then - CONFIG_ARGS="$CONFIG_ARGS --profile=dev $1 --auto-build" + CONFIG_ARGS="$CONFIG_ARGS --profile=dev $1" else CONFIG_ARGS="$CONFIG_ARGS $1" fi @@ -96,8 +96,9 @@ CLASSPATH_OPTS="'$DIRNAME'/../lib/quarkus-run.jar" JAVA_RUN_OPTS="$JAVA_OPTS $SERVER_OPTS -cp $CLASSPATH_OPTS io.quarkus.bootstrap.runner.QuarkusEntryPoint ${CONFIG_ARGS#?}" -if [[ $CONFIG_ARGS = *"--auto-build"* ]]; then - eval "$JAVA" -Dkc.config.rebuild-and-exit=true $JAVA_RUN_OPTS +if [[ (! $CONFIG_ARGS = *"--optimised"*) ]] && [[ ! "$CONFIG_ARGS" == " build"* ]]; then + eval "$JAVA" -Dkc.config.build-and-exit=true $JAVA_RUN_OPTS + JAVA_RUN_OPTS="-Dkc.config.built=true $JAVA_RUN_OPTS" EXIT_CODE=$? if [ $EXIT_CODE != 0 ]; then exit $EXIT_CODE diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/Environment.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/Environment.java index 9efb2b36aa..e873cd0e48 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/Environment.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/Environment.java @@ -224,6 +224,10 @@ public final class Environment { } public static boolean isRebuildCheck() { - return Boolean.getBoolean("kc.config.rebuild-and-exit"); + return Boolean.getBoolean("kc.config.build-and-exit"); + } + + public static boolean isRebuilt() { + return Boolean.getBoolean("kc.config.built"); } } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java index 25dfbd9fb2..db0bf9452f 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java @@ -23,6 +23,7 @@ import static org.keycloak.quarkus.runtime.Environment.getProfileOrDefault; import static org.keycloak.quarkus.runtime.Environment.isImportExportMode; import static org.keycloak.quarkus.runtime.Environment.isTestLaunchMode; import static org.keycloak.quarkus.runtime.cli.Picocli.parseAndRun; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.*; import static org.keycloak.quarkus.runtime.cli.command.Start.isDevProfileNotAllowed; import java.io.PrintWriter; @@ -69,7 +70,7 @@ public class KeycloakMain implements QuarkusApplication { cliArgs = new ArrayList<>(cliArgs); // default to show help message cliArgs.add("-h"); - } else if (cliArgs.contains(Start.NAME) && cliArgs.size() == 1) { + } else if (isFastStart(cliArgs)) { // fast path for starting the server without bootstrapping CLI ExecutionExceptionHandler errorHandler = new ExecutionExceptionHandler(); PrintWriter errStream = new PrintWriter(System.err, true); @@ -88,6 +89,11 @@ public class KeycloakMain implements QuarkusApplication { parseAndRun(cliArgs); } + private static boolean isFastStart(List cliArgs) { + // 'start --optimised' should start the server without parsing CLI + return cliArgs.size() == 2 && cliArgs.get(0).equals(Start.NAME) && cliArgs.stream().anyMatch(OPTIMISED_BUILD_OPTION_LONG::equals); + } + public static void start(ExecutionExceptionHandler errorHandler, PrintWriter errStream) { ClassLoader originalCl = Thread.currentThread().getContextClassLoader(); diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java index 1f3cd7b40f..7f6f89122d 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/Picocli.java @@ -17,6 +17,9 @@ package org.keycloak.quarkus.runtime.cli; +import static org.keycloak.quarkus.runtime.Environment.isRebuildCheck; +import static org.keycloak.quarkus.runtime.Environment.isRebuilt; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.*; import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_LONG; import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.AUTO_BUILD_OPTION_SHORT; import static org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource.parseConfigArgs; @@ -40,6 +43,7 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.BiConsumer; +import java.util.function.Predicate; import java.util.function.UnaryOperator; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -47,6 +51,7 @@ import java.util.stream.Collectors; import org.eclipse.microprofile.config.spi.ConfigSource; import org.keycloak.config.MultiOption; import org.keycloak.config.OptionCategory; +import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand; import org.keycloak.quarkus.runtime.cli.command.Build; import org.keycloak.quarkus.runtime.cli.command.ImportRealmMixin; import org.keycloak.quarkus.runtime.cli.command.Main; @@ -98,7 +103,7 @@ public final class Picocli { private static int runReAugmentationIfNeeded(List cliArgs, CommandLine cmd) { int exitCode = 0; - if (hasAutoBuildOption(cliArgs) && !isHelpCommand(cliArgs)) { + if (!isHelpCommand(cliArgs)) { if (cliArgs.contains(StartDev.NAME)) { String profile = Environment.getProfile(); @@ -118,10 +123,6 @@ public final class Picocli { return cliArgs.contains("--help") || cliArgs.contains("-h") || cliArgs.contains("--help-all"); } - public static boolean hasAutoBuildOption(List cliArgs) { - return cliArgs.contains(AUTO_BUILD_OPTION_LONG) || cliArgs.contains(AUTO_BUILD_OPTION_SHORT); - } - public static boolean requiresReAugmentation(CommandLine cmd) { if (hasConfigChanges()) { if (!ConfigArgsConfigSource.getAllCliArgs().contains(StartDev.NAME) && "dev".equals(getConfig().getOptionalValue("kc.profile", String.class).orElse(null))) { @@ -169,24 +170,18 @@ public final class Picocli { List configArgsList = new ArrayList<>(cliArgs); + // remove this once auto-build option is removed configArgsList.remove(AUTO_BUILD_OPTION_LONG); configArgsList.remove(AUTO_BUILD_OPTION_SHORT); + configArgsList.remove(ImportRealmMixin.IMPORT_REALM); - configArgsList.replaceAll(new UnaryOperator() { - @Override - public String apply(String arg) { - if (arg.equals(Start.NAME) || arg.equals(StartDev.NAME)) { - return Build.NAME; - } - return arg; - } - }); + configArgsList.replaceAll(Picocli::replaceStartWithBuild); exitCode = cmd.execute(configArgsList.toArray(new String[0])); if(!isDevMode() && exitCode == cmd.getCommandSpec().exitCodeOnSuccess()) { - cmd.getOut().printf("Next time you run the server, just run:%n%n\t%s %s %s%n%n", Environment.getCommand(), Start.NAME, String.join(" ", getSanitizedRuntimeCliOptions())); + cmd.getOut().printf("Next time you run the server, just run:%n%n\t%s %s %s %s%n%n", Environment.getCommand(), Start.NAME, OPTIMISED_BUILD_OPTION_LONG, String.join(" ", getSanitizedRuntimeCliOptions())); } return exitCode; @@ -346,9 +341,9 @@ public final class Picocli { .build()); } - addOption(spec, Start.NAME, hasAutoBuildOption(cliArgs), true); + addOption(spec, Start.NAME, isRebuilt(), true); addOption(spec, StartDev.NAME, true, true); - addOption(spec, Build.NAME, true, hasAutoBuildOption(cliArgs)); + addOption(spec, Build.NAME, true, isRebuildCheck()); CommandLine cmd = new CommandLine(spec); @@ -467,8 +462,19 @@ public final class Picocli { } } } + + if (!isRebuildCheck() && (arg.startsWith(AbstractStartCommand.AUTO_BUILD_OPTION_SHORT) || arg.startsWith(AUTO_BUILD_OPTION_LONG))) { + System.out.println(DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION); + } } return args; } + + private static String replaceStartWithBuild(String arg) { + if (arg.equals(Start.NAME) || arg.equals(StartDev.NAME)) { + return Build.NAME; + } + return arg; + } } diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/AbstractStartCommand.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/AbstractStartCommand.java index eed35588f7..b23f8512c4 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/AbstractStartCommand.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/AbstractStartCommand.java @@ -24,8 +24,11 @@ import picocli.CommandLine; public abstract class AbstractStartCommand extends AbstractCommand implements Runnable { + // remove this once auto-build is removed public static final String AUTO_BUILD_OPTION_LONG = "--auto-build"; public static final String AUTO_BUILD_OPTION_SHORT = "-b"; + public static final String OPTIMISED_BUILD_OPTION_LONG = "--optimised"; + public static final String DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION = "WARNING: The '" + AUTO_BUILD_OPTION_LONG + "' option for 'start' command is DEPRECATED and no longer needed. When executing the '" + Start.NAME + "' command, a new server image is automatically built based on the configuration. If you want to disable this behavior and achieve an optimal startup time, use the '" + OPTIMISED_BUILD_OPTION_LONG + "' option instead."; @Override public void run() { diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Build.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Build.java index ee3227d28d..b327dbd1db 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Build.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Build.java @@ -56,10 +56,7 @@ import picocli.CommandLine.Command; + " Enable metrics endpoints:%n%n" + " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --metrics-enabled=true%n%n" + " Change the relative path:%n%n" - + " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --http-relative-path=/auth%n%n" - + "You can also use the \"--auto-build\" option when starting the server to avoid running this command every time you change a configuration:%n%n" - + " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} start --auto-build %n%n" - + "By doing that you have an additional overhead when the server is starting.") + + " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --http-relative-path=/auth%n") public final class Build extends AbstractCommand implements Runnable { public static final String NAME = "build"; diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Start.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Start.java index 6daae10b31..778e2cc69f 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Start.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/cli/command/Start.java @@ -35,21 +35,27 @@ import java.util.Optional; description = { "%nUse this command to run the server in production." }, - footer = "%nYou may use the \"--auto-build\" option when starting the server to avoid running the \"build\" command everytime you need to change a static property:%n%n" - + " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} --auto-build %n%n" - + "By doing that you have an additional overhead when the server is starting. Run \"${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} build -h\" for more details.") + footer = "%nBy default, this command tries to update the server configuration by running a '" + Build.NAME + "' before starting the server. You can disable this behavior by using the '" + Start.OPTIMISED_BUILD_OPTION_LONG + "' option:%n%n" + + " $ ${PARENT-COMMAND-FULL-NAME:-$PARENTCOMMAND} ${COMMAND-NAME} '" + Start.OPTIMISED_BUILD_OPTION_LONG + "'%n%n" + + "By doing that, the server should start faster based on any previous configuration you have set when manually running the '" + Build.NAME + "' command.") public final class Start extends AbstractStartCommand implements Runnable { public static final String NAME = "start"; @CommandLine.Option(names = {AUTO_BUILD_OPTION_SHORT, AUTO_BUILD_OPTION_LONG}, - description = "Automatically detects whether the server configuration changed and a new server image must be built" + + description = "(Deprecated) Automatically detects whether the server configuration changed and a new server image must be built" + " prior to starting the server. This option provides an alternative to manually running the '" + Build.NAME + "'" + " prior to starting the server. Use this configuration carefully in production as it might impact the startup time.", paramLabel = NO_PARAM_LABEL, order = 1) Boolean autoConfig; + @CommandLine.Option(names = {OPTIMISED_BUILD_OPTION_LONG}, + description = "Use this option to achieve an optional startup time if you have previously built a server image using the 'build' command.", + paramLabel = NO_PARAM_LABEL, + order = 1) + Boolean noAutoConfig; + @CommandLine.Mixin ImportRealmMixin importRealmMixin; diff --git a/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java b/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java index 5c828bb44d..d948cdb646 100644 --- a/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java +++ b/quarkus/tests/integration/src/main/java/org/keycloak/it/junit5/extension/CLIResult.java @@ -21,7 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.testcontainers.shaded.org.hamcrest.MatcherAssert.assertThat; -import static org.testcontainers.shaded.org.hamcrest.Matchers.containsString; +import static org.testcontainers.shaded.org.hamcrest.Matchers.*; import java.util.List; @@ -92,6 +92,15 @@ public interface CLIResult extends LaunchResult { assertThat(getOutput(), containsString(message)); } + default void assertNoMessage(String message) { + assertThat(getOutput(), not(containsString(message))); + } + + default void assertMessageWasShownExactlyNumberOfTimes(String message, long numberOfShownTimes) { + long msgCount = getOutput().lines().filter(oneMessage -> oneMessage.contains(message)).count(); + assertThat(msgCount, equalTo(numberOfShownTimes)); + } + default void assertBuild() { assertMessage("Server configuration updated and persisted"); } @@ -140,4 +149,5 @@ public interface CLIResult extends LaunchResult { fail("No JSON found in output."); } } + } diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/HelpCommandTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/HelpCommandTest.java index 475ff1e778..4cbec9d949 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/HelpCommandTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/HelpCommandTest.java @@ -27,6 +27,8 @@ import io.quarkus.test.junit.main.LaunchResult; import org.keycloak.quarkus.runtime.cli.command.Start; import org.keycloak.quarkus.runtime.cli.command.StartDev; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG; + @CLITest public class HelpCommandTest { @@ -52,7 +54,7 @@ public class HelpCommandTest { } @Test - @Launch({ Start.NAME, "--help" }) + @Launch({ Start.NAME, "--help", OPTIMISED_BUILD_OPTION_LONG}) void testStartHelp(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertHelp(); diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/StartCommandTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/StartCommandTest.java index 1f4e62fb72..963df24375 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/StartCommandTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/StartCommandTest.java @@ -18,6 +18,7 @@ package org.keycloak.it.cli; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG; import org.junit.jupiter.api.Test; import org.keycloak.it.junit5.extension.CLIResult; @@ -51,7 +52,7 @@ public class StartCommandTest { } @Test - @Launch({ "-v", "start", "--db=dev-mem" }) + @Launch({ "-v", "start", "--db=dev-mem", OPTIMISED_BUILD_OPTION_LONG}) void failBuildPropertyNotAvailable(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertError("Unknown option: '--db'"); diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/BuildAndStartDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/BuildAndStartDistTest.java index 77ca07de40..d9a720a002 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/BuildAndStartDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/BuildAndStartDistTest.java @@ -31,6 +31,8 @@ import org.keycloak.it.utils.KeycloakDistribution; import io.quarkus.test.junit.main.Launch; import io.quarkus.test.junit.main.LaunchResult; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG; + @DistributionTest(reInstall = DistributionTest.ReInstall.NEVER) @RawDistOnly(reason = "Containers are immutable") @TestMethodOrder(OrderAnnotation.class) @@ -45,7 +47,7 @@ public class BuildAndStartDistTest { } @Test - @Launch({ "start", "--http-enabled=true", "--hostname-strict=false" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", OPTIMISED_BUILD_OPTION_LONG}) @Order(2) void testStartUsingCliArgs(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -63,7 +65,7 @@ public class BuildAndStartDistTest { } @Test - @Launch({ "start" }) + @Launch({ "start", OPTIMISED_BUILD_OPTION_LONG}) @Order(4) void testStartUsingConfFile(LaunchResult result) { CLIResult cliResult = (CLIResult) result; diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ClusterConfigDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ClusterConfigDistTest.java index 9561027452..a28fe54779 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ClusterConfigDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/ClusterConfigDistTest.java @@ -72,7 +72,7 @@ public class ClusterConfigDistTest { @Test @EnabledOnOs(value = { OS.LINUX, OS.MAC }, disabledReason = "different shell escaping behaviour on Windows.") - @Launch({ "start", "--auto-build", "--log-level=info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true", "--hostname-strict=false" }) + @Launch({ "start", "--log-level=info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true", "--hostname-strict=false" }) void testStartDefaultsToClustering(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertStarted(); @@ -82,7 +82,7 @@ public class ClusterConfigDistTest { @Test @EnabledOnOs(value = { OS.WINDOWS }, disabledReason = "different shell behaviour on Windows.") - @Launch({ "start", "--auto-build", "--log-level=\"info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true\"", "--hostname-strict=false" }) + @Launch({ "start", "--log-level=\"info,org.infinispan.remoting.transport.jgroups.JGroupsTransport:debug","--http-enabled=true\"", "--hostname-strict=false" }) void testWinStartDefaultsToClustering(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertStarted(); diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FeaturesDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FeaturesDistTest.java index 1f7f0bb179..3dd89d5ef2 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FeaturesDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/FeaturesDistTest.java @@ -19,6 +19,7 @@ import org.keycloak.quarkus.runtime.cli.command.StartDev; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG; @DistributionTest @RawDistOnly(reason = "Containers are immutable") @@ -35,7 +36,7 @@ public class FeaturesDistTest { } @Test - @Launch({ Start.NAME, "--http-enabled=true", "--hostname-strict=false"}) + @Launch({ Start.NAME, "--http-enabled=true", "--hostname-strict=false", OPTIMISED_BUILD_OPTION_LONG}) @Order(2) public void testFeatureEnabledOnStart(LaunchResult result) { assertPreviewFeaturesEnabled((CLIResult) result); diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/LoggingDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/LoggingDistTest.java index 93676edc6a..cc8d1ced65 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/LoggingDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/LoggingDistTest.java @@ -135,6 +135,7 @@ public class LoggingDistTest { void testWinLogLevelSettingsAppliedWhenJsonEnabled(LaunchResult result) { CLIResult cliResult = (CLIResult) result; assertFalse(cliResult.getOutput().contains("\"loggerName\":\"io.quarkus\",\"level\":\"INFO\")")); + assertTrue(cliResult.getOutput().contains("\"loggerName\":\"org.keycloak.quarkus.runtime.storage.legacy.database.LegacyJpaConnectionProviderFactory\",\"level\":\"DEBUG\"")); assertTrue(cliResult.getOutput().contains("\"loggerName\":\"org.keycloak.services.resources.KeycloakApplication\",\"level\":\"DEBUG\"")); assertTrue(cliResult.getOutput().contains("\"loggerName\":\"org.infinispan.CONTAINER\",\"level\":\"INFO\"")); } diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesAutoBuildDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesAutoBuildDistTest.java index 61a621e9df..9298215860 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesAutoBuildDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesAutoBuildDistTest.java @@ -41,7 +41,7 @@ import io.quarkus.test.junit.main.LaunchResult; public class QuarkusPropertiesAutoBuildDistTest { @Test - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(1) void reAugOnFirstRun(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -50,7 +50,7 @@ public class QuarkusPropertiesAutoBuildDistTest { @Test @BeforeStartDistribution(QuarkusPropertiesAutoBuildDistTest.UpdateConsoleLogLevelToWarn.class) - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(2) void testQuarkusRuntimePropDoesNotTriggerReAug(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -60,7 +60,7 @@ public class QuarkusPropertiesAutoBuildDistTest { @Test @BeforeStartDistribution(UpdateConsoleLogLevelToInfo.class) - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(3) void testNoReAugAfterChangingRuntimeProperty(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -70,7 +70,7 @@ public class QuarkusPropertiesAutoBuildDistTest { @Test @BeforeStartDistribution(AddAdditionalDatasource.class) - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(4) void testReAugForAdditionalDatasource(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -79,7 +79,7 @@ public class QuarkusPropertiesAutoBuildDistTest { @Test @BeforeStartDistribution(ChangeAdditionalDatasourceUsername.class) - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(5) void testNoReAugForAdditionalDatasourceRuntimeProperty(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -88,7 +88,7 @@ public class QuarkusPropertiesAutoBuildDistTest { @Test @BeforeStartDistribution(ChangeAdditionalDatasourceDbKind.class) - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(6) void testNoReAugWhenBuildTimePropertiesAreTheSame(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -97,7 +97,7 @@ public class QuarkusPropertiesAutoBuildDistTest { @Test @BeforeStartDistribution(AddAdditionalDatasource2.class) - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(7) void testReAugWhenAnotherDatasourceAdded(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -106,7 +106,7 @@ public class QuarkusPropertiesAutoBuildDistTest { @Test @BeforeStartDistribution(EnableDatasourceMetrics.class) - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(8) void testWrappedBuildPropertyTriggersBuildButGetsIgnoredWhenSetByQuarkus(LaunchResult result) { CLIResult cliResult = (CLIResult) result; diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java index ec60230b1c..514ac8c5d7 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/QuarkusPropertiesDistTest.java @@ -21,6 +21,7 @@ import static io.restassured.RestAssured.when; import static org.hamcrest.Matchers.containsString; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG; import java.util.function.Consumer; import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; @@ -119,7 +120,7 @@ public class QuarkusPropertiesDistTest { @Test @KeepServerAlive - @Launch({ "start", "--http-enabled=true", "--hostname-strict=false" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", OPTIMISED_BUILD_OPTION_LONG}) @Order(9) void testUnknownQuarkusBuildTimePropertyApplied(LaunchResult result) { CLIResult cliResult = (CLIResult) result; diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartAutoBuildDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartAutoBuildDistTest.java index 7eaa26cd6a..5f761677cb 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartAutoBuildDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartAutoBuildDistTest.java @@ -17,9 +17,8 @@ package org.keycloak.it.cli.dist; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - +import io.quarkus.test.junit.main.Launch; +import io.quarkus.test.junit.main.LaunchResult; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; @@ -27,10 +26,13 @@ import org.junit.jupiter.api.TestMethodOrder; import org.keycloak.it.junit5.extension.CLIResult; import org.keycloak.it.junit5.extension.DistributionTest; import org.keycloak.it.junit5.extension.RawDistOnly; - -import io.quarkus.test.junit.main.Launch; -import io.quarkus.test.junit.main.LaunchResult; import org.keycloak.it.utils.KeycloakDistribution; +import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG; @DistributionTest(reInstall = DistributionTest.ReInstall.NEVER) @RawDistOnly(reason = "Containers are immutable") @@ -38,7 +40,7 @@ import org.keycloak.it.utils.KeycloakDistribution; public class StartAutoBuildDistTest { @Test - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", AbstractStartCommand.AUTO_BUILD_OPTION_LONG, "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(1) void testStartAutoBuild(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -47,13 +49,14 @@ public class StartAutoBuildDistTest { cliResult.assertMessage("Server configuration updated and persisted. Run the following command to review the configuration:"); cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " show-config"); cliResult.assertMessage("Next time you run the server, just run:"); - cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " start --http-enabled=true --hostname-strict=false"); + cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " start " + OPTIMISED_BUILD_OPTION_LONG + " --http-enabled=true --hostname-strict=false"); + cliResult.assertMessage(DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION); assertFalse(cliResult.getOutput().contains("--cache")); cliResult.assertStarted(); } @Test - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(2) void testShouldNotReAugIfConfigIsSame(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -62,7 +65,7 @@ public class StartAutoBuildDistTest { } @Test - @Launch({ "start", "--auto-build", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(3) void testShouldReAugIfConfigChanged(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -71,7 +74,7 @@ public class StartAutoBuildDistTest { } @Test - @Launch({ "start", "--auto-build", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--db=dev-mem", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(4) void testShouldNotReAugIfSameDatabase(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -88,7 +91,7 @@ public class StartAutoBuildDistTest { } @Test - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(6) void testReAugWhenNoOptionAfterBuild(LaunchResult result) { CLIResult cliResult = (CLIResult) result; @@ -97,8 +100,25 @@ public class StartAutoBuildDistTest { } @Test - @Launch({ "start-dev" }) + @Launch({ "start", "--db=postgres", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) @Order(7) + void testShouldReAugWithoutAutoBuildOptionAfterDatabaseChange(LaunchResult result) { + CLIResult cliResult = (CLIResult) result; + cliResult.assertNoMessage(DEFAULT_WARN_MESSAGE_REPEATED_AUTO_BUILD_OPTION); + cliResult.assertBuild(); + } + + @Test + @Launch({ "start", "--db=dev-file", "--http-enabled=true", "--hostname-strict=false", "--cache=local", OPTIMISED_BUILD_OPTION_LONG}) + @Order(8) + void testShouldReAugAndNeedsAutoBuildOptionBecauseHasNoAutoBuildOption(LaunchResult result) { + CLIResult cliResult = (CLIResult) result; + cliResult.assertNoBuild(); + } + + @Test + @Launch({ "start-dev" }) + @Order(8) void testStartDevFirstTime(LaunchResult result) { CLIResult cliResult = (CLIResult) result; assertTrue(cliResult.getOutput().contains("Updating the configuration and installing your custom providers, if any. Please wait.")); @@ -107,7 +127,7 @@ public class StartAutoBuildDistTest { @Test @Launch({ "start-dev" }) - @Order(8) + @Order(9) void testShouldNotReAugStartDevIfConfigIsSame(LaunchResult result) { CLIResult cliResult = (CLIResult) result; assertFalse(cliResult.getOutput().contains("Updating the configuration and installing your custom providers, if any. Please wait.")); diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartCommandDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartCommandDistTest.java index cab9904bdd..fed792d828 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartCommandDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartCommandDistTest.java @@ -22,6 +22,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG; import org.junit.jupiter.api.Test; import org.keycloak.it.cli.StartCommandTest; @@ -36,7 +37,7 @@ import org.keycloak.it.utils.KeycloakDistribution; public class StartCommandDistTest extends StartCommandTest { @Test - @Launch({ "--profile=dev", "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false" }) + @Launch({ "--profile=dev", "start", "--http-enabled=true", "--hostname-strict=false" }) void failIfAutoBuildUsingDevProfile(LaunchResult result) { CLIResult cliResult = (CLIResult) result; assertThat(cliResult.getErrorOutput(), containsString("You can not 'start' the server in development mode. Please re-build the server first, using 'kc.sh build' for the default production mode.")); @@ -51,7 +52,7 @@ public class StartCommandDistTest extends StartCommandTest { } @Test - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--cache=local" }) void testStartUsingAutoBuild(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertMessage("Changes detected in configuration. Updating the server image."); @@ -59,7 +60,7 @@ public class StartCommandDistTest extends StartCommandTest { cliResult.assertMessage("Server configuration updated and persisted. Run the following command to review the configuration:"); cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " show-config"); cliResult.assertMessage("Next time you run the server, just run:"); - cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " start --http-enabled=true --hostname-strict=false"); + cliResult.assertMessage(KeycloakDistribution.SCRIPT_CMD + " start " + OPTIMISED_BUILD_OPTION_LONG + " --http-enabled=true --hostname-strict=false"); assertFalse(cliResult.getOutput().contains("--cache")); cliResult.assertStarted(); } diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartDevCommandDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartDevCommandDistTest.java index 44cf85a646..88725ffd3e 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartDevCommandDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/cli/dist/StartDevCommandDistTest.java @@ -17,9 +17,43 @@ package org.keycloak.it.cli.dist; +import io.quarkus.test.junit.main.Launch; +import io.quarkus.test.junit.main.LaunchResult; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; import org.keycloak.it.cli.StartDevCommandTest; +import org.keycloak.it.junit5.extension.CLIResult; import org.keycloak.it.junit5.extension.DistributionTest; +import org.keycloak.it.junit5.extension.RawDistOnly; -@DistributionTest +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@DistributionTest(reInstall = DistributionTest.ReInstall.NEVER) +@RawDistOnly(reason = "Containers are immutable") +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class StartDevCommandDistTest extends StartDevCommandTest { + + @Test + @Launch({ "start-dev", "--debug" }) + @Order(1) + void testStartDevShouldStartTwoJVMs(LaunchResult result) { + CLIResult cliResult = (CLIResult) result; + cliResult.assertMessage("Updating the configuration and installing your custom providers, if any. Please wait."); + cliResult.assertMessageWasShownExactlyNumberOfTimes("Listening for transport dt_socket at address:", 2); + cliResult.assertStartedDevMode(); + } + + @Test + @Launch({ "build", "--debug" }) + @Order(2) + void testBuildMustNotRunTwoJVMs(LaunchResult result) { + CLIResult cliResult = (CLIResult) result; + cliResult.assertMessage("Updating the configuration and installing your custom providers, if any. Please wait."); + cliResult.assertMessageWasShownExactlyNumberOfTimes("Listening for transport dt_socket at address:", 1); + cliResult.assertBuild(); + } + } diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/database/BasicDatabaseTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/database/BasicDatabaseTest.java index 62a913f9c3..4f004510bf 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/database/BasicDatabaseTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/database/BasicDatabaseTest.java @@ -22,6 +22,7 @@ import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; import org.keycloak.it.junit5.extension.CLIResult; +import org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand; import io.quarkus.test.junit.main.Launch; import io.quarkus.test.junit.main.LaunchResult; @@ -30,14 +31,14 @@ import io.quarkus.test.junit.main.LaunchResult; public abstract class BasicDatabaseTest { @Test - @Launch({ "start", "--http-enabled=true", "--hostname-strict=false" }) + @Launch({ "start", AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG, "--http-enabled=true", "--hostname-strict=false" }) void testSuccessful(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertStarted(); } @Test - @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--db-username=wrong" }) + @Launch({ "start", AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG,"--http-enabled=true", "--hostname-strict=false", "--db-username=wrong" }) void testWrongUsername(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertMessage("ERROR: Failed to obtain JDBC connection"); @@ -47,7 +48,7 @@ public abstract class BasicDatabaseTest { protected abstract void assertWrongUsername(CLIResult cliResult); @Test - @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--db-password=wrong" }) + @Launch({ "start", AbstractStartCommand.OPTIMISED_BUILD_OPTION_LONG,"--http-enabled=true", "--hostname-strict=false", "--db-password=wrong" }) void testWrongPassword(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertMessage("ERROR: Failed to obtain JDBC connection"); diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/map/ChmStorageDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/map/ChmStorageDistTest.java index 1ad8dc3a86..8a19b4b682 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/map/ChmStorageDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/map/ChmStorageDistTest.java @@ -32,7 +32,7 @@ import io.quarkus.test.junit.main.LaunchResult; public class ChmStorageDistTest { @Test - @Launch({ "start", "--auto-build", "--http-enabled=true", "--hostname-strict=false", "--storage=chm" }) + @Launch({ "start", "--http-enabled=true", "--hostname-strict=false", "--storage=chm" }) void testStartUsingChmsStorage(LaunchResult result, RawDistRootPath distPath) { CLIResult cliResult = (CLIResult) result; assertExpectedMessages(cliResult, distPath); diff --git a/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/map/JPAStoreDistTest.java b/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/map/JPAStoreDistTest.java index 0495d0956b..a6fadc3f4f 100644 --- a/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/map/JPAStoreDistTest.java +++ b/quarkus/tests/integration/src/test/java/org/keycloak/it/storage/map/JPAStoreDistTest.java @@ -30,7 +30,7 @@ import io.quarkus.test.junit.main.LaunchResult; public class JPAStoreDistTest { @Test - @Launch({ "start", "--http-enabled=true", "--hostname-strict=false" }) + @Launch({ "start", "--optimised", "--http-enabled=true", "--hostname-strict=false" }) void testSuccessful(LaunchResult result) { CLIResult cliResult = (CLIResult) result; cliResult.assertMessage("Experimental feature enabled: map_storage"); diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testBuildHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testBuildHelp.unix.approved.txt index 51844f33fe..18ca95b2e8 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testBuildHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testBuildHelp.unix.approved.txt @@ -102,11 +102,4 @@ Examples: Change the relative path: - $ kc.sh build --http-relative-path=/auth - -You can also use the "--auto-build" option when starting the server to avoid -running this command every time you change a configuration: - - $ kc.sh start --auto-build - -By doing that you have an additional overhead when the server is starting. \ No newline at end of file + $ kc.sh build --http-relative-path=/auth \ No newline at end of file diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartDevHelp.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartDevHelp.windows.approved.txt index b6dae8f80f..51acf26bba 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartDevHelp.windows.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartDevHelp.windows.approved.txt @@ -1,159 +1,160 @@ -Start the server in development mode. - -Usage: - -kc.bat start-dev [OPTIONS] - -Use this command if you want to run the server locally for development or -testing purposes. - -Options: - --h, --help This help message. ---help-all This same help message but with additional options. ---import-realm Import realms during startup by reading any realm configuration file from the - 'data/import' directory. - -Database: - ---db-password - The password of the database user. ---db-pool-initial-size - The initial size of the connection pool. ---db-pool-max-size - The maximum size of the connection pool. Default: 100. ---db-pool-min-size - The minimal size of the connection pool. ---db-schema The database schema to be used. ---db-url The full database JDBC URL. If not provided, a default URL is set based on the - selected database vendor. For instance, if using 'postgres', the default - JDBC URL would be 'jdbc:postgresql://localhost/keycloak'. ---db-url-database - Sets the database name of the default JDBC URL of the chosen vendor. If the - `db-url` option is set, this option is ignored. ---db-url-host - Sets the hostname of the default JDBC URL of the chosen vendor. If the - `db-url` option is set, this option is ignored. ---db-url-port Sets the port of the default JDBC URL of the chosen vendor. If the `db-url` - option is set, this option is ignored. ---db-url-properties - Sets the properties of the default JDBC URL of the chosen vendor. If the - `db-url` option is set, this option is ignored. ---db-username - The username of the database user. - -Hostname: - ---hostname - Hostname for the Keycloak server. ---hostname-admin - The hostname for accessing the administration console. Use this option if you - are exposing the administration console using a hostname other than the - value set to the 'hostname' option. ---hostname-path - This should be set if proxy uses a different context-path for Keycloak. ---hostname-port - The port used by the proxy when exposing the hostname. Set this option if the - proxy uses a port other than the default HTTP and HTTPS ports. Default: -1. ---hostname-strict - Disables dynamically resolving the hostname from request headers. Should - always be set to true in production, unless proxy verifies the Host header. - Default: true. ---hostname-strict-backchannel - By default backchannel URLs are dynamically resolved from request headers to - allow internal and external applications. If all applications use the public - URL this option should be enabled. Default: false. - -HTTP/TLS: - ---http-enabled - Enables the HTTP listener. Default: false. ---http-host The used HTTP Host. Default: 0.0.0.0. ---http-port The used HTTP port. Default: 8080. ---https-certificate-file - The file path to a server certificate or certificate chain in PEM format. ---https-certificate-key-file - The file path to a private key in PEM format. ---https-cipher-suites - The cipher suites to use. If none is given, a reasonable default is selected. ---https-client-auth - Configures the server to require/request client authentication. Possible - Values: none, request, required. Default: none. ---https-key-store-file - The key store which holds the certificate information instead of specifying - separate files. ---https-key-store-password - The password of the key store file. Default: password. ---https-key-store-type - The type of the key store file. If not given, the type is automatically - detected based on the file name. ---https-port The used HTTPS port. Default: 8443. ---https-protocols - The list of protocols to explicitly enable. Default: TLSv1.3. ---https-trust-store-file - The trust store which holds the certificate information of the certificates to - trust. ---https-trust-store-password - The password of the trust store file. ---https-trust-store-type - The type of the trust store file. If not given, the type is automatically - detected based on the file name. - -Proxy: - ---proxy The proxy address forwarding mode if the server is behind a reverse proxy. - Possible values are: edge,reencrypt,passthrough Default: none. - -Vault: - ---vault-dir If set, secrets can be obtained by reading the content of files within the - given directory. - -Logging: - ---log Enable one or more log handlers in a comma-separated list. Available log - handlers are: console,file,gelf Default: console. ---log-console-color - Enable or disable colors when logging to console. Default: false. ---log-console-format - The format of unstructured console log entries. If the format has spaces in - it, escape the value using "". Default: %d{yyyy-MM-dd HH:mm:ss,SSS} % - -5p [%c] (%t) %s%e%n. ---log-console-output - Set the log output to JSON or default (plain) unstructured logging. Default: - default. ---log-file /.log - Set the log file path and filename. Default: data\log\keycloak.log. ---log-file-format - Set a format specific to file log entries. Default: %d{yyyy-MM-dd HH:mm:ss, - SSS} %-5p [%c] (%t) %s%e%n. ---log-gelf-facility - The facility (name of the process) that sends the message. Default: keycloak. ---log-gelf-host - Hostname of the Logstash or Graylog Host. By default UDP is used, prefix the - host with 'tcp:' to switch to TCP. Example: 'tcp:localhost' Default: - localhost. ---log-gelf-include-location - Include source code location. Default: true. ---log-gelf-include-message-parameters - Include message parameters from the log event. Default: true. ---log-gelf-include-stack-trace - If set to true, occuring stack traces are included in the 'StackTrace' field - in the gelf output. Default: true. ---log-gelf-max-message-size - Maximum message size (in bytes). If the message size is exceeded, gelf will - submit the message in multiple chunks. Default: 8192. ---log-gelf-port - The port the Logstash or Graylog Host is called on. Default: 12201. ---log-gelf-timestamp-format - Set the format for the gelf timestamp field. Uses Java SimpleDateFormat - pattern. Default: yyyy-MM-dd HH:mm:ss,SSS. ---log-level - The log level of the root category or a comma-separated list of individual - categories and their levels. For the root category, you don't need to - specify a category. Default: info. - -Do NOT start the server using this command when deploying to production. - -Use 'kc.bat start-dev --help-all' to list all available options, including -build options. +WARNING: The '--auto-build' option for 'start' command is DEPRECATED and no longer needed. When executing the 'start' command, a new server image is automatically built based on the configuration. If you want to disable this behavior and achieve an optimal startup time, use the '--optimised' option instead. +Start the server in development mode. + +Usage: + +kc.bat start-dev [OPTIONS] + +Use this command if you want to run the server locally for development or +testing purposes. + +Options: + +-h, --help This help message. +--help-all This same help message but with additional options. +--import-realm Import realms during startup by reading any realm configuration file from the + 'data/import' directory. + +Database: + +--db-password + The password of the database user. +--db-pool-initial-size + The initial size of the connection pool. +--db-pool-max-size + The maximum size of the connection pool. Default: 100. +--db-pool-min-size + The minimal size of the connection pool. +--db-schema The database schema to be used. +--db-url The full database JDBC URL. If not provided, a default URL is set based on the + selected database vendor. For instance, if using 'postgres', the default + JDBC URL would be 'jdbc:postgresql://localhost/keycloak'. +--db-url-database + Sets the database name of the default JDBC URL of the chosen vendor. If the + `db-url` option is set, this option is ignored. +--db-url-host + Sets the hostname of the default JDBC URL of the chosen vendor. If the + `db-url` option is set, this option is ignored. +--db-url-port Sets the port of the default JDBC URL of the chosen vendor. If the `db-url` + option is set, this option is ignored. +--db-url-properties + Sets the properties of the default JDBC URL of the chosen vendor. If the + `db-url` option is set, this option is ignored. +--db-username + The username of the database user. + +Hostname: + +--hostname + Hostname for the Keycloak server. +--hostname-admin + The hostname for accessing the administration console. Use this option if you + are exposing the administration console using a hostname other than the + value set to the 'hostname' option. +--hostname-path + This should be set if proxy uses a different context-path for Keycloak. +--hostname-port + The port used by the proxy when exposing the hostname. Set this option if the + proxy uses a port other than the default HTTP and HTTPS ports. Default: -1. +--hostname-strict + Disables dynamically resolving the hostname from request headers. Should + always be set to true in production, unless proxy verifies the Host header. + Default: true. +--hostname-strict-backchannel + By default backchannel URLs are dynamically resolved from request headers to + allow internal and external applications. If all applications use the public + URL this option should be enabled. Default: false. + +HTTP/TLS: + +--http-enabled + Enables the HTTP listener. Default: false. +--http-host The used HTTP Host. Default: 0.0.0.0. +--http-port The used HTTP port. Default: 8080. +--https-certificate-file + The file path to a server certificate or certificate chain in PEM format. +--https-certificate-key-file + The file path to a private key in PEM format. +--https-cipher-suites + The cipher suites to use. If none is given, a reasonable default is selected. +--https-client-auth + Configures the server to require/request client authentication. Possible + Values: none, request, required. Default: none. +--https-key-store-file + The key store which holds the certificate information instead of specifying + separate files. +--https-key-store-password + The password of the key store file. Default: password. +--https-key-store-type + The type of the key store file. If not given, the type is automatically + detected based on the file name. +--https-port The used HTTPS port. Default: 8443. +--https-protocols + The list of protocols to explicitly enable. Default: TLSv1.3. +--https-trust-store-file + The trust store which holds the certificate information of the certificates to + trust. +--https-trust-store-password + The password of the trust store file. +--https-trust-store-type + The type of the trust store file. If not given, the type is automatically + detected based on the file name. + +Proxy: + +--proxy The proxy address forwarding mode if the server is behind a reverse proxy. + Possible values are: edge,reencrypt,passthrough Default: none. + +Vault: + +--vault-dir If set, secrets can be obtained by reading the content of files within the + given directory. + +Logging: + +--log Enable one or more log handlers in a comma-separated list. Available log + handlers are: console,file,gelf Default: console. +--log-console-color + Enable or disable colors when logging to console. Default: false. +--log-console-format + The format of unstructured console log entries. If the format has spaces in + it, escape the value using "". Default: %d{yyyy-MM-dd HH:mm:ss,SSS} % + -5p [%c] (%t) %s%e%n. +--log-console-output + Set the log output to JSON or default (plain) unstructured logging. Default: + default. +--log-file /.log + Set the log file path and filename. Default: data\log\keycloak.log. +--log-file-format + Set a format specific to file log entries. Default: %d{yyyy-MM-dd HH:mm:ss, + SSS} %-5p [%c] (%t) %s%e%n. +--log-gelf-facility + The facility (name of the process) that sends the message. Default: keycloak. +--log-gelf-host + Hostname of the Logstash or Graylog Host. By default UDP is used, prefix the + host with 'tcp:' to switch to TCP. Example: 'tcp:localhost' Default: + localhost. +--log-gelf-include-location + Include source code location. Default: true. +--log-gelf-include-message-parameters + Include message parameters from the log event. Default: true. +--log-gelf-include-stack-trace + If set to true, occuring stack traces are included in the 'StackTrace' field + in the gelf output. Default: true. +--log-gelf-max-message-size + Maximum message size (in bytes). If the message size is exceeded, gelf will + submit the message in multiple chunks. Default: 8192. +--log-gelf-port + The port the Logstash or Graylog Host is called on. Default: 12201. +--log-gelf-timestamp-format + Set the format for the gelf timestamp field. Uses Java SimpleDateFormat + pattern. Default: yyyy-MM-dd HH:mm:ss,SSS. +--log-level + The log level of the root category or a comma-separated list of individual + categories and their levels. For the root category, you don't need to + specify a category. Default: info. + +Do NOT start the server using this command when deploying to production. + +Use 'kc.bat start-dev --help-all' to list all available options, including +build options. \ No newline at end of file diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartHelp.unix.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartHelp.unix.approved.txt index 1f152e9221..4f52737779 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartHelp.unix.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartHelp.unix.approved.txt @@ -8,14 +8,16 @@ Use this command to run the server in production. Options: --b, --auto-build Automatically detects whether the server configuration changed and a new - server image must be built prior to starting the server. This option - provides an alternative to manually running the 'build' prior to starting - the server. Use this configuration carefully in production as it might - impact the startup time. +-b, --auto-build (Deprecated) Automatically detects whether the server configuration changed + and a new server image must be built prior to starting the server. This + option provides an alternative to manually running the 'build' prior to + starting the server. Use this configuration carefully in production as it + might impact the startup time. -h, --help This help message. --import-realm Import realms during startup by reading any realm configuration file from the 'data/import' directory. +--optimised Use this option to achieve an optional startup time if you have previously + built a server image using the 'build' command. Database: @@ -156,10 +158,11 @@ Logging: categories and their levels. For the root category, you don't need to specify a category. Default: info. -You may use the "--auto-build" option when starting the server to avoid running -the "build" command everytime you need to change a static property: +By default, this command tries to update the server configuration by running a +'build' before starting the server. You can disable this behavior by using the +'--optimised' option: - $ kc.sh start --auto-build + $ kc.sh start '--optimised' -By doing that you have an additional overhead when the server is starting. Run -"kc.sh build -h" for more details. \ No newline at end of file +By doing that, the server should start faster based on any previous +configuration you have set when manually running the 'build' command. \ No newline at end of file diff --git a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartHelp.windows.approved.txt b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartHelp.windows.approved.txt index 1dde861083..e4fc7fb7fe 100644 --- a/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartHelp.windows.approved.txt +++ b/quarkus/tests/integration/src/test/resources/org/keycloak/it/cli/approvals/cli/help/HelpCommandTest.testStartHelp.windows.approved.txt @@ -1,165 +1,168 @@ -Start the server. - -Usage: - -kc.bat start [OPTIONS] - -Use this command to run the server in production. - -Options: - --b, --auto-build Automatically detects whether the server configuration changed and a new - server image must be built prior to starting the server. This option - provides an alternative to manually running the 'build' prior to starting - the server. Use this configuration carefully in production as it might - impact the startup time. --h, --help This help message. ---import-realm Import realms during startup by reading any realm configuration file from the - 'data/import' directory. - -Database: - ---db-password - The password of the database user. ---db-pool-initial-size - The initial size of the connection pool. ---db-pool-max-size - The maximum size of the connection pool. Default: 100. ---db-pool-min-size - The minimal size of the connection pool. ---db-schema The database schema to be used. ---db-url The full database JDBC URL. If not provided, a default URL is set based on the - selected database vendor. For instance, if using 'postgres', the default - JDBC URL would be 'jdbc:postgresql://localhost/keycloak'. ---db-url-database - Sets the database name of the default JDBC URL of the chosen vendor. If the - `db-url` option is set, this option is ignored. ---db-url-host - Sets the hostname of the default JDBC URL of the chosen vendor. If the - `db-url` option is set, this option is ignored. ---db-url-port Sets the port of the default JDBC URL of the chosen vendor. If the `db-url` - option is set, this option is ignored. ---db-url-properties - Sets the properties of the default JDBC URL of the chosen vendor. If the - `db-url` option is set, this option is ignored. ---db-username - The username of the database user. - -Hostname: - ---hostname - Hostname for the Keycloak server. ---hostname-admin - The hostname for accessing the administration console. Use this option if you - are exposing the administration console using a hostname other than the - value set to the 'hostname' option. ---hostname-path - This should be set if proxy uses a different context-path for Keycloak. ---hostname-port - The port used by the proxy when exposing the hostname. Set this option if the - proxy uses a port other than the default HTTP and HTTPS ports. Default: -1. ---hostname-strict - Disables dynamically resolving the hostname from request headers. Should - always be set to true in production, unless proxy verifies the Host header. - Default: true. ---hostname-strict-backchannel - By default backchannel URLs are dynamically resolved from request headers to - allow internal and external applications. If all applications use the public - URL this option should be enabled. Default: false. - -HTTP/TLS: - ---http-enabled - Enables the HTTP listener. Default: false. ---http-host The used HTTP Host. Default: 0.0.0.0. ---http-port The used HTTP port. Default: 8080. ---https-certificate-file - The file path to a server certificate or certificate chain in PEM format. ---https-certificate-key-file - The file path to a private key in PEM format. ---https-cipher-suites - The cipher suites to use. If none is given, a reasonable default is selected. ---https-client-auth - Configures the server to require/request client authentication. Possible - Values: none, request, required. Default: none. ---https-key-store-file - The key store which holds the certificate information instead of specifying - separate files. ---https-key-store-password - The password of the key store file. Default: password. ---https-key-store-type - The type of the key store file. If not given, the type is automatically - detected based on the file name. ---https-port The used HTTPS port. Default: 8443. ---https-protocols - The list of protocols to explicitly enable. Default: TLSv1.3. ---https-trust-store-file - The trust store which holds the certificate information of the certificates to - trust. ---https-trust-store-password - The password of the trust store file. ---https-trust-store-type - The type of the trust store file. If not given, the type is automatically - detected based on the file name. - -Proxy: - ---proxy The proxy address forwarding mode if the server is behind a reverse proxy. - Possible values are: edge,reencrypt,passthrough Default: none. - -Vault: - ---vault-dir If set, secrets can be obtained by reading the content of files within the - given directory. - -Logging: - ---log Enable one or more log handlers in a comma-separated list. Available log - handlers are: console,file,gelf Default: console. ---log-console-color - Enable or disable colors when logging to console. Default: false. ---log-console-format - The format of unstructured console log entries. If the format has spaces in - it, escape the value using "". Default: %d{yyyy-MM-dd HH:mm:ss,SSS} % - -5p [%c] (%t) %s%e%n. ---log-console-output - Set the log output to JSON or default (plain) unstructured logging. Default: - default. ---log-file /.log - Set the log file path and filename. Default: data\log\keycloak.log. ---log-file-format - Set a format specific to file log entries. Default: %d{yyyy-MM-dd HH:mm:ss, - SSS} %-5p [%c] (%t) %s%e%n. ---log-gelf-facility - The facility (name of the process) that sends the message. Default: keycloak. ---log-gelf-host - Hostname of the Logstash or Graylog Host. By default UDP is used, prefix the - host with 'tcp:' to switch to TCP. Example: 'tcp:localhost' Default: - localhost. ---log-gelf-include-location - Include source code location. Default: true. ---log-gelf-include-message-parameters - Include message parameters from the log event. Default: true. ---log-gelf-include-stack-trace - If set to true, occuring stack traces are included in the 'StackTrace' field - in the gelf output. Default: true. ---log-gelf-max-message-size - Maximum message size (in bytes). If the message size is exceeded, gelf will - submit the message in multiple chunks. Default: 8192. ---log-gelf-port - The port the Logstash or Graylog Host is called on. Default: 12201. ---log-gelf-timestamp-format - Set the format for the gelf timestamp field. Uses Java SimpleDateFormat - pattern. Default: yyyy-MM-dd HH:mm:ss,SSS. ---log-level - The log level of the root category or a comma-separated list of individual - categories and their levels. For the root category, you don't need to - specify a category. Default: info. - -You may use the "--auto-build" option when starting the server to avoid running -the "build" command everytime you need to change a static property: - - $ kc.bat start --auto-build - -By doing that you have an additional overhead when the server is starting. Run -"kc.bat build -h" for more details. +Start the server. + +Usage: + +kc.bat start [OPTIONS] + +Use this command to run the server in production. + +Options: + +-b, --auto-build (Deprecated) Automatically detects whether the server configuration changed + and a new server image must be built prior to starting the server. This + option provides an alternative to manually running the 'build' prior to + starting the server. Use this configuration carefully in production as it + might impact the startup time. +-h, --help This help message. +--import-realm Import realms during startup by reading any realm configuration file from the + 'data/import' directory. +--optimised Use this option to achieve an optional startup time if you have previously + built a server image using the 'build' command. + +Database: + +--db-password + The password of the database user. +--db-pool-initial-size + The initial size of the connection pool. +--db-pool-max-size + The maximum size of the connection pool. Default: 100. +--db-pool-min-size + The minimal size of the connection pool. +--db-schema The database schema to be used. +--db-url The full database JDBC URL. If not provided, a default URL is set based on the + selected database vendor. For instance, if using 'postgres', the default + JDBC URL would be 'jdbc:postgresql://localhost/keycloak'. +--db-url-database + Sets the database name of the default JDBC URL of the chosen vendor. If the + `db-url` option is set, this option is ignored. +--db-url-host + Sets the hostname of the default JDBC URL of the chosen vendor. If the + `db-url` option is set, this option is ignored. +--db-url-port Sets the port of the default JDBC URL of the chosen vendor. If the `db-url` + option is set, this option is ignored. +--db-url-properties + Sets the properties of the default JDBC URL of the chosen vendor. If the + `db-url` option is set, this option is ignored. +--db-username + The username of the database user. + +Hostname: + +--hostname + Hostname for the Keycloak server. +--hostname-admin + The hostname for accessing the administration console. Use this option if you + are exposing the administration console using a hostname other than the + value set to the 'hostname' option. +--hostname-path + This should be set if proxy uses a different context-path for Keycloak. +--hostname-port + The port used by the proxy when exposing the hostname. Set this option if the + proxy uses a port other than the default HTTP and HTTPS ports. Default: -1. +--hostname-strict + Disables dynamically resolving the hostname from request headers. Should + always be set to true in production, unless proxy verifies the Host header. + Default: true. +--hostname-strict-backchannel + By default backchannel URLs are dynamically resolved from request headers to + allow internal and external applications. If all applications use the public + URL this option should be enabled. Default: false. + +HTTP/TLS: + +--http-enabled + Enables the HTTP listener. Default: false. +--http-host The used HTTP Host. Default: 0.0.0.0. +--http-port The used HTTP port. Default: 8080. +--https-certificate-file + The file path to a server certificate or certificate chain in PEM format. +--https-certificate-key-file + The file path to a private key in PEM format. +--https-cipher-suites + The cipher suites to use. If none is given, a reasonable default is selected. +--https-client-auth + Configures the server to require/request client authentication. Possible + Values: none, request, required. Default: none. +--https-key-store-file + The key store which holds the certificate information instead of specifying + separate files. +--https-key-store-password + The password of the key store file. Default: password. +--https-key-store-type + The type of the key store file. If not given, the type is automatically + detected based on the file name. +--https-port The used HTTPS port. Default: 8443. +--https-protocols + The list of protocols to explicitly enable. Default: TLSv1.3. +--https-trust-store-file + The trust store which holds the certificate information of the certificates to + trust. +--https-trust-store-password + The password of the trust store file. +--https-trust-store-type + The type of the trust store file. If not given, the type is automatically + detected based on the file name. + +Proxy: + +--proxy The proxy address forwarding mode if the server is behind a reverse proxy. + Possible values are: edge,reencrypt,passthrough Default: none. + +Vault: + +--vault-dir If set, secrets can be obtained by reading the content of files within the + given directory. + +Logging: + +--log Enable one or more log handlers in a comma-separated list. Available log + handlers are: console,file,gelf Default: console. +--log-console-color + Enable or disable colors when logging to console. Default: false. +--log-console-format + The format of unstructured console log entries. If the format has spaces in + it, escape the value using "". Default: %d{yyyy-MM-dd HH:mm:ss,SSS} % + -5p [%c] (%t) %s%e%n. +--log-console-output + Set the log output to JSON or default (plain) unstructured logging. Default: + default. +--log-file /.log + Set the log file path and filename. Default: data\log\keycloak.log. +--log-file-format + Set a format specific to file log entries. Default: %d{yyyy-MM-dd HH:mm:ss, + SSS} %-5p [%c] (%t) %s%e%n. +--log-gelf-facility + The facility (name of the process) that sends the message. Default: keycloak. +--log-gelf-host + Hostname of the Logstash or Graylog Host. By default UDP is used, prefix the + host with 'tcp:' to switch to TCP. Example: 'tcp:localhost' Default: + localhost. +--log-gelf-include-location + Include source code location. Default: true. +--log-gelf-include-message-parameters + Include message parameters from the log event. Default: true. +--log-gelf-include-stack-trace + If set to true, occuring stack traces are included in the 'StackTrace' field + in the gelf output. Default: true. +--log-gelf-max-message-size + Maximum message size (in bytes). If the message size is exceeded, gelf will + submit the message in multiple chunks. Default: 8192. +--log-gelf-port + The port the Logstash or Graylog Host is called on. Default: 12201. +--log-gelf-timestamp-format + Set the format for the gelf timestamp field. Uses Java SimpleDateFormat + pattern. Default: yyyy-MM-dd HH:mm:ss,SSS. +--log-level + The log level of the root category or a comma-separated list of individual + categories and their levels. For the root category, you don't need to + specify a category. Default: info. + +By default, this command tries to update the server configuration by running a +'build' before starting the server. You can disable this behavior by using the +'--optimised' option: + + $ kc.bat start '--optimised' + +By doing that, the server should start faster based on any previous +configuration you have set when manually running the 'build' command. \ No newline at end of file diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java index f86daac676..9913c7060c 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java @@ -177,6 +177,7 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta commands.add(getCommand()); commands.add("-v"); commands.add("start"); + commands.add("--optimised"); commands.add("--http-enabled=true"); if (Boolean.parseBoolean(System.getProperty("auth.server.debug", "false"))) { @@ -195,9 +196,9 @@ public class KeycloakQuarkusServerDeployableContainer implements DeployableConta commands.add("-Djboss.node.name=" + configuration.getRoute()); } - // only run auto-build during restarts or when running cluster tests + // only run build during restarts or when running cluster tests if (restart.get() || "ha".equals(System.getProperty("auth.server.quarkus.cluster.config"))) { - commands.add("--auto-build"); + commands.removeIf("--optimised"::equals); commands.add("--http-relative-path=/auth"); String cacheMode = System.getProperty("auth.server.quarkus.cluster.config", "local");