mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
closes: #41268 (cherry picked from commit 02cd3ddfb7ed550cb7c4ac97fb98b4af9f0f1f8d) Signed-off-by: Steve Hawkins <shawkins@redhat.com>
This commit is contained in:
parent
ec6e015dff
commit
4a6a66a449
@ -92,6 +92,8 @@ import picocli.CommandLine.ParseResult;
|
||||
|
||||
public class Picocli {
|
||||
|
||||
static final String PROVIDER_TIMESTAMP_ERROR = "A provider JAR was updated since the last build, please rebuild for this to be fully utilized.";
|
||||
static final String PROVIDER_TIMESTAMP_WARNING = "A provider jar has a different timestamp than when the optimized container image was created. If you are changing provider jars after the build, you must run another build to properly account for those modifications.";
|
||||
static final String KC_PROVIDER_FILE_PREFIX = "kc.provider.file.";
|
||||
public static final String ARG_PREFIX = "--";
|
||||
public static final String ARG_SHORT_PREFIX = "-";
|
||||
@ -105,6 +107,7 @@ public class Picocli {
|
||||
private final ExecutionExceptionHandler errorHandler = new ExecutionExceptionHandler();
|
||||
private Set<PropertyMapper<?>> allowedMappers;
|
||||
private final List<String> unrecognizedArgs = new ArrayList<>();
|
||||
private boolean warnedTimestampChanged;
|
||||
|
||||
public void parseAndRun(List<String> cliArgs) {
|
||||
// perform two passes over the cli args. First without option validation to determine the current command, then with option validation enabled
|
||||
@ -360,8 +363,19 @@ public class Picocli {
|
||||
// we have to ignore things like the profile properties because the commands set them at runtime
|
||||
checkChangesInBuildOptions((key, oldValue, newValue) -> {
|
||||
if (key.startsWith(KC_PROVIDER_FILE_PREFIX)) {
|
||||
if (timestampChanged(oldValue, newValue)) {
|
||||
throw new PropertyException("A provider JAR was updated since the last build, please rebuild for this to be fully utilized.");
|
||||
boolean changed = false;
|
||||
if (newValue == null || oldValue == null) {
|
||||
changed = true;
|
||||
} else if (!warnedTimestampChanged && timestampChanged(oldValue, newValue)) {
|
||||
if (Configuration.getOptionalBooleanKcValue("run-in-container").orElse(false)) {
|
||||
warnedTimestampChanged = true;
|
||||
warn(PROVIDER_TIMESTAMP_WARNING);
|
||||
} else {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
throw new PropertyException(PROVIDER_TIMESTAMP_ERROR);
|
||||
}
|
||||
} else if (newValue != null && !isIgnoredPersistedOption(key)
|
||||
&& isUserModifiable(Configuration.getConfigValue(key))
|
||||
@ -478,13 +492,10 @@ public class Picocli {
|
||||
}
|
||||
|
||||
static boolean timestampChanged(String oldValue, String newValue) {
|
||||
if (newValue != null && oldValue != null) {
|
||||
long longNewValue = Long.valueOf(newValue);
|
||||
long longOldValue = Long.valueOf(oldValue);
|
||||
// docker commonly truncates to the second at runtime, so we'll allow that special case
|
||||
return ((longNewValue / 1000) * 1000) != longNewValue || ((longOldValue / 1000) * 1000) != longNewValue;
|
||||
}
|
||||
return true;
|
||||
long longNewValue = Long.valueOf(newValue);
|
||||
long longOldValue = Long.valueOf(oldValue);
|
||||
// docker commonly truncates to the second at runtime, so we'll allow that special case
|
||||
return ((longNewValue / 1000) * 1000) != longNewValue || ((longOldValue / 1000) * 1000) != longNewValue;
|
||||
}
|
||||
|
||||
private void validateProperty(AbstractCommand abstractCommand, IncludeOptions options,
|
||||
|
||||
@ -47,6 +47,7 @@ import org.keycloak.quarkus.runtime.Environment;
|
||||
import org.keycloak.quarkus.runtime.KeycloakMain;
|
||||
import org.keycloak.quarkus.runtime.configuration.AbstractConfigurationTest;
|
||||
import org.keycloak.quarkus.runtime.configuration.ConfigArgsConfigSource;
|
||||
import org.keycloak.quarkus.runtime.configuration.PersistedConfigSource;
|
||||
|
||||
import io.smallrye.config.SmallRyeConfig;
|
||||
import picocli.CommandLine;
|
||||
@ -536,9 +537,22 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
|
||||
addPersistedConfigValues(Map.of(Picocli.KC_PROVIDER_FILE_PREFIX + "fake", "value"));
|
||||
|
||||
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start", "--optimized");
|
||||
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start", "--optimized", "--http-enabled=true", "--hostname-strict=false");
|
||||
assertEquals(CommandLine.ExitCode.USAGE, nonRunningPicocli.exitCode);
|
||||
assertTrue(nonRunningPicocli.getErrString().contains("A provider JAR was updated since the last build, please rebuild for this to be fully utilized."));
|
||||
assertTrue(nonRunningPicocli.getErrString().contains(Picocli.PROVIDER_TIMESTAMP_ERROR));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void warnProviderChanged() {
|
||||
build("build", "--db=dev-file");
|
||||
|
||||
putEnvVar("KC_RUN_IN_CONTAINER", "true");
|
||||
String key = PersistedConfigSource.getInstance().getConfigValueProperties().keySet().stream().filter(k -> k.startsWith(Picocli.KC_PROVIDER_FILE_PREFIX)).findAny().orElseThrow();
|
||||
addPersistedConfigValues(Map.of(key, "1")); // change to a fake timestamp
|
||||
|
||||
NonRunningPicocli nonRunningPicocli = pseudoLaunch("start", "--optimized", "--http-enabled=true", "--hostname-strict=false");
|
||||
assertEquals(nonRunningPicocli.getErrString(), CommandLine.ExitCode.OK, nonRunningPicocli.exitCode);
|
||||
assertTrue(nonRunningPicocli.getOutString().contains(Picocli.PROVIDER_TIMESTAMP_WARNING));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -766,7 +780,6 @@ public class PicocliTest extends AbstractConfigurationTest {
|
||||
|
||||
@Test
|
||||
public void timestampChanged() {
|
||||
assertTrue(Picocli.timestampChanged("12345", null));
|
||||
assertTrue(Picocli.timestampChanged("12345", "12346"));
|
||||
assertTrue(Picocli.timestampChanged("12000", "12346"));
|
||||
// new is truncated - should not be a change
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user