mrsk 0.8.1 → 0.8.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a560b5048509237f8c8440a41b35d674915ac493bcf0176256b1006a6aef004
4
- data.tar.gz: d69f0682c43e62fd0574d626456bcb62452ec972b8dd1182b1780958a65aadbd
3
+ metadata.gz: 1a99fc249415cbefb3b4fd405f26cfd85b7bcb8ad1bf8cdba11c62210ae66895
4
+ data.tar.gz: c8acc173b4b3f721559c92319ccc9691fd436a082d79fe25f7ac9375e5baaf2e
5
5
  SHA512:
6
- metadata.gz: d670dd54f94d64b2e35f5082f3a5cd78100780b0e0c5d51d050dc25f00ca4cdca26d0a4d797c01860d04205a2cd0fa4285089a944f72977d287e1c6fd313845e
7
- data.tar.gz: 6d28b436a2a0d33da1e32af340e5cd80972b57b946b6b51ec6481b5c832020867075ac53f24dd53f0d86e0d1738a78fb233986530a4ad0d9be1e83e73136522b
6
+ metadata.gz: 97d9b4cf8ab9fe6adfe684f537b40b901a0572e85a36aa752e86412e367976e963c9b417e48215d0b5e1025ed0649f8026ecbaf7c21024987291b842f34d2461
7
+ data.tar.gz: 1f8534b40d85e1d63a1979781411e4755aef9596403da9fbc5007e7c7935939b68bd4cc7c258231ae808fe9e1ec179486fc3b25962d577852cccb4ef45dc44e6
data/README.md CHANGED
@@ -498,7 +498,7 @@ If you wish to remove the entire application, including Traefik, containers, ima
498
498
 
499
499
  ## Stage of development
500
500
 
501
- This is alpha software. Lots of stuff is missing. Lots of stuff will keep moving around for a while.
501
+ This is beta software. Commands may still move around. But we're live in production at [37signals](https://37signals.com).
502
502
 
503
503
  ## License
504
504
 
@@ -13,7 +13,7 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base
13
13
  execute *accessory.run
14
14
  end
15
15
 
16
- audit_broadcast "Booted accessory #{name}"
16
+ audit_broadcast "Booted accessory #{name}" unless options[:skip_broadcast]
17
17
  end
18
18
  end
19
19
  end
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
- execute *MRSK.app.stop, raise_on_non_zero_exit: false
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
@@ -1,5 +1,7 @@
1
1
  class Mrsk::Cli::Healthcheck < Mrsk::Cli::Base
2
- MAX_ATTEMPTS = 5
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 "Stop current version, then start version #{version}...", :magenta
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
- execute *MRSK.app.stop, raise_on_non_zero_exit: false
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
@@ -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 current_container_id, xargs(docker(:stop))
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" => "3",
64
+ "traefik.http.middlewares.#{config.service}.retry.attempts" => "5",
65
65
  "traefik.http.middlewares.#{config.service}.retry.initialinterval" => "500ms"
66
66
  }
67
67
  else
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Mrsk
2
- VERSION = "0.8.1"
2
+ VERSION = "0.8.2"
3
3
  end
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.1
4
+ version: 0.8.2
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-20 00:00:00.000000000 Z
11
+ date: 2023-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport