kamal 1.8.2 → 2.0.0.alpha
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/lib/kamal/cli/alias/command.rb +9 -0
- data/lib/kamal/cli/app.rb +3 -2
- data/lib/kamal/cli/base.rb +10 -3
- data/lib/kamal/cli/build.rb +5 -11
- data/lib/kamal/cli/server.rb +2 -1
- data/lib/kamal/cli/templates/deploy.yml +4 -10
- data/lib/kamal/commander.rb +9 -1
- data/lib/kamal/commands/builder/base.rb +27 -10
- data/lib/kamal/commands/builder/hybrid.rb +21 -0
- data/lib/kamal/commands/builder/local.rb +14 -0
- data/lib/kamal/commands/builder/remote.rb +40 -0
- data/lib/kamal/commands/builder.rb +13 -29
- data/lib/kamal/configuration/alias.rb +15 -0
- data/lib/kamal/configuration/builder.rb +47 -19
- data/lib/kamal/configuration/docs/alias.yml +26 -0
- data/lib/kamal/configuration/docs/builder.yml +15 -22
- data/lib/kamal/configuration/docs/configuration.yml +6 -0
- data/lib/kamal/configuration/validator/alias.rb +15 -0
- data/lib/kamal/configuration/validator/builder.rb +2 -0
- data/lib/kamal/configuration/validator.rb +40 -24
- data/lib/kamal/configuration.rb +2 -1
- data/lib/kamal/utils.rb +16 -0
- data/lib/kamal/version.rb +1 -1
- metadata +12 -10
- data/lib/kamal/commands/builder/multiarch/remote.rb +0 -61
- data/lib/kamal/commands/builder/multiarch.rb +0 -41
- data/lib/kamal/commands/builder/native/cached.rb +0 -25
- data/lib/kamal/commands/builder/native/remote.rb +0 -67
- data/lib/kamal/commands/builder/native.rb +0 -20
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 4df682847a5becbc623450203537d42aa29fb4b001026a6b39ab266913660d4d
         | 
| 4 | 
            +
              data.tar.gz: 97ceb4c375f99605f1d874637273168f7274e95c615611d1d324cb0d635523e3
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 619e959821a7bd1590f0dcf6d3d3956e02c0832a51528b8f15d655ddcfe636a29a6c82fd0080a2d7d3104437368c63f607fd2f61623f230e547693a4accf65ea
         | 
| 7 | 
            +
              data.tar.gz: 1733b8db747dd71b1cb41ef7ca359856af278e5fb7ef29b0ed0cb677f67cdc82039246fb836bfd7c4260e992830f9a309315d5f98e83dcc3a2a7c5a2656e47a3
         | 
    
        data/lib/kamal/cli/app.rb
    CHANGED
    
    | @@ -71,11 +71,12 @@ class Kamal::Cli::App < Kamal::Cli::Base | |
| 71 71 | 
             
                end
         | 
| 72 72 | 
             
              end
         | 
| 73 73 |  | 
| 74 | 
            -
              desc "exec [CMD]", "Execute a custom command on servers within the app container (use --help to show options)"
         | 
| 74 | 
            +
              desc "exec [CMD...]", "Execute a custom command on servers within the app container (use --help to show options)"
         | 
| 75 75 | 
             
              option :interactive, aliases: "-i", type: :boolean, default: false, desc: "Execute command over ssh for an interactive shell (use for console/bash)"
         | 
| 76 76 | 
             
              option :reuse, type: :boolean, default: false, desc: "Reuse currently running container instead of starting a new one"
         | 
| 77 77 | 
             
              option :env, aliases: "-e", type: :hash, desc: "Set environment variables for the command"
         | 
| 78 | 
            -
              def exec(cmd)
         | 
| 78 | 
            +
              def exec(*cmd)
         | 
| 79 | 
            +
                cmd = Kamal::Utils.join_commands(cmd)
         | 
| 79 80 | 
             
                env = options[:env]
         | 
| 80 81 | 
             
                case
         | 
| 81 82 | 
             
                when options[:interactive] && options[:reuse]
         | 
    
        data/lib/kamal/cli/base.rb
    CHANGED
    
    | @@ -6,7 +6,8 @@ module Kamal::Cli | |
| 6 6 | 
             
              class Base < Thor
         | 
| 7 7 | 
             
                include SSHKit::DSL
         | 
| 8 8 |  | 
| 9 | 
            -
                def self.exit_on_failure?()  | 
| 9 | 
            +
                def self.exit_on_failure?() false end
         | 
| 10 | 
            +
                def self.dynamic_command_class() Kamal::Cli::Alias::Command end
         | 
| 10 11 |  | 
| 11 12 | 
             
                class_option :verbose, type: :boolean, aliases: "-v", desc: "Detailed logging"
         | 
| 12 13 | 
             
                class_option :quiet, type: :boolean, aliases: "-q", desc: "Minimal logging"
         | 
| @@ -22,8 +23,14 @@ module Kamal::Cli | |
| 22 23 |  | 
| 23 24 | 
             
                class_option :skip_hooks, aliases: "-H", type: :boolean, default: false, desc: "Don't run hooks"
         | 
