Skip to content

Commit

Permalink
Merge pull request #43 from palantir/feature/config
Browse files Browse the repository at this point in the history
Support extra settings in service/bin
  • Loading branch information
markelliot committed Jan 25, 2016
2 parents dad81ed + 29c9923 commit 28cc79b
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 19 deletions.
9 changes: 7 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ content of the package. The package will follow this structure:
[service-name] # start script
[service-name.bat] # Windows start script
init.sh # daemonizing script
config.sh # customized environment vars
lib/
[jars]
var/
Expand Down Expand Up @@ -52,14 +53,16 @@ The `distribution` block offers the following options:
* (optional) `defaultJvmOpts` a list of default JVM options to set on the program.
* (optional) `enableManifestClasspath` a boolean flag; if set to true, then the explicit Java
classpath is omitted from the generated Windows start script and instead infered
from a JAR file whose MANIFEST contains the classpath entries
from a JAR file whose MANIFEST contains the classpath entries.
* (optional) `javaHome` a fixed override for the `JAVA_HOME` environment variable that will
be applied when `init.sh` is run.


Packaging
---------
To create a compressed, gzipped tar file, run the `distTar` task.

As part of package creation, this plugin will create two shell scripts:
As part of package creation, this plugin will create three shell scripts:

* `service/bin/[service-name]`: a Gradle default start script for running
the defined `mainClass`
Expand All @@ -73,6 +76,8 @@ As part of package creation, this plugin will create two shell scripts:
process the id recorded in that file with a command matching the expected
start command is found in the process table.
- `stop`: if the process status is 0, issues a kill signal to the process.
* `service/bin/config.sh`: a shell script containing environment variables to apply
as overrides when `init.sh` is run.


