Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX #599 #598 Extended docs for application customization #601

Merged
merged 1 commit into from
Jun 15, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ object JavaAppBashScript {
val jarPrefixed = """^\-jar (.*)""".r
val args = mainClass match {
case jarPrefixed(jarName) => Seq("-jar", jarName)
case className => Seq(className)
case className => Seq(className)
}
val quotedArgsSpaceSeparated = args.map(s => "\"" + s + "\"").mkString(" ")
"declare -a app_mainclass=(%s)\n" format (quotedArgsSpaceSeparated)
Expand Down
118 changes: 100 additions & 18 deletions src/sphinx/archetypes/java_app/customize.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ script will effect all platform-specific builds. The server archetype provides a
specific System Loaders and Package types. These template file are described in
:doc:`configuring servers </archetypes/java_server/customize>`.

Customizing Templates (Bash/Bat)
--------------------------------
Customizing the Application
---------------------------

.. raw:: html

Expand All @@ -24,17 +24,88 @@ Customizing Templates (Bash/Bat)
</div>

After :doc:`creating a package <my-first-project>`, the very next thing needed, usually, is the ability for users/ops to customize
the application once it's deployed. Let's add some configuration to the newly deployed application.
the application once it's deployed. Let's add some configuration to the newly deployed application.

There are generally two types of configurations:

* Configuring the JVM and the process
* Configuring the Application itself.

The native packager provides a direct hook into the generated scripts for JVM configuration. Let's make use of this.
First, add the following to the ``src/universal/conf/application.ini`` file in the project ::
You have three options.

Via build.sbt
~~~~~~~~~~~~~

First, you can specify your options via the ``build.sbt``.

.. code-block :: scala

javaOptions in Universal ++= Seq(
// -J params will be added as jvm parameters
"-J-Xmx64m",
"-J-Xms64m",

// others will be added as app parameters
"-Dproperty=true",
"-port=8080",

// you can access any build setting/task here
s"-version=${version.value}"
)

For the ``-X`` settings you need to add a suffix ``-J`` so the start script will
recognize these as vm config parameters.

Via Application.ini
~~~~~~~~~~~~~~~~~~~

The second option is to create ``src/universal/conf/application.ini`` with the following template

.. code-block :: bash

# Setting -X directly (-J is stripped)
# -J-X
-J-Xmx1024

# Add additional jvm parameters
-Dkey=val

# Turn on JVM debugging, open at the given port
# -jvm-debug <port>

# Don't run the java version check
# -no-version-check

# enabling debug and sending -d as app argument
# the '--' prevents app-parameter swallowing when
# using a reserved parameter. See #184
# -d -- -d

The file will be installed to ``${app_home}/conf/application.ini`` and read from there
by the startscript. You can use ``#`` for comments and new lines as you like. This file
currently doesn't has any variable substitution. We recommend using the ``build.sbt`` if
you need any information from your build.

The configuration file for bash scripts takes arguments for the BASH file on each line,
and allows comments which start with the ``#`` character. Essentially, this provides
a set of default arguments when calling the script.

-DsomeProperty=true
By default, any file in the ``src/universal`` directory is packaged. This is a convenient
way to include things like licenses, and readmes.

BashScript defines
~~~~~~~~~~~~~~~~~~

The last option is to use the ``bashScriptExtraDefines``. Generally you can add arbitrary
bash commands here, but for configurations you have two methods to add jvm and app parameters. ::

bashScriptExtraDefines += """addJava "-Dconfig.file=${app_home}/../conf/app.config""""
bashScriptExtraDefines += """addApp "--port=8080"""



Testing the configuration
~~~~~~~~~~~~~~~~~~~~~~~~~

Now, if we run the ``stage`` task, we'll see this file show up in the distribution ::

Expand All @@ -45,17 +116,9 @@ Now, if we run the ``stage`` task, we'll see this file show up in the distributi
lib/
$ ls target/universal/stage/conf
application.ini

By default, any file in the ``src/universal`` directory is packaged. This is a convenient way to include things like licenses, and readmes.

Now, we need to modify the script templates to load this configuration. The following is enabled by default, but you can change
it if you don't like ``application.ini`` as a name. To do so, add the following
to ``build.sbt`` ::

bashScriptConfigLocation := Some("${app_home}/../conf/application.ini")

Here, we define the configuration location for the BASH script too look for the ``conf/application.ini`` file.
Now, let's run ``sbt stage`` and then execute the script in debug mode to see what command line it executes ::


Execute the script in debug mode to see what command line it executes ::

./target/universal/stage/bin/example-cli -d
# Executing command line:
Expand All @@ -68,9 +131,28 @@ Now, let's run ``sbt stage`` and then execute the script in debug mode to see wh
-cp
/home/jsuereth/projects/sbt/sbt-native-packager/tutorial-example/target/universal/stage/lib/example-cli.example-cli-1.0.jar:/home/jsuereth/projects/sbt/sbt-native-packager/tutorial-example/target/universal/stage/lib/org.scala-lang.scala-library-2.10.3.jar:/home/jsuereth/projects/sbt/sbt-native-packager/tutorial-example/target/universal/stage/lib/com.typesafe.config-1.2.0.jar
TestApp

As you can see ``-d`` is a reserved parameter. If you need to use this for your application you can
use the following syntax ::

./target/universal/stage/bin/example-cli -- -d

This will prevent the bashscript from interpreting the ``-d`` as the debug parameter

Customize application.ini name
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you don't like ``application.ini`` as a name, you can change this in the ``build.sbt``.
The default configuration looks like this ::

bashScriptConfigLocation := Some("${app_home}/../conf/application.ini")

These additions are useful if you need to reference existing variables from the
bashscript.

The configuration file for bash scripts takes arguments for the BASH file on each line, and allows comments which start with the ``#`` character. Essentially, this provides a set of default arguments when calling the script.

Example: Typesafe Config Library
--------------------------------

Now that we have ability to configure the JVM, let's add in a more robust method of customizing the application. We'll be using the `Typesafe Config <https://github.com/typesafehub/config>`_ library for this purpose.

Expand Down
63 changes: 17 additions & 46 deletions src/sphinx/archetypes/java_server/customize.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,20 @@ As this file is OS dependent, each OS gets section.
Linux Configuration
-------------------

You have three options. First, you can specify your options via the ``build.sbt``.
There are different ways described in :doc:`Customizing the Application </archetypes/java_app/customize>`
and can be used the same way.

.. code-block :: scala

javaOptions in Universal ++= Seq(
"-J-Xmx64m", "-J-Xms64m", "-Dproperty=true",
)

For the ``-X`` settings you need to add a suffix ``-J`` so the start script will
recognize these as vm config parameters.

The second option is to create ``src/universal/conf/application.ini`` with the following template
The server archetype adds an additional way with an ``etc-default`` file placed in ``src/templates``, which currently
only works for **SystemV**. The file gets sourced before the actual startscript is executed.
The file will be installed to ``/etc/default/<normalizedName>``

.. code-block :: bash

# Available replacements
# ------------------------------------------------
# ${{author}} debian author
# ${{descr}} debian package description
# ${{author}} package author
# ${{descr}} package description
# ${{exec}} startup script name
# ${{chdir}} app directory
# ${{retries}} retries for startup
Expand All @@ -45,38 +40,6 @@ The second option is to create ``src/universal/conf/application.ini`` with the f
# ${{daemon_user}} daemon user
# -------------------------------------------------

# Setting -X directly (-J is stripped)
# -J-X
-J-Xmx1024

# Add additional jvm parameters
-Dkey=val

# For play applications you may set
-Dpidfile.path=/var/run/${{app_name}}/play.pid

# Turn on JVM debugging, open at the given port
# -jvm-debug <port>

# Don't run the java version check
# -no-version-check

# enabling debug and sending -d as app argument
# the '--' prevents app-parameter swallowing when
# using a reserved parameter. See #184
# -d -- -d

The file will be installed to ``${app_home}/conf/application.ini`` and read from there
by the startscript. You can use ``#`` for comments and new lines as you like. The
available are listed in the template or you can display them via ``show linuxScriptReplacements``.


The last option is to provide a ``etc-default`` file placed in ``src/templates``, which currently
only works for **SystemV**. The file gets sourced before the actual startscript is executed.
The file will be installed to ``/etc/default/<normalizedName>``

.. code-block :: bash

# Setting JAVA_OPTS
# -----------------
JAVA_OPTS="-Dpidfile.path=/var/run/${{app_name}}/play.pid $JAVA_OPTS"
Expand Down Expand Up @@ -182,10 +145,18 @@ There is also experimental SystemD support for Fedora release 20 (Heisenbug). Yo

.. code-block:: scala

serverLoading in Rpm:= ServerLoader.Systemd
import com.typesafe.sbt.packager.archetypes.ServerLoader

serverLoading in Rpm := ServerLoader.Systemd

There is only partial systemd support in Ubuntu 14.04 LTS which prevents sbt-native-packager systemd from working correctly on
Ubuntu.
Ubuntu. Ubuntu 15.04 is the first version that switched to Systemd and the default Upstart won't work. Switch to Systemd with

.. code-block:: scala

import com.typesafe.sbt.packager.archetypes.ServerLoader

serverLoading in Debian := ServerLoader.Systemd

Package Lifecycle Configuration
===============================
Expand Down
5 changes: 3 additions & 2 deletions test-project-simple/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ rpmChangelogFile := Some("changelog.txt")

// these settings are conflicting
javaOptions in Universal ++= Seq(
"-J-Xmx64m", "-J-Xms64m"
"-J-Xmx64m", "-J-Xms64m",
"-jvm-debug 12345"
)

//bashScriptConfigLocation := Some("${app_home}/../conf/jvmopts")
//bashScriptConfigLocation := Some("${app_home}/../conf/jvmopts")
5 changes: 3 additions & 2 deletions test-project-simple/src/main/scala/ExampleApp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ object ExampleApp extends App {
val executorService = Executors newFixedThreadPool 2

val memory = Runtime.getRuntime.maxMemory() / (1024L * 1024L)
println("Memory " + memory + "m")
println(s"Memory $memory m")
println(s"Args: ${args mkString " | "}")

while (true) {
for (i <- 0 to 5) executorService execute HelloWorld(i)
for (i <- 0 to 2) executorService execute HelloWorld(i)
Thread sleep 5000
}

Expand Down