mrsk 0.1.0 → 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.
@@ -9,22 +9,22 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base
9
9
 
10
10
  desc "push", "Build locally and push app image to registry"
11
11
  def push
12
+ verbose = options[:verbose]
13
+
12
14
  run_locally do
13
15
  begin
14
- debug "Using builder: #{MRSK.builder.name}"
15
- info "Building image may take a while (run with --verbose for progress logging)"
16
- execute *MRSK.builder.push
16
+ MRSK.verbosity(:debug) { execute *MRSK.builder.push }
17
17
  rescue SSHKit::Command::Failed => e
18
18
  error "Missing compatible builder, so creating a new one first"
19
19
  execute *MRSK.builder.create
20
- execute *MRSK.builder.push
20
+ MRSK.verbosity(:debug) { execute *MRSK.builder.push }
21
21
  end
22
22
  end
23
23
  end
24
24
 
25
25
  desc "pull", "Pull app image from the registry onto servers"
26
26
  def pull
27
- on(MRSK.config.hosts) { execute *MRSK.builder.pull }
27
+ on(MRSK.hosts) { execute *MRSK.builder.pull }
28
28
  end
29
29
 
30
30
  desc "create", "Create a local build setup"
@@ -46,7 +46,7 @@ class Mrsk::Cli::Build < Mrsk::Cli::Base
46
46
  desc "details", "Show the name of the configured builder"
47
47
  def details
48
48
  run_locally do
49
- puts "Builder: #{MRSK.builder.name} (#{MRSK.builder.target.class.name})"
49
+ puts "Builder: #{MRSK.builder.name}"
50
50
  puts capture(*MRSK.builder.info)
51
51
  end
52
52
  end
data/lib/mrsk/cli/main.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "mrsk/cli/base"
2
2
 
3
+ require "mrsk/cli/accessory"
3
4
  require "mrsk/cli/app"
4
5
  require "mrsk/cli/build"
5
6
  require "mrsk/cli/prune"
@@ -32,7 +33,7 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
32
33
 
33
34
  desc "rollback [VERSION]", "Rollback the app to VERSION (that must already be on servers)"
34
35
  def rollback(version)
35
- on(MRSK.config.hosts) do
36
+ on(MRSK.hosts) do
36
37
  execute *MRSK.app.stop, raise_on_non_zero_exit: false
37
38
  execute *MRSK.app.start(version: version)
38
39
  end
@@ -44,6 +45,13 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
44
45
  invoke "mrsk:cli:app:details"
45
46
  end
46
47
 
48
+ desc "config", "Show combined config"
49
+ def config
50
+ run_locally do
51
+ pp MRSK.config.to_h
52
+ end
53
+ end
54
+
47
55
  desc "install", "Create config stub in config/deploy.yml and binstub in bin/mrsk"
48
56
  option :skip_binstub, type: :boolean, default: false, desc: "Skip adding MRSK to the Gemfile and creating bin/mrsk binstub"
49
57
  def install
@@ -79,6 +87,9 @@ class Mrsk::Cli::Main < Mrsk::Cli::Base
79
87
  puts Mrsk::VERSION
80
88
  end
81
89
 
90
+ desc "accessory", "Manage the accessories"
91
+ subcommand "accessory", Mrsk::Cli::Accessory
92
+
82
93
  desc "app", "Manage the application"
83
94
  subcommand "app", Mrsk::Cli::App
84
95
 
@@ -9,11 +9,11 @@ class Mrsk::Cli::Prune < Mrsk::Cli::Base
9
9
 
10
10
  desc "images", "Prune unused images older than 30 days"
11
11
  def images
12
- on(MRSK.config.hosts) { execute *MRSK.prune.images }
12
+ on(MRSK.hosts) { execute *MRSK.prune.images }
13
13
  end
14
14
 
15
15
  desc "containers", "Prune stopped containers for the service older than 3 days"
16
16
  def containers
17
- on(MRSK.config.hosts) { execute *MRSK.prune.containers }
17
+ on(MRSK.hosts) { execute *MRSK.prune.containers }
18
18
  end
19
19
  end
@@ -4,11 +4,15 @@ class Mrsk::Cli::Registry < Mrsk::Cli::Base
4
4
  desc "login", "Login to the registry locally and remotely"
5
5
  def login
6
6
  run_locally { execute *MRSK.registry.login }
