-
Notifications
You must be signed in to change notification settings - Fork 445
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New structured completed. Next step is to merge overriding/configure …
…templates
- Loading branch information
Showing
20 changed files
with
1,733 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Akka Microkernel | ||
################ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
.. _Archetypes: | ||
|
||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
java_app/index.rst | ||
java_server/index.rst | ||
akka_app/index.rst | ||
|
||
Project Archetypes | ||
================== | ||
|
||
Project archetypes are default deployment scripts that try to "do the right thing" for a given type of project. | ||
Because not all projects are created equal, there is no one single archetype for all native packages, but a set | ||
of them for usage. | ||
|
||
The architecture of the plugin is set up so that you can customize your packages at any level of complexity. | ||
For example, if you'd like to write Windows Installer XML by hand and manually map files, you should be able to do this while | ||
still leveraging the default configuration for other platforms. | ||
|
||
|
||
Curently, in the nativepackager these archetypes are available: | ||
|
||
* Java Command Line Application | ||
* Java Server Application (Experimental - Debian Only) | ||
|
||
|
||
Java Command Line Application | ||
----------------------------- | ||
|
||
A Java Command Line application is a Java application that consists of a set of JARs and a main method. There is no | ||
custom start scripts, or services. It is just a bash/bat script that starts up a Java project. To use | ||
this archetype in your build, do the following in your ``build.sbt``: | ||
|
||
.. code-block:: scala | ||
packageArchetype.java_application | ||
name := "A-package-friendly-name" | ||
packageSummary in Linux := "The name you want displayed in package summaries" | ||
packageSummary in Windows := "The name you want displayed in Add/Remove Programs" | ||
packageDescription := " A description of your project" | ||
maintainer in Windows := "Company" | ||
maintainer in Debian := "Your Name <[email protected]>" | ||
wixProductId := "ce07be71-510d-414a-92d4-dff47631848a" | ||
wixProductUpgradeId := "4552fb0e-e257-4dbd-9ecb-dba9dbacf424" | ||
This archetype will use the ``mainClass`` setting of sbt (automatically discovers your main class) to generate ``bat`` and ``bin`` scripts for your project. It | ||
produces a universal layout that looks like the following: | ||
|
||
.. code-block:: none | ||
bin/ | ||
<app_name> <- BASH script | ||
<app_name>.bat <- cmd.exe script | ||
lib/ | ||
<Your project and dependent jar files here.> | ||
You can add additional files to the project by placing things in ``src/windows``, ``src/universal`` or ``src/linux`` as needed. | ||
|
||
The scripts under ``bin`` will execute the ``main`` method of a class found in your application. But you can specific a custom main class method with the ``-main`` flag. | ||
|
||
The default bash script also supports having a configuration file. This config file can be used to specify default arguments to the BASH script. | ||
To define a config location for your bash script, you can manually override the template defines: | ||
|
||
.. code-block:: scala | ||
bashScriptConfigLocation := "$app_home/conf/my.conf" | ||
This string can include any variable defines in the BASH script. In this case, ``app_home`` refers to the install location of the script. | ||
|
||
Java Server | ||
----------- | ||
|
||
This archetype is designed for Java applications that are intended to run as | ||
servers or services. This archetype includes wiring an application to start | ||
immediately upon startup. To activate this archetype replace ``packageArchetype.java_application`` with | ||
|
||
.. code-block:: scala | ||
packageArchetype.java_server | ||
Currently supported operating systems: | ||
|
||
* Ubuntu 12.04 LTS - Upstart | ||
* Ubuntu 12.04 LTS - init.d | ||
|
||
|
||
The Java Server archetype has a similar installation layout as the java | ||
application archetype. The primary differneces are: | ||
|
||
* Linux | ||
|
||
* ``/var/log/<pkg>`` is symlinked from ``<install>/logs`` | ||
|
||
* Creates a start script in ``/etc/init.d`` or ``/etc/init/`` | ||
|
||
* Creates a startup config file in ``/etc/default/<pkg>`` | ||
|
||
|
||
For Debian servers, you can select to either use SystemV or Upstart for your servers. By default, Upstart (the current Ubuntu LTS default), is used. To switch to SystemV, add the following: | ||
|
||
.. code-block:: scala | ||
import NativePackagerKeys._ | ||
import com.typesafe.sbt.packager.archetypes.ServerLoader | ||
serverLoading in Debian := ServerLoader.SystemV | ||
By default, the native packager will install and run services using a user and group based on your package name. You can change the installation and usage user via the ``appUser`` and ``appGroup`` key: | ||
|
||
.. code-block:: scala | ||
appUser in Linux := "my_app_user" | ||
appGroup in Linux := "my_app_group" | ||
The archetype will automatically append/prepend the creation/deletion of the user | ||
to your packaging for Debian. *Note:* All specified users are **deleted** on an ``apt-get purge <dpkg>``. | ||
|
||
*Note:* It is not a good idea to use **root** as the ``appUser`` for services as it represents a security risk. | ||
|
||
Akka Microkernel Application | ||
---------------------------- | ||
|
||
An Akka microkernel application is simlar to a Java Command Line application. Instead of running the classic ``mainClass``, | ||
an Akka microkernel application instantiates and runs a subclass of | ||
`Bootable <https://github.com/akka/akka/blob/master/akka-kernel/src/main/scala/akka/kernel/Main.scala>`_ . A minimal example | ||
could look like this | ||
|
||
.. code-block:: scala | ||
class HelloKernel extends Bootable { | ||
val system = ActorSystem("hellokernel") | ||
def startup = { | ||
// HelloActor and Start case object must of course be defined | ||
system.actorOf(Props[HelloActor]) ! Start | ||
} | ||
def shutdown = { | ||
system.terminate() | ||
} | ||
} | ||
The *bash/bat* script that starts up the Akka application is copied from the Akka distribution. | ||
|
||
To use this archetype in your build, add the following to your ``build.sbt``: | ||
|
||
.. code-block:: scala | ||
packageArchetype.akka_application | ||
name := "A-package-friendly-name" | ||
mainClass in Compile := Some("HelloKernel") | ||
For more information take a look at the akka docs | ||
|
||
* `Akka microkernel <http://doc.akka.io/docs/akka/snapshot/scala/microkernel.html>`_ | ||
* `akka.kernel.Main source <https://github.com/akka/akka/blob/master/akka-kernel/src/main/scala/akka/kernel/Main.scala>`_ | ||
* `akka.kernel.Bootable docs <http://doc.akka.io/api/akka/snapshot/index.html#akka.kernel.Bootable>`_ | ||
|
||
|
||
Overriding Templates | ||
-------------------- | ||
|
||
You can override the default template used to generate any of the scripts in | ||
any archetype. Listed below are the overridable files and variables that | ||
you can use when generating scripts. | ||
|
||
``src/templates/bat-template`` | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Creating a file here will override the default template used to | ||
generate the ``.bat`` script for windows distributions. | ||
|
||
**Syntax** | ||
|
||
``@@APP_ENV_NAME@@`` - will be replaced with the script friendly name of your package. | ||
|
||
``@@APP_NAME@@`` - will be replaced with user friendly name of your package. | ||
|
||
``@APP_DEFINES@@`` - will be replaced with a set of variable definitions, like | ||
``APP_MAIN_CLASS``, ``APP_MAIN_CLASS``. | ||
|
||
You can define addiitonal variable definitions using ``batScriptExtraDefines``. | ||
|
||
``src/templates/bash-template`` | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Creating a file here will override the default template used to | ||
generate the BASH start script found in ``bin/<application>`` in the | ||
universal distribution | ||
|
||
**Syntax** | ||
|
||
``${{template_declares}}`` - Will be replaced with a series of ``declare <var>`` | ||
lines based on the ``bashScriptDefines`` key. You can add more defines to | ||
the ``bashScriptExtraDefines`` that will be used in addition to the default set: | ||
|
||
* ``app_mainclass`` - The main class entry point for the application. | ||
* ``app_classpath`` - The complete classpath for the application (in order). | ||
|
||
|
||
|
||
``src/templates/start`` | ||
~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Creating a file here will override either the init.d startup script or | ||
the upstart start script. It will either be located at | ||
``/etc/init/<application>`` or ``/etc/init.d/<application>`` depending on which | ||
serverLoader is being used. | ||
|
||
**Syntax** | ||
|
||
You can use ``${{variable_name}}`` to reference variables when writing your scirpt. The default set of variables is: | ||
|
||
* ``descr`` - The description of the server. | ||
* ``author`` - The configured author name. | ||
* ``exec`` - The script/binary to execute when starting the server | ||
* ``chdir`` - The working directory for the server. | ||
* ``retries`` - The number of times to retry starting the server. | ||
* ``retryTimeout`` - The amount of time to wait before trying to run the server. | ||
* ``app_name`` - The name of the application (linux friendly) | ||
* ``app_main_class`` - The main class / entry point of the application. | ||
* ``app_classpath`` - The (ordered) classpath of the application. | ||
* ``daemon_user`` - The user that the server should run as. | ||
|
||
``src/templates/etc-default`` | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
Creating a file here will override the ``/etc/default/<application>`` template | ||
used when SystemV is the server loader. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
Adding configuration | ||
#################### | ||
|
||
After :doc:`creating a package <MyFirstProject>`, 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. | ||
|
||
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/jvmopts`` file in the project :: | ||
|
||
-DsomeProperty=true | ||
|
||
Now, if we run the ``stage`` task, we'll see this file show up in the distribution :: | ||
|
||
$ sbt stage | ||
$ ls target/universal/stage | ||
bin/ | ||
conf/ | ||
lib/ | ||
$ ls target/universal/stage/conf | ||
jvmopts | ||
|
||
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. To do so, add the following | ||
to ``build.sbt`` :: | ||
|
||
bashScriptConfigLocation := Some("${app_home}/../conf/jvmopts") | ||
|
||
Here, we define the configuration location for the BASH script too look for the ``conf/jvmopts`` file. Now, let's run ``sbt stage`` and then execute the script in debug mode to see what command line it executes :: | ||
|
||
./target/universal/stage/bin/example-cli -d | ||
# Executing command line: | ||
java | ||
-Xms1024m | ||
-Xmx1024m | ||
-XX:MaxPermSize=256m | ||
-XX:ReservedCodeCacheSize=128m | ||
-DsomeProperty=true | ||
-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 | ||
|
||
|
||
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. | ||
|
||
Now that we have ability to configure the JVM, let's add in a more robust method of customizing the applciation. We'll be using the `Typesafe Config <https://github.com/typesafehub/config>`_ library for this purpose. | ||
|
||
First, let's add it as a dependency in ``build.sbt`` :: | ||
|
||
libraryDependencies += "com.typesafe" % "config" % "1.2.0" | ||
|
||
Next, let's create the configuration file itself. Add the following to ``src/universal/conf/app.config`` :: | ||
|
||
example { | ||
greeting = "Hello, World!" | ||
} | ||
|
||
Now, we need a means of telling the typesafe config library where to find our configuration. The library supports | ||
a JVM property "``config.file``" which it will use to look for configuration. Let's expose this file | ||
in the startup BASH script. To do so, add the following to ``build.sbt`` :: | ||
|
||
bashScriptExtraDefines += """addJava "-Dconfig.file=${app_home}/../conf/app.config"""" | ||
|
||
This line modifies the generated BASH script to add the JVM options the location of the application configuration on disk. Now, let's modify the application (``src/main/scala/TestApp.scala``) to read this configuration :: | ||
|
||
import com.typesafe.config.ConfigFactory | ||
object TestApp extends App { | ||
val config = ConfigFactory.load() | ||
println(config.getString("example.greeting")) | ||
} | ||
|
||
Now, let's try it out on the command line :: | ||
|
||
$ sbt stage | ||
$ ./target/universal/stage/bin/example-cli | ||
Hello, World! | ||
|
||
|
||
Finally, let's see what this configuration looks like in a linux distribution. Let's run the debian packaging again :: | ||
|
||
$ sbt debian:packageBin | ||
|
||
The resulting structure is the following :: | ||
|
||
/usr/ | ||
share/example-cli/ | ||
conf/ | ||
app.config | ||
jvmopts | ||
bin/ | ||
example-cli | ||
lib/ | ||
example-cli.example-cli-1.0.jar | ||
org.scala-lang.scala-library-2.10.3.jar | ||
bin/ | ||
example-cli -> ../share/example-cli/bin/example-cli | ||
/etc/ | ||
example-cli -> /usr/share/example-cli/conf | ||
|
||
Here, we can see that the entire ``conf`` directory for the application is exposed on ``/etc`` as is standard for other linux applications. By convention, all files in the universal ``conf`` directory are marked as configuration files when packaged, allowing users to modify them. | ||
|
||
Configuring for Windows | ||
~~~~~~~~~~~~~~~~~~~~~~~ | ||
While we just covered how to do configuration for linux/mac, windows offers some subtle differences. | ||
|
||
First, while the BASH file allows you to configure where to load JVM options and default arguments, in | ||
windows we can only configure JVM options. The path is hardcoded, as well to: | ||
|
||
``<install directory>/@@APP_ENV_NAME@@_config.txt`` | ||
|
||
where ``@@APP_ENV_NAME@@`` is replaced with an environment friendly name for your app. In this example, that would be: ``EXAMPLE_CLI``. | ||
|
||
We can provide a configuration for JVM options on windows by creating a ``src/universal/EXAMPLE_CLI_config.txt`` file with the following contents :: | ||
|
||
-Xmx512M | ||
-Xms128M | ||
|
||
This will add each line of the file as arguments to the JVM when running your application. | ||
|
||
|
||
Now, if we want to add the typesafe config library again, we need to write the ``config.file`` property into the JVM options again. | ||
|
||
One means of doing this is hooking the ``batScriptExtraDefines`` key. This allows us to insert various BAT settings/commands into the script. Let's use this to hook the config file location, using the other variables in the BASH script. Modify your ``build.sbt`` as follows :: | ||
|
||
batScriptExtraDefines += """set _JAVA_OPTS=%_JAVA_OPTS% -Dconfig.file=%EXAMPLE_CLI_HOME%\\conf\\app.config""" | ||
|
||
Now, the windows version will also load the configuration from the ``conf/`` directory of the package. | ||
|
||
More Complex Scripts | ||
-------------------- | ||
|
||
As you read earlier the ``bashScriptExtraDefines`` sequence allows you to add new lines to the default bash script used to start the application. | ||
This is useful when you need a setting which isn't mean for the command-line parameter list passed to the java process. The lines added to | ||
``bashScriptExtraDefines`` are placed near the end of the script and have access to a number of utility bash functions (e.g. ``addJava``, | ||
``addApp``, ``addResidual``, ``addDebugger``). You can add lines to this script as we did for the Typesage config file above. For more complex | ||
scripts you can also inject a seperate file managed in your source tree or resource directory: :: | ||
|
||
bashScriptExtraDefines ++= IO.readLines(baseDirectory.value / "scripts" / "extra.sh") | ||
|
||
This will add the contents of ``/scripts/extra.sh`` in the resource directory to the bash script. Note you should always concatenate lines | ||
to ``bashScriptExtraDefines`` as other stages in the pipeline may be include linex to the start-script. | ||
|
||
Next, let's :doc:`add some generated files <GeneratingFiles>`. |
Oops, something went wrong.