Skip to content

Commit

Permalink
Aligning kc.bat with latest changes to kc.sh
Browse files Browse the repository at this point in the history
  • Loading branch information
pedroigor authored and hmlnarik committed Aug 3, 2022
1 parent ec38470 commit 0d3ca43
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 67 deletions.
42 changes: 31 additions & 11 deletions quarkus/dist/src/main/content/bin/kc.bat
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@ if not "%KEY:~0,2%"=="--" if "%KEY:~0,2%"=="-D" (
if not "%KEY:~0,2%"=="--" if not "%KEY:~0,1%"=="-" (
set "CONFIG_ARGS=%CONFIG_ARGS% %KEY%"
)
if "%KEY:~0,2%"=="--" if not "%KEY:~0,2%"=="-D" if "%KEY:~0,1%"=="-" (
if "%~2"=="" (
set "CONFIG_ARGS=%CONFIG_ARGS% %KEY%"
) else (
set "CONFIG_ARGS=%CONFIG_ARGS% %KEY% %~2%"
if not "%KEY:~0,2%"=="-D" (
if "%KEY:~0,1%"=="-" (
if "%~2"=="" (
set "CONFIG_ARGS=%CONFIG_ARGS% %KEY%"
) else (
set "CONFIG_ARGS=%CONFIG_ARGS% %KEY% %~2%"
)
shift
)

shift
)
shift
goto READ-ARGS
Expand Down Expand Up @@ -129,14 +130,33 @@ set "JAVA_RUN_OPTS=%JAVA_OPTS% -Dkc.home.dir="%DIRNAME%.." -Djboss.server.config

SetLocal EnableDelayedExpansion

set "ONLY_BUILD_OPTION= build"
set "NO_AUTO_BUILD_OPTION=optimized"
set "OPTIMIZED_OPTION=--optimized"
set "HELP_LONG_OPTION=--help"
set "BUILD_OPTION= build"
set IS_HELP_SHORT=false

echo "%CONFIG_ARGS%" | findstr /r "\<-h\>" > nul

if not errorlevel == 1 (
set IS_HELP_SHORT=true
)

set START_SERVER=true

if "!CONFIG_ARGS:%OPTIMIZED_OPTION%=!"=="!CONFIG_ARGS!" if "!CONFIG_ARGS:%BUILD_OPTION%=!"=="!CONFIG_ARGS!" if "!CONFIG_ARGS:%HELP_LONG_OPTION%=!"=="!CONFIG_ARGS!" if "%IS_HELP_SHORT%" == "false" (
setlocal enabledelayedexpansion

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%

if not !errorlevel! == 0 (
set START_SERVER=false
)

set "JAVA_RUN_OPTS=-Dkc.config.built=true %JAVA_RUN_OPTS%"
)

"%JAVA%" %JAVA_RUN_OPTS%
if "%START_SERVER%" == "true" (
"%JAVA%" %JAVA_RUN_OPTS%
)

:END
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,13 @@
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
Expand All @@ -52,20 +50,22 @@
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import io.quarkus.deployment.util.FileUtil;
import io.quarkus.fs.util.ZipUtils;
import org.apache.commons.io.FileUtils;

import org.keycloak.common.Version;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.quarkus.runtime.Environment;
import org.keycloak.quarkus.runtime.cli.command.Build;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;

import static org.keycloak.quarkus.runtime.Environment.LAUNCH_MODE;
import static org.keycloak.quarkus.runtime.Environment.isWindows;

public final class RawKeycloakDistribution implements KeycloakDistribution {

private static final int DEFAULT_SHUTDOWN_TIMEOUT_SECONDS = 10;

private Process keycloak;
private int exitCode = -1;
private final Path distPath;
Expand Down Expand Up @@ -128,24 +128,14 @@ public CLIResult run(List<String> arguments) {
public void stop() {
if (isRunning()) {
try {
if (Environment.isWindows()) {
// On Windows, we're executing kc.bat in a runtime as "keycloak",
// so tha java process is an actual child process
// we have to kill first.
killChildProcessesOnWindows(false);
}
// On Windows, we need to make sure sub-processes are terminated first
destroyDescendantsOnWindows(keycloak, false);

keycloak.destroy();
keycloak.waitFor(10, TimeUnit.SECONDS);
keycloak.waitFor(DEFAULT_SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS);
exitCode = keycloak.exitValue();
} catch (Exception cause) {
if (Environment.isWindows()) {
try {
killChildProcessesOnWindows(true);
} catch (Exception e) {
throw new RuntimeException("Failed to stop the server", e);
}
}
destroyDescendantsOnWindows(keycloak, true);
keycloak.destroyForcibly();
throw new RuntimeException("Failed to stop the server", cause);
}
Expand All @@ -154,19 +144,36 @@ public void stop() {
shutdownOutputExecutor();
}

private void killChildProcessesOnWindows(boolean isForced) {
for (ProcessHandle childProcessHandle : keycloak.children().collect(Collectors.toList())) {
CompletableFuture<ProcessHandle> onExit = childProcessHandle.onExit();
if (isForced) {
childProcessHandle.destroyForcibly();
private void destroyDescendantsOnWindows(Process parent, boolean force) {
if (!isWindows()) {
return;
}

CompletableFuture allProcesses = CompletableFuture.completedFuture(null);

for (ProcessHandle process : parent.descendants().collect(Collectors.toList())) {
if (force) {
process.destroyForcibly();
} else {
childProcessHandle.destroy();
process.destroy();
}
//for whatever reason windows doesnt wait for the termination,
// and parent process returns immediately with exitCode 1 but is not exited, leading to
// "failed to start the distribution" bc files that should be deleted
// are used by another process, so we need this here.
onExit.join();

allProcesses = CompletableFuture.allOf(allProcesses, process.onExit());
}

try {
allProcesses.get(DEFAULT_SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (Exception cause) {
throw new RuntimeException("Failed to terminate descendants processes", cause);
}

try {
// TODO: remove this. do not ask why, but on Windows we are here even though the process was previously terminated
// without this pause, tests re-installing dist before tests should fail
// looks like pausing the current thread let windows to cleanup processes?
// more likely it is env dependent
Thread.sleep(500);
} catch (InterruptedException e) {
}
}

Expand Down Expand Up @@ -195,7 +202,7 @@ public int getExitCode() {
public String[] getCliArgs(List<String> arguments) {
List<String> allArgs = new ArrayList<>();

if (Environment.isWindows()) {
if (isWindows()) {
allArgs.add(distPath.resolve("bin") + File.separator + SCRIPT_CMD_INVOKABLE);
} else {
allArgs.add(SCRIPT_CMD_INVOKABLE);
Expand Down Expand Up @@ -340,13 +347,7 @@ private Path prepareDistribution() {
Path dPath = distRootPath.resolve(distDirName.substring(0, distDirName.lastIndexOf('.')));

if (!inited || (reCreate || !dPath.toFile().exists())) {

if (!Environment.isWindows()) {
FileUtils.deleteDirectory(dPath.toFile());
} else {
deleteTempFilesOnWindows(dPath);
}

FileUtil.deleteDirectory(dPath);
ZipUtils.unzip(distFile.toPath(), distRootPath);
}

Expand All @@ -363,23 +364,6 @@ private Path prepareDistribution() {
}
}

private void deleteTempFilesOnWindows(Path dPath) {
if (Files.exists(dPath)) {
try (Stream<Path> walk = Files.walk(dPath)) {
walk.sorted(Comparator.reverseOrder())
.forEach(s -> {
try {
Files.delete(s);
} catch (IOException e) {
throw new RuntimeException("Could not delete temp directory for distribution", e);
}
});
} catch (IOException e) {
throw new RuntimeException("Could not traverse temp directory for distribution to delete files", e);
}
}
}

private void readOutput() {
try (
BufferedReader outStream = new BufferedReader(new InputStreamReader(keycloak.getInputStream()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.util.List;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.OS;
import org.keycloak.it.cli.HelpCommandTest;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.it.junit5.extension.DistributionTest;
Expand All @@ -35,7 +36,13 @@ public class HelpCommandDistTest extends HelpCommandTest {
public void testHelpDoesNotStartReAugJvm(KeycloakDistribution dist) {
for (String helpCmd : List.of("-h", "--help", "--help-all")) {
for (String cmd : List.of("", "start", "start-dev", "build")) {
CLIResult run = dist.run("--debug", cmd, helpCmd);
String debugOption = "--debug";

if (OS.WINDOWS.isCurrentOs()) {
debugOption = "--debug=8787";
}

CLIResult run = dist.run(debugOption, cmd, helpCmd);
assertSingleJvmStarted(run);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import java.nio.file.Path;
import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.keycloak.it.junit5.extension.BeforeStartDistribution;
import org.keycloak.it.junit5.extension.CLIResult;
import org.keycloak.it.junit5.extension.DistributionTest;
Expand Down Expand Up @@ -60,6 +62,7 @@ void testIgnoreFileWithUnsupportedExtension(LaunchResult result) {
}

@Test
@EnabledOnOs(value = { OS.LINUX, OS.MAC }, disabledReason = "different shell escaping behaviour on Windows.")
@BeforeStartDistribution(CreateRealmConfigurationFile.class)
@Launch({"start-dev", "--import-realm=some-file"})
void failSetValueToImportRealmOption(LaunchResult result) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,11 @@ void testStartUsingAutoBuild(LaunchResult result) {
cliResult.assertStarted();
}

@Test
@Launch({ "start", "--optimized", "--http-enabled=true", "--hostname-strict=false", "--cache=local" })
void testStartUsingOptimizedDoesNotAllowBuildOptions(LaunchResult result) {
CLIResult cliResult = (CLIResult) result;
cliResult.assertError("Unknown option: '--cache'");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,3 @@ Examples:
Change the relative path:

$ kc.bat build --http-relative-path=/auth

0 comments on commit 0d3ca43

Please sign in to comment.