mrsk 0.4.0 → 0.5.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 +17 -5
- data/lib/mrsk/cli/accessory.rb +19 -31
- data/lib/mrsk/cli/app.rb +106 -62
- data/lib/mrsk/cli/main.rb +19 -4
- data/lib/mrsk/commander.rb +7 -0
- data/lib/mrsk/commands/accessory.rb +11 -8
- data/lib/mrsk/commands/app.rb +59 -22
- data/lib/mrsk/commands/base.rb +4 -0
- data/lib/mrsk/configuration/accessory.rb +1 -1
- data/lib/mrsk/configuration.rb +2 -5
- 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: d7f288f243a0192ea977464282b13b71f4ba585db01db7e7d7ae805e5509cffe
|
4
|
+
data.tar.gz: e96ababf967b92aa6236339d7eb24382207789a3b2c2b64d95caff08fabda32c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1e33f7d1598785b107a4c7610df678c341c2d26899b2c6e67739991ed573f9fcfeb511ac422f78b1447c5952f8e90d4c581795729f3503bc18f89b6334c3686
|
7
|
+
data.tar.gz: 1d3db7364c2574a3222ec1ab5c03c91ad1c1d55c83d0d397075b9d86fd41d2dc3e9d67068b619a3d5495036357301b7d2d2be618e58e2b8e40c972534da95c89
|
data/README.md
CHANGED
@@ -302,9 +302,9 @@ Now run `mrsk accessory start mysql` to start the MySQL server on 1.1.1.3. See `
|
|
302
302
|
|
303
303
|
## Commands
|
304
304
|
|
305
|
-
### Running
|
305
|
+
### Running commands on servers
|
306
306
|
|
307
|
-
|
307
|
+
You can execute one-off commands on the servers:
|
308
308
|
|
309
309
|
```bash
|
310
310
|
# Runs command on all servers
|
@@ -347,13 +347,25 @@ Database adapter sqlite3
|
|
347
347
|
Database schema version 20221231233303
|
348
348
|
|
349
349
|
# Run Rails runner on primary server
|
350
|
-
mrsk app
|
350
|
+
mrsk app exec -p 'bin/rails runner "puts Rails.application.config.time_zone"'
|
351
351
|
UTC
|
352
352
|
```
|
353
353
|
|
354
|
-
### Running
|
354
|
+
### Running interactive commands over SSH
|
355
|
+
|
356
|
+
You can run interactive commands, like a Rails console or a bash session, on a server (default is primary, use `--hosts` to connect to another):
|
357
|
+
|
358
|
+
```bash
|
359
|
+
# Starts a bash session in a new container made from the most recent app image
|
360
|
+
mrsk app exec -i bash
|
361
|
+
|
362
|
+
# Starts a bash session in the currently running container for the app
|
363
|
+
mrsk app exec -i --reuse bash
|
364
|
+
|
365
|
+
# Starts a Rails console in a new container made from the most recent app image
|
366
|
+
mrsk app exec -i 'bin/rails console'
|
367
|
+
```
|
355
368
|
|
356
|
-
If you need to interact with the production console for the app, you can use `mrsk app console`, which will start a Rails console session on the primary host. You can start the console on a different host using `mrsk app console --host 192.168.0.2`. Be mindful that this is a live wire! Any changes made to the production database will take effect immeditately.
|
357
369
|
|
358
370
|
### Running details to see state of containers
|
359
371
|
|
data/lib/mrsk/cli/accessory.rb
CHANGED
@@ -82,39 +82,27 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
-
desc "exec [NAME] [CMD]", "Execute a custom command on
|
86
|
-
option :
|
85
|
+
desc "exec [NAME] [CMD]", "Execute a custom command on servers"
|
86
|
+
option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)"
|
87
|
+
option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one"
|
87
88
|
def exec(name, cmd)
|
88
|
-
runner = \
|
89
|
-
case options[:method]
|
90
|
-
when "exec" then "exec"
|
91
|
-
when "run" then "run_exec"
|
92
|
-
when "ssh_exec" then "exec_over_ssh"
|
93
|
-
when "ssh_run" then "run_over_ssh"
|
94
|
-
else raise "Unknown method: #{options[:method]}"
|
95
|
-
end.inquiry
|
96
|
-
|
97
89
|
with_accessory(name) do |accessory|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
103
|
-
else
|
104
|
-
on(accessory.host) do
|
105
|
-
info "Launching command on #{accessory.host}"
|
106
|
-
execute *accessory.send(runner, cmd)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
90
|
+
case
|
91
|
+
when options[:interactive] && options[:reuse]
|
92
|
+
say "Launching interactive command with via SSH from existing container...", :magenta
|
93
|
+
run_locally { exec accessory.execute_in_existing_container_over_ssh(cmd) }
|
111
94
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
95
|
+
when options[:interactive]
|
96
|
+
say "Launching interactive command via SSH from new container...", :magenta
|
97
|
+
run_locally { exec accessory.execute_in_new_container_over_ssh(cmd) }
|
98
|
+
|
99
|
+
when options[:reuse]
|
100
|
+
say "Launching command from existing container...", :magenta
|
101
|
+
on(accessory.host) { capture_with_info(*accessory.execute_in_existing_container(cmd)) }
|
102
|
+
|
103
|
+
else
|
104
|
+
say "Launching command from new container...", :magenta
|
105
|
+
on(accessory.host) { capture_with_info(*accessory.execute_in_new_container(cmd)) }
|
118
106
|
end
|
119
107
|
end
|
120
108
|
end
|
@@ -166,7 +154,7 @@ class Mrsk::Cli::Accessory < Mrsk::Cli::Base
|
|
166
154
|
end
|
167
155
|
end
|
168
156
|
|
169
|
-
desc "
|
157
|
+
desc "remove_image [NAME]", "Remove accessory image from host"
|
170
158
|
def remove_image(name)
|
171
159
|
with_accessory(name) do |accessory|
|
172
160
|
on(accessory.host) { execute *accessory.remove_image }
|
data/lib/mrsk/cli/app.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
1
|
require "mrsk/cli/base"
|
2
2
|
|
3
3
|
class Mrsk::Cli::App < Mrsk::Cli::Base
|
4
|
-
desc "boot", "Boot app on servers (or
|
4
|
+
desc "boot", "Boot app on servers (or reboot app if already running)"
|
5
5
|
def boot
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
cli = self
|
7
|
+
|
8
|
+
say "Ensure no other version of the app is running...", :magenta
|
9
|
+
stop
|
10
|
+
|
11
|
+
say "Get most recent version available as an image...", :magenta unless options[:version]
|
12
|
+
using_version(options[:version] || most_recent_version_available) do |version|
|
13
|
+
say "Start container with version #{version} (or reboot if already running)...", :magenta
|
14
|
+
|
15
|
+
MRSK.config.roles.each do |role|
|
16
|
+
on(role.hosts) do |host|
|
17
|
+
begin
|
18
|
+
execute *MRSK.app.run(role: role.name)
|
19
|
+
rescue SSHKit::Command::Failed => e
|
20
|
+
if e.message =~ /already in use/
|
21
|
+
error "Rebooting container with same version already deployed on #{host}"
|
22
|
+
|
23
|
+
cli.remove_container version
|
24
|
+
execute *MRSK.app.run(role: role.name)
|
25
|
+
else
|
26
|
+
raise
|
27
|
+
end
|
16
28
|
end
|
17
29
|
end
|
18
30
|
end
|
19
31
|
end
|
20
32
|
end
|
21
|
-
|
33
|
+
|
22
34
|
desc "start", "Start existing app on servers (use --version=<git-hash> to designate specific version)"
|
23
|
-
option :version, desc: "Defaults to the most recent git-hash in local repository"
|
24
35
|
def start
|
25
|
-
|
26
|
-
on(MRSK.hosts) { execute *MRSK.app.start(version: version) }
|
27
|
-
else
|
28
|
-
on(MRSK.hosts) { execute *MRSK.app.start, raise_on_non_zero_exit: false }
|
29
|
-
end
|
36
|
+
on(MRSK.hosts) { execute *MRSK.app.start, raise_on_non_zero_exit: false }
|
30
37
|
end
|
31
38
|
|
32
39
|
desc "stop", "Stop app on servers"
|
@@ -40,45 +47,38 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|
40
47
|
end
|
41
48
|
|
42
49
|
desc "exec [CMD]", "Execute a custom command on servers"
|
43
|
-
option :
|
50
|
+
option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)"
|
51
|
+
option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one"
|
44
52
|
def exec(cmd)
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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)
|
53
|
+
case
|
54
|
+
when options[:interactive] && options[:reuse]
|
55
|
+
say "Get current version of running container...", :magenta unless options[:version]
|
56
|
+
using_version(options[:version] || current_running_version) do |version|
|
57
|
+
say "Launching interactive command with version #{version} via SSH from existing container on #{MRSK.primary_host}...", :magenta
|
58
|
+
run_locally { exec MRSK.app.execute_in_existing_container_over_ssh(cmd, host: MRSK.primary_host) }
|
57
59
|
end
|
58
|
-
else
|
59
|
-
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.send(runner, cmd)) }
|
60
|
-
end
|
61
|
-
end
|
62
60
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
61
|
+
when options[:interactive]
|
62
|
+
say "Get most recent version available as an image...", :magenta unless options[:version]
|
63
|
+
using_version(options[:version] || most_recent_version_available) do |version|
|
64
|
+
say "Launching interactive command with version #{version} via SSH from new container on #{MRSK.primary_host}...", :magenta
|
65
|
+
run_locally { exec MRSK.app.execute_in_new_container_over_ssh(cmd, host: MRSK.primary_host) }
|
66
|
+
end
|
70
67
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
68
|
+
when options[:reuse]
|
69
|
+
say "Get current version of running container...", :magenta unless options[:version]
|
70
|
+
using_version(options[:version] || current_running_version) do |version|
|
71
|
+
say "Launching command with version #{version} from existing container on #{MRSK.primary_host}...", :magenta
|
72
|
+
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.execute_in_existing_container(cmd)) }
|
73
|
+
end
|
78
74
|
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
else
|
76
|
+
say "Get most recent version available as an image...", :magenta unless options[:version]
|
77
|
+
using_version(options[:version] || most_recent_version_available) do |version|
|
78
|
+
say "Launching command with version #{version} from new container on #{MRSK.primary_host}...", :magenta
|
79
|
+
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.execute_in_new_container(cmd)) }
|
80
|
+
end
|
81
|
+
end
|
82
82
|
end
|
83
83
|
|
84
84
|
desc "containers", "List all the app containers currently on servers"
|
@@ -86,6 +86,11 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|
86
86
|
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.list_containers) }
|
87
87
|
end
|
88
88
|
|
89
|
+
desc "images", "List all the app images currently on servers"
|
90
|
+
def images
|
91
|
+
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.list_images) }
|
92
|
+
end
|
93
|
+
|
89
94
|
desc "current", "Return the current running container ID"
|
90
95
|
def current
|
91
96
|
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.current_container_id) }
|
@@ -122,16 +127,55 @@ class Mrsk::Cli::App < Mrsk::Cli::Base
|
|
122
127
|
end
|
123
128
|
|
124
129
|
desc "remove", "Remove app containers and images from servers"
|
125
|
-
option :only, default: "", desc: "Use 'containers' or 'images'"
|
126
130
|
def remove
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
on(MRSK.hosts) { execute *MRSK.app.remove_images }
|
135
|
-
end
|
131
|
+
remove_containers
|
132
|
+
remove_images
|
133
|
+
end
|
134
|
+
|
135
|
+
desc "remove_container [VERSION]", "Remove app container with given version from servers"
|
136
|
+
def remove_container(version)
|
137
|
+
on(MRSK.hosts) { execute *MRSK.app.remove_container(version: version) }
|
136
138
|
end
|
139
|
+
|
140
|
+
desc "remove_containers", "Remove all app containers from servers"
|
141
|
+
def remove_containers
|
142
|
+
on(MRSK.hosts) { execute *MRSK.app.remove_containers }
|
143
|
+
end
|
144
|
+
|
145
|
+
desc "remove_images", "Remove all app images from servers"
|
146
|
+
def remove_images
|
147
|
+
on(MRSK.hosts) { execute *MRSK.app.remove_images }
|
148
|
+
end
|
149
|
+
|
150
|
+
desc "current_version", "Shows the version currently running"
|
151
|
+
def current_version
|
152
|
+
on(MRSK.hosts) { |host| puts_by_host host, capture_with_info(*MRSK.app.current_running_version).strip }
|
153
|
+
end
|
154
|
+
|
155
|
+
private
|
156
|
+
def using_version(new_version)
|
157
|
+
if new_version
|
158
|
+
begin
|
159
|
+
old_version = MRSK.config.version
|
160
|
+
MRSK.config.version = new_version
|
161
|
+
yield new_version
|
162
|
+
ensure
|
163
|
+
MRSK.config.version = old_version
|
164
|
+
end
|
165
|
+
else
|
166
|
+
yield MRSK.config.version
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def most_recent_version_available(host: MRSK.primary_host)
|
171
|
+
version = nil
|
172
|
+
on(host) { version = capture_with_info(*MRSK.app.most_recent_version_from_available_images).strip }
|
173
|
+
version.presence
|
174
|
+
end
|
175
|
+
|
176
|
+
def current_running_version(host: MRSK.primary_host)
|
177
|
+
version = nil
|
178
|
+
on(host) { version = capture_with_info(*MRSK.app.current_running_version).strip }
|
179
|
+
version.presence
|
180
|
+
end
|
137
181
|
end
|
data/lib/mrsk/cli/main.rb
CHANGED
@@ -21,12 +21,21 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
|
21
21
|
desc "deploy", "Deploy the app to servers"
|
22
22
|
def deploy
|
23
23
|
print_runtime do
|
24
|
+
say "Ensure Docker is installed...", :magenta
|
24
25
|
invoke "mrsk:cli:server:bootstrap"
|
26
|
+
|
27
|
+
say "Log into image registry...", :magenta
|
25
28
|
invoke "mrsk:cli:registry:login"
|
29
|
+
|
30
|
+
say "Build and push app image...", :magenta
|
26
31
|
invoke "mrsk:cli:build:deliver"
|
32
|
+
|
33
|
+
say "Ensure Traefik is running...", :magenta
|
27
34
|
invoke "mrsk:cli:traefik:boot"
|
28
|
-
|
35
|
+
|
29
36
|
invoke "mrsk:cli:app:boot"
|
37
|
+
|
38
|
+
say "Prune old containers and images...", :magenta
|
30
39
|
invoke "mrsk:cli:prune:all"
|
31
40
|
end
|
32
41
|
end
|
@@ -34,17 +43,23 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
|
|
34
43
|
desc "redeploy", "Deploy new version of the app to servers (without bootstrapping servers, starting Traefik, pruning, and registry login)"
|
35
44
|
def redeploy
|
36
45
|
print_runtime do
|
46
|
+
say "Build and push app image...", :magenta
|
37
47
|
invoke "mrsk:cli:build:deliver"
|
38
|
-
|
48
|
+
|
39
49
|
invoke "mrsk:cli:app:boot"
|
40
50
|
end
|
41
51
|
end
|
42
52
|
|
43
|
-
desc "rollback [VERSION]", "Rollback the app to VERSION
|
53
|
+
desc "rollback [VERSION]", "Rollback the app to VERSION"
|
44
54
|
def rollback(version)
|
55
|
+
MRSK.version = version
|
56
|
+
|
57
|
+
cli = self
|
58
|
+
|
59
|
+
cli.say "Stop current version, then start version #{version}...", :magenta
|
45
60
|
on(MRSK.hosts) do
|
46
61
|
execute *MRSK.app.stop, raise_on_non_zero_exit: false
|
47
|
-
execute *MRSK.app.start
|
62
|
+
execute *MRSK.app.start
|
48
63
|
end
|
49
64
|
end
|
50
65
|
|
data/lib/mrsk/commander.rb
CHANGED
@@ -86,6 +86,13 @@ class Mrsk::Commander
|
|
86
86
|
SSHKit.config.output_verbosity = old_level
|
87
87
|
end
|
88
88
|
|
89
|
+
# Test-induced damage!
|
90
|
+
def reset
|
91
|
+
@config = @config_file = @destination = @version = nil
|
92
|
+
@app = @builder = @traefik = @registry = @prune = nil
|
93
|
+
@verbosity = :info
|
94
|
+
end
|
95
|
+
|
89
96
|
private
|
90
97
|
def cascading_version
|
91
98
|
version.presence || ENV["VERSION"] || `git rev-parse HEAD`.strip
|
@@ -33,6 +33,7 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
|
33
33
|
docker :ps, *service_filter
|
34
34
|
end
|
35
35
|
|
36
|
+
|
36
37
|
def logs(since: nil, lines: nil, grep: nil)
|
37
38
|
pipe \
|
38
39
|
docker(:logs, service_name, (" --since #{since}" if since), (" -n #{lines}" if lines), "-t", "2>&1"),
|
@@ -46,14 +47,15 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
|
46
47
|
).join(" ")
|
47
48
|
end
|
48
49
|
|
49
|
-
|
50
|
+
|
51
|
+
def execute_in_existing_container(*command, interactive: false)
|
50
52
|
docker :exec,
|
51
53
|
("-it" if interactive),
|
52
54
|
service_name,
|
53
55
|
*command
|
54
56
|
end
|
55
57
|
|
56
|
-
def
|
58
|
+
def execute_in_new_container(*command, interactive: false)
|
57
59
|
docker :run,
|
58
60
|
("-it" if interactive),
|
59
61
|
"--rm",
|
@@ -63,18 +65,19 @@ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
|
|
63
65
|
*command
|
64
66
|
end
|
65
67
|
|
66
|
-
def
|
67
|
-
|
68
|
+
def execute_in_existing_container_over_ssh(*command)
|
69
|
+
run_over_ssh execute_in_existing_container(*command, interactive: true).join(" ")
|
68
70
|
end
|
69
71
|
|
70
|
-
def
|
71
|
-
run_over_ssh
|
72
|
+
def execute_in_new_container_over_ssh(*command)
|
73
|
+
run_over_ssh execute_in_new_container(*command, interactive: true).join(" ")
|
72
74
|
end
|
73
75
|
|
74
|
-
def
|
75
|
-
|
76
|
+
def run_over_ssh(command)
|
77
|
+
super command, host: host
|
76
78
|
end
|
77
79
|
|
80
|
+
|
78
81
|
def ensure_local_file_present(local_file)
|
79
82
|
if !local_file.is_a?(StringIO) && !Pathname.new(local_file).exist?
|
80
83
|
raise "Missing file: #{local_file}"
|
data/lib/mrsk/commands/app.rb
CHANGED
@@ -7,7 +7,7 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|
7
7
|
docker :run,
|
8
8
|
"-d",
|
9
9
|
"--restart unless-stopped",
|
10
|
-
"--name",
|
10
|
+
"--name", service_with_version,
|
11
11
|
*rails_master_key_arg,
|
12
12
|
*role.env_args,
|
13
13
|
*config.volume_args,
|
@@ -16,22 +16,19 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|
16
16
|
role.cmd
|
17
17
|
end
|
18
18
|
|
19
|
-
def start
|
20
|
-
docker :start,
|
21
|
-
end
|
22
|
-
|
23
|
-
def current_container_id
|
24
|
-
docker :ps, "-q", *service_filter
|
19
|
+
def start
|
20
|
+
docker :start, service_with_version
|
25
21
|
end
|
26
22
|
|
27
23
|
def stop
|
28
|
-
pipe current_container_id,
|
24
|
+
pipe current_container_id, xargs(docker(:stop))
|
29
25
|
end
|
30
26
|
|
31
27
|
def info
|
32
28
|
docker :ps, *service_filter
|
33
29
|
end
|
34
30
|
|
31
|
+
|
35
32
|
def logs(since: nil, lines: nil, grep: nil)
|
36
33
|
pipe \
|
37
34
|
current_container_id,
|
@@ -39,14 +36,23 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|
39
36
|
("grep '#{grep}'" if grep)
|
40
37
|
end
|
41
38
|
|
42
|
-
def
|
39
|
+
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
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def execute_in_existing_container(*command, interactive: false)
|
43
49
|
docker :exec,
|
44
50
|
("-it" if interactive),
|
45
51
|
config.service_with_version,
|
46
52
|
*command
|
47
53
|
end
|
48
54
|
|
49
|
-
def
|
55
|
+
def execute_in_new_container(*command, interactive: false)
|
50
56
|
docker :run,
|
51
57
|
("-it" if interactive),
|
52
58
|
"--rm",
|
@@ -57,39 +63,70 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
|
|
57
63
|
*command
|
58
64
|
end
|
59
65
|
|
60
|
-
def
|
61
|
-
run_over_ssh
|
66
|
+
def execute_in_existing_container_over_ssh(*command, host:)
|
67
|
+
run_over_ssh execute_in_existing_container(*command, interactive: true).join(" "), host: host
|
62
68
|
end
|
63
69
|
|
64
|
-
def
|
65
|
-
run_over_ssh
|
66
|
-
current_container_id,
|
67
|
-
"xargs docker logs -t -n 10 -f 2>&1",
|
68
|
-
(%(grep "#{grep}") if grep)
|
69
|
-
).join(" "), host: host
|
70
|
+
def execute_in_new_container_over_ssh(*command, host:)
|
71
|
+
run_over_ssh execute_in_new_container(*command, interactive: true).join(" "), host: host
|
70
72
|
end
|
71
73
|
|
72
|
-
|
73
|
-
|
74
|
+
|
75
|
+
def current_container_id
|
76
|
+
docker :ps, "-q", *service_filter
|
77
|
+
end
|
78
|
+
|
79
|
+
def container_id_for(container_name:)
|
80
|
+
docker :container, :ls, "-a", "-f", "name=#{container_name}", "-q"
|
74
81
|
end
|
75
82
|
|
76
|
-
def
|
77
|
-
|
83
|
+
def current_running_version
|
84
|
+
# FIXME: Find more graceful way to extract the version from "app-version" than using sed and tail!
|
85
|
+
pipe \
|
86
|
+
docker(:ps, "--filter", "label=service=#{config.service}", "--format", '"{{.Names}}"'),
|
87
|
+
%(sed 's/-/\\n/g'),
|
88
|
+
"tail -n 1"
|
78
89
|
end
|
79
90
|
|
91
|
+
def most_recent_version_from_available_images
|
92
|
+
pipe \
|
93
|
+
docker(:image, :ls, "--format", '"{{.Tag}}"', config.repository),
|
94
|
+
"head -n 1"
|
95
|
+
end
|
96
|
+
|
97
|
+
|
80
98
|
def list_containers
|
81
99
|
docker :container, :ls, "-a", *service_filter
|
82
100
|
end
|
83
101
|
|
102
|
+
def remove_container(version:)
|
103
|
+
pipe \
|
104
|
+
container_id_for(container_name: service_with_version(version)),
|
105
|
+
xargs(docker(:container, :rm))
|
106
|
+
end
|
107
|
+
|
84
108
|
def remove_containers
|
85
109
|
docker :container, :prune, "-f", *service_filter
|
86
110
|
end
|
87
111
|
|
112
|
+
def list_images
|
113
|
+
docker :image, :ls, config.repository
|
114
|
+
end
|
115
|
+
|
88
116
|
def remove_images
|
89
117
|
docker :image, :prune, "-a", "-f", *service_filter
|
90
118
|
end
|
91
119
|
|
120
|
+
|
92
121
|
private
|
122
|
+
def service_with_version(version = nil)
|
123
|
+
if version
|
124
|
+
"#{config.service}-#{version}"
|
125
|
+
else
|
126
|
+
config.service_with_version
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
93
130
|
def service_filter
|
94
131
|
[ "--filter", "label=service=#{config.service}" ]
|
95
132
|
end
|
data/lib/mrsk/commands/base.rb
CHANGED
data/lib/mrsk/configuration.rb
CHANGED
@@ -9,6 +9,7 @@ class Mrsk::Configuration
|
|
9
9
|
delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :raw_config, allow_nil: true
|
10
10
|
delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils
|
11
11
|
|
12
|
+
attr_accessor :version
|
12
13
|
attr_accessor :raw_config
|
13
14
|
|
14
15
|
class << self
|
@@ -52,7 +53,7 @@ class Mrsk::Configuration
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def accessories
|
55
|
-
@accessories ||= raw_config.accessories&.keys&.collect { |name| Mrsk::Configuration::
|
56
|
+
@accessories ||= raw_config.accessories&.keys&.collect { |name| Mrsk::Configuration::Accessory.new(name, config: self) } || []
|
56
57
|
end
|
57
58
|
|
58
59
|
def accessory(name)
|
@@ -73,10 +74,6 @@ class Mrsk::Configuration
|
|
73
74
|
end
|
74
75
|
|
75
76
|
|
76
|
-
def version
|
77
|
-
@version
|
78
|
-
end
|
79
|
-
|
80
77
|
def repository
|
81
78
|
[ raw_config.registry["server"], image ].compact.join("/")
|
82
79
|
end
|
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.5.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-
|
11
|
+
date: 2023-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
127
|
- !ruby/object:Gem::Version
|
128
128
|
version: '0'
|
129
129
|
requirements: []
|
130
|
-
rubygems_version: 3.4.
|
130
|
+
rubygems_version: 3.4.6
|
131
131
|
signing_key:
|
132
132
|
specification_version: 4
|
133
133
|
summary: Deploy Rails apps in containers to servers running Docker with zero downtime.
|