mrsk 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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