jeremyrsmith / sbt-csd-packager

SBT plugin for creating Custom Service Descriptors

Version Matrix


Sbt-csd-packager is an SBT plugin for packaging Custom Service Descriptors for Cloudera Manager.

The eventual goal of sbt-csd-packager is to be able to generate most, if not all, of the CSD from the source of the application. But currently, it is much more limited. You can create the CSD by hand, and sbt-csd-packager will perform some (limited) validation of your service.sdl. Read the CSD documentation to get started. Alternatively, you can define service.sdl using SBT settings and the provided ADT.

The current value of sbt-csd-packager comes mostly from the ability to deploy CSD artifacts using publish. This is useful for not only publishing CSDs that include Scala programs, but also for creating SDLC around CSDs that don't necessarily contain Scala programs or other executables (besides shell scripts or other scripts).


To include the plugin, add the following to project/plugins.sbt:

addSbtPlugin("io.github.jeremyrsmith" % "sbt-csd-packager" % "0.1.5")

Creating a CSD

  1. Create a directory src/main/csd
  2. Create a directory src/main/csd/scripts and add your CSD scripts
  3. Define your service.sdl:
    1. To create the service.sdl by hand:
      1. Create a directory src/main/csd/descriptor
      2. Create the file service.sdl in that directory and define the service
    2. To create the service.sdl using SBT settings:
      1. Set csdGenerateSdl := true in build.sbt
      2. Use settings described under SBT Settings to build the service descriptor. It will be written out to service.sdl when the csd package task is run.

Adding other artifacts

You may want to include your main artifact in your CSD so that it can be executed by your driver scripts. Typically, artifacts will be included in a parcel rather than a CSD; particularly if the artifact is large, as large CSDs can cause problems with Cloudera Manager. Therefore, no artifacts are included in the CSD by default.

An artifact can be included using the csdIncludeArtifact task. If you want to include your main build artifact, use:

csdIncludeArtifact <<= sbt.Keys.`package`.map(pf => Some(pf ->

If I'm using the [sbt-assembly]( plugin, and I want to include the assembled JAR instead of the main build artifact (this is highly discouraged; again, you should use parcels for this):

csdIncludeArtifact := Some((assembly in Compile).value -> (assembly in Compile)

This will cause:

  1. The csd task to depend on the assembly task
  2. The assembly JAR to be included (in the scripts/ directory) using its original filename.

You might want to override the filename of the included artifact - for example, so you can refer to it with a stable filename in your driver scripts. csdIncludeArtifact is an optional tuple (File, String) - the File will be included in the scripts directory with the String filename. For example:

csdIncludeArtifact := Some((assembly in Compile).value -> "my-service.jar")

This will include the assembly JAR (instead of the package JAR) under scripts/ with the stable filename my-service.jar.

Publishing a CSD

As long as the SDL is defined correctly, the CSD will be published with the main publish task:

sbt publish

The artifact generated by csd will be published along with the other artifacts of your build. The CSD artifact will have the csd classifier.

If your deploy process uses Ivy to fetch CSD artifacts, you'll have to set:

publishMavenStyle := false

to use an Ivy repository rather than a Maven repository. This is because Ivy won't recognize the csd classifier in a Maven repository.

Building the CSD without publishing

A csd task is included which builds the CSD:

sbt csd

SBT Settings

Base Settings

The following settings are available directly in build.sbt. They control things about the CSD itself:

csdAddScripts : Seq[(File, String)]

This is actually a Task rather than a Setting, so that it can depend on other tasks (like package or assembly). Each File key referenced will be added to the scripts/ directory of the CSD using the String value as its filename.

Default: Include the artifact created by package with its original filename.

csdAddAux : Seq[(File, String)]

Like csdAddScripts above, except files are added to the aux/ directory of the CSD.

csdRoot : File

The base directory for the CSD source. This can be overridden to use a different directory from the default.

Default: (sourceDirectory in Compile).value / "csd" (typically src/main/csd)

csdClassifier : String

The classifier that will be attached to the CSD artifact upon publishing

Default: csd

csdGenerateSdl : Boolean

Whether to generate a service.sdl from SBT settings rather than using an existing descriptor/service.sdl file in the csdRoot. See the following section for more details.

Default: false

SDL Generation Settings

These settings are included under the csdSettings namespace. To use them, you can either prefix them with csdSettings., or import them with import csdSettings._. Many of these settings use the ADT from csd-base; see that project for documentation.

csdName : String

The name of the service.

Default: The name of the build

csdVersion : String

The version of the service.

Default: The version of the build

csdDescription : String

A description of the service.

Default: The description of the build

runAs : csdbase.UserGroup

The user and group that the service will run as.

Default: UserGroup(user = "nobody", group = "nobody")

serviceInit : Option[csdbase.ServiceInit]

Service commands to run when the service is initialized.

Default: `None``

inExpressWizard : Boolean

Whether the service should show up in Cloudera Manager's Express Wizard

Default: false

maxInstances : Option[Int]

The maximum number of instances of the service in a cluster

Default: None

icon : Option[String]

The path (relative to the CSD) of an icon to use for the service in Cloudera Manager. If specified, it should be a 16x16 PNG. If not specified, a default icon is used.

Default: None

compatibility: Option[csdbase.Compatibility]

Specifier for compatibility with other versions of the service, as well as with CDH.

Default: None


There are several other settings to be described. Take a look at Plugin.scala to see the rest.