7
- on(MRSK.config.hosts) { execute *MRSK.registry.login }
7
+ on(MRSK.hosts) { execute *MRSK.registry.login }
8
+ rescue ArgumentError => e
9
+ puts e.message
8
10
  end
9
11
 
10
12
  desc "logout", "Logout of the registry remotely"
11
13
  def logout
12
- on(MRSK.config.hosts) { execute *MRSK.registry.logout }
14
+ on(MRSK.hosts) { execute *MRSK.registry.logout }
15
+ rescue ArgumentError => e
16
+ puts e.message
13
17
  end
14
18
  end
@@ -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.config.hosts) { execute "which docker || apt-get install docker.io -y" }
6
+ on(MRSK.hosts) { execute "which docker || (apt-get update -y && apt-get install docker.io -y)" }
7
7
  end
8
8
  end
@@ -3,17 +3,24 @@ require "mrsk/cli/base"
3
3
  class Mrsk::Cli::Traefik < Mrsk::Cli::Base
4
4
  desc "boot", "Boot Traefik on servers"
5
5
  def boot
6
- on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.run, raise_on_non_zero_exit: false }
6
+ on(MRSK.traefik_hosts) { execute *MRSK.traefik.run, raise_on_non_zero_exit: false }
7
+ end
8
+
9
+ desc "reboot", "Reboot Traefik on servers (stop container, remove container, start new container)"
10
+ def reboot
11
+ invoke :stop
12
+ invoke :remove_container
13
+ invoke :boot
7
14
  end
8
15
 
9
16
  desc "start", "Start existing Traefik on servers"
10
17
  def start
11
- on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.start, raise_on_non_zero_exit: false }
18
+ on(MRSK.traefik_hosts) { execute *MRSK.traefik.start, raise_on_non_zero_exit: false }
12
19
  end
13
20
 
14
21
  desc "stop", "Stop Traefik on servers"
15
22
  def stop
16
- on(MRSK.config.role(:web).hosts) { execute *MRSK.traefik.stop, raise_on_non_zero_exit: false }
23
+ on(MRSK.traefik_hosts) { execute *MRSK.traefik.stop, raise_on_non_zero_exit: false }
17
24
  end
18
25
 
19
26
  desc "restart", "Restart Traefik on servers"
@@ -24,21 +31,47 @@ class Mrsk::Cli::Traefik < Mrsk::Cli::Base
24
31
 
25
32
  desc "details", "Display details about Traefik containers from servers"
26
33
  def details
27
- on(MRSK.config.role(:web).hosts) { |host| puts "Traefik Host: #{host}\n" + capture(*MRSK.traefik.info, verbosity: Logger::INFO) + "\n\n" }
34
+ on(MRSK.traefik_hosts) { |host| puts_by_host host, capture_with_info(*MRSK.traefik.info), type: "Traefik" }
28
35
  end
29
36
 
30
- desc "logs", "Show last 100 log lines from Traefik on servers"
37
+ desc "logs", "Show log lines from Traefik on servers"
38
+ option :since, aliases: "-s", desc: "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)"
39
+ option :lines, type: :numeric, aliases: "-n", desc: "Number of log lines to pull from each server"
40
+ option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)"
41
+ option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)"
31
42
  def logs
32
- on(MRSK.config.hosts) { |host| puts "Traefik Host: #{host}\n" + capture(*MRSK.traefik.logs) + "\n\n" }
43
+ grep = options[:grep]
44
+
45
+ if options[:follow]
46
+ run_locally do
47
+ info "Following logs on #{MRSK.primary_host}..."
48
+ info MRSK.traefik.follow_logs(host: MRSK.primary_host, grep: grep)
49
+ exec MRSK.traefik.follow_logs(host: MRSK.primary_host, grep: grep)
50
+ end
51
+ else
52
+ since = options[:since]
53
+ lines = options[:lines]
54
+
55
+ on(MRSK.traefik_hosts) do |host|
56
+ puts_by_host host, capture(*MRSK.traefik.logs(since: since, lines: lines, grep: grep)), type: "Traefik"
57
+ end
58
+ end
33
59
  end
34
60
 
35
61
  desc "remove", "Remove Traefik container and image from servers"
36
62
  def remove
37
63
  invoke :stop
64
+ invoke :remove_container
65
+ invoke :remove_image
66
+ end
38
67
 
39
- on(MRSK.config.role(:web).hosts) do
40
- execute *MRSK.traefik.remove_container
41
- execute *MRSK.traefik.remove_image
42
- end
68
+ desc "remove_container", "Remove Traefik container from servers"
69
+ def remove_container
70
+ on(MRSK.traefik_hosts) { execute *MRSK.traefik.remove_container }
71
+ end
72
+
73
+ desc "remove_container", "Remove Traefik image from servers"
74
+ def remove_image
75
+ on(MRSK.traefik_hosts) { execute *MRSK.traefik.remove_image }
43
76
  end
44
77
  end
data/lib/mrsk/cli.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  require "mrsk"
2
2
 
3
- MRSK = Mrsk::Commander.new \
4
- config_file: Pathname.new(File.expand_path("config/deploy.yml"))
5
-
6
3
  module Mrsk::Cli
7
4
  end
8
5
 
6
+ # SSHKit uses instance eval, so we need a global const for ergonomics
7
+ MRSK = Mrsk::Commander.new
8
+
9
9
  require "mrsk/cli/main"
@@ -1,4 +1,7 @@
1
+ require "active_support/core_ext/enumerable"
2
+
1
3
  require "mrsk/configuration"
4
+ require "mrsk/commands/accessory"
2
5
  require "mrsk/commands/app"
3
6
  require "mrsk/commands/builder"
4
7
  require "mrsk/commands/prune"
@@ -6,15 +9,43 @@ require "mrsk/commands/traefik"
6
9
  require "mrsk/commands/registry"
7
10
 
8
11
  class Mrsk::Commander
9
- attr_reader :config
10
- attr_accessor :verbose
12
+ attr_accessor :config_file, :destination, :verbose, :version
11
13
 
12
- def initialize(config_file:)
13
- @config_file = config_file
14
+ def initialize(config_file: nil, destination: nil, verbose: false)
15
+ @config_file, @destination, @verbose = config_file, destination, verbose
14
16
  end
15
17
 
16
18
  def config
17
- @config ||= Mrsk::Configuration.load_file(@config_file).tap { |config| setup_with(config) }
19
+ @config ||= \
20
+ Mrsk::Configuration
21
+ .create_from(config_file, destination: destination, version: cascading_version)
22
+ .tap { |config| configure_sshkit_with(config) }
23
+ end
24
+
25
+ attr_accessor :specific_hosts
26
+
27
+ def specific_primary!
28
+ self.specific_hosts = [ config.primary_web_host ]
29
+ end
30
+
31
+ def specific_roles=(role_names)
32
+ self.specific_hosts = config.roles.select { |r| role_names.include?(r.name) }.flat_map(&:hosts) if role_names.present?
33
+ end
34
+
35
+ def primary_host
36
+ specific_hosts&.sole || config.primary_web_host
37
+ end
38
+
39
+ def hosts
40
+ specific_hosts || config.all_hosts
41
+ end
42
+
43
+ def traefik_hosts
44
+ specific_hosts || config.traefik_hosts
45
+ end
46
+
47
+ def accessory_hosts
48
+ specific_hosts || config.accessories.collect(&:host)
18
49
  end
19
50
 
20
51
 
@@ -38,6 +69,10 @@ class Mrsk::Commander
38
69
  @prune ||= Mrsk::Commands::Prune.new(config)
39
70
  end
40
71
 
72
+ def accessory(name)
73
+ (@accessories ||= {})[name] ||= Mrsk::Commands::Accessory.new(config, name: name)
74
+ end
75
+
41
76
 
42
77
  def verbosity(level)
43
78
  old_level = SSHKit.config.output_verbosity
@@ -48,8 +83,12 @@ class Mrsk::Commander
48
83
  end
49
84
 
50
85
  private
86
+ def cascading_version
87
+ version.presence || ENV["VERSION"] || `git rev-parse HEAD`.strip
88
+ end
89
+
51
90
  # Lazy setup of SSHKit
52
- def setup_with(config)
91
+ def configure_sshkit_with(config)
53
92
  SSHKit::Backend::Netssh.configure { |ssh| ssh.ssh_options = config.ssh_options }
54
93
  SSHKit.config.command_map[:docker] = "docker" # No need to use /usr/bin/env, just clogs up the logs
55
94
  SSHKit.config.output_verbosity = :debug if verbose
