Commit 854cacdb authored by Andy Wilkinson's avatar Andy Wilkinson

Fix useStartStopDaemon in launch script and allow config via conf file

Commit 5a1ee6eb added support for disabling use of start-stop-daemon
via a placeholder in the default launch script. Unfortunately, that
placeholder was subsequently broken in 81a47639.

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
parent 44f50820
......@@ -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"));
}
......
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" \
......
/*
* 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;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment