mrsk 0.2.0 → 0.3.0
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 +8 -0
- data/bin/mrsk +9 -1
- data/lib/mrsk/cli/accessory.rb +134 -38
- data/lib/mrsk/cli/app.rb +17 -3
- data/lib/mrsk/cli/build.rb +21 -5
- data/lib/mrsk/cli/main.rb +11 -1
- data/lib/mrsk/cli/server.rb +1 -1
- data/lib/mrsk/commander.rb +5 -1
- data/lib/mrsk/commands/accessory.rb +46 -1
- data/lib/mrsk/commands/app.rb +9 -5
- data/lib/mrsk/commands/base.rb +4 -0
- data/lib/mrsk/commands/builder/native/remote.rb +3 -3
- data/lib/mrsk/configuration/accessory.rb +57 -1
- data/lib/mrsk/configuration.rb +7 -4
- data/lib/mrsk/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3cbef66064bc4d1a20707788eefd3827d4054d1278d85a8e2b425c4c5ad643e
|
4
|
+
data.tar.gz: 26e48f594d93f1b1a409a4601cc43c6d62fc35e935c7000c17addd6d5f720ac9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c84c6bada6dc82715349630807685d4f8a6c5dd64995760efd88666bc99a1c1b20230f47b23a7b71f8dfab5f4b2f34317d1fd2a5245b8c8a6b45575fa606002
|
7
|
+
data.tar.gz: 83565d28bcde4d782a829312685c2669512f6111233685309b015ed2b087ac5557456faae0460f472b18c480ef20892ae712a07f1b22de2cb2340a9f187c936b
|
data/README.md
CHANGED
@@ -244,6 +244,14 @@ ARG RUBY_VERSION
|
|
244
244
|
FROM ruby:$RUBY_VERSION-slim as base
|
245
245
|
```
|
246
246
|
|
247
|
+
### Using without RAILS_MASTER_KEY
|
248
|
+
|
249
|
+
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:
|
250
|
+
|
251
|
+
```yaml
|
252
|
+
skip_master_key: true
|
253
|
+
```
|
254
|
+
|
247
255
|
### Using accessories for database, cache, search services
|
248
256
|
|
249
257
|
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:
|
data/bin/mrsk
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
# Prevent failures from being reported twice.
|
4
|
+
Thread.report_on_exception = false
|
5
|
+
|
3
6
|
require "mrsk/cli"
|
4
7
|
|
5
|
-
|
8
|
+
begin
|
9
|
+
Mrsk::Cli::Main.start(ARGV)
|
10
|
+
rescue SSHKit::Runner::ExecuteError => e
|
11
|
+
puts " \e[31mERROR (#{e.cause.class}): #{e.cause.message}\e[0m"
|
12
|
+
puts e.cause.backtrace if ENV["VERBOSE"]
|
13
|
+
end
|
data/lib/mrsk/cli/accessory.rb
CHANGED
@@ -1,41 +1,104 @@
|
|
1
1
|
require "mrsk/cli/base"
|
2
2
|
|
3
3
|
class Mrsk::Cli::Accessory < Mrsk::Cli::Base
|
4
|
-
desc "boot [NAME]", "Boot accessory service on host"
|
4
|
+
desc "boot [NAME]", "Boot accessory service on host (use NAME=all to boot all accessories)"
|
5
5
|
def boot(name)
|
6
|
-
|
7
|
-
|
6
|
+
if name == "all"
|
7
|
+
MRSK.accessory_names.each { |accessory_name| boot(accessory_name) }
|
8
|
+
else
|
9
|
+
with_accessory(name) do |accessory|
|
10
|
+
directories(name)
|
11
|
+
upload(name)
|
12
|
+
on(accessory.host) { execute *accessory.run }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "upload [NAME]", "Upload accessory files to host"
|
18
|
+
def upload(name)
|
19
|
+
with_accessory(name) do |accessory|
|
20
|
+
on(accessory.host) do
|
21
|
+
accessory.files.each do |(local, remote)|
|
22
|
+
accessory.ensure_local_file_present(local)
|
23
|
+
|
24
|
+
execute *accessory.make_directory_for(remote)
|
25
|
+
upload! local, remote
|
26
|
+
execute :chmod, "755", remote
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "directories [NAME]", "Create accessory directories on host"
|
33
|
+
def directories(name)
|
34
|
+
with_accessory(name) do |accessory|
|
35
|
+
on(accessory.host) do
|
36
|
+
accessory.directories.keys.each do |host_path|
|
37
|
+
execute *accessory.make_directory(host_path)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
8
41
|
end
|
9
42
|
|
10
43
|
desc "reboot [NAME]", "Reboot accessory on host (stop container, remove container, start new container)"
|
11
44
|
def reboot(name)
|
12
|
-
|
13
|
-
|
14
|
-
|
45
|
+
with_accessory(name) do |accessory|
|
46
|
+
stop(name)
|
47
|
+
remove_container(name)
|
48
|
+
boot(name)
|
49
|
+
end
|
15
50
|
end
|
16
51
|
|
17
52
|
desc "start [NAME]", "Start existing accessory on host"
|
18
53
|
def start(name)
|
19
|
-
|
20
|
-
|
54
|
+
with_accessory(name) do |accessory|
|
55
|
+
on(accessory.host) { execute *accessory.start }
|
56
|
+
end
|
21
57
|
end
|
22
58
|
|
23
59
|
desc "stop [NAME]", "Stop accessory on host"
|
24
60
|
def stop(name)
|
25
|
-
|
26
|
-
|
61
|
+
with_accessory(name) do |accessory|
|
62
|
+
on(accessory.host) { execute *accessory.stop, raise_on_non_zero_exit: false }
|
63
|
+
end
|
27
64
|
end
|
28
65
|
|
29
66
|
desc "restart [NAME]", "Restart accessory on host"
|
30
67
|
def restart(name)
|
31
|
-
|
32
|
-
|
68
|
+
with_accessory(name) do
|
69
|
+
stop(name)
|
70
|
+
start(name)
|
71
|
+
end
|
33
72
|
end
|
34
73
|
|
35
|
-
desc "details [NAME]", "Display details about accessory on host"
|
74
|
+
desc "details [NAME]", "Display details about accessory on host (use NAME=all to boot all accessories)"
|
36
75
|
def details(name)
|
37
|
-
|
38
|
-
|
76
|
+
if name == "all"
|
77
|
+
MRSK.accessory_names.each { |accessory_name| details(accessory_name) }
|
78
|
+
else
|
79
|
+
with_accessory(name) do |accessory|
|
80
|
+
on(accessory.host) { puts capture_with_info(*accessory.info) }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
desc "exec [NAME] [CMD]", "Execute a custom command on accessory host"
|
86
|
+
option :run, type: :boolean, default: false, desc: "Start a new container to run the command rather than reusing existing"
|
87
|
+
def exec(name, cmd)
|
88
|
+
with_accessory(name) do |accessory|
|
89
|
+
runner = options[:run] ? :run_exec : :exec
|
90
|
+
on(accessory.host) { |host| puts_by_host host, capture_with_info(*accessory.send(runner, cmd)) }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
desc "bash [NAME]", "Start a bash session on primary host (or specific host set by --hosts)"
|
95
|
+
def bash(name)
|
96
|
+
with_accessory(name) do |accessory|
|
97
|
+
run_locally do
|
98
|
+
info "Launching bash session on #{accessory.host}"
|
99
|
+
exec accessory.bash(host: accessory.host)
|
100
|
+
end
|
101
|
+
end
|
39
102
|
end
|
40
103
|
|
41
104
|
desc "logs [NAME]", "Show log lines from accessory on host"
|
@@ -44,42 +107,75 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base
|
|
44
107
|
option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)"
|
45
108
|
option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)"
|
46
109
|
def logs(name)
|
47
|
-
|
48
|
-
|
49
|
-
grep = options[:grep]
|
110
|
+
with_accessory(name) do |accessory|
|
111
|
+
grep = options[:grep]
|
50
112
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
113
|
+
if options[:follow]
|
114
|
+
run_locally do
|
115
|
+
info "Following logs on #{accessory.host}..."
|
116
|
+
info accessory.follow_logs(grep: grep)
|
117
|
+
exec accessory.follow_logs(grep: grep)
|
118
|
+
end
|
119
|
+
else
|
120
|
+
since = options[:since]
|
121
|
+
lines = options[:lines]
|
60
122
|
|
61
|
-
|
62
|
-
|
123
|
+
on(accessory.host) do
|
124
|
+
puts capture_with_info(*accessory.logs(since: since, lines: lines, grep: grep))
|
125
|
+
end
|
63
126
|
end
|
64
127
|
end
|
65
128
|
end
|
66
129
|
|
67
|
-
desc "remove [NAME]", "Remove accessory container and image from host"
|
130
|
+
desc "remove [NAME]", "Remove accessory container and image from host (use NAME=all to boot all accessories)"
|
68
131
|
def remove(name)
|
69
|
-
|
70
|
-
|
71
|
-
|
132
|
+
if name == "all"
|
133
|
+
MRSK.accessory_names.each { |accessory_name| remove(accessory_name) }
|
134
|
+
else
|
135
|
+
with_accessory(name) do
|
136
|
+
stop(name)
|
137
|
+
remove_container(name)
|
138
|
+
remove_image(name)
|
139
|
+
remove_service_directory(name)
|
140
|
+
end
|
141
|
+
end
|
72
142
|
end
|
73
143
|
|
74
144
|
desc "remove_container [NAME]", "Remove accessory container from host"
|
75
145
|
def remove_container(name)
|
76
|
-
|
77
|
-
|
146
|
+
with_accessory(name) do |accessory|
|
147
|
+
on(accessory.host) { execute *accessory.remove_container }
|
148
|
+
end
|
78
149
|
end
|
79
150
|
|
80
|
-
desc "remove_container [NAME]", "Remove accessory image from
|
151
|
+
desc "remove_container [NAME]", "Remove accessory image from host"
|
81
152
|
def remove_image(name)
|
82
|
-
|
83
|
-
|
153
|
+
with_accessory(name) do |accessory|
|
154
|
+
on(accessory.host) { execute *accessory.remove_image }
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
desc "remove_service_directory [NAME]", "Remove accessory directory used for uploaded files and data directories from host"
|
159
|
+
def remove_service_directory(name)
|
160
|
+
with_accessory(name) do |accessory|
|
161
|
+
on(accessory.host) { execute *accessory.remove_service_directory }
|
162
|
+
end
|
84
163
|
end
|
164
|
+
|
165
|
+
private
|
166
|
+
def with_accessory(name)
|
167
|
+
if accessory = MRSK.accessory(name)
|
168
|
+
yield accessory
|
169
|
+
else
|
170
|
+
error_on_missing_accessory(name)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def error_on_missing_accessory(name)
|
175
|
+
options = MRSK.accessory_names.presence
|
176
|
+
|
177
|
+
error \
|
178
|
+
"No accessory by the name of '#{name}'" +
|
179
|
+
(options ? " (options: #{options.to_sentence})" : "")
|
180
|
+
end
|
85
181
|
end
|
data/lib/mrsk/cli/app.rb
CHANGED
@@ -40,10 +40,24 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|
40
40
|
end
|
41
41
|
|
42
42
|
desc "exec [CMD]", "Execute a custom command on servers"
|
43
|
-
option :
|
43
|
+
option :method, aliases: "-m", default: "exec", desc: "Execution method: [exec] perform inside app container / [run] perform in new container / [ssh] perform over ssh"
|
44
44
|
def exec(cmd)
|
45
|
-
runner =
|
46
|
-
|
45
|
+
runner = \
|
46
|
+
case options[:method]
|
47
|
+
when "exec" then "exec"
|
48
|
+
when "run" then "run_exec"
|
49
|
+
when "ssh" then "exec_over_ssh"
|
50
|
+
else raise "Unknown method: #{options[:method]}"
|
51
|
+
end.inquiry
|
52
|
+
|
53
|
+
if runner.exec_over_ssh?
|
54
|
+
run_locally do
|
55
|
+
info "Launching command on #{MRSK.primary_host}"
|
56
|
+
exec MRSK.app.exec_over_ssh(cmd, host: MRSK.primary_host)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.send(runner, cmd)) }
|
60
|
+
end
|
47
61
|
end
|
48
62
|
|
49
63
|
desc "console", "Start Rails Console on primary host (or specific host set by --hosts)"
|
data/lib/mrsk/cli/build.rb
CHANGED
@@ -10,14 +10,21 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base
|
|
10
10
|
desc "push", "Build locally and push app image to registry"
|
11
11
|
def push
|
12
12
|
verbose = options[:verbose]
|
13
|
+
cli = self
|
13
14
|
|
14
15
|
run_locally do
|
15
16
|
begin
|
16
17
|
MRSK.verbosity(:debug) { execute *MRSK.builder.push }
|
17
18
|
rescue SSHKit::Command::Failed => e
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
if e.message =~ /(no builder)|(no such file or directory)/
|
20
|
+
error "Missing compatible builder, so creating a new one first"
|
21
|
+
|
22
|
+
if cli.create
|
23
|
+
MRSK.verbosity(:debug) { execute *MRSK.builder.push }
|
24
|
+
end
|
25
|
+
else
|
26
|
+
raise
|
27
|
+
end
|
21
28
|
end
|
22
29
|
end
|
23
30
|
end
|
@@ -30,8 +37,17 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base
|
|
30
37
|
desc "create", "Create a local build setup"
|
31
38
|
def create
|
32
39
|
run_locally do
|
33
|
-
|
34
|
-
|
40
|
+
begin
|
41
|
+
debug "Using builder: #{MRSK.builder.name}"
|
42
|
+
execute *MRSK.builder.create
|
43
|
+
rescue SSHKit::Command::Failed => e
|
44
|
+
if e.message =~ /stderr=(.*)/
|
45
|
+
error "Couldn't create remote builder: #{$1}"
|
46
|
+
false
|
47
|
+
else
|
48
|
+
raise
|
49
|
+
end
|
50
|
+
end
|
35
51
|
end
|
36
52
|
end
|
37
53
|
|
data/lib/mrsk/cli/main.rb
CHANGED
@@ -9,6 +9,15 @@ require "mrsk/cli/server"
|
|
9
9
|
require "mrsk/cli/traefik"
|
10
10
|
|
11
11
|
class Mrsk::Cli::Main < Mrsk::Cli::Base
|
12
|
+
desc "setup", "Setup all accessories and deploy the app to servers"
|
13
|
+
def setup
|
14
|
+
print_runtime do
|
15
|
+
invoke "mrsk:cli:server:bootstrap"
|
16
|
+
invoke "mrsk:cli:accessory:boot", [ "all" ]
|
17
|
+
deploy
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
12
21
|
desc "deploy", "Deploy the app to servers"
|
13
22
|
def deploy
|
14
23
|
print_runtime do
|
@@ -43,12 +52,13 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
|
43
52
|
def details
|
44
53
|
invoke "mrsk:cli:traefik:details"
|
45
54
|
invoke "mrsk:cli:app:details"
|
55
|
+
invoke "mrsk:cli:accessory:details", [ "all" ]
|
46
56
|
end
|
47
57
|
|
48
58
|
desc "config", "Show combined config"
|
49
59
|
def config
|
50
60
|
run_locally do
|
51
|
-
|
61
|
+
puts MRSK.config.to_h.to_yaml
|
52
62
|
end
|
53
63
|
end
|
54
64
|
|
data/lib/mrsk/cli/server.rb
CHANGED
@@ -3,6 +3,6 @@ require "mrsk/cli/base"
|
|
3
3
|
class Mrsk::Cli::Server < Mrsk::Cli::Base
|
4
4
|
desc "bootstrap", "Ensure Docker is installed on the servers"
|
5
5
|
def bootstrap
|
6
|
-
on(MRSK.hosts) { execute "which docker || (apt-get update -y && apt-get install docker.io -y)" }
|
6
|
+
on(MRSK.hosts + MRSK.accessory_hosts) { execute "which docker || (apt-get update -y && apt-get install docker.io -y)" }
|
7
7
|
end
|
8
8
|
end
|
data/lib/mrsk/commander.rb
CHANGED
@@ -48,6 +48,10 @@ class Mrsk::Commander
|
|
48
48
|
specific_hosts || config.accessories.collect(&:host)
|
49
49
|
end
|
50
50
|
|
51
|
+
def accessory_names
|
52
|
+
config.accessories&.collect(&:name) || []
|
53
|
+
end
|
54
|
+
|
51
55
|
|
52
56
|
def app
|
53
57
|
@app ||= Mrsk::Commands::App.new(config)
|
@@ -70,7 +74,7 @@ class Mrsk::Commander
|
|
70
74
|
end
|
71
75
|
|
72
76
|
def accessory(name)
|
73
|
-
|
77
|
+
config.accessories.detect { |a| a.name == name }
|
74
78
|
end
|
75
79
|
|
76
80
|
|
@@ -2,7 +2,7 @@ require "mrsk/commands/base"
|
|
2
2
|
|
3
3
|
class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
4
4
|
attr_reader :accessory_config
|
5
|
-
delegate :service_name, :image, :host, :port, :env_args, :volume_args, :label_args, to: :accessory_config
|
5
|
+
delegate :service_name, :image, :host, :port, :files, :directories, :env_args, :volume_args, :label_args, to: :accessory_config
|
6
6
|
|
7
7
|
def initialize(config, name:)
|
8
8
|
super(config)
|
@@ -46,6 +46,47 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
|
46
46
|
).join(" "), host: host
|
47
47
|
end
|
48
48
|
|
49
|
+
def exec(*command, interactive: false)
|
50
|
+
docker :exec,
|
51
|
+
("-it" if interactive),
|
52
|
+
*env_args,
|
53
|
+
*volume_args,
|
54
|
+
service_name,
|
55
|
+
*command
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_exec(*command, interactive: false)
|
59
|
+
docker :run,
|
60
|
+
("-it" if interactive),
|
61
|
+
"--rm",
|
62
|
+
*env_args,
|
63
|
+
*volume_args,
|
64
|
+
image,
|
65
|
+
*command
|
66
|
+
end
|
67
|
+
|
68
|
+
def bash(host:)
|
69
|
+
exec_over_ssh "bash", host: host
|
70
|
+
end
|
71
|
+
|
72
|
+
def ensure_local_file_present(local_file)
|
73
|
+
if !local_file.is_a?(StringIO) && !Pathname.new(local_file).exist?
|
74
|
+
raise "Missing file: #{local_file}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def make_directory_for(remote_file)
|
79
|
+
make_directory Pathname.new(remote_file).dirname.to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
def make_directory(path)
|
83
|
+
[ :mkdir, "-p", path ]
|
84
|
+
end
|
85
|
+
|
86
|
+
def remove_service_directory
|
87
|
+
[ :rm, "-rf", service_name ]
|
88
|
+
end
|
89
|
+
|
49
90
|
def remove_container
|
50
91
|
docker :container, :prune, "-f", *service_filter
|
51
92
|
end
|
@@ -55,6 +96,10 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
|
55
96
|
end
|
56
97
|
|
57
98
|
private
|
99
|
+
def exec_over_ssh(*command, host:)
|
100
|
+
run_over_ssh run_exec(*command, interactive: true).join(" "), host: host
|
101
|
+
end
|
102
|
+
|
58
103
|
def service_filter
|
59
104
|
[ "--filter", "label=service=#{service_name}" ]
|
60
105
|
end
|
data/lib/mrsk/commands/app.rb
CHANGED
@@ -60,6 +60,10 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|
60
60
|
*command
|
61
61
|
end
|
62
62
|
|
63
|
+
def exec_over_ssh(*command, host:)
|
64
|
+
run_over_ssh run_exec(*command, interactive: true).join(" "), host: host
|
65
|
+
end
|
66
|
+
|
63
67
|
def follow_logs(host:, grep: nil)
|
64
68
|
run_over_ssh pipe(
|
65
69
|
current_container_id,
|
@@ -89,15 +93,15 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|
89
93
|
end
|
90
94
|
|
91
95
|
private
|
92
|
-
def exec_over_ssh(*command, host:)
|
93
|
-
run_over_ssh run_exec(*command, interactive: true).join(" "), host: host
|
94
|
-
end
|
95
|
-
|
96
96
|
def service_filter
|
97
97
|
[ "--filter", "label=service=#{config.service}" ]
|
98
98
|
end
|
99
99
|
|
100
100
|
def rails_master_key_arg
|
101
|
-
|
101
|
+
if master_key = config.master_key
|
102
|
+
[ "-e", redact("RAILS_MASTER_KEY=#{master_key}") ]
|
103
|
+
else
|
104
|
+
[]
|
105
|
+
end
|
102
106
|
end
|
103
107
|
end
|
data/lib/mrsk/commands/base.rb
CHANGED
@@ -2,13 +2,13 @@ require "mrsk/commands/builder/native"
|
|
2
2
|
|
3
3
|
class Mrsk::Commands::Builder::Native::Remote < Mrsk::Commands::Builder::Native
|
4
4
|
def create
|
5
|
-
|
5
|
+
chain \
|
6
6
|
create_context,
|
7
7
|
create_buildx
|
8
8
|
end
|
9
9
|
|
10
10
|
def remove
|
11
|
-
|
11
|
+
chain \
|
12
12
|
remove_context,
|
13
13
|
remove_buildx
|
14
14
|
end
|
@@ -25,7 +25,7 @@ class Mrsk::Commands::Builder::Native::Remote < Mrsk::Commands::Builder::Native
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def info
|
28
|
-
|
28
|
+
chain \
|
29
29
|
docker(:context, :ls),
|
30
30
|
docker(:buildx, :ls)
|
31
31
|
end
|
@@ -43,8 +43,22 @@ class Mrsk::Configuration::Assessory
|
|
43
43
|
argumentize_env_with_secrets env
|
44
44
|
end
|
45
45
|
|
46
|
+
def files
|
47
|
+
specifics["files"]&.to_h do |local_to_remote_mapping|
|
48
|
+
local_file, remote_file = local_to_remote_mapping.split(":")
|
49
|
+
[ expand_local_file(local_file), expand_remote_file(remote_file) ]
|
50
|
+
end || {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def directories
|
54
|
+
specifics["directories"]&.to_h do |host_to_container_mapping|
|
55
|
+
host_relative_path, container_path = host_to_container_mapping.split(":")
|
56
|
+
[ expand_host_path(host_relative_path), container_path ]
|
57
|
+
end || {}
|
58
|
+
end
|
59
|
+
|
46
60
|
def volumes
|
47
|
-
|
61
|
+
specific_volumes + remote_files_as_volumes + remote_directories_as_volumes
|
48
62
|
end
|
49
63
|
|
50
64
|
def volume_args
|
@@ -57,4 +71,46 @@ class Mrsk::Configuration::Assessory
|
|
57
71
|
def default_labels
|
58
72
|
{ "service" => service_name }
|
59
73
|
end
|
74
|
+
|
75
|
+
def expand_local_file(local_file)
|
76
|
+
if local_file.end_with?("erb")
|
77
|
+
read_dynamic_file(local_file)
|
78
|
+
else
|
79
|
+
Pathname.new(File.expand_path(local_file)).to_s
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def read_dynamic_file(local_file)
|
84
|
+
StringIO.new(ERB.new(IO.read(local_file)).result)
|
85
|
+
end
|
86
|
+
|
87
|
+
def expand_remote_file(remote_file)
|
88
|
+
service_name + remote_file
|
89
|
+
end
|
90
|
+
|
91
|
+
def specific_volumes
|
92
|
+
specifics["volumes"] || []
|
93
|
+
end
|
94
|
+
|
95
|
+
def remote_files_as_volumes
|
96
|
+
specifics["files"]&.collect do |local_to_remote_mapping|
|
97
|
+
_, remote_file = local_to_remote_mapping.split(":")
|
98
|
+
"#{service_data_directory + remote_file}:#{remote_file}"
|
99
|
+
end || []
|
100
|
+
end
|
101
|
+
|
102
|
+
def remote_directories_as_volumes
|
103
|
+
specifics["directories"]&.collect do |host_to_container_mapping|
|
104
|
+
host_relative_path, container_path = host_to_container_mapping.split(":")
|
105
|
+
[ expand_host_path(host_relative_path), container_path ].join(":")
|
106
|
+
end || []
|
107
|
+
end
|
108
|
+
|
109
|
+
def expand_host_path(host_relative_path)
|
110
|
+
"#{service_data_directory}/#{host_relative_path}"
|
111
|
+
end
|
112
|
+
|
113
|
+
def service_data_directory
|
114
|
+
"$PWD/#{service_name}"
|
115
|
+
end
|
60
116
|
end
|
data/lib/mrsk/configuration.rb
CHANGED
@@ -15,7 +15,7 @@ class Mrsk::Configuration
|
|
15
15
|
def create_from(base_config_file, destination: nil, version: "missing")
|
16
16
|
new(load_config_file(base_config_file).tap do |config|
|
17
17
|
if destination
|
18
|
-
config.
|
18
|
+
config.deep_merge! \
|
19
19
|
load_config_file destination_config_file(base_config_file, destination)
|
20
20
|
end
|
21
21
|
end, version: version)
|
@@ -52,7 +52,7 @@ class Mrsk::Configuration
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def accessories
|
55
|
-
@accessories ||= raw_config.accessories
|
55
|
+
@accessories ||= raw_config.accessories&.keys&.collect { |name| Mrsk::Configuration::Assessory.new(name, config: self) } || []
|
56
56
|
end
|
57
57
|
|
58
58
|
def accessory(name)
|
@@ -115,7 +115,9 @@ class Mrsk::Configuration
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def master_key
|
118
|
-
|
118
|
+
unless raw_config.skip_master_key
|
119
|
+
ENV["RAILS_MASTER_KEY"] || File.read(Pathname.new(File.expand_path("config/master.key")))
|
120
|
+
end
|
119
121
|
end
|
120
122
|
|
121
123
|
def to_h
|
@@ -130,7 +132,8 @@ class Mrsk::Configuration
|
|
130
132
|
env_args: env_args,
|
131
133
|
volume_args: volume_args,
|
132
134
|
ssh_options: ssh_options,
|
133
|
-
builder: raw_config.builder
|
135
|
+
builder: raw_config.builder,
|
136
|
+
accessories: raw_config.accessories
|
134
137
|
}.compact
|
135
138
|
end
|
136
139
|
|
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.
|
4
|
+
version: 0.3.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-01-
|
11
|
+
date: 2023-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -113,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
113
|
- !ruby/object:Gem::Version
|
114
114
|
version: '0'
|
115
115
|
requirements: []
|
116
|
-
rubygems_version: 3.4.
|
116
|
+
rubygems_version: 3.4.5
|
117
117
|
signing_key:
|
118
118
|
specification_version: 4
|
119
119
|
summary: Deploy Rails apps in containers to servers running Docker with zero downtime.
|