In addition to creating these scripts, this plugin will merge the entire
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class DistributionExtension {
private List<String> args = []
private List<String> defaultJvmOpts = []
private boolean enableManifestClasspath = false
private String javaHome = null

public void serviceName(String serviceName) {
this.serviceName = serviceName
Expand All @@ -43,24 +44,32 @@ class DistributionExtension {
this.enableManifestClasspath = enableManifestClasspath
}

public void javaHome(String javaHome) {
this.javaHome = javaHome
}

public String getServiceName() {
return serviceName;
return serviceName
}

public String getMainClass() {
return mainClass;
return mainClass
}

public List<String> getArgs() {
return args;
return args
}

public List<String> getDefaultJvmOpts() {
return defaultJvmOpts;
return defaultJvmOpts
}

public boolean isEnableManifestClasspath() {
return enableManifestClasspath;
return enableManifestClasspath
}

public String getJavaHome() {
return javaHome
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@
*/
package com.palantir.gradle.javadist

import java.nio.file.Paths

import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task

import java.nio.file.Paths

class JavaDistributionPlugin implements Plugin<Project> {

private static final String GROUP_NAME = "Distribution"

void apply(Project project) {
// force application of java
project.plugins.apply('java')
Expand All @@ -31,13 +33,13 @@ class JavaDistributionPlugin implements Plugin<Project> {

// Specify classpath using pathing jar rather than command line argument on Windows, since
// Windows path sizes are limited.
ManifestClasspathJarTask manifestClasspathJar =
project.tasks.create("manifestClasspathJar", ManifestClasspathJarTask)
manifestClasspathJar.setOnlyIf {
ext.isEnableManifestClasspath()
}
ManifestClasspathJarTask manifestClasspathJar = project.tasks.create("manifestClasspathJar", ManifestClasspathJarTask, {
group = GROUP_NAME
onlyIf { ext.isEnableManifestClasspath() }
})

Task startScripts = project.tasks.create('createStartScripts', DistributionCreateStartScriptsTask, {
group = GROUP_NAME
description = "Generates standard Java start scripts."
}) << {
if (ext.isEnableManifestClasspath()) {
Expand All @@ -57,18 +59,31 @@ class JavaDistributionPlugin implements Plugin<Project> {
}

Task initScript = project.tasks.create('createInitScript', {
group = GROUP_NAME
description = "Generates daemonizing init.sh script."
}) << {
EmitFiles.replaceVars(
JavaDistributionPlugin.class.getResourceAsStream('/init.sh'),
Paths.get("${project.buildDir}/scripts/init.sh"),
['@serviceName@': ext.serviceName,
'@args@': ext.args.iterator().join(' ')])
'@args@': ext.args.iterator().join(' ')])
.toFile()
.setExecutable(true)
}

Task configScript = project.tasks.create('createConfigScript', {
group = GROUP_NAME
description = "Generates config.sh script."
}) << {
String javaHome = ext.javaHome != null ? 'JAVA_HOME="' + ext.javaHome + '"' : '#JAVA_HOME=""'
EmitFiles.replaceVars(
JavaDistributionPlugin.class.getResourceAsStream('/config.sh'),
Paths.get("${project.buildDir}/scripts/config.sh"),
['@javaHome@': javaHome])
}

Task manifest = project.tasks.create('createManifest', {
group = GROUP_NAME
description = "Generates a simple yaml file describing the package content."
}) << {
EmitFiles.replaceVars(
Expand All @@ -81,11 +96,13 @@ class JavaDistributionPlugin implements Plugin<Project> {
}

DistTarTask distTar = project.tasks.create('distTar', DistTarTask, {
group = GROUP_NAME
description = "Creates a compressed, gzipped tar file that contains required runtime resources."
dependsOn startScripts, initScript, manifest, manifestClasspathJar
dependsOn startScripts, initScript, configScript, manifest, manifestClasspathJar
})

RunTask run = project.tasks.create('run', RunTask, {
group = GROUP_NAME
description = "Runs the specified project using configured mainClass and with default args."
})

Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# override the JAVA_HOME value with a known JRE location
@javaHome@

# use JVM_OPTS to set JVM settings, such as minimum and maximum heap
#JVM_OPTS="-Xms1g -Xmx1g"
7 changes: 5 additions & 2 deletions src/main/resources/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@

ACTION=$1
SERVICE="@serviceName@"
SERVICE_CMD="service/bin/$SERVICE"
PIDFILE="var/run/$SERVICE.pid"
ARGS="@args@"

# uses SERVICE_HOME when set, else, traverse up two directories respecting symlinks
SERVICE_HOME=${SERVICE_HOME:-$(cd "$(dirname "$0")/../../" && pwd)}
cd "$SERVICE_HOME"

source service/bin/config.sh

is_process_active() {
local PID=$1
ps $PID > /dev/null;
Expand All @@ -42,7 +45,7 @@ start)
# ensure log and pid directories exist
mkdir -p "var/log"
mkdir -p "var/run"
PID=$(service/bin/$SERVICE $ARGS > var/log/$SERVICE-startup.log 2>&1 & echo $!)
PID=$($SERVICE_CMD $ARGS > var/log/$SERVICE-startup.log 2>&1 & echo $!)
sleep 1
if [ $(is_process_active $PID) -eq 0 ]; then
echo $PID > $PIDFILE
Expand Down Expand Up @@ -102,7 +105,7 @@ console)
trap "service/bin/init.sh stop &> /dev/null" SIGTERM EXIT
mkdir -p "$(dirname $PIDFILE)"

service/bin/$SERVICE $ARGS &
$SERVICE_CMD $ARGS &
echo $! > $PIDFILE
wait
;;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*
* Copyright 2015 Palantir Technologies
*
Expand Down Expand Up @@ -61,7 +62,8 @@ class JavaDistributionPluginTests extends Specification {
new File(projectDir, 'dist/service-name-0.1').exists()

// try all of the service commands
exec('dist/service-name-0.1/service/bin/init.sh', 'start') ==~ /(?m)Running 'service-name'\.\.\.\s+Started \(\d+\)\n/
String output = exec('dist/service-name-0.1/service/bin/init.sh', 'start')
output ==~ /(?m)Running 'service-name'\.\.\.\s+Started \(\d+\)\n/
readFully('dist/service-name-0.1/var/log/service-name-startup.log').equals('Test started\n')
exec('dist/service-name-0.1/service/bin/init.sh', 'status') ==~ /(?m)Checking 'service-name'\.\.\.\s+Running \(\d+\)\n/
exec('dist/service-name-0.1/service/bin/init.sh', 'restart') ==~
Expand Down Expand Up @@ -207,6 +209,31 @@ class JavaDistributionPluginTests extends Specification {
startScript.contains('DEFAULT_JVM_OPTS=\'"-Xmx4M" "-Djavax.net.ssl.trustStore=truststore.jks"\'')
}

def 'produce distribution bundle that populates config.sh' () {
given:
createUntarBuildFile(buildFile)
buildFile << '''
distribution {
javaHome 'foo'
}
'''.stripIndent()

when:
BuildResult buildResult = run('build', 'distTar', 'untar').build()

then:
buildResult.task(':build').outcome == TaskOutcome.SUCCESS
buildResult.task(':distTar').outcome == TaskOutcome.SUCCESS
buildResult.task(':untar').outcome == TaskOutcome.SUCCESS

new File(projectDir, 'dist/service-name-0.1').exists()

// check start script uses default JVM options
new File(projectDir, 'dist/service-name-0.1/service/bin/config.sh').exists()
String startScript = readFully('dist/service-name-0.1/service/bin/config.sh')
startScript.contains('JAVA_HOME="foo"')
}

def 'produces manifest-classpath jar and windows start script with no classpath length limitations' () {
given:
createUntarBuildFile(buildFile)
Expand Down

0 comments on commit 28cc79b

Please sign in to comment.