mrsk 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d76643b4635191a3301d23e41f5f4c18ca0db674c44d66b98610df0279c85c66
4
- data.tar.gz: cd19d1ed503529b6876232d88f5133f782ddfca7f16e13d781120ed269e155d4
3
+ metadata.gz: 8bb523ac89ed682e739e8312da6ee60bc45baace7f1d3b836d3fb62b9c75539f
4
+ data.tar.gz: 5f3552e54648aa2f0c7c795b921c0523a3deca6aeb22d5bd2fa6901dec169e33
5
5
  SHA512:
6
- metadata.gz: f3fc1e47cc35077797dbcc366924c470d877f3f7980ba3b0c87c1dcd4230eb563f4b478a6ee1dfe48cf07c1ae1373d2f746dbd9433c494fd20bfd64a6096058b
7
- data.tar.gz: 4c6c4875c4f91712b6dd2fbeeb0c662c45aaf373508a9696a2cf47cd7d9a2fe486774f9b2897c9416dc9bb7f1dcb6890a5be3ef781654e264792c0858beb9f6c
6
+ metadata.gz: afd16123f8681337a1f30c0908221b96c8e9540485126f20a63741ed524bd9f282cc7bdaa1aad50f61f68887f7fe1176435f5dd2f58605780de2866ee141c40c
7
+ data.tar.gz: e40f284df37ec58990c4a2e2ebd8765641eb797fb83abeed8d02aa857dd40a079793a62c5c98bfe3204c9bddeb8ebf1e2a33dde09cf337050cb4283eb05485df
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # MRSK
2
2
 
3
- MRSK deploys Rails apps in containers to servers running Docker with zero downtime. It uses the dynamic reverse-proxy Traefik to hold requests while the new application container is started and the old one is stopped. It works seamlessly across multiple hosts, using SSHKit to execute commands.
3
+ MRSK deploys web apps in containers to servers running Docker with zero downtime. It uses the dynamic reverse-proxy Traefik to hold requests while the new application container is started and the old one is stopped. It works seamlessly across multiple hosts, using SSHKit to execute commands.
4
4
 
5
5
  ## Installation
6
6
 
7
- Install MRSK globally with `gem install mrsk`. Then, inside your app directory, run `mrsk install`. Now edit the new file `config/deploy.yml`. It could look as simple as this:
7
+ Install MRSK globally with `gem install mrsk`. Then, inside your app directory, run `mrsk init` (or `mrsk init --bundle` within Rails apps where you want a bin/mrsk binstub). Now edit the new file `config/deploy.yml`. It could look as simple as this:
8
8
 
9
9
  ```yaml
10
10
  service: hey
@@ -15,12 +15,17 @@ servers:
15
15
  registry:
16
16
  username: registry-user-name
17
17
  password: <%= ENV.fetch("MRSK_REGISTRY_PASSWORD") %>
18
+ env:
19
+ secret:
20
+ - RAILS_MASTER_KEY
18
21
  ```
19
22
 
20
- Now you're ready to deploy a multi-arch image to the servers:
23
+ Then edit your `.env` file to add your registry password as `MRSK_REGISTRY_PASSWORD` (and your `RAILS_MASTER_KEY` for production with a Rails app).
24
+
25
+ Now you're ready to deploy to the servers:
21
26
 
22
27
  ```
23
- MRSK_REGISTRY_PASSWORD=pw mrsk deploy
28
+ mrsk deploy
24
29
  ```
25
30
 
26
31
  This will:
@@ -68,10 +73,27 @@ registry:
68
73
 
69
74
  ### Using a different SSH user than root
70
75
 
71
- The default SSH user is root, but you can change it using `ssh_user`:
76
+ The default SSH user is root, but you can change it using `ssh/user`:
77
+
78
+ ```yaml
79
+ ssh:
80
+ user: app
81
+ ```
82
+
83
+ ### Using a proxy SSH host
84
+
85
+ If you need to connect to server through a proxy host, you can use `ssh/proxy`:
86
+
87
+ ```yaml
88
+ ssh:
89
+ proxy: "192.168.0.1" # defaults to root as the user
90
+ ```
91
+
92
+ Or with specific user:
72
93
 
