mrsk 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -1
- data/lib/mrsk/cli/accessory.rb +1 -1
- data/lib/mrsk/cli/app.rb +11 -2
- data/lib/mrsk/cli/base.rb +2 -0
- data/lib/mrsk/cli/healthcheck.rb +5 -3
- data/lib/mrsk/cli/main.rb +14 -6
- data/lib/mrsk/commands/app.rb +8 -2
- data/lib/mrsk/configuration/role.rb +1 -1
- data/lib/mrsk/configuration.rb +3 -0
- data/lib/mrsk/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0065b91bb3c00ef0ef6db78eb605d8db5df3606ccf97be15bb059ab1985231d5
|
4
|
+
data.tar.gz: 2ed2b0c6235ea398bc5717aebf99e2a4f1e6c9434c64da5eed6d8899b0ca335e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c00ed2e4693b62e0eeb238c17d4c17b3e06ed03ed580aea7ca724a4629c28274d77bc31fa63ca1d1e5f07b1f73e6b2ecc164a076d2ad5307b7e30625cea2ee7a
|
7
|
+
data.tar.gz: ee273834e9e330640ef6b55acc4dabeeef6c4e9178112351376c3ab1e23afeb9fa389a08b6cf5a8c3bbaafc079d7cabc98d316fd08030a8886c12d5020a68653
|
data/README.md
CHANGED
@@ -330,6 +330,21 @@ accessories:
|
|
330
330
|
|
331
331
|
Now run `mrsk accessory start mysql` to start the MySQL server on 1.1.1.3. See `mrsk accessory` for all the commands possible.
|
332
332
|
|
333
|
+
### Using Cron
|
334
|
+
|
335
|
+
You can use a specific container to run your Cron jobs:
|
336
|
+
|
337
|
+
```yaml
|
338
|
+
servers:
|
339
|
+
cron:
|
340
|
+
hosts:
|
341
|
+
- 192.168.0.1
|
342
|
+
cmd:
|
343
|
+
bash -c "cat config/crontab | crontab - && cron -f"
|
344
|
+
```
|
345
|
+
|
346
|
+
This assumes the Cron settings are stored in `config/crontab`.
|
347
|
+
|
333
348
|
### Using a generated .env file
|
334
349
|
|
335
350
|
If you're using a centralized secret store, like 1Password, you can create `.env.erb` as a template which looks up the secrets. Example of a .env.erb file:
|
@@ -498,7 +513,7 @@ If you wish to remove the entire application, including Traefik, containers, ima
|
|
498
513
|
|
499
514
|
## Stage of development
|
500
515
|
|
501
|
-
This is
|
516
|
+
This is beta software. Commands may still move around. But we're live in production at [37signals](https://37signals.com).
|
502
517
|
|
503
518
|
## License
|
504
519
|
|
data/lib/mrsk/cli/accessory.rb
CHANGED
data/lib/mrsk/cli/app.rb
CHANGED
@@ -5,18 +5,27 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|
5
5
|
using_version(options[:version] || most_recent_version_available) do |version|
|
6
6
|
say "Start container with version #{version} (or reboot if already running)...", :magenta
|
7
7
|
|
8
|
+
cli = self
|
9
|
+
|
8
10
|
MRSK.config.roles.each do |role|
|
9
11
|
on(role.hosts) do |host|
|
10
12
|
execute *MRSK.auditor.record("Booted app version #{version}"), verbosity: :debug
|
11
13
|
|
12
14
|
begin
|
13
|
-
|
15
|
+
old_version = capture_with_info(*MRSK.app.current_running_version).strip
|
14
16
|
execute *MRSK.app.run(role: role.name)
|
17
|
+
|
18
|
+
cli.say "Waiting #{MRSK.config.readiness_delay}s for app to boot...", :magenta
|
19
|
+
sleep MRSK.config.readiness_delay
|
20
|
+
|
21
|
+
execute *MRSK.app.stop(version: old_version), raise_on_non_zero_exit: false if old_version.present?
|
22
|
+
|
15
23
|
rescue SSHKit::Command::Failed => e
|
16
24
|
if e.message =~ /already in use/
|
17
|
-
error "Rebooting container with same version already deployed on #{host}"
|
25
|
+
error "Rebooting container with same version #{version} already deployed on #{host} (may cause gap in zero-downtime promise!)"
|
18
26
|
execute *MRSK.auditor.record("Rebooted app version #{version}"), verbosity: :debug
|
19
27
|
|
28
|
+
execute *MRSK.app.stop(version: version)
|
20
29
|
execute *MRSK.app.remove_container(version: version)
|
21
30
|
execute *MRSK.app.run(role: role.name)
|
22
31
|
else
|
data/lib/mrsk/cli/base.rb
CHANGED
@@ -20,6 +20,8 @@ module Mrsk::Cli
|
|
20
20
|
class_option :config_file, aliases: "-c", default: "config/deploy.yml", desc: "Path to config file"
|
21
21
|
class_option :destination, aliases: "-d", desc: "Specify destination to be used for config file (staging -> deploy.staging.yml)"
|
22
22
|
|
23
|
+
class_option :skip_broadcast, aliases: "-B", type: :boolean, default: false, desc: "Skip audit broadcasts"
|
24
|
+
|
23
25
|
def initialize(*)
|
24
26
|
super
|
25
27
|
load_envs
|
data/lib/mrsk/cli/healthcheck.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
class Mrsk::Cli::Healthcheck < Mrsk::Cli::Base
|
2
|
-
MAX_ATTEMPTS =
|
2
|
+
MAX_ATTEMPTS = 7
|
3
|
+
|
4
|
+
class HealthcheckError < StandardError; end
|
3
5
|
|
4
6
|
default_command :perform
|
5
7
|
|
@@ -18,7 +20,7 @@ class Mrsk::Cli::Healthcheck < Mrsk::Cli::Base
|
|
18
20
|
if status == "200"
|
19
21
|
info "#{target} succeeded with 200 OK!"
|
20
22
|
else
|
21
|
-
raise "#{target} failed with status #{status}"
|
23
|
+
raise HealthcheckError, "#{target} failed with status #{status}"
|
22
24
|
end
|
23
25
|
rescue SSHKit::Command::Failed
|
24
26
|
if attempt <= MAX_ATTEMPTS
|
@@ -31,7 +33,7 @@ class Mrsk::Cli::Healthcheck < Mrsk::Cli::Base
|
|
31
33
|
raise
|
32
34
|
end
|
33
35
|
end
|
34
|
-
rescue SSHKit::Command::Failed => e
|
36
|
+
rescue SSHKit::Command::Failed, HealthcheckError => e
|
35
37
|
error capture_with_info(*MRSK.healthcheck.logs)
|
36
38
|
|
37
39
|
if e.message =~ /curl/
|
data/lib/mrsk/cli/main.rb
CHANGED
@@ -32,7 +32,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
|
32
32
|
invoke "mrsk:cli:prune:all"
|
33
33
|
end
|
34
34
|
|
35
|
-
audit_broadcast "Deployed app in #{runtime.to_i} seconds"
|
35
|
+
audit_broadcast "Deployed app in #{runtime.to_i} seconds" unless options[:skip_broadcast]
|
36
36
|
end
|
37
37
|
|
38
38
|
desc "redeploy", "Deploy app to servers without bootstrapping servers, starting Traefik, pruning, and registry login"
|
@@ -47,7 +47,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
|
47
47
|
invoke "mrsk:cli:app:boot"
|
48
48
|
end
|
49
49
|
|
50
|
-
audit_broadcast "Redeployed app in #{runtime.to_i} seconds"
|
50
|
+
audit_broadcast "Redeployed app in #{runtime.to_i} seconds" unless options[:skip_broadcast]
|
51
51
|
end
|
52
52
|
|
53
53
|
desc "rollback [VERSION]", "Rollback app to VERSION"
|
@@ -55,14 +55,22 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
|
55
55
|
MRSK.version = version
|
56
56
|
|
57
57
|
if container_name_available?(MRSK.config.service_with_version)
|
58
|
-
say "
|
58
|
+
say "Start version #{version}, then stop the old version...", :magenta
|
59
|
+
|
60
|
+
cli = self
|
59
61
|
|
60
62
|
on(MRSK.hosts) do |host|
|
61
|
-
|
63
|
+
old_version = capture_with_info(*MRSK.app.current_running_version).strip.presence
|
64
|
+
|
62
65
|
execute *MRSK.app.start
|
66
|
+
|
67
|
+
cli.say "Waiting #{MRSK.config.readiness_delay}s for app to start...", :magenta
|
68
|
+
sleep MRSK.config.readiness_delay
|
69
|
+
|
70
|
+
execute *MRSK.app.stop(version: old_version), raise_on_non_zero_exit: false
|
63
71
|
end
|
64
72
|
|
65
|
-
audit_broadcast "Rolled back app to version #{version}"
|
73
|
+
audit_broadcast "Rolled back app to version #{version}" unless options[:skip_broadcast]
|
66
74
|
else
|
67
75
|
say "The app version '#{version}' is not available as a container (use 'mrsk app containers' for available versions)", :red
|
68
76
|
end
|
@@ -138,7 +146,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
|
138
146
|
if options[:confirmed] || ask(remove_confirmation_question, limited_to: %w( y N ), default: "N") == "y"
|
139
147
|
invoke "mrsk:cli:traefik:remove", [], options.without(:confirmed)
|
140
148
|
invoke "mrsk:cli:app:remove", [], options.without(:confirmed)
|
141
|
-
invoke "mrsk:cli:accessory:remove", [ "all" ]
|
149
|
+
invoke "mrsk:cli:accessory:remove", [ "all" ], options
|
142
150
|
invoke "mrsk:cli:registry:logout", [], options.without(:confirmed)
|
143
151
|
end
|
144
152
|
end
|
data/lib/mrsk/commands/app.rb
CHANGED
@@ -18,8 +18,10 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|
18
18
|
docker :start, service_with_version
|
19
19
|
end
|
20
20
|
|
21
|
-
def stop
|
22
|
-
pipe
|
21
|
+
def stop(version: nil)
|
22
|
+
pipe \
|
23
|
+
version ? container_id_for_version(version) : current_container_id,
|
24
|
+
xargs(docker(:stop))
|
23
25
|
end
|
24
26
|
|
25
27
|
def info
|
@@ -132,6 +134,10 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|
132
134
|
end
|
133
135
|
end
|
134
136
|
|
137
|
+
def container_id_for_version(version)
|
138
|
+
container_id_for(container_name: service_with_version(version))
|
139
|
+
end
|
140
|
+
|
135
141
|
def service_filter
|
136
142
|
[ "--filter", "label=service=#{config.service}" ]
|
137
143
|
end
|
@@ -61,7 +61,7 @@ class Mrsk::Configuration::Role
|
|
61
61
|
"traefik.http.routers.#{config.service}.rule" => "PathPrefix(`/`)",
|
62
62
|
"traefik.http.services.#{config.service}.loadbalancer.healthcheck.path" => config.healthcheck["path"],
|
63
63
|
"traefik.http.services.#{config.service}.loadbalancer.healthcheck.interval" => "1s",
|
64
|
-
"traefik.http.middlewares.#{config.service}.retry.attempts" => "
|
64
|
+
"traefik.http.middlewares.#{config.service}.retry.attempts" => "5",
|
65
65
|
"traefik.http.middlewares.#{config.service}.retry.initialinterval" => "500ms"
|
66
66
|
}
|
67
67
|
else
|
data/lib/mrsk/configuration.rb
CHANGED
@@ -136,6 +136,9 @@ class Mrsk::Configuration
|
|
136
136
|
{ "path" => "/up", "port" => 3000 }.merge(raw_config.healthcheck || {})
|
137
137
|
end
|
138
138
|
|
139
|
+
def readiness_delay
|
140
|
+
raw_config.readiness_delay || 7
|
141
|
+
end
|
139
142
|
|
140
143
|
def valid?
|
141
144
|
ensure_required_keys_present && ensure_env_available
|
data/lib/mrsk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mrsk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|