GitLab SWAT
A Successful Deployment Ends Peacefully With No Bullets Fired. If That’s Simply Not Possible, SWAT Uses Special Weapons and Tactics to Keep the Public Safe
Defining ~~Weapons~~ Scripts
A script should only contain one class with the following structure
module Swat
#
# Command to use when calling the script file, it has to respect the module and class name
# because it will be imported from rails and called by name
#
class Command < BaseCommand
def prepare(context)
fail "I need at least 1 argument" if @args.empty?
context[:some_key] = "something"
"text to add to the prepare stage result"
end
def pre_check(context)
fail "something is not right" unless context[:some_key] == "something"
"text to add to the pre_check stage result"
end
def execute(context)
fail "execution failed!" if context.empty?
"Context so far is #{context}"
end
end
end
Execution Stages
- prepare: initial stage, used to parse arguments, or whatever is necessary before getting into the pre_check stage.
- pre_check: stage used to validate that the command should continue to the execute stage if it is running in execute mode. Dryrun would only reach this stage.
- execute: the actual operation.
Any stage that raises an exception will stop the execution, and will force and early return with a failure state and the different messages from the executed phases.
Available tools
@args
the arguments tha are sent from the execution and reach the command, simply a string array.context
a hashmap that is created before the prepare stage and is sent to all methods, use this to accumulate state across stages.
Configuring in cog
Environment variables
- SCRIPTS_REMOTE_URL url pointing to the remote repository
- SCRIPTS_LOCAL_PATH folder where the remote repository will be downloaded to
- RAILS_RUNNER_COMMAND command used to run rails, for example: rails runner ./scripts/lib/swat_run.rb
- RAILS_WORKING_DIR working dir in which to execute the rails runner command
Cog Commands
dryrun <script> [args]
executes the given script with arguments in dryrun modestrike <script> [args]
executes the given script with arguments in execute modereload [-f]
clones or pulls the scripts repo, use -f to wipe the repo and clone it from scratch
Development
How to run integration tests
Dry Run Mode
$ SCRIPTS_LOCAL_PATH=/home/user/src/gitlab.com/gitlab-cog/swat/scripts RAILS_RUNNER_COMMAND="rails r /home/user/src/gitlab.com/gitlab-cog/swat/lib/swat_run.rb" RAILS_WORKING_DIR=/home/user/src/gitlab.com/gitlab-cog/rails-project COG_COMMAND="dryrun" COG_ARGV_0="test" COG_ARGV_1="success" COG_ARGV_2="success" COG_ARGC=3 ./cog-command
COG_TEMPLATE: execution_result
JSON
{"execution_mode":"dryrun","prepare":{"successful":true,"output":"preparation is fine so far"},"pre_check":{"successful":true,"output":"all is gut"}}
Strike Mode
$ SCRIPTS_LOCAL_PATH=/home/user/src/gitlab.com/gitlab-cog/swat/scripts RAILS_RUNNER_COMMAND="rails r /home/user/src/gitlab.com/gitlab-cog/swat/lib/swat_run.rb" RAILS_WORKING_DIR=/home/user/src/gitlab.com/gitlab-cog/rails-project COG_COMMAND="strike" COG_ARGV_0="test" COG_ARGV_1="success" COG_ARGV_2="success" COG_ARGC=3 ./cog-command
COG_TEMPLATE: execution_result
JSON
{"execution_mode":"execute","prepare":{"successful":true,"output":"preparation is fine so far"},"pre_check":{"successful":true,"output":"all is gut"},"execute":{"successful":true,"output":"Context so far is {:prepared=\u003e\"done\", :checks=\u003e\"done\"}"}}
Reload command
$ SCRIPTS_LOCAL_PATH=/tmp/testing-cog/second SCRIPTS_REMOTE_URL=$(pwd) COG_COMMAND="reload" ./cog-command
JSON
{"source":"/home/user/src/gitlab.com/gitlab-cog/swat","target":"/tmp/testing-cog/scripts","action":"clone","wiped":false, "head":"1234 current commit"}
$ SCRIPTS_LOCAL_PATH=/tmp/testing-cog/second SCRIPTS_REMOTE_URL=$(pwd) COG_COMMAND="reload" ./cog-command
JSON
{"source":"/home/user/src/gitlab.com/gitlab-cog/swat","target":"/tmp/testing-cog/scripts","action":"pull","wiped":false, "head":"1234 current commit"}
$ SCRIPTS_LOCAL_PATH=/tmp/testing-cog/second SCRIPTS_REMOTE_URL=$(pwd) COG_COMMAND="reload" COG_OPTS=wipe COG_OPT_WIPE=true ./cog-command
JSON
{"source":"/home/user/src/gitlab.com/gitlab-cog/swat","target":"/tmp/testing-cog/scripts","action":"clone","wiped":true, "head":"1234 current commit"}