Custom Satorix Jobs

Creating custom jobs

In this example we will be creating two custom Satorix jobs to execute during your Satorix CI/CD run. A test for your application and a deployment target. You will need to create the following files in your application root directory.

First we create a satorix/custom.rb file to add your custom jobs to. This file will provide a list of jobs for the Satorix CI/CD application to run. The jobs are broken down into tiers using sub-directories. The first tier describes the stage. Gitlab default stages are build, test, and deploy. The second tier describes the jobs available within each tier and the class they map to. The key should be the actual job name to be used in the .gitlab-ci.yml file. The value should be a Ruby class or module with a go() method.

For example, the available_jobs method below defines two new jobs - one for the deploy stage and one for the test stage. The deploy job is named example_deploy and the test job is named example_test. In this example, the Satorix::CI::Test::ExampleTest#go method will be called by an entry in .gitlab-ci.yml that looks like:

# We are using the Satorix base image from https://hub.docker.com/r/satorix/base/
image: 'satorix/base:18'

.satorix: &satorix
  script:
    - gem install satorix --no-document
    - satorix

example_test:
  stage: test
  <<: *satorix

example_deploy:
  stage: deploy
  only:
    - staging
    - production
  <<: *satorix

The file satorix/custom.rb should contain the follow ruby code:

module Satorix
  module Custom

    # Ensure the files required by the available_jobs method are available.
    require_relative 'CI/deploy/example_deploy.rb'
    require_relative 'CI/test/example_test.rb'


    extend self


    def available_jobs
      {
        deploy: {
          example_deploy: Satorix::CI::Deploy::ExampleDeploy
        },
        test: {
          example_test: Satorix::CI::Test::ExampleTest
        }
      }
    end


  end
end

Now that we have our custom jobs defined we can start to create the actual jobs themselves. First we will create the satorix/CI/deploy/example_deploy.rb file to define our custom deploy job.

module Satorix
  module CI
    module Deploy
      module ExampleDeploy

        # Satorix built in terminal module
        include Satorix::Shared::Console


        extend self


        def go
          log_bench('Atomic batteries to power...') { batnap }
          log_bench('Turbines to speed...') { turbines_to_speed }
          log_bench('Moving out...') { batnap }
        end


        def skip_buildpack
          # Change to `false` below if you want to execute in the context of the app's buildpack environment.
          true
        end


        private ########################################################################################################


        def turbines_to_speed
          batnap
          puts 'Roger. Ready to move out.'
        end


        def batnap
          sleep(rand(6))
        end


      end
    end
  end
end

Next we will create the satorix/CI/test/example_test.rb file to define our custom test job.

module Satorix
  module CI
    module Test
      module ExampleTest


        include Satorix::Shared::Console


        extend self

        # go() is the method that will be called during the CI run.
        # You can add your own logic to do whatever you want.
        def go

          log_bench('Describing logging...') do
            describe_log
            describe_log_error
            describe_log_error_and_abort
          end

          log_bench('Describing console commands...') do
            describe_run_command_string
            describe_run_command_array
            describe_run_command_filtered
            describe_run_command_quiet
            describe_run_command_with_error
          end

          log_bench('Describing environment variables...') { describe_environment_variables }
        end


        def skip_buildpack
          # Change to `false` below if you want to execute in the context of the app's buildpack environment.
          false
        end


        private ########################################################################################################


        def describe_environment_variables
          puts "Remember, #{ ENV['GITLAB_USER_EMAIL'] }, that you have access to all of the environment variables ",
               ' described at https://docs.gitlab.com/ce/ci/variables/#predefined-variables-environment-variables'
        end


        def describe_log
          log 'The log() method writes a message to the log'
          colors.keys.each { |color| log "You can provide an optional color, like :#{ color }", color }
        end


        def describe_log_error
          log_error 'The log_error() method writes an error to the log'
        end


        def describe_log_error_and_abort
          log_error 'The log_error_and_abort() method writes an error to the log and aborts the job'
        rescue SystemExit => e
          puts 'Rescuing from the error, to continue the tutorial.',
               e.inspect
        end


        def describe_run_command_string
          run_command "echo 'We can safely run string console commands with the run_command() method'"
        end


        def describe_run_command_array
          run_command ['echo', "'We can safely run array console commands with the run_command() method'"]
        end


        def describe_run_command_quiet
          run_command "echo 'This will not be displayed'", quiet: true
        end


        def describe_run_command_filtered
          run_command "echo 'You can filter secrets, like 1234 and 5678 (unless you explicitly display them)'", filtered_text: %w(1234 5678)
        end


        def describe_run_command_with_error
          run_command 'false'
        rescue SystemExit
          puts 'Commands that exit with a non-zero return code abort operation, unless rescued.',
               'Rescuing from the error, to continue the tutorial.',
               e.inspect
        end


      end
    end
  end
end

Job methods

In addition to the standard Ruby methods there are a variety of Satorix supplied methods you can use in your custom job.

Logging methods

The following methods can be used to log output.

log 'text', color:

The log() method writes a message to the log. You can provide an optional color from the list below.

  • red:
  • light_red:
  • green:
  • light_green:
  • yellow:
  • light_yellow:
  • blue:
  • light_blue:
  • magenta:
  • light_magenta:
  • cyan:
  • light_cyan:
  • white:
  • light_white:

log_bench('Message...') { ruby_method }

Used to show elapsed time for the Ruby method being performed. Often used with the run_command() method to document how long a task takes to complete.
Example: log_bench('Displaying current Ruby version...') { run_command 'ruby -v' }.

log_error 'Error text'

The log_error() method writes an error to the log.

log_error_and_abort 'Error text'

The log_error_and_abort() method writes an error to the log and aborts the job.

Console methods

Methods used to safely run console commands in your job.

run_command 'command -options', quiet: true,false, filtered_text: %w(secret1 secret2)

You can run console commands with the run_command() method by supplying a string or by using an array instead (run_command ['command', '-options']). The quiet: option will silence all out from the command. You can filter secrets, like “secret1” and “secret2” using the filtered_text: option and supplying an array of text to not display.

If a command exits with a non-zero return code it will abort your job unless you rescue it.
For example:

def describe_run_command_with_error
    run_command 'false'
rescue SystemExit
    puts 'Commands that exit with a non-zero return code abort operation, unless rescued.',
         'Rescuing from the error, to continue the example.',
         e.inspect
end

Satorix buildpack environment

By default your custom jobs will execute within a buildpack environment built for your application just as if you were running your application on the Satorix Hosting Cluster. Satorix will create a buildpack environment for your job and execute any commands within that environment.

When you run your custom jobs you have the option to skip building an execution environment using a buildpack for your application. If you specify true with the skip_buildpack method Satorix will not create a buildpack environment for your job and any commands you run will be in a directory of your checked out code.

How to disable buildpacks

To disable you just have to add a method to your job after your go() method:

def skip_buildpack
    # Change to `false` below if you want to execute in the context of the app's buildpack environment.
    true
end

Directory methods

There are some methods to assist with directory locations for your buildpack environment.

Satorix.build_dir

This is the directory where your code is initially checked out and the build is performed from. The same as the CI_PROJECT_DIR Gitlab environment variable. You should only use this location if you are skipping the buildpack step. Once a buildpack creates an environment the Satorix.app_dir is where all following executions occur.

Satorix.app_dir

Once your application is built with the selected buildpack this is the directory that it can be found in.

Satorix.bin_dir

A location to tell programs to install a binary to. This directory is in the PATH of the user context that is executed. It is found at Satorix.app_dir/bin