@@ -0,0 +1,61 @@
1
+ require "mrsk/commands/base"
2
+
3
+ class Mrsk::Commands::Accessory < Mrsk::Commands::Base
4
+ attr_reader :accessory_config
5
+ delegate :service_name, :image, :host, :port, :env_args, :volume_args, :label_args, to: :accessory_config
6
+
7
+ def initialize(config, name:)
8
+ super(config)
9
+ @accessory_config = config.accessory(name)
10
+ end
11
+
12
+ def run
13
+ docker :run,
14
+ "--name", service_name,
15
+ "-d",
16
+ "--restart", "unless-stopped",
17
+ "-p", port,
18
+ *env_args,
19
+ *volume_args,
20
+ *label_args,
21
+ image
22
+ end
23
+
24
+ def start
25
+ docker :container, :start, service_name
26
+ end
27
+
28
+ def stop
29
+ docker :container, :stop, service_name
30
+ end
31
+
32
+ def info
33
+ docker :ps, *service_filter
34
+ end
35
+
36
+ def logs(since: nil, lines: nil, grep: nil)
37
+ pipe \
38
+ docker(:logs, service_name, (" --since #{since}" if since), (" -n #{lines}" if lines), "-t", "2>&1"),
39
+ ("grep '#{grep}'" if grep)
40
+ end
41
+
42
+ def follow_logs(grep: nil)
43
+ run_over_ssh pipe(
44
+ docker(:logs, service_name, "-t", "-n", "10", "-f", "2>&1"),
45
+ ("grep '#{grep}'" if grep)
46
+ ).join(" "), host: host
47
+ end
48
+
49
+ def remove_container
50
+ docker :container, :prune, "-f", *service_filter
51
+ end
52
+
53
+ def remove_image
54
+ docker :image, :prune, "-a", "-f", *service_filter
55
+ end
56
+
57
+ private
58
+ def service_filter
59
+ [ "--filter", "label=service=#{service_name}" ]
60
+ end
61
+ end
@@ -8,8 +8,9 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
8
8
  "-d",
9
9
  "--restart unless-stopped",
10
10
  "--name", config.service_with_version,
11
- "-e", redact("RAILS_MASTER_KEY=#{config.master_key}"),
12
- *config.env_args,
11
+ *rails_master_key_arg,
12
+ *role.env_args,
13
+ *config.volume_args,
13
14
  *role.label_args,
14
15
  config.absolute_image,
15
16
  role.cmd
@@ -19,29 +20,60 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
19
20
  docker :start, "#{config.service}-#{version}"
20
21
  end
21
22
 
23
+ def current_container_id
24
+ docker :ps, "-q", *service_filter
25
+ end
26
+
22
27
  def stop
23
- [ "docker ps -q #{service_filter.join(" ")} | xargs docker stop" ]
28
+ pipe current_container_id, "xargs docker stop"
24
29
  end
25
30
 
26
31
  def info
27
32
  docker :ps, *service_filter
28
33
  end
29
34
 
30
- def logs
31
- [ "docker ps -q #{service_filter.join(" ")} | xargs docker logs -n 100 -t" ]
35
+ def logs(since: nil, lines: nil, grep: nil)
36
+ pipe \
37
+ current_container_id,
38
+ "xargs docker logs#{" --since #{since}" if since}#{" -n #{lines}" if lines} -t 2>&1",
39
+ ("grep '#{grep}'" if grep)
32
40
  end
33
41
 
34
42
  def exec(*command, interactive: false)
35
43
  docker :exec,
36
44
  ("-it" if interactive),
37
- "-e", redact("RAILS_MASTER_KEY=#{config.master_key}"),
45
+ *rails_master_key_arg,
38
46
  *config.env_args,
47
+ *config.volume_args,
39
48
  config.service_with_version,
40
49
  *command
41
50
  end
42
51
 
43
- def console(host: config.primary_host)
44
- "ssh -t #{config.ssh_user}@#{host} '#{exec("bin/rails", "c", interactive: true).join(" ")}'"
52
+ def run_exec(*command, interactive: false)
53
+ docker :run,
54
+ ("-it" if interactive),
55
+ "--rm",
56
+ *rails_master_key_arg,
57
+ *config.env_args,
58
+ *config.volume_args,
59
+ config.absolute_image,
60
+ *command
61
+ end
62
+
63
+ def follow_logs(host:, grep: nil)
64
+ run_over_ssh pipe(
65
+ current_container_id,
66
+ "xargs docker logs -t -n 10 -f 2>&1",
67
+ ("grep '#{grep}'" if grep)
68
+ ).join(" "), host: host
69
+ end
70
+
71
+ def console(host:)
72
+ exec_over_ssh "bin/rails", "c", host: host
73
+ end
74
+
75
+ def bash(host:)
76
+ exec_over_ssh "bash", host: host
45
77
  end
