From 8567ce9bf9761dd7d53a734a3ee92454af72126e Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Thu, 6 Jun 2024 12:17:07 +0100 Subject: [PATCH] Move multiarch remote builder to hybrid builder Include the host name in the builder name, so we can have one builder per host/arch across all kamal projects. Inherit from the remote builder. The difference in the hybrid builder is that we create a local buildx instance and append the remote context to it. --- lib/kamal/commands/builder.rb | 6 +- lib/kamal/commands/builder/hybrid.rb | 34 ++++++++ .../commands/builder/multiarch/remote.rb | 84 ------------------- lib/kamal/commands/builder/remote.rb | 28 +++---- 4 files changed, 51 insertions(+), 101 deletions(-) create mode 100644 lib/kamal/commands/builder/hybrid.rb delete mode 100644 lib/kamal/commands/builder/multiarch/remote.rb diff --git a/lib/kamal/commands/builder.rb b/lib/kamal/commands/builder.rb index f73fb5f8..c34b6492 100644 --- a/lib/kamal/commands/builder.rb +++ b/lib/kamal/commands/builder.rb @@ -17,7 +17,7 @@ class Kamal::Commands::Builder < Kamal::Commands::Base when !config.builder.multiarch? && config.builder.cached? local when config.builder.local? && config.builder.remote? - multiarch_remote + hybrid when config.builder.remote? remote else @@ -33,8 +33,8 @@ class Kamal::Commands::Builder < Kamal::Commands::Base @local ||= Kamal::Commands::Builder::Local.new(config) end - def multiarch_remote - @multiarch_remote ||= Kamal::Commands::Builder::Multiarch::Remote.new(config) + def hybrid + @hybrid ||= Kamal::Commands::Builder::Hybrid.new(config) end diff --git a/lib/kamal/commands/builder/hybrid.rb b/lib/kamal/commands/builder/hybrid.rb new file mode 100644 index 00000000..3db6a10c --- /dev/null +++ b/lib/kamal/commands/builder/hybrid.rb @@ -0,0 +1,34 @@ +class Kamal::Commands::Builder::Hybrid < Kamal::Commands::Builder::Base + def create + combine \ + create_local_buildx, + create_remote_context, + append_remote_buildx + end + + def context_hosts + chain \ + context_host(builder_name) + end + + def config_context_hosts + [ remote_host ].compact + end + + private + def builder_name + "kamal-hybrid-#{remote_host.gsub(/[^a-z0-9_-]/, "-")}-#{local_arch}-#{remote_arch}" + end + + def create_local_buildx + docker :buildx, :create, "--name", builder_name, "--platform", "linux/#{local_arch}", "--driver=docker-container" + end + + def append_remote_buildx + docker :buildx, :create, "--append", "--name", builder_name, builder_name, "--platform", "linux/#{remote_arch}" + end + + def platform_options + [ "--platform", "linux/#{local_arch},linux/#{remote_arch}" ] + end +end diff --git a/lib/kamal/commands/builder/multiarch/remote.rb b/lib/kamal/commands/builder/multiarch/remote.rb deleted file mode 100644 index 01114bce..00000000 --- a/lib/kamal/commands/builder/multiarch/remote.rb +++ /dev/null @@ -1,84 +0,0 @@ -class Kamal::Commands::Builder::Multiarch::Remote < Kamal::Commands::Builder::Base - def create - combine \ - create_contexts, - create_local_buildx, - append_remote_buildx - end - - def remove - combine \ - remove_contexts, - super - end - - def info - combine \ - docker(:context, :ls), - docker(:buildx, :ls) - end - - def push - docker :buildx, :build, - "--push", - *platform_options, - "--builder", builder_name, - *build_options, - build_context - end - - def context_hosts - chain \ - context_host(builder_name_with_arch(local_arch)), - context_host(builder_name_with_arch(remote_arch)) - end - - def config_context_hosts - [ local_host, remote_host ].compact - end - - private - def builder_name - "kamal-#{config.service}-multiarch-remote" - end - - def builder_name_with_arch(arch) - "#{builder_name}-#{arch}" - end - - def create_local_buildx - docker :buildx, :create, "--name", builder_name, builder_name_with_arch(local_arch), "--platform", "linux/#{local_arch}" - end - - def append_remote_buildx - docker :buildx, :create, "--append", "--name", builder_name, builder_name_with_arch(remote_arch), "--platform", "linux/#{remote_arch}" - end - - def create_contexts - combine \ - create_context(local_arch, local_host), - create_context(remote_arch, remote_host) - end - - def create_context(arch, host) - docker :context, :create, builder_name_with_arch(arch), "--description", "'#{builder_name} #{arch} native host'", "--docker", "'host=#{host}'" - end - - def remove_contexts - combine \ - remove_context(local_arch), - remove_context(remote_arch) - end - - def remove_context(arch) - docker :context, :rm, builder_name_with_arch(arch) - end - - def platform_options - if local_arch - [ "--platform", "linux/#{local_arch}" ] - else - [ "--platform", "linux/amd64,linux/arm64" ] - end - end -end diff --git a/lib/kamal/commands/builder/remote.rb b/lib/kamal/commands/builder/remote.rb index d4c56990..cad8cd0b 100644 --- a/lib/kamal/commands/builder/remote.rb +++ b/lib/kamal/commands/builder/remote.rb @@ -1,13 +1,13 @@ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base def create chain \ - create_context, + create_remote_context, create_buildx end def remove chain \ - remove_context, + remove_remote_context, remove_buildx end @@ -19,11 +19,11 @@ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base def push docker :buildx, :build, - "--push", - "--platform", platform, - "--builder", builder_name, - *build_options, - build_context + "--push", + *platform_options, + "--builder", builder_name, + *build_options, + build_context end def context_hosts @@ -37,18 +37,14 @@ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base private def builder_name - "kamal-remote-#{remote_arch}" + "kamal-remote-#{remote_host.gsub(/[^a-z0-9_-]/, "-")}-#{remote_arch}" end - def platform - "linux/#{remote_arch}" - end - - def create_context + def create_remote_context docker :context, :create, builder_name, "--description", "'#{builder_name} host'", "--docker", "'host=#{remote_host}'" end - def remove_context + def remove_remote_context docker :context, :rm, builder_name end @@ -59,4 +55,8 @@ class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base def remove_buildx docker :buildx, :rm, builder_name end + + def platform_options + [ "--platform", "linux/#{remote_arch}" ] + end end