73
94
  ```yaml
74
- ssh_user: app
95
+ ssh:
96
+ proxy: "app@192.168.0.1"
75
97
  ```
76
98
 
77
99
  ### Using env variables
@@ -265,14 +287,6 @@ ARG RUBY_VERSION
265
287
  FROM ruby:$RUBY_VERSION-slim as base
266
288
  ```
267
289
 
268
- ### Using without RAILS_MASTER_KEY
269
-
270
- If you're using MRSK with older Rails apps that predate RAILS_MASTER_KEY, or with a non-Rails app, you can skip the default usage and reference:
271
-
272
- ```yaml
273
- skip_master_key: true
274
- ```
275
-
276
290
  ### Using accessories for database, cache, search services
277
291
 
278
292
  You can manage your accessory services via MRSK as well. The services will build off public images, and will not be automatically updated when you deploy:
@@ -300,6 +314,23 @@ accessories:
300
314
 
301
315
  Now run `mrsk accessory start mysql` to start the MySQL server on 1.1.1.3. See `mrsk accessory` for all the commands possible.
302
316
 
317
+ ### Using a generated .env file
318
+
319
+ 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:
320
+
321
+ ```erb
322
+ <% if (session_token = `op signin --account my-one-password-account --raw`.strip) != "" %># Generated by mrsk envify
323
+ GITHUB_TOKEN=<%= `gh config get -h github.com oauth_token`.strip %>
324
+ MRSK_REGISTRY_PASSWORD=<%= `op read "op://Vault/Docker Hub/password" -n --session #{session_token}` %>
325
+ RAILS_MASTER_KEY=<%= `op read "op://Vault/My App/RAILS_MASTER_SECRET" -n --session #{session_token}` %>
326
+ MYSQL_ROOT_PASSWORD=<%= `op read "op://Vault/My App/MYSQL_ROOT_PASSWORD" -n --session #{session_token}` %>
327
+ <% else raise ArgumentError, "Session token missing" end %>
328
+ ```
329
+
330
+ This template can safely be checked into git. Then everyone deploying the app can run `mrsk envify` when they setup the app for the first time or passwords change to get the correct `.env` file.
331
+
332
+ If you need separate env variables for different destinations, you can set them with `.env.destination.erb` for the template, which will generate `.env.staging` when run with `mrsk envify -d staging`.
333
+
303
334
  ## Commands
304
335
 
305
336
  ### Running commands on servers
data/bin/mrsk CHANGED
@@ -3,8 +3,7 @@
3
3
  # Prevent failures from being reported twice.
4
4
  Thread.report_on_exception = false
5
5
 
6
- require "dotenv/load"
7
- require "mrsk/cli"
6
+ require "mrsk"
8
7
 
9
8
  begin
10
9
  Mrsk::Cli::Main.start(ARGV)
@@ -1,5 +1,3 @@
1
- require "mrsk/cli/base"
2
-
3
1
  class Mrsk::Cli::Accessory < Mrsk::Cli::Base
4
2
  desc "boot [NAME]", "Boot accessory service on host (use NAME=all to boot all accessories)"
5
3
  def boot(name)
@@ -9,6 +7,7 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base
9
7
  with_accessory(name) do |accessory|
10
8
  directories(name)
11
9
  upload(name)
10
+
12
11
  on(accessory.host) do
13
12
  execute *MRSK.auditor.record("accessory #{name} boot"), verbosity: :debug
14
13
  execute *accessory.run
data/lib/mrsk/cli/app.rb CHANGED
@@ -1,5 +1,3 @@
1
- require "mrsk/cli/base"
2
-
3
1
  class Mrsk::Cli::App < Mrsk::Cli::Base
4
2
  desc "boot", "Boot app on servers (or reboot app if already running)"
5
3
  def boot
@@ -40,7 +38,7 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
40
38
  execute *MRSK.app.start, raise_on_non_zero_exit: false
41
39
  end
42
40
  end
43
-
41
+
44
42
  desc "stop", "Stop app on servers"
45
43
  def stop
46
44
  on(MRSK.hosts) do
@@ -48,12 +46,12 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
48
46
  execute *MRSK.app.stop, raise_on_non_zero_exit: false
49
47
  end
50
48
  end
51
-
49
+
52
50
  desc "details", "Display details about app containers"
53
51
  def details
54
52
  on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.info) }
55
53
  end
56
-
54
+
57
55
  desc "exec [CMD]", "Execute a custom command on servers"
58
56
  option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)"
59
57
  option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one"
@@ -106,11 +104,6 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
106
104
  on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.list_images) }
107
105
  end
108
106
 
109
- desc "current", "Return the current running container ID"
110
- def current
111
- on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.current_container_id) }
112
- end
113
-
114
107
  desc "logs", "Show lines from app on servers"
115
108
  option :since, aliases: "-s", desc: "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)"
116
109
  option :lines, type: :numeric, aliases: "-n", desc: "Number of log lines to pull from each server"
data/lib/mrsk/cli/base.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "thor"
2
+ require "dotenv"
2
3
  require "mrsk/sshkit_with_ext"
3
4
 
4
5
  module Mrsk::Cli
@@ -21,10 +22,19 @@ module Mrsk::Cli
21
22
 
22
23
  def initialize(*)
23
24
  super
25
+ load_envs
24
26
  initialize_commander(options)
25
27
  end
26
28
 
27
29
  private
30
+ def load_envs
31
+ if destination = options[:destination]
32
+ Dotenv.load(".env.#{destination}", ".env")
33
+ else
34
+ Dotenv.load(".env")
35
+ end
36
+ end
37
+
28
38
  def initialize_commander(options)
29
39
  MRSK.tap do |commander|
30
40
  commander.config_file = Pathname.new(File.expand_path(options[:config_file]))
@@ -1,5 +1,3 @@
1
- require "mrsk/cli/base"
2
-
3
1
  class Mrsk::Cli::Build < Mrsk::Cli::Base
4
2
  desc "deliver", "Deliver a newly built app image to servers"
5
3
  def deliver
@@ -11,7 +9,7 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base
11
9
  def push
12
10
  cli = self
13
11
 
14
- run_locally do
12
+ run_locally do
15
13
  begin
16
14
  MRSK.with_verbosity(:debug) { execute *MRSK.builder.push }
17
15
  rescue SSHKit::Command::Failed => e
data/lib/mrsk/cli/main.rb CHANGED
@@ -1,13 +1,3 @@
1
- require "mrsk/cli/base"
2
-
3
- require "mrsk/cli/accessory"
4
- require "mrsk/cli/app"
5
- require "mrsk/cli/build"
6
- require "mrsk/cli/prune"
7
- require "mrsk/cli/registry"
8
- require "mrsk/cli/server"
9
- require "mrsk/cli/traefik"
10
-
11
1
  class Mrsk::Cli::Main < Mrsk::Cli::Base
12
2
  desc "setup", "Setup all accessories and deploy the app to servers"
13
3
  def setup
@@ -84,22 +74,29 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
84
74
  end
85
75
  end
86
76
 
87
- desc "install", "Create config stub in config/deploy.yml and binstub in bin/mrsk"
88
- option :skip_binstub, type: :boolean, default: false, desc: "Skip adding MRSK to the Gemfile and creating bin/mrsk binstub"
89
- def install
77
+ desc "init", "Create config stub in config/deploy.yml and env stub in .env"
78
+ option :bundle, type: :boolean, default: false, desc: "Add MRSK to the Gemfile and create a bin/mrsk binstub"
79
+ def init
90
80
  require "fileutils"
91
81
 
92
82
  if (deploy_file = Pathname.new(File.expand_path("config/deploy.yml"))).exist?
93
83
  puts "Config file already exists in config/deploy.yml (remove first to create a new one)"
94
84
  else
85
+ FileUtils.mkdir_p deploy_file.dirname
95
86
  FileUtils.cp_r Pathname.new(File.expand_path("templates/deploy.yml", __dir__)), deploy_file
96
87
  puts "Created configuration file in config/deploy.yml"
97
88
  end
98
89
 
99
- unless options[:skip_binstub]
90
+ unless (deploy_file = Pathname.new(File.expand_path(".env"))).exist?
91
+ FileUtils.cp_r Pathname.new(File.expand_path("templates/template.env", __dir__)), deploy_file
92
+ puts "Created .env file"
93
+ end
94
+
95
+ if options[:bundle]
100
96
  if (binstub = Pathname.new(File.expand_path("bin/mrsk"))).exist?
101
97
  puts "Binstub already exists in bin/mrsk (remove first to create a new one)"
102
98
  else
99
+ puts "Adding MRSK to Gemfile and bundle..."
103
100
  `bundle add mrsk`
104
101
  `bundle binstubs mrsk`
105
102
  puts "Created binstub file in bin/mrsk"
@@ -107,6 +104,15 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
107
104
  end
108
105
  end
109
106
 
107
+ desc "envify", "Create .env by evaluating .env.erb (or .env.staging.erb -> .env.staging when using -d staging)"
108
+ def envify
109
+ if destination = options[:destination]
110
+ File.write(".env.#{destination}", ERB.new(IO.read(Pathname.new(File.expand_path(".env.#{destination}.erb")))).result)
111
+ else
112
+ File.write(".env", ERB.new(IO.read(Pathname.new(File.expand_path(".env.erb")))).result)
113
+ end
114
+ end
115
+
110
116
  desc "remove", "Remove Traefik, app, and registry session from servers"
111
117
  def remove
112
118
  invoke "mrsk:cli:traefik:remove"
@@ -1,5 +1,3 @@
1
- require "mrsk/cli/base"
2
-
3
1
  class Mrsk::Cli::Prune < Mrsk::Cli::Base
4
2
  desc "all", "Prune unused images and stopped containers"
5
3
  def all
@@ -1,5 +1,3 @@
1
- require "mrsk/cli/base"
2
-
3
1
  class Mrsk::Cli::Registry < Mrsk::Cli::Base
4
2
  desc "login", "Login to the registry locally and remotely"
5
3
  def login
@@ -1,5 +1,3 @@
1
- require "mrsk/cli/base"
2
-
3
1
  class Mrsk::Cli::Server < Mrsk::Cli::Base
4
2
  desc "bootstrap", "Ensure Docker is installed on the servers"
5
3
  def bootstrap
@@ -0,0 +1,2 @@
1
+ MRSK_REGISTRY_PASSWORD=change-this
2
+ RAILS_MASTER_KEY=another-env
@@ -1,5 +1,3 @@
1
- require "mrsk/cli/base"
2
-
3
1
  class Mrsk::Cli::Traefik < Mrsk::Cli::Base
4
2
  desc "boot", "Boot Traefik on servers"
5
3
  def boot
data/lib/mrsk/cli.rb CHANGED
@@ -1,9 +1,5 @@
1
- require "mrsk"
2
-
3
1
  module Mrsk::Cli
4
2
  end
5
3
 
6
4
  # SSHKit uses instance eval, so we need a global const for ergonomics
7
5
  MRSK = Mrsk::Commander.new
8
-
9
- require "mrsk/cli/main"
@@ -1,14 +1,5 @@
1
1
  require "active_support/core_ext/enumerable"
2
2
 
3
- require "mrsk/configuration"
4
- require "mrsk/commands/accessory"
5
- require "mrsk/commands/app"
6
- require "mrsk/commands/auditor"
7
- require "mrsk/commands/builder"
8
- require "mrsk/commands/prune"
9
- require "mrsk/commands/traefik"
10
- require "mrsk/commands/registry"
11
-
12
3
  class Mrsk::Commander
13
4
  attr_accessor :config_file, :destination, :verbosity, :version
14
5
 
@@ -83,7 +74,7 @@ class Mrsk::Commander
83
74
  end
84
75
 
85
76
 
86
- def with_verbosity(level)
77
+ def with_verbosity(level)
87
78
  old_level = SSHKit.config.output_verbosity
88
79
  SSHKit.config.output_verbosity = level
89
80
  yield
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/base"
2
-
3
1
  class Mrsk::Commands::Accessory < Mrsk::Commands::Base
4
2
  attr_reader :accessory_config
5
3
  delegate :service_name, :image, :host, :port, :files, :directories, :env_args, :volume_args, :label_args, to: :accessory_config
@@ -10,7 +8,7 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
10
8
  end
11
9
 
12
10
  def run
13
- docker :run,
11
+ docker :run,
14
12
  "--name", service_name,
15
13
  "-d",
16
14
  "--restart", "unless-stopped",
@@ -41,10 +39,10 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
41
39
  end
42
40
 
43
41
  def follow_logs(grep: nil)
44
- run_over_ssh pipe(
45
- docker(:logs, service_name, "-t", "-n", "10", "-f", "2>&1"),
46
- (%(grep "#{grep}") if grep)
47
- ).join(" ")
42
+ run_over_ssh \
43
+ pipe \
44
+ docker(:logs, service_name, "-t", "-n", "10", "-f", "2>&1"),
45
+ (%(grep "#{grep}") if grep)
48
46
  end
49
47
 
50
48
 
@@ -66,11 +64,11 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
66
64
  end
67
65
 
68
66
  def execute_in_existing_container_over_ssh(*command)
69
- run_over_ssh execute_in_existing_container(*command, interactive: true).join(" ")
67
+ run_over_ssh execute_in_existing_container(*command, interactive: true)
70
68
  end
71
69
 
72
70
  def execute_in_new_container_over_ssh(*command)
73
- run_over_ssh execute_in_new_container(*command, interactive: true).join(" ")
71
+ run_over_ssh execute_in_new_container(*command, interactive: true)
74
72
  end
75
73
 
76
74
  def run_over_ssh(command)
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/base"
2
-
3
1
  class Mrsk::Commands::App < Mrsk::Commands::Base
4
2
  def run(role: :web)
5
3
  role = config.role(role)
@@ -8,7 +6,6 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
8
6
  "-d",
9
7
  "--restart unless-stopped",
10
8
  "--name", service_with_version,
11
- *rails_master_key_arg,
12
9
  *role.env_args,
13
10
  *config.volume_args,
14
11
  *role.label_args,
@@ -37,11 +34,13 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
37
34
  end
38
35
 
39
36
  def follow_logs(host:, grep: nil)
40
- run_over_ssh pipe(
41
- current_container_id,
42
- "xargs docker logs -t -n 10 -f 2>&1",
43
- (%(grep "#{grep}") if grep)
44
- ).join(" "), host: host
37
+ run_over_ssh \
38
+ pipe(
39
+ current_container_id,
40
+ "xargs docker logs -t -n 10 -f 2>&1",
41
+ (%(grep "#{grep}") if grep)
42
+ ),
43
+ host: host
45
44
  end
46
45
 
47
46
 
@@ -56,7 +55,6 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
56
55
  docker :run,
57
56
  ("-it" if interactive),
58
57
  "--rm",
59
- *rails_master_key_arg,
60
58
  *config.env_args,
61
59
  *config.volume_args,
62
60
  config.absolute_image,
@@ -64,11 +62,11 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
64
62
  end
65
63
 
66
64
  def execute_in_existing_container_over_ssh(*command, host:)
67
- run_over_ssh execute_in_existing_container(*command, interactive: true).join(" "), host: host
65
+ run_over_ssh execute_in_existing_container(*command, interactive: true), host: host
68
66
  end
69
67
 
70
68
  def execute_in_new_container_over_ssh(*command, host:)
71
- run_over_ssh execute_in_new_container(*command, interactive: true).join(" "), host: host
69
+ run_over_ssh execute_in_new_container(*command, interactive: true), host: host
72
70
  end
73
71
 
74
72
 
@@ -130,12 +128,4 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
130
128
  def service_filter
131
129
  [ "--filter", "label=service=#{config.service}" ]
132
130
  end
133
-
134
- def rails_master_key_arg
135
- if master_key = config.master_key
136
- [ "-e", redact("RAILS_MASTER_KEY=#{master_key}") ]
137
- else
138
- []
139
- end
140
- end
141
131
  end
@@ -1,10 +1,9 @@
1
1
  require "active_support/core_ext/time/conversions"
2
- require "mrsk/commands/base"
3
2
 
4
3
  class Mrsk::Commands::Auditor < Mrsk::Commands::Base
5
4
  def record(line)
6
5
  append \
7
- [ :echo, "'#{tags} #{line}'" ],
6
+ [ :echo, tagged_line(line) ],
8
7
  audit_log_file
9
8
  end
10
9
 
@@ -17,6 +16,10 @@ class Mrsk::Commands::Auditor < Mrsk::Commands::Base
17
16
  "mrsk-#{config.service}-audit.log"
18
17
  end
19
18
 
19
+ def tagged_line(line)
20
+ "'#{tags} #{line}'"
21
+ end
22
+
20
23
  def tags
21
24
  "[#{timestamp}] [#{performer}]"
22
25
  end
@@ -8,8 +8,11 @@ module Mrsk::Commands
8
8
  @config = config
9
9
  end
10
10
 
11
- def run_over_ssh(command, host:)
12
- "ssh -t #{config.ssh_user}@#{host} '#{command}'"
11
+ def run_over_ssh(*command, host:)
12
+ "ssh".tap do |cmd|
13
+ cmd << " -J #{config.ssh_proxy.jump_proxies}" if config.ssh_proxy
14
+ cmd << " -t #{config.ssh_user}@#{host} '#{command.join(" ")}'"
15
+ end
13
16
  end
14
17
 
15
18
  private
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/base"
2
-
3
1
  class Mrsk::Commands::Builder::Base < Mrsk::Commands::Base
4
2
  delegate :argumentize, to: Mrsk::Utils
5
3
 
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/builder/multiarch"
2
-
3
1
  class Mrsk::Commands::Builder::Multiarch::Remote < Mrsk::Commands::Builder::Multiarch
4
2
  def create
5
3
  combine \
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/builder/base"
2
-
3
1
  class Mrsk::Commands::Builder::Multiarch < Mrsk::Commands::Builder::Base
4
2
  def create
5
3
  docker :buildx, :create, "--use", "--name", builder_name
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/builder/native"
2
-
3
1
  class Mrsk::Commands::Builder::Native::Remote < Mrsk::Commands::Builder::Native
4
2
  def create
5
3
  chain \
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/builder/base"
2
-
3
1
  class Mrsk::Commands::Builder::Native < Mrsk::Commands::Builder::Base
4
2
  def create
5
3
  # No-op on native
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/base"
2
-
3
1
  class Mrsk::Commands::Builder < Mrsk::Commands::Base
4
2
  delegate :create, :remove, :push, :pull, :info, to: :target
5
3
 
@@ -36,8 +34,3 @@ class Mrsk::Commands::Builder < Mrsk::Commands::Base
36
34
  @multiarch_remote ||= Mrsk::Commands::Builder::Multiarch::Remote.new(config)
37
35
  end
38
36
  end
39
-
40
- require "mrsk/commands/builder/native"
41
- require "mrsk/commands/builder/native/remote"
42
- require "mrsk/commands/builder/multiarch"
43
- require "mrsk/commands/builder/multiarch/remote"
@@ -1,4 +1,3 @@
1
- require "mrsk/commands/base"
2
1
  require "active_support/duration"
3
2
  require "active_support/core_ext/numeric/time"
4
3
 
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/base"
2
-
3
1
  class Mrsk::Commands::Registry < Mrsk::Commands::Base
4
2
  delegate :registry, to: :config
5
3
 
@@ -1,5 +1,3 @@
1
- require "mrsk/commands/base"
2
-
3
1
  class Mrsk::Commands::Traefik < Mrsk::Commands::Base
4
2
  def run
5
3
  docker :run, "--name traefik",
@@ -96,7 +96,12 @@ class Mrsk::Configuration::Role
96
96
  def merged_env_with_secrets
97
97
  merged_env.tap do |new_env|
98
98
  new_env["secret"] = Array(config.env["secret"]) + Array(specialized_env["secret"])
99
- new_env["clear"] = (Array(config.env["clear"] || config.env) + Array(specialized_env["clear"] || specialized_env)).uniq
99
+
100
+ # If there's no secret/clear split, everything is clear
101
+ clear_app_env = config.env["secret"] ? Array(config.env["clear"]) : Array(config.env["clear"] || config.env)
102
+ clear_role_env = specialized_env["secret"] ? Array(specialized_env["clear"]) : Array(specialized_env["clear"] || specialized_env)
103
+
104
+ new_env["clear"] = (clear_app_env + clear_role_env).uniq
100
105
  end
101
106
  end
102
107
  end
@@ -3,7 +3,7 @@ require "active_support/core_ext/string/inquiry"
3
3
  require "active_support/core_ext/module/delegation"
4
4
  require "pathname"
5
5
  require "erb"
6
- require "mrsk/utils"
6
+ require "net/ssh/proxy/jump"
7
7
 
8
8
  class Mrsk::Configuration
9
9
  delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :raw_config, allow_nil: true
@@ -104,17 +104,22 @@ class Mrsk::Configuration
104
104
  end
105
105
 
106
106
  def ssh_user
107
- raw_config.ssh_user || "root"
107
+ if raw_config.ssh.present?
108
+ raw_config.ssh["user"] || "root"
109
+ else
110
+ "root"
111
+ end
108
112
  end
109
113
 
110
- def ssh_options
111
- { user: ssh_user, auth_methods: [ "publickey" ] }
114
+ def ssh_proxy
115
+ if raw_config.ssh.present? && raw_config.ssh["proxy"]
116
+ Net::SSH::Proxy::Jump.new \
117
+ raw_config.ssh["proxy"].include?("@") ? raw_config.ssh["proxy"] : "root@#{raw_config.ssh["proxy"]}"
118
+ end
112
119
  end
113
120
 
114
- def master_key
115
- unless raw_config.skip_master_key
116
- ENV["RAILS_MASTER_KEY"] || File.read(Pathname.new(File.expand_path("config/master.key")))
117
- end
121
+ def ssh_options
122
+ { user: ssh_user, proxy: ssh_proxy, auth_methods: [ "publickey" ] }.compact
118
123
  end
119
124
 
120
125
 
@@ -171,6 +176,3 @@ class Mrsk::Configuration
171
176
  raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort
172
177
  end
173
178
  end
174
-
175
- require "mrsk/configuration/role"
176
- require "mrsk/configuration/accessory"
data/lib/mrsk/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mrsk
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
data/lib/mrsk.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  module Mrsk
2
2
  end
3
3
 
4
- require "mrsk/version"
5
- require "mrsk/commander"
4
+ require "zeitwerk"
5
+
6
+ loader = Zeitwerk::Loader.for_gem
7
+ loader.ignore("#{__dir__}/mrsk/sshkit_with_ext.rb")
8
+ loader.setup
9
+ loader.eager_load # We need all commands loaded.
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.5.1
4
+ version: 0.6.0
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-03 00:00:00.000000000 Z
11
+ date: 2023-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '2.8'
69
+ - !ruby/object:Gem::Dependency
70
+ name: zeitwerk
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.5'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.5'
69
83
  description:
70
84
  email: dhh@hey.com
71
85
  executables:
@@ -87,6 +101,7 @@ files:
87
101
  - lib/mrsk/cli/registry.rb
88
102
  - lib/mrsk/cli/server.rb
89
103
  - lib/mrsk/cli/templates/deploy.yml
104
+ - lib/mrsk/cli/templates/template.env
90
105
  - lib/mrsk/cli/traefik.rb
91
106
  - lib/mrsk/commander.rb
92
107
  - lib/mrsk/commands.rb