mrsk 0.0.3 → 0.2.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 +193 -77
- data/bin/mrsk +5 -0
- data/lib/mrsk/cli/accessory.rb +85 -0
- data/lib/mrsk/cli/app.rb +123 -0
- data/lib/mrsk/cli/base.rb +48 -0
- data/lib/mrsk/cli/build.rb +53 -0
- data/lib/mrsk/cli/main.rb +110 -0
- data/lib/mrsk/cli/prune.rb +19 -0
- data/lib/mrsk/cli/registry.rb +18 -0
- data/lib/mrsk/cli/server.rb +8 -0
- data/lib/mrsk/cli/templates/deploy.yml +17 -0
- data/lib/mrsk/cli/traefik.rb +77 -0
- data/lib/mrsk/cli.rb +9 -0
- data/lib/mrsk/commander.rb +45 -5
- data/lib/mrsk/commands/accessory.rb +61 -0
- data/lib/mrsk/commands/app.rb +50 -10
- data/lib/mrsk/commands/base.rb +13 -9
- data/lib/mrsk/commands/builder/base.rb +26 -0
- data/lib/mrsk/commands/builder/multiarch/remote.rb +12 -4
- data/lib/mrsk/commands/builder/multiarch.rb +17 -9
- data/lib/mrsk/commands/builder/native/remote.rb +71 -0
- data/lib/mrsk/commands/builder/native.rb +3 -7
- data/lib/mrsk/commands/builder.rb +11 -7
- data/lib/mrsk/commands/traefik.rb +13 -3
- data/lib/mrsk/configuration/accessory.rb +60 -0
- data/lib/mrsk/configuration/role.rb +46 -14
- data/lib/mrsk/configuration.rb +86 -43
- data/lib/mrsk/sshkit_with_ext.rb +12 -0
- data/lib/mrsk/utils.rb +29 -0
- data/lib/mrsk/version.rb +1 -1
- data/lib/mrsk.rb +0 -1
- metadata +40 -18
- data/lib/mrsk/engine.rb +0 -4
- data/lib/tasks/mrsk/app.rake +0 -97
- data/lib/tasks/mrsk/build.rake +0 -52
- data/lib/tasks/mrsk/mrsk.rake +0 -37
- data/lib/tasks/mrsk/prune.rake +0 -18
- data/lib/tasks/mrsk/registry.rake +0 -16
- data/lib/tasks/mrsk/server.rake +0 -11
- data/lib/tasks/mrsk/setup.rb +0 -6
- data/lib/tasks/mrsk/templates/deploy.yml +0 -24
- data/lib/tasks/mrsk/templates/mrsk +0 -8
- data/lib/tasks/mrsk/traefik.rake +0 -41
@@ -15,12 +15,20 @@ class Mrsk::Commands::Builder::Multiarch::Remote < Mrsk::Commands::Builder::Mult
|
|
15
15
|
end
|
16
16
|
|
17
17
|
private
|
18
|
+
def builder_name
|
19
|
+
super + "-remote"
|
20
|
+
end
|
21
|
+
|
22
|
+
def builder_name_with_arch(arch)
|
23
|
+
"#{builder_name}-#{arch}"
|
24
|
+
end
|
25
|
+
|
18
26
|
def create_local_buildx
|
19
|
-
docker :buildx, :create, "--
|
27
|
+
docker :buildx, :create, "--name", builder_name, builder_name_with_arch(local["arch"]), "--platform", "linux/#{local["arch"]}"
|
20
28
|
end
|
21
29
|
|
22
30
|
def append_remote_buildx
|
23
|
-
docker :buildx, :create, "--append", "--name",
|
31
|
+
docker :buildx, :create, "--append", "--name", builder_name, builder_name_with_arch(remote["arch"]), "--platform", "linux/#{remote["arch"]}"
|
24
32
|
end
|
25
33
|
|
26
34
|
def create_contexts
|
@@ -30,7 +38,7 @@ class Mrsk::Commands::Builder::Multiarch::Remote < Mrsk::Commands::Builder::Mult
|
|
30
38
|
end
|
31
39
|
|
32
40
|
def create_context(arch, host)
|
33
|
-
docker :context, :create,
|
41
|
+
docker :context, :create, builder_name_with_arch(arch), "--description", "'#{builder_name} #{arch} native host'", "--docker", "'host=#{host}'"
|
34
42
|
end
|
35
43
|
|
36
44
|
def remove_contexts
|
@@ -40,7 +48,7 @@ class Mrsk::Commands::Builder::Multiarch::Remote < Mrsk::Commands::Builder::Mult
|
|
40
48
|
end
|
41
49
|
|
42
50
|
def remove_context(arch)
|
43
|
-
docker :context, :rm,
|
51
|
+
docker :context, :rm, builder_name_with_arch(arch)
|
44
52
|
end
|
45
53
|
|
46
54
|
def local
|
@@ -1,20 +1,23 @@
|
|
1
|
-
require "mrsk/commands/base"
|
1
|
+
require "mrsk/commands/builder/base"
|
2
2
|
|
3
|
-
class Mrsk::Commands::Builder::Multiarch < Mrsk::Commands::Base
|
3
|
+
class Mrsk::Commands::Builder::Multiarch < Mrsk::Commands::Builder::Base
|
4
4
|
def create
|
5
|
-
docker :buildx, :create, "--use", "--name",
|
5
|
+
docker :buildx, :create, "--use", "--name", builder_name
|
6
6
|
end
|
7
7
|
|
8
8
|
def remove
|
9
|
-
docker :buildx, :rm,
|
9
|
+
docker :buildx, :rm, builder_name
|
10
10
|
end
|
11
11
|
|
12
12
|
def push
|
13
|
-
docker :buildx, :build,
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
docker :buildx, :build,
|
14
|
+
"--push",
|
15
|
+
"--platform", "linux/amd64,linux/arm64",
|
16
|
+
"--builder", builder_name,
|
17
|
+
"-t", config.absolute_image,
|
18
|
+
*build_args,
|
19
|
+
*build_secrets,
|
20
|
+
"."
|
18
21
|
end
|
19
22
|
|
20
23
|
def info
|
@@ -22,4 +25,9 @@ class Mrsk::Commands::Builder::Multiarch < Mrsk::Commands::Base
|
|
22
25
|
docker(:context, :ls),
|
23
26
|
docker(:buildx, :ls)
|
24
27
|
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def builder_name
|
31
|
+
"mrsk-#{config.service}-multiarch"
|
32
|
+
end
|
25
33
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "mrsk/commands/builder/native"
|
2
|
+
|
3
|
+
class Mrsk::Commands::Builder::Native::Remote < Mrsk::Commands::Builder::Native
|
4
|
+
def create
|
5
|
+
combine \
|
6
|
+
create_context,
|
7
|
+
create_buildx
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove
|
11
|
+
combine \
|
12
|
+
remove_context,
|
13
|
+
remove_buildx
|
14
|
+
end
|
15
|
+
|
16
|
+
def push
|
17
|
+
docker :buildx, :build,
|
18
|
+
"--push",
|
19
|
+
"--platform", platform,
|
20
|
+
"--builder", builder_name,
|
21
|
+
"-t", config.absolute_image,
|
22
|
+
*build_args,
|
23
|
+
*build_secrets,
|
24
|
+
"."
|
25
|
+
end
|
26
|
+
|
27
|
+
def info
|
28
|
+
combine \
|
29
|
+
docker(:context, :ls),
|
30
|
+
docker(:buildx, :ls)
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
private
|
35
|
+
def arch
|
36
|
+
config.builder["remote"]["arch"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def host
|
40
|
+
config.builder["remote"]["host"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def builder_name
|
44
|
+
"mrsk-#{config.service}-native-remote"
|
45
|
+
end
|
46
|
+
|
47
|
+
def builder_name_with_arch
|
48
|
+
"#{builder_name}-#{arch}"
|
49
|
+
end
|
50
|
+
|
51
|
+
def platform
|
52
|
+
"linux/#{arch}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_context
|
56
|
+
docker :context, :create,
|
57
|
+
builder_name_with_arch, "--description", "'#{builder_name} #{arch} native host'", "--docker", "'host=#{host}'"
|
58
|
+
end
|
59
|
+
|
60
|
+
def remove_context
|
61
|
+
docker :context, :rm, builder_name_with_arch
|
62
|
+
end
|
63
|
+
|
64
|
+
def create_buildx
|
65
|
+
docker :buildx, :create, "--name", builder_name, builder_name_with_arch, "--platform", platform
|
66
|
+
end
|
67
|
+
|
68
|
+
def remove_buildx
|
69
|
+
docker :buildx, :rm, builder_name
|
70
|
+
end
|
71
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require "mrsk/commands/base"
|
1
|
+
require "mrsk/commands/builder/base"
|
2
2
|
|
3
|
-
class Mrsk::Commands::Builder::Native < Mrsk::Commands::Base
|
3
|
+
class Mrsk::Commands::Builder::Native < Mrsk::Commands::Builder::Base
|
4
4
|
def create
|
5
5
|
# No-op on native
|
6
6
|
end
|
@@ -11,14 +11,10 @@ class Mrsk::Commands::Builder::Native < Mrsk::Commands::Base
|
|
11
11
|
|
12
12
|
def push
|
13
13
|
combine \
|
14
|
-
docker(:build, "-t", config.absolute_image, "."),
|
14
|
+
docker(:build, "-t", *build_args, *build_secrets, config.absolute_image, "."),
|
15
15
|
docker(:push, config.absolute_image)
|
16
16
|
end
|
17
17
|
|
18
|
-
def pull
|
19
|
-
docker :pull, config.absolute_image
|
20
|
-
end
|
21
|
-
|
22
18
|
def info
|
23
19
|
# No-op on native
|
24
20
|
end
|
@@ -2,22 +2,21 @@ require "mrsk/commands/base"
|
|
2
2
|
|
3
3
|
class Mrsk::Commands::Builder < Mrsk::Commands::Base
|
4
4
|
delegate :create, :remove, :push, :pull, :info, to: :target
|
5
|
-
delegate :native?, :multiarch?, :remote?, to: :name
|
6
5
|
|
7
6
|
def name
|
8
|
-
target.class.to_s.
|
7
|
+
target.class.to_s.remove("Mrsk::Commands::Builder::").underscore
|
9
8
|
end
|
10
9
|
|
11
10
|
def target
|
12
11
|
case
|
13
|
-
when config.builder.
|
14
|
-
multiarch
|
15
|
-
when config.builder["multiarch"] == false
|
12
|
+
when config.builder && config.builder["multiarch"] == false
|
16
13
|
native
|
17
|
-
when config.builder["local"] && config.builder["
|
14
|
+
when config.builder && config.builder["local"] && config.builder["remote"]
|
18
15
|
multiarch_remote
|
16
|
+
when config.builder && config.builder["remote"]
|
17
|
+
native_remote
|
19
18
|
else
|
20
|
-
|
19
|
+
multiarch
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
@@ -25,6 +24,10 @@ class Mrsk::Commands::Builder < Mrsk::Commands::Base
|
|
25
24
|
@native ||= Mrsk::Commands::Builder::Native.new(config)
|
26
25
|
end
|
27
26
|
|
27
|
+
def native_remote
|
28
|
+
@native ||= Mrsk::Commands::Builder::Native::Remote.new(config)
|
29
|
+
end
|
30
|
+
|
28
31
|
def multiarch
|
29
32
|
@multiarch ||= Mrsk::Commands::Builder::Multiarch.new(config)
|
30
33
|
end
|
@@ -35,5 +38,6 @@ class Mrsk::Commands::Builder < Mrsk::Commands::Base
|
|
35
38
|
end
|
36
39
|
|
37
40
|
require "mrsk/commands/builder/native"
|
41
|
+
require "mrsk/commands/builder/native/remote"
|
38
42
|
require "mrsk/commands/builder/multiarch"
|
39
43
|
require "mrsk/commands/builder/multiarch/remote"
|
@@ -8,7 +8,8 @@ class Mrsk::Commands::Traefik < Mrsk::Commands::Base
|
|
8
8
|
"-p 80:80",
|
9
9
|
"-v /var/run/docker.sock:/var/run/docker.sock",
|
10
10
|
"traefik",
|
11
|
-
"--providers.docker"
|
11
|
+
"--providers.docker",
|
12
|
+
"--log.level=DEBUG"
|
12
13
|
end
|
13
14
|
|
14
15
|
def start
|
@@ -23,8 +24,17 @@ class Mrsk::Commands::Traefik < Mrsk::Commands::Base
|
|
23
24
|
docker :ps, "--filter", "name=traefik"
|
24
25
|
end
|
25
26
|
|
26
|
-
def logs
|
27
|
-
|
27
|
+
def logs(since: nil, lines: nil, grep: nil)
|
28
|
+
pipe \
|
29
|
+
docker(:logs, "traefik", (" --since #{since}" if since), (" -n #{lines}" if lines), "-t", "2>&1"),
|
30
|
+
("grep '#{grep}'" if grep)
|
31
|
+
end
|
32
|
+
|
33
|
+
def follow_logs(host:, grep: nil)
|
34
|
+
run_over_ssh pipe(
|
35
|
+
docker(:logs, "traefik", "-t", "-n", "10", "-f", "2>&1"),
|
36
|
+
("grep '#{grep}'" if grep)
|
37
|
+
).join(" "), host: host
|
28
38
|
end
|
29
39
|
|
30
40
|
def remove_container
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class Mrsk::Configuration::Assessory
|
2
|
+
delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils
|
3
|
+
|
4
|
+
attr_accessor :name, :specifics
|
5
|
+
|
6
|
+
def initialize(name, config:)
|
7
|
+
@name, @config, @specifics = name.inquiry, config, config.raw_config["accessories"][name]
|
8
|
+
end
|
9
|
+
|
10
|
+
def service_name
|
11
|
+
"#{config.service}-#{name}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def image
|
15
|
+
specifics["image"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def host
|
19
|
+
specifics["host"] || raise(ArgumentError, "Missing host for accessory")
|
20
|
+
end
|
21
|
+
|
22
|
+
def port
|
23
|
+
if specifics["port"].to_s.include?(":")
|
24
|
+
specifics["port"]
|
25
|
+
else
|
26
|
+
"#{specifics["port"]}:#{specifics["port"]}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def labels
|
31
|
+
default_labels.merge(specifics["labels"] || {})
|
32
|
+
end
|
33
|
+
|
34
|
+
def label_args
|
35
|
+
argumentize "--label", labels
|
36
|
+
end
|
37
|
+
|
38
|
+
def env
|
39
|
+
specifics["env"] || {}
|
40
|
+
end
|
41
|
+
|
42
|
+
def env_args
|
43
|
+
argumentize_env_with_secrets env
|
44
|
+
end
|
45
|
+
|
46
|
+
def volumes
|
47
|
+
specifics["volumes"] || []
|
48
|
+
end
|
49
|
+
|
50
|
+
def volume_args
|
51
|
+
argumentize "--volume", volumes
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
attr_accessor :config
|
56
|
+
|
57
|
+
def default_labels
|
58
|
+
{ "service" => service_name }
|
59
|
+
end
|
60
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Mrsk::Configuration::Role
|
2
|
-
delegate :argumentize, to: Mrsk::
|
2
|
+
delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils
|
3
3
|
|
4
4
|
attr_accessor :name
|
5
5
|
|
@@ -12,21 +12,33 @@ class Mrsk::Configuration::Role
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def labels
|
15
|
-
|
16
|
-
default_labels.merge(traefik_labels).merge(custom_labels)
|
17
|
-
else
|
18
|
-
default_labels.merge(custom_labels)
|
19
|
-
end
|
15
|
+
default_labels.merge(traefik_labels).merge(custom_labels)
|
20
16
|
end
|
21
17
|
|
22
18
|
def label_args
|
23
19
|
argumentize "--label", labels
|
24
20
|
end
|
25
21
|
|
22
|
+
def env
|
23
|
+
if config.env && config.env["secret"]
|
24
|
+
merged_env_with_secrets
|
25
|
+
else
|
26
|
+
merged_env
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def env_args
|
31
|
+
argumentize_env_with_secrets env
|
32
|
+
end
|
33
|
+
|
26
34
|
def cmd
|
27
35
|
specializations["cmd"]
|
28
36
|
end
|
29
37
|
|
38
|
+
def running_traefik?
|
39
|
+
name.web? || specializations["traefik"]
|
40
|
+
end
|
41
|
+
|
30
42
|
private
|
31
43
|
attr_accessor :config
|
32
44
|
|
@@ -44,13 +56,17 @@ class Mrsk::Configuration::Role
|
|
44
56
|
end
|
45
57
|
|
46
58
|
def traefik_labels
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
59
|
+
if running_traefik?
|
60
|
+
{
|
61
|
+
"traefik.http.routers.#{config.service}.rule" => "'PathPrefix(`/`)'",
|
62
|
+
"traefik.http.services.#{config.service}.loadbalancer.healthcheck.path" => "/up",
|
63
|
+
"traefik.http.services.#{config.service}.loadbalancer.healthcheck.interval" => "1s",
|
64
|
+
"traefik.http.middlewares.#{config.service}.retry.attempts" => "3",
|
65
|
+
"traefik.http.middlewares.#{config.service}.retry.initialinterval" => "500ms"
|
66
|
+
}
|
67
|
+
else
|
68
|
+
{}
|
69
|
+
end
|
54
70
|
end
|
55
71
|
|
56
72
|
def custom_labels
|
@@ -64,7 +80,23 @@ class Mrsk::Configuration::Role
|
|
64
80
|
if config.servers.is_a?(Array) || config.servers[name].is_a?(Array)
|
65
81
|
{ }
|
66
82
|
else
|
67
|
-
config.servers[name].
|
83
|
+
config.servers[name].except("hosts")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def specialized_env
|
88
|
+
specializations["env"] || {}
|
89
|
+
end
|
90
|
+
|
91
|
+
def merged_env
|
92
|
+
config.env&.merge(specialized_env) || {}
|
93
|
+
end
|
94
|
+
|
95
|
+
# Secrets are stored in an array, which won't merge by default, so have to do it by hand.
|
96
|
+
def merged_env_with_secrets
|
97
|
+
merged_env.tap do |new_env|
|
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
|
68
100
|
end
|
69
101
|
end
|
70
102
|
end
|
data/lib/mrsk/configuration.rb
CHANGED
@@ -1,26 +1,44 @@
|
|
1
1
|
require "active_support/ordered_options"
|
2
2
|
require "active_support/core_ext/string/inquiry"
|
3
|
+
require "active_support/core_ext/module/delegation"
|
4
|
+
require "pathname"
|
3
5
|
require "erb"
|
6
|
+
require "mrsk/utils"
|
4
7
|
|
5
8
|
class Mrsk::Configuration
|
6
|
-
delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :
|
9
|
+
delegate :service, :image, :servers, :env, :labels, :registry, :builder, to: :raw_config, allow_nil: true
|
10
|
+
delegate :argumentize, :argumentize_env_with_secrets, to: Mrsk::Utils
|
11
|
+
|
12
|
+
attr_accessor :raw_config
|
7
13
|
|
8
14
|
class << self
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
+
def create_from(base_config_file, destination: nil, version: "missing")
|
16
|
+
new(load_config_file(base_config_file).tap do |config|
|
17
|
+
if destination
|
18
|
+
config.merge! \
|
19
|
+
load_config_file destination_config_file(base_config_file, destination)
|
20
|
+
end
|
21
|
+
end, version: version)
|
15
22
|
end
|
16
23
|
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
private
|
25
|
+
def load_config_file(file)
|
26
|
+
if file.exist?
|
27
|
+
YAML.load(ERB.new(IO.read(file)).result).symbolize_keys
|
28
|
+
else
|
29
|
+
raise "Configuration file not found in #{file}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def destination_config_file(base_config_file, destination)
|
34
|
+
dir, basename = base_config_file.split
|
35
|
+
dir.join basename.to_s.remove(".yml") + ".#{destination}.yml"
|
36
|
+
end
|
20
37
|
end
|
21
38
|
|
22
|
-
def initialize(
|
23
|
-
@
|
39
|
+
def initialize(raw_config, version: "missing", validate: true)
|
40
|
+
@raw_config = ActiveSupport::InheritableOptions.new(raw_config)
|
41
|
+
@version = version
|
24
42
|
ensure_required_keys_present if validate
|
25
43
|
end
|
26
44
|
|
@@ -33,36 +51,34 @@ class Mrsk::Configuration
|
|
33
51
|
roles.detect { |r| r.name == name.to_s }
|
34
52
|
end
|
35
53
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
when ENV["HOSTS"]
|
40
|
-
ENV["HOSTS"].split(",")
|
41
|
-
when ENV["ROLES"]
|
42
|
-
role_names = ENV["ROLES"].split(",")
|
43
|
-
roles.select { |r| role_names.include?(r.name) }.flat_map(&:hosts)
|
44
|
-
else
|
45
|
-
roles.flat_map(&:hosts)
|
46
|
-
end
|
54
|
+
def accessories
|
55
|
+
@accessories ||= raw_config.accessories.keys.collect { |name| Mrsk::Configuration::Assessory.new(name, config: self) }
|
56
|
+
end
|
47
57
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
58
|
+
def accessory(name)
|
59
|
+
accessories.detect { |a| a.name == name.to_s }
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def all_hosts
|
64
|
+
roles.flat_map(&:hosts)
|
53
65
|
end
|
54
66
|
|
55
|
-
def
|
67
|
+
def primary_web_host
|
56
68
|
role(:web).hosts.first
|
57
69
|
end
|
58
70
|
|
71
|
+
def traefik_hosts
|
72
|
+
roles.select(&:running_traefik?).flat_map(&:hosts)
|
73
|
+
end
|
74
|
+
|
59
75
|
|
60
76
|
def version
|
61
|
-
@version
|
77
|
+
@version
|
62
78
|
end
|
63
79
|
|
64
80
|
def repository
|
65
|
-
[
|
81
|
+
[ raw_config.registry["server"], image ].compact.join("/")
|
66
82
|
end
|
67
83
|
|
68
84
|
def absolute_image
|
@@ -75,15 +91,23 @@ class Mrsk::Configuration
|
|
75
91
|
|
76
92
|
|
77
93
|
def env_args
|
78
|
-
if
|
79
|
-
|
94
|
+
if raw_config.env.present?
|
95
|
+
argumentize_env_with_secrets(raw_config.env)
|
96
|
+
else
|
97
|
+
[]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def volume_args
|
102
|
+
if raw_config.volumes.present?
|
103
|
+
argumentize "--volume", raw_config.volumes
|
80
104
|
else
|
81
105
|
[]
|
82
106
|
end
|
83
107
|
end
|
84
108
|
|
85
109
|
def ssh_user
|
86
|
-
|
110
|
+
raw_config.ssh_user || "root"
|
87
111
|
end
|
88
112
|
|
89
113
|
def ssh_options
|
@@ -91,26 +115,45 @@ class Mrsk::Configuration
|
|
91
115
|
end
|
92
116
|
|
93
117
|
def master_key
|
94
|
-
ENV["RAILS_MASTER_KEY"] || File.read(
|
118
|
+
ENV["RAILS_MASTER_KEY"] || File.read(Pathname.new(File.expand_path("config/master.key")))
|
95
119
|
end
|
96
120
|
|
121
|
+
def to_h
|
122
|
+
{
|
123
|
+
roles: role_names,
|
124
|
+
hosts: all_hosts,
|
125
|
+
primary_host: primary_web_host,
|
126
|
+
version: version,
|
127
|
+
repository: repository,
|
128
|
+
absolute_image: absolute_image,
|
129
|
+
service_with_version: service_with_version,
|
130
|
+
env_args: env_args,
|
131
|
+
volume_args: volume_args,
|
132
|
+
ssh_options: ssh_options,
|
133
|
+
builder: raw_config.builder
|
134
|
+
}.compact
|
135
|
+
end
|
97
136
|
|
98
|
-
private
|
99
|
-
attr_accessor :config
|
100
137
|
|
138
|
+
private
|
101
139
|
def ensure_required_keys_present
|
102
|
-
%i[ service image registry ].each do |key|
|
103
|
-
raise ArgumentError, "Missing required configuration for #{key}" unless
|
140
|
+
%i[ service image registry servers ].each do |key|
|
141
|
+
raise ArgumentError, "Missing required configuration for #{key}" unless raw_config[key].present?
|
104
142
|
end
|
105
143
|
|
106
|
-
|
107
|
-
raise ArgumentError, "
|
108
|
-
end
|
144
|
+
if raw_config.registry["username"].blank?
|
145
|
+
raise ArgumentError, "You must specify a username for the registry in config/deploy.yml"
|
146
|
+
end
|
147
|
+
|
148
|
+
if raw_config.registry["password"].blank?
|
149
|
+
raise ArgumentError, "You must specify a password for the registry in config/deploy.yml (or set the ENV variable if that's used)"
|
150
|
+
end
|
109
151
|
end
|
110
152
|
|
111
153
|
def role_names
|
112
|
-
|
154
|
+
raw_config.servers.is_a?(Array) ? [ "web" ] : raw_config.servers.keys.sort
|
113
155
|
end
|
114
156
|
end
|
115
157
|
|
116
158
|
require "mrsk/configuration/role"
|
159
|
+
require "mrsk/configuration/accessory"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "sshkit"
|
2
|
+
require "sshkit/dsl"
|
3
|
+
|
4
|
+
class SSHKit::Backend::Abstract
|
5
|
+
def capture_with_info(*args)
|
6
|
+
capture(*args, verbosity: Logger::INFO)
|
7
|
+
end
|
8
|
+
|
9
|
+
def puts_by_host(host, output, type: "App")
|
10
|
+
puts "#{type} Host: #{host}\n#{output}\n\n"
|
11
|
+
end
|
12
|
+
end
|
data/lib/mrsk/utils.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Mrsk::Utils
|
2
|
+
extend self
|
3
|
+
|
4
|
+
# Return a list of shell arguments using the same named argument against the passed attributes (hash or array).
|
5
|
+
def argumentize(argument, attributes, redacted: false)
|
6
|
+
Array(attributes).flat_map do |k, v|
|
7
|
+
if v.present?
|
8
|
+
[ argument, redacted ? redact("#{k}=#{v}") : "#{k}=#{v}" ]
|
9
|
+
else
|
10
|
+
[ argument, k ]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Return a list of shell arguments using the same named argument against the passed attributes,
|
16
|
+
# but redacts and expands secrets.
|
17
|
+
def argumentize_env_with_secrets(env)
|
18
|
+
if (secrets = env["secret"]).present?
|
19
|
+
argumentize("-e", secrets.to_h { |key| [ key, ENV.fetch(key) ] }, redacted: true) + argumentize("-e", env["clear"])
|
20
|
+
else
|
21
|
+
argumentize "-e", env
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Copied from SSHKit::Backend::Abstract#redact to be available inside Commands classes
|
26
|
+
def redact(arg) # Used in execute_command to hide redact() args a user passes in
|
27
|
+
arg.to_s.extend(SSHKit::Redaction) # to_s due to our inability to extend Integer, etc
|
28
|
+
end
|
29
|
+
end
|
data/lib/mrsk/version.rb
CHANGED