Add a deploy lock for commands that are unsafe to run concurrently.
The lock is taken by creating a `mrsk_lock` directory on the primary
host. Details of who took the lock are added to a details file in that
directory.
Additional CLI commands have been added to manual release and acquire
the lock and to check its status.
```
Commands:
mrsk lock acquire -m, --message=MESSAGE # Acquire the deploy lock
mrsk lock help [COMMAND] # Describe subcommands or one specific subcommand
mrsk lock release # Release the deploy lock
mrsk lock status # Report lock status
Options:
-v, [--verbose], [--no-verbose] # Detailed logging
-q, [--quiet], [--no-quiet] # Minimal logging
[--version=VERSION] # Run commands against a specific app version
-p, [--primary], [--no-primary] # Run commands only on primary host instead of all
-h, [--hosts=HOSTS] # Run commands on these hosts instead of all (separate by comma)
-r, [--roles=ROLES] # Run commands on these roles instead of all (separate by comma)
-c, [--config-file=CONFIG_FILE] # Path to config file
# Default: config/deploy.yml
-d, [--destination=DESTINATION] # Specify destination to be used for config file (staging -> deploy.staging.yml)
-B, [--skip-broadcast], [--no-skip-broadcast] # Skip audit broadcasts
```
If we add support for running multiple deployments on a single server
we'll need to extend the locking to lock per deployment.
34 lines
913 B
Ruby
34 lines
913 B
Ruby
require "test_helper"
|
|
|
|
class CommandsLockTest < ActiveSupport::TestCase
|
|
setup do
|
|
@config = {
|
|
service: "app", image: "dhh/app", registry: { "username" => "dhh", "password" => "secret" }, servers: [ "1.1.1.1" ],
|
|
traefik: { "args" => { "accesslog.format" => "json", "metrics.prometheus.buckets" => "0.1,0.3,1.2,5.0" } }
|
|
}
|
|
end
|
|
|
|
test "status" do
|
|
assert_equal \
|
|
"stat mrsk_lock > /dev/null && cat mrsk_lock/details | base64 -d",
|
|
new_command.status.join(" ")
|
|
end
|
|
|
|
test "acquire" do
|
|
assert_match \
|
|
/mkdir mrsk_lock && echo ".*" > mrsk_lock\/details/m,
|
|
new_command.acquire("Hello", "123").join(" ")
|
|
end
|
|
|
|
test "release" do
|
|
assert_match \
|
|
"rm mrsk_lock/details && rm -r mrsk_lock",
|
|
new_command.release.join(" ")
|
|
end
|
|
|
|
private
|
|
def new_command
|
|
Mrsk::Commands::Lock.new(Mrsk::Configuration.new(@config, version: "123"))
|
|
end
|
|
end
|