Adding Custom Stager to Staging Pipeline

This tutorial shows how to append a custom stager to the built-in Ruby staging pipeline. The custom stager is an RSpec test runner that runs a number of RSpec tests once the code been compiled by the built-in stager. If any of the tests fail, the custom stager reports an error to the staging coordinator causing it to fail the staging process.


To complete this tutorial you must first clone the sample-apps repository to your local machine. You will be using the demo-ruby-sinatra sample application included in that repository.

About the Custom Stager

The demo-ruby-sinatra sample application includes a custom stager that executes RSpec tests. It implements the Stager API, an HTTP-based API for communicating with the staging coordinator. It performs the following basic steps:

  • Downloads the application package (source code) from the staging coordinator.
  • Install dependencies (using Bundler) required to run the specs.
  • Executes the rspec tests.
  • Issues an HTTP POST to $STAGER_URL/done if the tests completed successfully, or to $STAGER_URL/failed if there were failures. The $STAGER_URL environment variable is made available to the running stager instance.

Deploy the Custom Stager

Stagers are jobs that run within Apcera like any other job. The first step is to deploy the custom stager using APC.

To deploy the custom Ruby stager:

  1. Open a terminal and navigate to the sample-apps/demo-ruby-sinatra directory.

    Note: You can safely ignore any message about "ruby-1.9.3-p392 is not installed".

  2. Run the following command to create a new stager:

     apc stager create my-rspec-stager --path rspec-stager --start-command ./rspec-stager --additive --allow-egress

    This creates a custom stager named "my-rspec-stager" using the bash script located in the rspec-stager directory, and specifies the command to start the stager. The --allow-egress permits the stager external network access so that it can install required Ruby dependencies. To verify that the custom stager was created, run the following command:

     apc package list

    The summary table list the new stager.


The next step is to append the my-rspec-stager stager to a clone of the pre-built ruby staging pipeline.

Append the Custom Stager

Next you'll create a clone of the built-in Ruby staging pipeline in your own namespace and append the custom stager to it. A staging pipeline is an ordered set of one or more stagers. You can change the order in which stagers run within a staging pipeline by adding one or more stagers to the beginning (prepend) or end (append) of the pipeline.

To append the custom stager to a clone of the Ruby pipeline:

  1. Clone the built-in Ruby staging pipeline to your current namespace:

     apc staging pipeline clone /apcera::ruby

    This command clones the system-provided Ruby staging pipeline to your /sandbox/<user-name>/ namespace. You can verify the cloned staging pipeline exists with the following command:

     apc staging pipeline list
    Working in "/sandbox/tim"
  2. Append the custom stager to your cloned Ruby pipeline:

     apc staging pipeline append ruby my-rspec-stager

    You should see that the ruby staging pipeline is successfully updated. To view the properties of the cloned pipeline run the following command:

     apc staging pipeline show ruby

    The Stagers field displayed in the summary table should list two stagers: the cloned ruby stager and the custom my-rspec-stager.

    Staging Pipeline:ruby
    Created by:tim
    Created at:2015-07-07 23:46:48.468797811 +0000 UTC
    Updated by:tim
    Updated at:2015-07-07 23:48:05.093408341 +0000 UTC

Deploy an Application using the custom Ruby pipeline

Now you're ready to deploy the demo Ruby application using the customized ruby pipeline. First you'll stage the app successfully (with passing tests). Then you'll modify the test spec so it will fail and attempt to re-deploy the application, which fails due to the test failures.

To successfully deploy the application using the custom Ruby pipeline:

  • Still in the demo-ruby-sinatra/ directory, run the following command from a terminal prompt:

      apc app create my-ruby-app --start --staging ruby

    Note that the pipeline is referenced simply by name (without any namespace) since it exists in your current namespace (user/sandbox).

It's useful to look at the output of this command to learn how staging pipelines are processed. First, the staging coordinator loads the ruby pipeline specified on the command line and notices it consists of two stagers (namely, the ruby and my-rspec-stager stagers).

[staging] Beginning staging with 'stagpipe::/sandbox/tim::ruby' pipeline, 2 stager(s) defined.

First, it launches the ruby stager, which compiles the Ruby source provided to APC:

[staging] Launching instance of stager 'ruby'...
[staging] Downloading package for processing...

Once the ruby stager has completed successfully, the appended my-rspec-stager stager is launched. The package contents are downloaded and extracted to the /app folder, dependencies are installed, and finally the tests are run. In this case, all the tests passed and the application is successfully staged as a runnable package.

[staging] Launching instance of stager 'my-rspec-stager'...
[staging] Downloading to /app
[staging] -----> Running bundle install for test dependencies
[staging] Installing diff-lcs 1.2.4
[staging] ...
[staging] -----> Running tests
[staging] ...
[staging] 3 examples, 0 failures
[staging] -----> Rspec tests passed.
[staging] Staging is complete.

Because the --start option was included with the apc app create invocation, the application is immediately provisioned and started.

Creating app "my-ruby-app"... done
Start Command: bundle exec rackup -p
Waiting for the application to start...
App should be accessible at ""

Next you'll "break" the rspec test so it fails, causing the staging process to abort.

To re-deploy the application with a broken rspec test:

  1. Open demo-ruby-sinatra/spec/app_spec.rb and change the expectation at line 14 from last_response.body.should == "Alive" to last_response.body.should == "Dead".

  2. Re-deploy the application:

     apc app deploy my-ruby-app --staging ruby

The command output includes the failure messages from the test runner and, lastly, "Error: Staging has failed." Fix the error you injected into the test case and deploy the app again, which should complete successfully.