46
78
 
47
79
  def list_containers
@@ -57,7 +89,15 @@ class Mrsk::Commands::App < Mrsk::Commands::Base
57
89
  end
58
90
 
59
91
  private
92
+ def exec_over_ssh(*command, host:)
93
+ run_over_ssh run_exec(*command, interactive: true).join(" "), host: host
94
+ end
95
+
60
96
  def service_filter
61
97
  [ "--filter", "label=service=#{config.service}" ]
62
98
  end
99
+
100
+ def rails_master_key_arg
101
+ [ "-e", redact("RAILS_MASTER_KEY=#{config.master_key}") ]
102
+ end
63
103
  end
@@ -1,7 +1,7 @@
1
- require "sshkit"
2
-
3
1
  module Mrsk::Commands
4
2
  class Base
3
+ delegate :redact, to: Mrsk::Utils
4
+
5
5
  attr_accessor :config
6
6
 
7
7
  def initialize(config)
@@ -9,19 +9,23 @@ module Mrsk::Commands
9
9
  end
10
10
 
11
11
  private
12
- def combine(*commands)
12
+ def combine(*commands, by: "&&")
13
13
  commands
14
- .collect { |command| command + [ "&&" ] }.flatten # Join commands with &&
15
- .tap { |commands| commands.pop } # Remove trailing &&
14
+ .compact
15
+ .collect { |command| Array(command) + [ by ] }.flatten # Join commands
16
+ .tap { |commands| commands.pop } # Remove trailing combiner
17
+ end
18
+
19
+ def pipe(*commands)
20
+ combine *commands, by: "|"
16
21
  end
17
22
 
18
23
  def docker(*args)
19
24
  args.compact.unshift :docker
20
25
  end
21
26
 
22
- # Copied from SSHKit::Backend::Abstract#redact to be available inside Commands classes
23
- def redact(arg) # Used in execute_command to hide redact() args a user passes in
24
- arg.to_s.extend(SSHKit::Redaction) # to_s due to our inability to extend Integer, etc
25
- end
27
+ def run_over_ssh(command, host:)
28
+ "ssh -t #{config.ssh_user}@#{host} '#{command}'"
29
+ end
26
30
  end
27
31
  end
@@ -0,0 +1,26 @@
1
+ require "mrsk/commands/base"
2
+
3
+ class Mrsk::Commands::Builder::Base < Mrsk::Commands::Base
4
+ delegate :argumentize, to: Mrsk::Utils
5
+
6
+ def pull
7
+ docker :pull, config.absolute_image
8
+ end
9
+
10
+ def build_args
11
+ argumentize "--build-arg", args, redacted: true
12
+ end
13
+
14
+ def build_secrets
15
+ argumentize "--secret", secrets.collect { |secret| [ "id", secret ] }
16
+ end
17
+
18
+ private
19
+ def args
20
+ (config.builder && config.builder["args"]) || {}
21
+ end
22
+
23
+ def secrets
24
+ (config.builder && config.builder["secrets"]) || []
25
+ end
26
+ end
@@ -15,8 +15,16 @@ 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, "--use", "--name", builder_name, builder_name_with_arch(local["arch"]), "--platform", "linux/#{local["arch"]}"
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
@@ -50,9 +58,4 @@ class Mrsk::Commands::Builder::Multiarch::Remote < Mrsk::Commands::Builder::Mult
50
58
  def remote
51
59
  config.builder["remote"]
52
60
  end
53
-
54
- private
55
- def builder_name_with_arch(arch)
56
- "#{builder_name}-#{arch}"
57
- end
58
61
  end
@@ -1,6 +1,6 @@
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
5
  docker :buildx, :create, "--use", "--name", builder_name
6
6
  end
@@ -10,11 +10,14 @@ class Mrsk::Commands::Builder::Multiarch < Mrsk::Commands::Base
10
10
  end
11
11
 
12
12
  def push
13
- docker :buildx, :build, "--push", "--platform linux/amd64,linux/arm64", "-t", config.absolute_image, "."
14
- end
15
-
16
- def pull
17
- docker :pull, config.absolute_image
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
@@ -25,6 +28,6 @@ class Mrsk::Commands::Builder::Multiarch < Mrsk::Commands::Base
25
28
 
26
29
  private
27
30
  def builder_name
28
- "mrsk-#{config.service}"
31
+ "mrsk-#{config.service}-multiarch"
29
32
  end
30
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