| 24 25 |  | 
| 25 | 
            -
                def initialize( | 
| 26 | 
            -
                   | 
| 26 | 
            +
                def initialize(args = [], local_options = {}, config = {})
         | 
| 27 | 
            +
                  if config[:current_command].is_a?(Kamal::Cli::Alias::Command)
         | 
| 28 | 
            +
                    # When Thor generates a dynamic command, it doesn't attempt to parse the arguments.
         | 
| 29 | 
            +
                    # For our purposes, it means the arguments are passed in args rather than local_options.
         | 
| 30 | 
            +
                    super([], args, config)
         | 
| 31 | 
            +
                  else
         | 
| 32 | 
            +
                    super
         | 
| 33 | 
            +
                  end
         | 
| 27 34 | 
             
                  @original_env = ENV.to_h.dup
         | 
| 28 35 | 
             
                  load_env
         | 
| 29 36 | 
             
                  initialize_commander(options_with_subcommand_class_options)
         | 
    
        data/lib/kamal/cli/build.rb
    CHANGED
    
    | @@ -30,18 +30,9 @@ class Kamal::Cli::Build < Kamal::Cli::Base | |
| 30 30 | 
             
                  say "Building with uncommitted changes:\n #{uncommitted_changes}", :yellow
         | 
| 31 31 | 
             
                end
         | 
| 32 32 |  | 
| 33 | 
            -
                # Get the command here to ensure the Dir.chdir doesn't interfere with it
         | 
| 34 | 
            -
                push = KAMAL.builder.push
         | 
| 35 | 
            -
             | 
| 36 33 | 
             
                run_locally do
         | 
| 37 34 | 
             
                  begin
         | 
| 38 | 
            -
                     | 
| 39 | 
            -
             | 
| 40 | 
            -
                    if context_hosts != KAMAL.builder.config_context_hosts
         | 
| 41 | 
            -
                      warn "Context hosts have changed, so re-creating builder, was: #{context_hosts.join(", ")}], now: #{KAMAL.builder.config_context_hosts.join(", ")}"
         | 
| 42 | 
            -
                      cli.remove
         | 
| 43 | 
            -
                      cli.create
         | 
| 44 | 
            -
                    end
         | 
| 35 | 
            +
                    execute *KAMAL.builder.buildx_inspect
         | 
| 45 36 | 
             
                  rescue SSHKit::Command::Failed => e
         | 
| 46 37 | 
             
                    if e.message =~ /(context not found|no builder|does not exist)/
         | 
| 47 38 | 
             
                      warn "Missing compatible builder, so creating a new one first"
         | 
| @@ -51,6 +42,9 @@ class Kamal::Cli::Build < Kamal::Cli::Base | |
| 51 42 | 
             
                    end
         | 
| 52 43 | 
             
                  end
         | 
| 53 44 |  | 
| 45 | 
            +
                  # Get the command here to ensure the Dir.chdir doesn't interfere with it
         | 
| 46 | 
            +
                  push = KAMAL.builder.push
         | 
| 47 | 
            +
             | 
| 54 48 | 
             
                  KAMAL.with_verbosity(:debug) do
         | 
| 55 49 | 
             
                    Dir.chdir(KAMAL.config.builder.build_directory) { execute *push }
         | 
| 56 50 | 
             
                  end
         | 
| @@ -72,7 +66,7 @@ class Kamal::Cli::Build < Kamal::Cli::Base | |
| 72 66 |  | 
| 73 67 | 
             
              desc "create", "Create a build setup"
         | 
| 74 68 | 
             
              def create
         | 
| 75 | 
            -
                if (remote_host = KAMAL.config.builder. | 
| 69 | 
            +
                if (remote_host = KAMAL.config.builder.remote)
         | 
| 76 70 | 
             
                  connect_to_remote_host(remote_host)
         | 
| 77 71 | 
             
                end
         | 
| 78 72 |  | 
    
        data/lib/kamal/cli/server.rb
    CHANGED
    
    | @@ -1,7 +1,8 @@ | |
| 1 1 | 
             
            class Kamal::Cli::Server < Kamal::Cli::Base
         | 
| 2 2 | 
             
              desc "exec", "Run a custom command on the server (use --help to show options)"
         | 
| 3 3 | 
             
              option :interactive, type: :boolean, aliases: "-i", default: false, desc: "Run the command interactively (use for console/bash)"
         | 
| 4 | 
            -
              def exec(cmd)
         | 
| 4 | 
            +
              def exec(*cmd)
         | 
| 5 | 
            +
                cmd = Kamal::Utils.join_commands(cmd)
         | 
| 5 6 | 
             
                hosts = KAMAL.hosts | KAMAL.accessory_hosts
         | 
| 6 7 |  | 
| 7 8 | 
             
                case
         | 
| @@ -18,6 +18,10 @@ registry: | |
| 18 18 | 
             
              password:
         | 
| 19 19 | 
             
                - KAMAL_REGISTRY_PASSWORD
         | 
| 20 20 |  | 
| 21 | 
            +
            # Configure builder setup.
         | 
| 22 | 
            +
            builder:
         | 
| 23 | 
            +
              arch: amd64
         | 
| 24 | 
            +
             | 
| 21 25 | 
             
            # Inject ENV variables into containers (secrets come from .env).
         | 
| 22 26 | 
             
            # Remember to run `kamal env push` after making changes!
         | 
| 23 27 | 
             
            # env:
         | 
| @@ -30,16 +34,6 @@ registry: | |
| 30 34 | 
             
            # ssh:
         | 
| 31 35 | 
             
            #   user: app
         | 
| 32 36 |  | 
| 33 | 
            -
            # Configure builder setup.
         | 
| 34 | 
            -
            # builder:
         | 
| 35 | 
            -
            #   args:
         | 
| 36 | 
            -
            #     RUBY_VERSION: 3.2.0
         | 
| 37 | 
            -
            #   secrets:
         | 
| 38 | 
            -
            #     - GITHUB_TOKEN
         | 
| 39 | 
            -
            #   remote:
         | 
| 40 | 
            -
            #     arch: amd64
         | 
| 41 | 
            -
            #     host: ssh://app@192.168.0.1
         | 
| 42 | 
            -
             | 
| 43 37 | 
             
            # Use accessory services (secrets come from .env).
         | 
| 44 38 | 
             
            # accessories:
         | 
| 45 39 | 
             
            #   db:
         | 
    
        data/lib/kamal/commander.rb
    CHANGED
    
    | @@ -27,7 +27,11 @@ class Kamal::Commander | |
| 27 27 |  | 
| 28 28 | 
             
              def specific_primary!
         | 
| 29 29 | 
             
                @specifics = nil
         | 
| 30 | 
            -
                 | 
| 30 | 
            +
                if specific_roles.present?
         | 
| 31 | 
            +
                  self.specific_hosts = [ specific_roles.first.primary_host ]
         | 
| 32 | 
            +
                else
         | 
| 33 | 
            +
                  self.specific_hosts = [ config.primary_host ]
         | 
| 34 | 
            +
                end
         | 
| 31 35 | 
             
              end
         | 
| 32 36 |  | 
| 33 37 | 
             
              def specific_roles=(role_names)
         | 
| @@ -113,6 +117,10 @@ class Kamal::Commander | |
| 113 117 | 
             
                @traefik ||= Kamal::Commands::Traefik.new(config)
         | 
| 114 118 | 
             
              end
         | 
| 115 119 |  | 
| 120 | 
            +
              def alias(name)
         | 
| 121 | 
            +
                config.aliases[name]
         | 
| 122 | 
            +
              end
         | 
| 123 | 
            +
             | 
| 116 124 |  | 
| 117 125 | 
             
              def with_verbosity(level)
         | 
| 118 126 | 
             
                old_level = self.verbosity
         | 
| @@ -1,20 +1,41 @@ | |
| 1 | 
            -
             | 
| 2 1 | 
             
            class Kamal::Commands::Builder::Base < Kamal::Commands::Base
         | 
| 3 2 | 
             
              class BuilderError < StandardError; end
         | 
| 4 3 |  | 
| 5 4 | 
             
              ENDPOINT_DOCKER_HOST_INSPECT = "'{{.Endpoints.docker.Host}}'"
         | 
| 6 5 |  | 
| 7 6 | 
             
              delegate :argumentize, to: Kamal::Utils
         | 
| 8 | 
            -
              delegate  | 
| 7 | 
            +
              delegate \
         | 
| 8 | 
            +
                :args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote,
         | 
| 9 | 
            +
                :cache_from, :cache_to, :ssh, :driver, :docker_driver?,
         | 
| 10 | 
            +
                to: :builder_config
         | 
| 9 11 |  | 
| 10 12 | 
             
              def clean
         | 
| 11 13 | 
             
                docker :image, :rm, "--force", config.absolute_image
         | 
| 12 14 | 
             
              end
         | 
| 13 15 |  | 
| 16 | 
            +
              def push
         | 
| 17 | 
            +
                docker :buildx, :build,
         | 
| 18 | 
            +
                  "--push",
         | 
| 19 | 
            +
                  *platform_options(arches),
         | 
| 20 | 
            +
                  *([ "--builder", builder_name ] unless docker_driver?),
         | 
| 21 | 
            +
                  *build_options,
         | 
| 22 | 
            +
                  build_context
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
             | 
| 14 25 | 
             
              def pull
         | 
| 15 26 | 
             
                docker :pull, config.absolute_image
         | 
| 16 27 | 
             
              end
         | 
| 17 28 |  | 
| 29 | 
            +
              def info
         | 
| 30 | 
            +
                combine \
         | 
| 31 | 
            +
                  docker(:context, :ls),
         | 
| 32 | 
            +
                  docker(:buildx, :ls)
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              def buildx_inspect
         | 
| 36 | 
            +
                docker :buildx, :inspect, builder_name unless docker_driver?
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
             | 
| 18 39 | 
             
              def build_options
         | 
| 19 40 | 
             
                [ *build_tags, *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh ]
         | 
| 20 41 | 
             
              end
         | 
| @@ -32,14 +53,6 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base | |
| 32 53 | 
             
                  )
         | 
| 33 54 | 
             
              end
         | 
| 34 55 |  | 
| 35 | 
            -
              def context_hosts
         | 
| 36 | 
            -
                :true
         | 
| 37 | 
            -
              end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
              def config_context_hosts
         | 
| 40 | 
            -
                []
         | 
| 41 | 
            -
              end
         | 
| 42 | 
            -
             | 
| 43 56 | 
             
              def first_mirror
         | 
| 44 57 | 
             
                docker(:info, "--format '{{index .RegistryConfig.Mirrors 0}}'")
         | 
| 45 58 | 
             
              end
         | 
| @@ -91,4 +104,8 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base | |
| 91 104 | 
             
                def context_host(builder_name)
         | 
| 92 105 | 
             
                  docker :context, :inspect, builder_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT
         | 
| 93 106 | 
             
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                def platform_options(arches)
         | 
| 109 | 
            +
                  argumentize "--platform", arches.map { |arch| "linux/#{arch}" }.join(",") if arches.any?
         | 
| 110 | 
            +
                end
         | 
| 94 111 | 
             
            end
         | 
| @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            class Kamal::Commands::Builder::Hybrid < Kamal::Commands::Builder::Remote
         | 
| 2 | 
            +
              def create
         | 
| 3 | 
            +
                combine \
         | 
| 4 | 
            +
                  create_local_buildx,
         | 
| 5 | 
            +
                  create_remote_context,
         | 
| 6 | 
            +
                  append_remote_buildx
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              private
         | 
| 10 | 
            +
                def builder_name
         | 
| 11 | 
            +
                  "kamal-hybrid-#{driver}-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def create_local_buildx
         | 
| 15 | 
            +
                  docker :buildx, :create, *platform_options(local_arches), "--name", builder_name, "--driver=#{driver}"
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def append_remote_buildx
         | 
| 19 | 
            +
                  docker :buildx, :create, *platform_options(remote_arches), "--append", "--name", builder_name, builder_name
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
            end
         | 
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            class Kamal::Commands::Builder::Local < Kamal::Commands::Builder::Base
         | 
| 2 | 
            +
              def create
         | 
| 3 | 
            +
                docker :buildx, :create, "--name", builder_name, "--driver=#{driver}" unless docker_driver?
         | 
| 4 | 
            +
              end
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def remove
         | 
| 7 | 
            +
                docker :buildx, :rm, builder_name unless docker_driver?
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              private
         | 
| 11 | 
            +
                def builder_name
         | 
| 12 | 
            +
                  "kamal-local-#{driver}"
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            class Kamal::Commands::Builder::Remote < Kamal::Commands::Builder::Base
         | 
| 2 | 
            +
              def create
         | 
| 3 | 
            +
                chain \
         | 
| 4 | 
            +
                  create_remote_context,
         | 
| 5 | 
            +
                  create_buildx
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              def remove
         | 
| 9 | 
            +
                chain \
         | 
| 10 | 
            +
                  remove_remote_context,
         | 
| 11 | 
            +
                  remove_buildx
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              def info
         | 
| 15 | 
            +
                chain \
         | 
| 16 | 
            +
                  docker(:context, :ls),
         | 
| 17 | 
            +
                  docker(:buildx, :ls)
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              private
         | 
| 21 | 
            +
                def builder_name
         | 
| 22 | 
            +
                  "kamal-remote-#{driver}-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def create_remote_context
         | 
| 26 | 
            +
                  docker :context, :create, builder_name, "--description", "'#{builder_name} host'", "--docker", "'host=#{remote}'"
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def remove_remote_context
         | 
| 30 | 
            +
                  docker :context, :rm, builder_name
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def create_buildx
         | 
| 34 | 
            +
                  docker :buildx, :create, "--name", builder_name, builder_name
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def remove_buildx
         | 
| 38 | 
            +
                  docker :buildx, :rm, builder_name
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
            end
         | 
| @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            require "active_support/core_ext/string/filters"
         | 
| 2 2 |  | 
| 3 3 | 
             
            class Kamal::Commands::Builder < Kamal::Commands::Base
         | 
| 4 | 
            -
              delegate :create, :remove, :push, :clean, :pull, :info, : | 
| 5 | 
            -
             | 
| 4 | 
            +
              delegate :create, :remove, :push, :clean, :pull, :info, :buildx_inspect, :validate_image, :first_mirror, to: :target
         | 
| 5 | 
            +
              delegate :local?, :remote?, to: "config.builder"
         | 
| 6 6 |  | 
| 7 7 | 
             
              include Clone
         | 
| 8 8 |  | 
| @@ -11,43 +11,27 @@ class Kamal::Commands::Builder < Kamal::Commands::Base | |
| 11 11 | 
             
              end
         | 
| 12 12 |  | 
| 13 13 | 
             
              def target
         | 
| 14 | 
            -
                if  | 
| 15 | 
            -
                  if  | 
| 16 | 
            -
                     | 
| 17 | 
            -
                      multiarch_remote
         | 
| 18 | 
            -
                    else
         | 
| 19 | 
            -
                      native_remote
         | 
| 20 | 
            -
                    end
         | 
| 14 | 
            +
                if remote?
         | 
| 15 | 
            +
                  if local?
         | 
| 16 | 
            +
                    hybrid
         | 
| 21 17 | 
             
                  else
         | 
| 22 | 
            -
                     | 
| 18 | 
            +
                    remote
         | 
| 23 19 | 
             
                  end
         | 
| 24 20 | 
             
                else
         | 
| 25 | 
            -
                   | 
| 26 | 
            -
                    native_cached
         | 
| 27 | 
            -
                  else
         | 
| 28 | 
            -
                    native
         | 
| 29 | 
            -
                  end
         | 
| 21 | 
            +
                  local
         | 
| 30 22 | 
             
                end
         | 
| 31 23 | 
             
              end
         | 
| 32 24 |  | 
| 33 | 
            -
              def  | 
| 34 | 
            -
                @ | 
| 35 | 
            -
              end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
              def native_cached
         | 
| 38 | 
            -
                @native ||= Kamal::Commands::Builder::Native::Cached.new(config)
         | 
| 39 | 
            -
              end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
              def native_remote
         | 
| 42 | 
            -
                @native ||= Kamal::Commands::Builder::Native::Remote.new(config)
         | 
| 25 | 
            +
              def remote
         | 
| 26 | 
            +
                @remote ||= Kamal::Commands::Builder::Remote.new(config)
         | 
| 43 27 | 
             
              end
         | 
| 44 28 |  | 
| 45 | 
            -
              def  | 
| 46 | 
            -
                @ | 
| 29 | 
            +
              def local
         | 
| 30 | 
            +
                @local ||= Kamal::Commands::Builder::Local.new(config)
         | 
| 47 31 | 
             
              end
         | 
| 48 32 |  | 
| 49 | 
            -
              def  | 
| 50 | 
            -
                @ | 
| 33 | 
            +
              def hybrid
         | 
| 34 | 
            +
                @hybrid ||= Kamal::Commands::Builder::Hybrid.new(config)
         | 
| 51 35 | 
             
              end
         | 
| 52 36 |  | 
| 53 37 |  | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            class Kamal::Configuration::Alias
         | 
| 2 | 
            +
              include Kamal::Configuration::Validation
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              attr_reader :name, :command
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              def initialize(name, config:)
         | 
| 7 | 
            +
                @name, @command = name.inquiry, config.raw_config["aliases"][name]
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                validate! \
         | 
| 10 | 
            +
                  command,
         | 
| 11 | 
            +
                  example: validation_yml["aliases"]["uname"],
         | 
| 12 | 
            +
                  context: "aliases/#{name}",
         | 
| 13 | 
            +
                  with: Kamal::Configuration::Validator::Alias
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -19,16 +19,36 @@ class Kamal::Configuration::Builder | |
| 19 19 | 
             
                builder_config
         | 
| 20 20 | 
             
              end
         | 
| 21 21 |  | 
| 22 | 
            -
              def  | 
| 23 | 
            -
                builder_config[" | 
| 22 | 
            +
              def remote
         | 
| 23 | 
            +
                builder_config["remote"]
         | 
| 24 24 | 
             
              end
         | 
| 25 25 |  | 
| 26 | 
            -
              def  | 
| 27 | 
            -
                 | 
| 26 | 
            +
              def arches
         | 
| 27 | 
            +
                Array(builder_config.fetch("arch", default_arch))
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              def local_arches
         | 
| 31 | 
            +
                @local_arches ||= if remote
         | 
| 32 | 
            +
                  arches & [ Kamal::Utils.docker_arch ]
         | 
| 33 | 
            +
                else
         | 
| 34 | 
            +
                  arches
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def remote_arches
         | 
| 39 | 
            +
                @remote_arches ||= if remote
         | 
| 40 | 
            +
                  arches - local_arches
         | 
| 41 | 
            +
                else
         | 
| 42 | 
            +
                  []
         | 
| 43 | 
            +
                end
         | 
| 28 44 | 
             
              end
         | 
| 29 45 |  | 
| 30 46 | 
             
              def remote?
         | 
| 31 | 
            -
                 | 
| 47 | 
            +
                remote_arches.any?
         | 
| 48 | 
            +
              end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              def local?
         | 
| 51 | 
            +
                arches.empty? || local_arches.any?
         | 
| 32 52 | 
             
              end
         | 
| 33 53 |  | 
| 34 54 | 
             
              def cached?
         | 
| @@ -55,20 +75,8 @@ class Kamal::Configuration::Builder | |
| 55 75 | 
             
                builder_config["context"] || "."
         | 
| 56 76 | 
             
              end
         | 
| 57 77 |  | 
| 58 | 
            -
              def  | 
| 59 | 
            -
                builder_config | 
| 60 | 
            -
              end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
              def local_host
         | 
| 63 | 
            -
                builder_config["local"]["host"] if local?
         | 
| 64 | 
            -
              end
         | 
| 65 | 
            -
             | 
| 66 | 
            -
              def remote_arch
         | 
| 67 | 
            -
                builder_config["remote"]["arch"] if remote?
         | 
| 68 | 
            -
              end
         | 
| 69 | 
            -
             | 
| 70 | 
            -
              def remote_host
         | 
| 71 | 
            -
                builder_config["remote"]["host"] if remote?
         | 
| 78 | 
            +
              def driver
         | 
| 79 | 
            +
                builder_config.fetch("driver", "docker-container")
         | 
| 72 80 | 
             
              end
         | 
| 73 81 |  | 
| 74 82 | 
             
              def cache_from
         | 
| @@ -114,7 +122,23 @@ class Kamal::Configuration::Builder | |
| 114 122 | 
             
                  end
         | 
| 115 123 | 
             
              end
         | 
| 116 124 |  | 
| 125 | 
            +
              def docker_driver?
         | 
| 126 | 
            +
                driver == "docker"
         | 
| 127 | 
            +
              end
         | 
| 128 | 
            +
             | 
| 117 129 | 
             
              private
         | 
| 130 | 
            +
                def valid?
         | 
| 131 | 
            +
                  if docker_driver?
         | 
| 132 | 
            +
                    raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support remote builders" if remote
         | 
| 133 | 
            +
                    raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support caching" if cached?
         | 
| 134 | 
            +
                    raise ArgumentError, "Invalid builder configuration: the `docker` driver does not not support multiple arches" if arches.many?
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  if @options["cache"] && @options["cache"]["type"]
         | 
| 138 | 
            +
                    raise ArgumentError, "Invalid cache type: #{@options["cache"]["type"]}" unless [ "gha", "registry" ].include?(@options["cache"]["type"])
         | 
| 139 | 
            +
                  end
         | 
| 140 | 
            +
                end
         | 
| 141 | 
            +
             | 
| 118 142 | 
             
                def cache_image
         | 
| 119 143 | 
             
                  builder_config["cache"]&.fetch("image", nil) || "#{image}-build-cache"
         | 
| 120 144 | 
             
                end
         | 
| @@ -150,4 +174,8 @@ class Kamal::Configuration::Builder | |
| 150 174 | 
             
                def pwd_sha
         | 
| 151 175 | 
             
                  Digest::SHA256.hexdigest(Dir.pwd)[0..12]
         | 
| 152 176 | 
             
                end
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                def default_arch
         | 
| 179 | 
            +
                  docker_driver? ? [] : [ "amd64", "arm64" ]
         | 
| 180 | 
            +
                end
         | 
| 153 181 | 
             
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            # Aliases
         | 
| 2 | 
            +
            #
         | 
| 3 | 
            +
            # Aliases are shortcuts for Kamal commands.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # For example, for a Rails app, you might open a console with:
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            # ```shell
         | 
| 8 | 
            +
            # kamal app exec -i -r console "rails console"
         | 
| 9 | 
            +
            # ```
         | 
| 10 | 
            +
            #
         | 
| 11 | 
            +
            # By defining an alias, like this:
         | 
| 12 | 
            +
            aliases:
         | 
| 13 | 
            +
              console: app exec -r console -i "rails console"
         | 
| 14 | 
            +
            # You can now open the console with:
         | 
| 15 | 
            +
            # ```shell
         | 
| 16 | 
            +
            # kamal console
         | 
| 17 | 
            +
            # ```
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            # Configuring aliases
         | 
| 20 | 
            +
            #
         | 
| 21 | 
            +
            # Aliases are defined in the root config under the alias key
         | 
| 22 | 
            +
            #
         | 
| 23 | 
            +
            # Each alias is named and can only contain lowercase letters, numbers, dashes and underscores.
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            aliases:
         | 
| 26 | 
            +
              uname: app exec -p -q -r web "uname -a"
         | 
| @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            # Builder
         | 
| 2 2 | 
             
            #
         | 
| 3 | 
            -
            # The builder configuration controls how the application is built with `docker build` | 
| 3 | 
            +
            # The builder configuration controls how the application is built with `docker build`
         | 
| 4 4 | 
             
            #
         | 
| 5 5 | 
             
            # If no configuration is specified, Kamal will:
         | 
| 6 | 
            -
            # 1. Create a buildx context called `kamal | 
| 7 | 
            -
            # 2. Use `docker  | 
| 6 | 
            +
            # 1. Create a buildx context called `kamal-local-docker-container`, using the docker-container driver
         | 
| 7 | 
            +
            # 2. Use `docker build` to build a multiarch image for linux/amd64,linux/arm64 with that context
         | 
| 8 8 | 
             
            #
         | 
| 9 9 | 
             
            # See https://kamal-deploy.org/docs/configuration/builder-examples/ for more information
         | 
| 10 10 |  | 
| @@ -12,36 +12,29 @@ | |
| 12 12 | 
             
            #
         | 
| 13 13 | 
             
            # Options go under the builder key in the root configuration.
         | 
| 14 14 | 
             
            builder:
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              # Multiarch
         | 
| 15 | 
            +
              # Driver
         | 
| 17 16 | 
             
              #
         | 
| 18 | 
            -
              #  | 
| 19 | 
            -
               | 
| 17 | 
            +
              # The build driver to use, defaults to `docker-container`
         | 
| 18 | 
            +
              driver: docker
         | 
| 20 19 |  | 
| 21 | 
            -
              #  | 
| 22 | 
            -
              #
         | 
| 23 | 
            -
              # The build configuration for local builds, only used if multiarch is enabled (the default)
         | 
| 20 | 
            +
              # Arch
         | 
| 24 21 | 
             
              #
         | 
| 25 | 
            -
              #  | 
| 26 | 
            -
              #  | 
| 27 | 
            -
              #  | 
| 28 | 
            -
               | 
| 29 | 
            -
                 | 
| 30 | 
            -
                host: /var/run/docker.sock
         | 
| 22 | 
            +
              # The architectures to build for, defaults to `[ amd64, arm64 ]`
         | 
| 23 | 
            +
              # Unless you are using the docker driver, when it defaults to the local architecture
         | 
| 24 | 
            +
              # You can set an array or just a single value
         | 
| 25 | 
            +
              arch:
         | 
| 26 | 
            +
                - amd64
         | 
| 31 27 |  | 
| 32 28 | 
             
              # Remote configuration
         | 
| 33 29 | 
             
              #
         | 
| 34 | 
            -
              #  | 
| 35 | 
            -
               | 
| 36 | 
            -
              remote:
         | 
| 37 | 
            -
                arch: arm64
         | 
| 38 | 
            -
                host: ssh://docker@docker-builder
         | 
| 30 | 
            +
              # If you have a remote builder, you can configure it here
         | 
| 31 | 
            +
              remote: ssh://docker@docker-builder
         | 
| 39 32 |  | 
| 40 33 | 
             
              # Builder cache
         | 
| 41 34 | 
             
              #
         | 
| 42 35 | 
             
              # The type must be either 'gha' or 'registry'
         | 
| 43 36 | 
             
              #
         | 
| 44 | 
            -
              # The image is only used for registry cache
         | 
| 37 | 
            +
              # The image is only used for registry cache. Not compatible with the docker driver
         | 
| 45 38 | 
             
              cache:
         | 
| 46 39 | 
             
                type: registry
         | 
| 47 40 | 
             
                options: mode=max
         | 
| @@ -0,0 +1,15 @@ | |
| 1 | 
            +
            class Kamal::Configuration::Validator::Alias < Kamal::Configuration::Validator
         | 
| 2 | 
            +
              def validate!
         | 
| 3 | 
            +
                super
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                name = context.delete_prefix("aliases/")
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                if name !~ /\A[a-z0-9_-]+\z/
         | 
| 8 | 
            +
                  error "Invalid alias name: '#{name}'. Must only contain lowercase letters, alphanumeric, hyphens and underscores."
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                if Kamal::Cli::Main.commands.include?(name)
         | 
| 12 | 
            +
                  error "Alias '#{name}' conflicts with a built-in command."
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            end
         | 
| @@ -5,5 +5,7 @@ class Kamal::Configuration::Validator::Builder < Kamal::Configuration::Validator | |
| 5 5 | 
             
                if config["cache"] && config["cache"]["type"]
         | 
| 6 6 | 
             
                  error "Invalid cache type: #{config["cache"]["type"]}" unless [ "gha", "registry" ].include?(config["cache"]["type"])
         | 
| 7 7 | 
             
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                error "Builder arch not set" unless config["arch"].present?
         | 
| 8 10 | 
             
              end
         | 
| 9 11 | 
             
            end
         | 
| @@ -13,32 +13,38 @@ class Kamal::Configuration::Validator | |
| 13 13 |  | 
| 14 14 | 
             
              private
         | 
| 15 15 | 
             
                def validate_against_example!(validation_config, example)
         | 
| 16 | 
            -
                  validate_type! validation_config,  | 
| 17 | 
            -
             | 
| 18 | 
            -
                   | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 21 | 
            -
                     | 
| 22 | 
            -
             | 
| 23 | 
            -
                       | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 26 | 
            -
                         | 
| 27 | 
            -
             | 
| 28 | 
            -
                         | 
| 29 | 
            -
             | 
| 30 | 
            -
                         | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
             | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 16 | 
            +
                  validate_type! validation_config, example.class
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  if example.class == Hash
         | 
| 19 | 
            +
                    check_unknown_keys! validation_config, example
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    validation_config.each do |key, value|
         | 
| 22 | 
            +
                      next if extension?(key)
         | 
| 23 | 
            +
                      with_context(key) do
         | 
| 24 | 
            +
                        example_value = example[key]
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                        if example_value == "..."
         | 
| 27 | 
            +
                          validate_type! value, *(Array if key == :servers), Hash
         | 
| 28 | 
            +
                        elsif key == "hosts"
         | 
| 29 | 
            +
                          validate_servers! value
         | 
| 30 | 
            +
                        elsif example_value.is_a?(Array)
         | 
| 31 | 
            +
                          if key == "arch"
         | 
| 32 | 
            +
                            validate_array_of_or_type! value, example_value.first.class
         | 
| 33 | 
            +
                          else
         | 
| 34 | 
            +
                            validate_array_of! value, example_value.first.class
         | 
| 35 | 
            +
                          end
         | 
| 36 | 
            +
                        elsif example_value.is_a?(Hash)
         | 
| 37 | 
            +
                          case key.to_s
         | 
| 38 | 
            +
                          when "options", "args"
         | 
| 39 | 
            +
                            validate_type! value, Hash
         | 
| 40 | 
            +
                          when "labels"
         | 
| 41 | 
            +
                            validate_hash_of! value, example_value.first[1].class
         | 
| 42 | 
            +
                          else
         | 
| 43 | 
            +
                            validate_against_example! value, example_value
         | 
| 44 | 
            +
                          end
         | 
| 37 45 | 
             
                        else
         | 
| 38 | 
            -
                           | 
| 46 | 
            +
                          validate_type! value, example_value.class
         | 
| 39 47 | 
             
                        end
         | 
| 40 | 
            -
                      else
         | 
| 41 | 
            -
                        validate_type! value, example_value.class
         | 
| 42 48 | 
             
                      end
         | 
| 43 49 | 
             
                    end
         | 
| 44 50 | 
             
                  end
         | 
| @@ -69,6 +75,16 @@ class Kamal::Configuration::Validator | |
| 69 75 | 
             
                  value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(Numeric) || value.is_a?(TrueClass) || value.is_a?(FalseClass)
         | 
| 70 76 | 
             
                end
         | 
| 71 77 |  | 
| 78 | 
            +
                def validate_array_of_or_type!(value, type)
         | 
| 79 | 
            +
                  if value.is_a?(Array)
         | 
| 80 | 
            +
                    validate_array_of! value, type
         | 
| 81 | 
            +
                  else
         | 
| 82 | 
            +
                    validate_type! value, type
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
                rescue Kamal::ConfigurationError
         | 
| 85 | 
            +
                  type_error(Array, type)
         | 
| 86 | 
            +
                end
         | 
| 87 | 
            +
             | 
| 72 88 | 
             
                def validate_array_of!(array, type)
         | 
| 73 89 | 
             
                  validate_type! array, Array
         | 
| 74 90 |  | 
    
        data/lib/kamal/configuration.rb
    CHANGED
    
    | @@ -11,7 +11,7 @@ class Kamal::Configuration | |
| 11 11 | 
             
              delegate :argumentize, :optionize, to: Kamal::Utils
         | 
| 12 12 |  | 
| 13 13 | 
             
              attr_reader :destination, :raw_config
         | 
| 14 | 
            -
              attr_reader :accessories, :boot, :builder, :env, :healthcheck, :logging, :traefik, :servers, :ssh, :sshkit, :registry
         | 
| 14 | 
            +
              attr_reader :accessories, :aliases, :boot, :builder, :env, :healthcheck, :logging, :traefik, :servers, :ssh, :sshkit, :registry
         | 
| 15 15 |  | 
| 16 16 | 
             
              include Validation
         | 
| 17 17 |  | 
| @@ -54,6 +54,7 @@ class Kamal::Configuration | |
| 54 54 | 
             
                @registry = Registry.new(config: self)
         | 
| 55 55 |  | 
| 56 56 | 
             
                @accessories = @raw_config.accessories&.keys&.collect { |name| Accessory.new(name, config: self) } || []
         | 
| 57 | 
            +
                @aliases = @raw_config.aliases&.keys&.to_h { |name| [ name, Alias.new(name, config: self) ] } || {}
         | 
| 57 58 | 
             
                @boot = Boot.new(config: self)
         | 
| 58 59 | 
             
                @builder = Builder.new(config: self)
         | 
| 59 60 | 
             
                @env = Env.new(config: @raw_config.env || {})
         | 
    
        data/lib/kamal/utils.rb
    CHANGED
    
    | @@ -77,4 +77,20 @@ module Kamal::Utils | |
| 77 77 | 
             
              def stable_sort!(elements, &block)
         | 
| 78 78 | 
             
                elements.sort_by!.with_index { |element, index| [ block.call(element), index ] }
         | 
| 79 79 | 
             
              end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
              def join_commands(commands)
         | 
| 82 | 
            +
                commands.map(&:strip).join(" ")
         | 
| 83 | 
            +
              end
         | 
| 84 | 
            +
             | 
| 85 | 
            +
              def docker_arch
         | 
| 86 | 
            +
                arch = `docker info --format '{{.Architecture}}'`.strip
         | 
| 87 | 
            +
                case arch
         | 
| 88 | 
            +
                when /aarch64/
         | 
| 89 | 
            +
                  "arm64"
         | 
| 90 | 
            +
                when /x86_64/
         | 
| 91 | 
            +
                  "amd64"
         | 
| 92 | 
            +
                else
         | 
| 93 | 
            +
                  arch
         | 
| 94 | 
            +
                end
         | 
| 95 | 
            +
              end
         | 
| 80 96 | 
             
            end
         | 
    
        data/lib/kamal/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: kamal
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 2.0.0.alpha
         | 
| 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: 2024- | 
| 11 | 
            +
            date: 2024-09-01 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -64,14 +64,14 @@ dependencies: | |
| 64 64 | 
             
                requirements:
         | 
| 65 65 | 
             
                - - "~>"
         | 
| 66 66 | 
             
                  - !ruby/object:Gem::Version
         | 
| 67 | 
            -
                    version: '1. | 
| 67 | 
            +
                    version: '1.3'
         | 
| 68 68 | 
             
              type: :runtime
         | 
| 69 69 | 
             
              prerelease: false
         | 
| 70 70 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 71 71 | 
             
                requirements:
         | 
| 72 72 | 
             
                - - "~>"
         | 
| 73 73 | 
             
                  - !ruby/object:Gem::Version
         | 
| 74 | 
            -
                    version: '1. | 
| 74 | 
            +
                    version: '1.3'
         | 
| 75 75 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 76 76 | 
             
              name: dotenv
         | 
| 77 77 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -211,6 +211,7 @@ files: | |
| 211 211 | 
             
            - lib/kamal.rb
         | 
| 212 212 | 
             
            - lib/kamal/cli.rb
         | 
| 213 213 | 
             
            - lib/kamal/cli/accessory.rb
         | 
| 214 | 
            +
            - lib/kamal/cli/alias/command.rb
         | 
| 214 215 | 
             
            - lib/kamal/cli/app.rb
         | 
| 215 216 | 
             
            - lib/kamal/cli/app/boot.rb
         | 
| 216 217 | 
             
            - lib/kamal/cli/app/prepare_assets.rb
         | 
| @@ -252,11 +253,9 @@ files: | |
| 252 253 | 
             
            - lib/kamal/commands/builder.rb
         | 
| 253 254 | 
             
            - lib/kamal/commands/builder/base.rb
         | 
| 254 255 | 
             
            - lib/kamal/commands/builder/clone.rb
         | 
| 255 | 
            -
            - lib/kamal/commands/builder/ | 
| 256 | 
            -
            - lib/kamal/commands/builder/ | 
| 257 | 
            -
            - lib/kamal/commands/builder/ | 
| 258 | 
            -
            - lib/kamal/commands/builder/native/cached.rb
         | 
| 259 | 
            -
            - lib/kamal/commands/builder/native/remote.rb
         | 
| 256 | 
            +
            - lib/kamal/commands/builder/hybrid.rb
         | 
| 257 | 
            +
            - lib/kamal/commands/builder/local.rb
         | 
| 258 | 
            +
            - lib/kamal/commands/builder/remote.rb
         | 
| 260 259 | 
             
            - lib/kamal/commands/docker.rb
         | 
| 261 260 | 
             
            - lib/kamal/commands/hook.rb
         | 
| 262 261 | 
             
            - lib/kamal/commands/lock.rb
         | 
| @@ -266,9 +265,11 @@ files: | |
| 266 265 | 
             
            - lib/kamal/commands/traefik.rb
         | 
| 267 266 | 
             
            - lib/kamal/configuration.rb
         | 
| 268 267 | 
             
            - lib/kamal/configuration/accessory.rb
         | 
| 268 | 
            +
            - lib/kamal/configuration/alias.rb
         | 
| 269 269 | 
             
            - lib/kamal/configuration/boot.rb
         | 
| 270 270 | 
             
            - lib/kamal/configuration/builder.rb
         | 
| 271 271 | 
             
            - lib/kamal/configuration/docs/accessory.yml
         | 
| 272 | 
            +
            - lib/kamal/configuration/docs/alias.yml
         | 
| 272 273 | 
             
            - lib/kamal/configuration/docs/boot.yml
         | 
| 273 274 | 
             
            - lib/kamal/configuration/docs/builder.yml
         | 
| 274 275 | 
             
            - lib/kamal/configuration/docs/configuration.yml
         | 
| @@ -294,6 +295,7 @@ files: | |
| 294 295 | 
             
            - lib/kamal/configuration/validation.rb
         | 
| 295 296 | 
             
            - lib/kamal/configuration/validator.rb
         | 
| 296 297 | 
             
            - lib/kamal/configuration/validator/accessory.rb
         | 
| 298 | 
            +
            - lib/kamal/configuration/validator/alias.rb
         | 
| 297 299 | 
             
            - lib/kamal/configuration/validator/builder.rb
         | 
| 298 300 | 
             
            - lib/kamal/configuration/validator/configuration.rb
         | 
| 299 301 | 
             
            - lib/kamal/configuration/validator/env.rb
         | 
| @@ -327,7 +329,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 327 329 | 
             
                - !ruby/object:Gem::Version
         | 
| 328 330 | 
             
                  version: '0'
         | 
| 329 331 | 
             
            requirements: []
         | 
| 330 | 
            -
            rubygems_version: 3.5. | 
| 332 | 
            +
            rubygems_version: 3.5.17
         | 
| 331 333 | 
             
            signing_key:
         | 
| 332 334 | 
             
            specification_version: 4
         | 
| 333 335 | 
             
            summary: Deploy web apps in containers to servers running Docker with zero downtime.
         | 
| @@ -1,61 +0,0 @@ | |
| 1 | 
            -
            class Kamal::Commands::Builder::Multiarch::Remote < Kamal::Commands::Builder::Multiarch
         | 
| 2 | 
            -
              def create
         | 
| 3 | 
            -
                combine \
         | 
| 4 | 
            -
                  create_contexts,
         | 
| 5 | 
            -
                  create_local_buildx,
         | 
| 6 | 
            -
                  append_remote_buildx
         | 
| 7 | 
            -
              end
         | 
| 8 | 
            -
             | 
| 9 | 
            -
              def remove
         | 
| 10 | 
            -
                combine \
         | 
| 11 | 
            -
                  remove_contexts,
         | 
| 12 | 
            -
                  super
         | 
| 13 | 
            -
              end
         | 
| 14 | 
            -
             | 
| 15 | 
            -
              def context_hosts
         | 
| 16 | 
            -
                chain \
         | 
| 17 | 
            -
                  context_host(builder_name_with_arch(local_arch)),
         | 
| 18 | 
            -
                  context_host(builder_name_with_arch(remote_arch))
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
              def config_context_hosts
         | 
| 22 | 
            -
                [ local_host, remote_host ].compact
         | 
| 23 | 
            -
              end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              private
         | 
| 26 | 
            -
                def builder_name
         | 
| 27 | 
            -
                  super + "-remote"
         | 
| 28 | 
            -
                end
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                def builder_name_with_arch(arch)
         | 
| 31 | 
            -
                  "#{builder_name}-#{arch}"
         | 
| 32 | 
            -
                end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                def create_local_buildx
         | 
| 35 | 
            -
                  docker :buildx, :create, "--name", builder_name, builder_name_with_arch(local_arch), "--platform", "linux/#{local_arch}"
         | 
| 36 | 
            -
                end
         | 
| 37 | 
            -
             | 
| 38 | 
            -
                def append_remote_buildx
         | 
| 39 | 
            -
                  docker :buildx, :create, "--append", "--name", builder_name, builder_name_with_arch(remote_arch), "--platform", "linux/#{remote_arch}"
         | 
| 40 | 
            -
                end
         | 
| 41 | 
            -
             | 
| 42 | 
            -
                def create_contexts
         | 
| 43 | 
            -
                  combine \
         | 
| 44 | 
            -
                    create_context(local_arch, local_host),
         | 
| 45 | 
            -
                    create_context(remote_arch, remote_host)
         | 
| 46 | 
            -
                end
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                def create_context(arch, host)
         | 
| 49 | 
            -
                  docker :context, :create, builder_name_with_arch(arch), "--description", "'#{builder_name} #{arch} native host'", "--docker", "'host=#{host}'"
         | 
| 50 | 
            -
                end
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                def remove_contexts
         | 
| 53 | 
            -
                  combine \
         | 
| 54 | 
            -
                    remove_context(local_arch),
         | 
| 55 | 
            -
                    remove_context(remote_arch)
         | 
| 56 | 
            -
                end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                def remove_context(arch)
         | 
| 59 | 
            -
                  docker :context, :rm, builder_name_with_arch(arch)
         | 
| 60 | 
            -
                end
         | 
| 61 | 
            -
            end
         | 
| @@ -1,41 +0,0 @@ | |
| 1 | 
            -
            class Kamal::Commands::Builder::Multiarch < Kamal::Commands::Builder::Base
         | 
| 2 | 
            -
              def create
         | 
| 3 | 
            -
                docker :buildx, :create, "--use", "--name", builder_name
         | 
| 4 | 
            -
              end
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              def remove
         | 
| 7 | 
            -
                docker :buildx, :rm, builder_name
         | 
| 8 | 
            -
              end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              def info
         | 
| 11 | 
            -
                combine \
         | 
| 12 | 
            -
                  docker(:context, :ls),
         | 
| 13 | 
            -
                  docker(:buildx, :ls)
         | 
| 14 | 
            -
              end
         | 
| 15 | 
            -
             | 
| 16 | 
            -
              def push
         | 
| 17 | 
            -
                docker :buildx, :build,
         | 
| 18 | 
            -
                  "--push",
         | 
| 19 | 
            -
                  "--platform", platform_names,
         | 
| 20 | 
            -
                  "--builder", builder_name,
         | 
| 21 | 
            -
                  *build_options,
         | 
| 22 | 
            -
                  build_context
         | 
| 23 | 
            -
              end
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              def context_hosts
         | 
| 26 | 
            -
                docker :buildx, :inspect, builder_name, "> /dev/null"
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              private
         | 
| 30 | 
            -
                def builder_name
         | 
| 31 | 
            -
                  "kamal-#{config.service}-multiarch"
         | 
| 32 | 
            -
                end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                def platform_names
         | 
| 35 | 
            -
                  if local_arch
         | 
| 36 | 
            -
                    "linux/#{local_arch}"
         | 
| 37 | 
            -
                  else
         | 
| 38 | 
            -
                    "linux/amd64,linux/arm64"
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
                end
         | 
| 41 | 
            -
            end
         | 
| @@ -1,25 +0,0 @@ | |
| 1 | 
            -
            class Kamal::Commands::Builder::Native::Cached < Kamal::Commands::Builder::Native
         | 
| 2 | 
            -
              def create
         | 
| 3 | 
            -
                docker :buildx, :create, "--name", builder_name, "--use", "--driver=docker-container"
         | 
| 4 | 
            -
              end
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              def remove
         | 
| 7 | 
            -
                docker :buildx, :rm, builder_name
         | 
| 8 | 
            -
              end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              def push
         | 
| 11 | 
            -
                docker :buildx, :build,
         | 
| 12 | 
            -
                  "--push",
         | 
| 13 | 
            -
                  *build_options,
         | 
| 14 | 
            -
                  build_context
         | 
| 15 | 
            -
              end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
              def context_hosts
         | 
| 18 | 
            -
                docker :buildx, :inspect, builder_name, "> /dev/null"
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
              private
         | 
| 22 | 
            -
                def builder_name
         | 
| 23 | 
            -
                  "kamal-#{config.service}-native-cached"
         | 
| 24 | 
            -
                end
         | 
| 25 | 
            -
            end
         | 
| @@ -1,67 +0,0 @@ | |
| 1 | 
            -
            class Kamal::Commands::Builder::Native::Remote < Kamal::Commands::Builder::Native
         | 
| 2 | 
            -
              def create
         | 
| 3 | 
            -
                chain \
         | 
| 4 | 
            -
                  create_context,
         | 
| 5 | 
            -
                  create_buildx
         | 
| 6 | 
            -
              end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
              def remove
         | 
| 9 | 
            -
                chain \
         | 
| 10 | 
            -
                  remove_context,
         | 
| 11 | 
            -
                  remove_buildx
         | 
| 12 | 
            -
              end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
              def info
         | 
| 15 | 
            -
                chain \
         | 
| 16 | 
            -
                  docker(:context, :ls),
         | 
| 17 | 
            -
                  docker(:buildx, :ls)
         | 
| 18 | 
            -
              end
         | 
| 19 | 
            -
             | 
| 20 | 
            -
              def push
         | 
| 21 | 
            -
                docker :buildx, :build,
         | 
| 22 | 
            -
                "--push",
         | 
| 23 | 
            -
                "--platform", platform,
         | 
| 24 | 
            -
                "--builder", builder_name,
         | 
| 25 | 
            -
                *build_options,
         | 
| 26 | 
            -
                build_context
         | 
| 27 | 
            -
              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
              def context_hosts
         | 
| 30 | 
            -
                context_host(builder_name_with_arch)
         | 
| 31 | 
            -
              end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
              def config_context_hosts
         | 
| 34 | 
            -
                [ remote_host ]
         | 
| 35 | 
            -
              end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
              private
         | 
| 39 | 
            -
                def builder_name
         | 
| 40 | 
            -
                  "kamal-#{config.service}-native-remote"
         | 
| 41 | 
            -
                end
         | 
| 42 | 
            -
             | 
| 43 | 
            -
                def builder_name_with_arch
         | 
| 44 | 
            -
                  "#{builder_name}-#{remote_arch}"
         | 
| 45 | 
            -
                end
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                def platform
         | 
| 48 | 
            -
                  "linux/#{remote_arch}"
         | 
| 49 | 
            -
                end
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                def create_context
         | 
| 52 | 
            -
                  docker :context, :create,
         | 
| 53 | 
            -
                    builder_name_with_arch, "--description", "'#{builder_name} #{remote_arch} native host'", "--docker", "'host=#{remote_host}'"
         | 
| 54 | 
            -
                end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                def remove_context
         | 
| 57 | 
            -
                  docker :context, :rm, builder_name_with_arch
         | 
| 58 | 
            -
                end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                def create_buildx
         | 
| 61 | 
            -
                  docker :buildx, :create, "--name", builder_name, builder_name_with_arch, "--platform", platform
         | 
| 62 | 
            -
                end
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                def remove_buildx
         | 
| 65 | 
            -
                  docker :buildx, :rm, builder_name
         | 
| 66 | 
            -
                end
         | 
| 67 | 
            -
            end
         | 
| @@ -1,20 +0,0 @@ | |
| 1 | 
            -
            class Kamal::Commands::Builder::Native < Kamal::Commands::Builder::Base
         | 
| 2 | 
            -
              def create
         | 
| 3 | 
            -
                # No-op on native without cache
         | 
| 4 | 
            -
              end
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              def remove
         | 
| 7 | 
            -
                # No-op on native without cache
         | 
| 8 | 
            -
              end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
              def info
         | 
| 11 | 
            -
                # No-op on native
         | 
| 12 | 
            -
              end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
              def push
         | 
| 15 | 
            -
                combine \
         | 
| 16 | 
            -
                  docker(:build, *build_options, build_context),
         | 
| 17 | 
            -
                  docker(:push, config.absolute_image),
         | 
| 18 | 
            -
                  docker(:push, config.latest_image)
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
            end
         |