Fix useStartStopDaemon in launch script and allow config via conf file
Commit5a1ee6ebadded support for disabling use of start-stop-daemon via a placeholder in the default launch script. Unfortunately, that placeholder was subsequently broken in81a47639. This commit reinstates the placeholder and adds tests to verify that all of the placeholders in the launch script can be replaced and that they have the required default values. Furthermore, it also allows the use of start-stop-daemon to be configured via USE_START_STOP_DAEMON in an app’s .conf file. This allows the configuration to be changed after the app has been built. Closes gh-4985
This commit is contained in:
parent
44f508208a
commit
854cacdb4f
|
|
@ -541,6 +541,10 @@ the default behavior in a script or on the command line:
|
|||
that the `stop\|start\|status\|restart` commands work, or to `run` if you just want to
|
||||
run the script in the foreground.
|
||||
|
||||
|`USE_START_STOP_DAEMON`
|
||||
|If the `start-stop-daemon` command, when it's available, should be used to control the
|
||||
process. Defaults to `true`.
|
||||
|
||||
|`PID_FOLDER`
|
||||
|The root name of the pid folder (`/var/run` by default).
|
||||
|
||||
|
|
@ -606,8 +610,8 @@ for Gradle and to `${project.name}` for Maven.
|
|||
|The `chkconfig` section of "`INIT INFO`". Defaults to `2345 99 01`.
|
||||
|
||||
|`useStartStopDaemon`
|
||||
|If the start-stop command should be used to control the process when it's available.
|
||||
Defaults to `true`.
|
||||
|If the `start-stop-daemon` command, when it's available, should be used to control the
|
||||
process. Defaults to `true`.
|
||||
|===
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,10 @@ import org.junit.runners.Parameterized.Parameters;
|
|||
import org.springframework.boot.ansi.AnsiColor;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
|
||||
/**
|
||||
* Integration tests for Spring Boot's launch script on OSs that use SysVinit.
|
||||
|
|
@ -188,6 +191,13 @@ public class SysVinitLaunchScriptIT {
|
|||
doLaunch("launch-with-multiple-java-opts.sh");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void launchWithUseOfStartStopDaemonDisabled() throws Exception {
|
||||
// CentOS doesn't have start-stop-daemon
|
||||
assumeThat(this.os, is(not("CentOS")));
|
||||
doLaunch("launch-with-use-of-start-stop-daemon-disabled.sh");
|
||||
}
|
||||
|
||||
private void doLaunch(String script) throws Exception {
|
||||
assertThat(doTest(script), containsString("Launched"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
source ./test-functions.sh
|
||||
chmod -x $(type -p start-stop-daemon)
|
||||
echo 'USE_START_STOP_DAEMON=false' > /spring-boot-app.conf
|
||||
install_service
|
||||
start_service
|
||||
await_app
|
||||
curl -s http://127.0.0.1:8080/
|
||||
|
|
@ -51,8 +51,9 @@ configfile="$(basename "${jarfile%.*}.conf")"
|
|||
! [[ -x "$PID_FOLDER" ]] && PID_FOLDER="/tmp"
|
||||
! [[ -x "$LOG_FOLDER" ]] && LOG_FOLDER="/tmp"
|
||||
|
||||
# Setup defaults
|
||||
# Set up defaults
|
||||
[[ -z "$MODE" ]] && MODE="{{mode:auto}}" # modes are "auto", "service" or "run"
|
||||
[[ -z "$USE_START_STOP_DAEMON" ]] && USE_START_STOP_DAEMON="{{useStartStopDaemon:true}}"
|
||||
|
||||
# Create an identity for log/pid files
|
||||
if [[ -z "$identity" ]]; then
|
||||
|
|
@ -146,7 +147,7 @@ do_start() {
|
|||
chown "$run_user" "$PID_FOLDER"
|
||||
chown "$run_user" "$pid_file"
|
||||
chown "$run_user" "$log_file"
|
||||
if [ "${useStartStopDaemon:-true}" = true ] && type start-stop-daemon > /dev/null 2>&1; then
|
||||
if [ $USE_START_STOP_DAEMON = true ] && type start-stop-daemon > /dev/null 2>&1; then
|
||||
arguments=(-Dsun.misc.URLClassPath.disableJarChecking=true $JAVA_OPTS -jar $jarfile $RUN_ARGS "$@")
|
||||
start-stop-daemon --start --quiet \
|
||||
--chuid "$run_user" \
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
* Copyright 2012-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,7 +17,8 @@
|
|||
package org.springframework.boot.loader.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
|
|
@ -33,6 +34,7 @@ import static org.junit.Assert.assertThat;
|
|||
* Tests for {@link DefaultLaunchScript}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class DefaultLaunchScriptTests {
|
||||
|
||||
|
|
@ -44,6 +46,49 @@ public class DefaultLaunchScriptTests {
|
|||
DefaultLaunchScript script = new DefaultLaunchScript(null, null);
|
||||
String content = new String(script.toByteArray());
|
||||
assertThat(content, containsString("Spring Boot Startup Script"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initInfoProvidesCanBeReplaced() throws Exception {
|
||||
assertThatPlaceholderCanBeReplaced("initInfoProvides");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initInfoShortDescriptionCanBeReplaced() throws Exception {
|
||||
assertThatPlaceholderCanBeReplaced("initInfoShortDescription");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initInfoDescriptionCanBeReplaced() throws Exception {
|
||||
assertThatPlaceholderCanBeReplaced("initInfoDescription");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initInfoChkconfigCanBeReplaced() throws Exception {
|
||||
assertThatPlaceholderCanBeReplaced("initInfoChkconfig");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void modeCanBeReplaced() throws Exception {
|
||||
assertThatPlaceholderCanBeReplaced("mode");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void useStartStopDaemonCanBeReplaced() throws Exception {
|
||||
assertThatPlaceholderCanBeReplaced("useStartStopDaemon");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultForUseStartStopDaemonIsTrue() throws Exception {
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(null, null);
|
||||
String content = new String(script.toByteArray());
|
||||
assertThat(content, containsString("USE_START_STOP_DAEMON=\"true\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultForModeIsAuto() throws Exception {
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(null, null);
|
||||
String content = new String(script.toByteArray());
|
||||
assertThat(content, containsString("MODE=\"auto\""));
|
||||
}
|
||||
|
||||
|
|
@ -60,10 +105,8 @@ public class DefaultLaunchScriptTests {
|
|||
public void expandVariables() throws Exception {
|
||||
File file = this.temporaryFolder.newFile();
|
||||
FileCopyUtils.copy("h{{a}}ll{{b}}".getBytes(), file);
|
||||
Properties properties = new Properties();
|
||||
properties.put("a", "e");
|
||||
properties.put("b", "o");
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(file, properties);
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(file,
|
||||
createProperties("a:e", "b:o"));
|
||||
String content = new String(script.toByteArray());
|
||||
assertThat(content, equalTo("hello"));
|
||||
}
|
||||
|
|
@ -72,10 +115,8 @@ public class DefaultLaunchScriptTests {
|
|||
public void expandVariablesMultiLine() throws Exception {
|
||||
File file = this.temporaryFolder.newFile();
|
||||
FileCopyUtils.copy("h{{a}}l\nl{{b}}".getBytes(), file);
|
||||
Properties properties = new Properties();
|
||||
properties.put("a", "e");
|
||||
properties.put("b", "o");
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(file, properties);
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(file,
|
||||
createProperties("a:e", "b:o"));
|
||||
String content = new String(script.toByteArray());
|
||||
assertThat(content, equalTo("hel\nlo"));
|
||||
}
|
||||
|
|
@ -93,9 +134,8 @@ public class DefaultLaunchScriptTests {
|
|||
public void expandVariablesWithDefaultsOverride() throws Exception {
|
||||
File file = this.temporaryFolder.newFile();
|
||||
FileCopyUtils.copy("h{{a:e}}ll{{b:o}}".getBytes(), file);
|
||||
Properties properties = new Properties();
|
||||
properties.put("a", "a");
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(file, properties);
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(file,
|
||||
createProperties("a:a"));
|
||||
String content = new String(script.toByteArray());
|
||||
assertThat(content, equalTo("hallo"));
|
||||
}
|
||||
|
|
@ -109,4 +149,20 @@ public class DefaultLaunchScriptTests {
|
|||
assertThat(content, equalTo("h{{a}}ll{{b}}"));
|
||||
}
|
||||
|
||||
private void assertThatPlaceholderCanBeReplaced(String placeholder) throws Exception {
|
||||
DefaultLaunchScript script = new DefaultLaunchScript(null,
|
||||
createProperties(placeholder + ":__test__"));
|
||||
String content = new String(script.toByteArray());
|
||||
assertThat(content, containsString("__test__"));
|
||||
}
|
||||
|
||||
private Map<?, ?> createProperties(String... pairs) {
|
||||
Map<Object, Object> properties = new HashMap<Object, Object>();
|
||||
for (String pair : pairs) {
|
||||
String[] keyValue = pair.split(":");
|
||||
properties.put(keyValue[0], keyValue[1]);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue