kamal 1.8.3 → 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/kamal/cli/accessory.rb +92 -38
- data/lib/kamal/cli/alias/command.rb +10 -0
- data/lib/kamal/cli/app/{prepare_assets.rb → assets.rb} +1 -1
- data/lib/kamal/cli/app/boot.rb +23 -16
- data/lib/kamal/cli/app/error_pages.rb +33 -0
- data/lib/kamal/cli/app/ssl_certificates.rb +28 -0
- data/lib/kamal/cli/app.rb +132 -30
- data/lib/kamal/cli/base.rb +57 -53
- data/lib/kamal/cli/build.rb +81 -38
- data/lib/kamal/cli/healthcheck/barrier.rb +2 -0
- data/lib/kamal/cli/healthcheck/poller.rb +18 -39
- data/lib/kamal/cli/lock.rb +2 -3
- data/lib/kamal/cli/main.rb +60 -59
- data/lib/kamal/cli/proxy.rb +290 -0
- data/lib/kamal/cli/prune.rb +0 -1
- data/lib/kamal/cli/registry.rb +2 -0
- data/lib/kamal/cli/secrets.rb +49 -0
- data/lib/kamal/cli/server.rb +6 -5
- data/lib/kamal/cli/templates/deploy.yml +53 -53
- data/lib/kamal/cli/templates/sample_hooks/docker-setup.sample +2 -12
- data/lib/kamal/cli/templates/sample_hooks/post-app-boot.sample +3 -0
- data/lib/kamal/cli/templates/sample_hooks/post-deploy.sample +1 -1
- data/lib/kamal/cli/templates/sample_hooks/post-proxy-reboot.sample +3 -0
- data/lib/kamal/cli/templates/sample_hooks/pre-app-boot.sample +3 -0
- data/lib/kamal/cli/templates/sample_hooks/pre-build.sample +1 -1
- data/lib/kamal/cli/templates/sample_hooks/pre-connect.sample +1 -1
- data/lib/kamal/cli/templates/sample_hooks/pre-deploy.sample +19 -6
- data/lib/kamal/cli/templates/sample_hooks/pre-proxy-reboot.sample +3 -0
- data/lib/kamal/cli/templates/secrets +17 -0
- data/lib/kamal/cli.rb +2 -0
- data/lib/kamal/commander/specifics.rb +19 -6
- data/lib/kamal/commander.rb +39 -32
- data/lib/kamal/commands/accessory/proxy.rb +16 -0
- data/lib/kamal/commands/accessory.rb +19 -19
- data/lib/kamal/commands/app/assets.rb +10 -10
- data/lib/kamal/commands/app/containers.rb +2 -2
- data/lib/kamal/commands/app/error_pages.rb +9 -0
- data/lib/kamal/commands/app/execution.rb +7 -4
- data/lib/kamal/commands/app/images.rb +1 -1
- data/lib/kamal/commands/app/logging.rb +16 -6
- data/lib/kamal/commands/app/proxy.rb +32 -0
- data/lib/kamal/commands/app.rb +25 -24
- data/lib/kamal/commands/auditor.rb +12 -3
- data/lib/kamal/commands/base.rb +54 -8
- data/lib/kamal/commands/builder/base.rb +46 -16
- data/lib/kamal/commands/builder/clone.rb +16 -14
- data/lib/kamal/commands/builder/cloud.rb +22 -0
- data/lib/kamal/commands/builder/hybrid.rb +21 -0
- data/lib/kamal/commands/builder/local.rb +14 -0
- data/lib/kamal/commands/builder/pack.rb +46 -0
- data/lib/kamal/commands/builder/remote.rb +63 -0
- data/lib/kamal/commands/builder.rb +21 -45
- data/lib/kamal/commands/docker.rb +4 -0
- data/lib/kamal/commands/hook.rb +8 -2
- data/lib/kamal/commands/lock.rb +2 -6
- data/lib/kamal/commands/proxy.rb +127 -0
- data/lib/kamal/commands/prune.rb +1 -9
- data/lib/kamal/commands/registry.rb +9 -7
- data/lib/kamal/commands/server.rb +11 -1
- data/lib/kamal/configuration/accessory.rb +89 -12
- data/lib/kamal/configuration/alias.rb +15 -0
- data/lib/kamal/configuration/builder.rb +73 -15
- data/lib/kamal/configuration/docs/accessory.yml +53 -15
- data/lib/kamal/configuration/docs/alias.yml +26 -0
- data/lib/kamal/configuration/docs/boot.yml +3 -3
- data/lib/kamal/configuration/docs/builder.yml +63 -38
- data/lib/kamal/configuration/docs/configuration.yml +62 -46
- data/lib/kamal/configuration/docs/env.yml +61 -17
- data/lib/kamal/configuration/docs/logging.yml +3 -3
- data/lib/kamal/configuration/docs/proxy.yml +168 -0
- data/lib/kamal/configuration/docs/registry.yml +20 -13
- data/lib/kamal/configuration/docs/role.yml +14 -13
- data/lib/kamal/configuration/docs/servers.yml +2 -2
- data/lib/kamal/configuration/docs/ssh.yml +23 -19
- data/lib/kamal/configuration/docs/sshkit.yml +4 -4
- data/lib/kamal/configuration/env/tag.rb +4 -3
- data/lib/kamal/configuration/env.rb +19 -17
- data/lib/kamal/configuration/proxy/boot.rb +129 -0
- data/lib/kamal/configuration/proxy.rb +124 -0
- data/lib/kamal/configuration/registry.rb +7 -6
- data/lib/kamal/configuration/role.rb +69 -98
- data/lib/kamal/configuration/servers.rb +8 -1
- data/lib/kamal/configuration/validator/accessory.rb +6 -2
- data/lib/kamal/configuration/validator/alias.rb +15 -0
- data/lib/kamal/configuration/validator/builder.rb +6 -0
- data/lib/kamal/configuration/validator/proxy.rb +25 -0
- data/lib/kamal/configuration/validator/role.rb +3 -1
- data/lib/kamal/configuration/validator/servers.rb +1 -1
- data/lib/kamal/configuration/validator.rb +62 -24
- data/lib/kamal/configuration.rb +96 -50
- data/lib/kamal/docker.rb +30 -0
- data/lib/kamal/env_file.rb +7 -1
- data/lib/kamal/git.rb +10 -0
- data/lib/kamal/secrets/adapters/aws_secrets_manager.rb +51 -0
- data/lib/kamal/secrets/adapters/base.rb +33 -0
- data/lib/kamal/secrets/adapters/bitwarden.rb +81 -0
- data/lib/kamal/secrets/adapters/bitwarden_secrets_manager.rb +66 -0
- data/lib/kamal/secrets/adapters/doppler.rb +57 -0
- data/lib/kamal/secrets/adapters/enpass.rb +71 -0
- data/lib/kamal/secrets/adapters/gcp_secret_manager.rb +112 -0
- data/lib/kamal/secrets/adapters/last_pass.rb +40 -0
- data/lib/kamal/secrets/adapters/one_password.rb +104 -0
- data/lib/kamal/secrets/adapters/passbolt.rb +130 -0
- data/lib/kamal/secrets/adapters/test.rb +14 -0
- data/lib/kamal/secrets/adapters.rb +16 -0
- data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +33 -0
- data/lib/kamal/secrets.rb +42 -0
- data/lib/kamal/sshkit_with_ext.rb +1 -0
- data/lib/kamal/utils.rb +30 -0
- data/lib/kamal/version.rb +1 -1
- data/lib/kamal.rb +3 -1
- metadata +63 -36
- data/lib/kamal/cli/env.rb +0 -54
- data/lib/kamal/cli/templates/sample_hooks/post-traefik-reboot.sample +0 -3
- data/lib/kamal/cli/templates/sample_hooks/pre-traefik-reboot.sample +0 -3
- data/lib/kamal/cli/templates/template.env +0 -2
- data/lib/kamal/cli/traefik.rb +0 -122
- data/lib/kamal/commands/app/cord.rb +0 -22
- data/lib/kamal/commands/builder/multiarch/remote.rb +0 -65
- 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
- data/lib/kamal/commands/traefik.rb +0 -85
- data/lib/kamal/configuration/docs/healthcheck.yml +0 -59
- data/lib/kamal/configuration/docs/traefik.yml +0 -62
- data/lib/kamal/configuration/healthcheck.rb +0 -63
- data/lib/kamal/configuration/traefik.rb +0 -60
data/lib/kamal/commands/base.rb
CHANGED
@@ -11,14 +11,7 @@ module Kamal::Commands
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def run_over_ssh(*command, host:)
|
14
|
-
"ssh".
|
15
|
-
if config.ssh.proxy && config.ssh.proxy.is_a?(Net::SSH::Proxy::Jump)
|
16
|
-
cmd << " -J #{config.ssh.proxy.jump_proxies}"
|
17
|
-
elsif config.ssh.proxy && config.ssh.proxy.is_a?(Net::SSH::Proxy::Command)
|
18
|
-
cmd << " -o ProxyCommand='#{config.ssh.proxy.command_line_template}'"
|
19
|
-
end
|
20
|
-
cmd << " -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'"
|
21
|
-
end
|
14
|
+
"ssh#{ssh_proxy_args}#{ssh_keys_args} -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'"
|
22
15
|
end
|
23
16
|
|
24
17
|
def container_id_for(container_name:, only_running: false)
|
@@ -37,6 +30,16 @@ module Kamal::Commands
|
|
37
30
|
[ :rm, "-r", path ]
|
38
31
|
end
|
39
32
|
|
33
|
+
def remove_file(path)
|
34
|
+
[ :rm, path ]
|
35
|
+
end
|
36
|
+
|
37
|
+
def ensure_docker_installed
|
38
|
+
combine \
|
39
|
+
ensure_local_docker_installed,
|
40
|
+
ensure_local_buildx_installed
|
41
|
+
end
|
42
|
+
|
40
43
|
private
|
41
44
|
def combine(*commands, by: "&&")
|
42
45
|
commands
|
@@ -65,6 +68,10 @@ module Kamal::Commands
|
|
65
68
|
combine *commands, by: "||"
|
66
69
|
end
|
67
70
|
|
71
|
+
def substitute(*commands)
|
72
|
+
"\$\(#{commands.join(" ")}\)"
|
73
|
+
end
|
74
|
+
|
68
75
|
def xargs(command)
|
69
76
|
[ :xargs, command ].flatten
|
70
77
|
end
|
@@ -77,12 +84,51 @@ module Kamal::Commands
|
|
77
84
|
args.compact.unshift :docker
|
78
85
|
end
|
79
86
|
|
87
|
+
def pack(*args)
|
88
|
+
args.compact.unshift :pack
|
89
|
+
end
|
90
|
+
|
80
91
|
def git(*args, path: nil)
|
81
92
|
[ :git, *([ "-C", path ] if path), *args.compact ]
|
82
93
|
end
|
83
94
|
|
95
|
+
def grep(*args)
|
96
|
+
args.compact.unshift :grep
|
97
|
+
end
|
98
|
+
|
84
99
|
def tags(**details)
|
85
100
|
Kamal::Tags.from_config(config, **details)
|
86
101
|
end
|
102
|
+
|
103
|
+
def ssh_proxy_args
|
104
|
+
case config.ssh.proxy
|
105
|
+
when Net::SSH::Proxy::Jump
|
106
|
+
" -J #{config.ssh.proxy.jump_proxies}"
|
107
|
+
when Net::SSH::Proxy::Command
|
108
|
+
" -o ProxyCommand='#{config.ssh.proxy.command_line_template}'"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def ssh_keys_args
|
113
|
+
"#{ ssh_keys.join("") if ssh_keys}" + "#{" -o IdentitiesOnly=yes" if config.ssh&.keys_only}"
|
114
|
+
end
|
115
|
+
|
116
|
+
def ssh_keys
|
117
|
+
config.ssh.keys&.map do |key|
|
118
|
+
" -i #{key}"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def ensure_local_docker_installed
|
123
|
+
docker "--version"
|
124
|
+
end
|
125
|
+
|
126
|
+
def ensure_local_buildx_installed
|
127
|
+
docker :buildx, "version"
|
128
|
+
end
|
129
|
+
|
130
|
+
def docker_interactive_args
|
131
|
+
STDIN.isatty ? "-it" : "-i"
|
132
|
+
end
|
87
133
|
end
|
88
134
|
end
|
@@ -1,22 +1,46 @@
|
|
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
|
+
:pack?, :pack_builder, :pack_buildpacks,
|
10
|
+
:cache_from, :cache_to, :ssh, :provenance, :sbom, :driver, :docker_driver?,
|
11
|
+
to: :builder_config
|
9
12
|
|
10
13
|
def clean
|
11
14
|
docker :image, :rm, "--force", config.absolute_image
|
12
15
|
end
|
13
16
|
|
17
|
+
def push(export_action = "registry", tag_as_dirty: false)
|
18
|
+
docker :buildx, :build,
|
19
|
+
"--output=type=#{export_action}",
|
20
|
+
*platform_options(arches),
|
21
|
+
*([ "--builder", builder_name ] unless docker_driver?),
|
22
|
+
*build_tag_options(tag_as_dirty: tag_as_dirty),
|
23
|
+
*build_options,
|
24
|
+
build_context,
|
25
|
+
"2>&1"
|
26
|
+
end
|
27
|
+
|
14
28
|
def pull
|
15
29
|
docker :pull, config.absolute_image
|
16
30
|
end
|
17
31
|
|
32
|
+
def info
|
33
|
+
combine \
|
34
|
+
docker(:context, :ls),
|
35
|
+
docker(:buildx, :ls)
|
36
|
+
end
|
37
|
+
|
38
|
+
def inspect_builder
|
39
|
+
docker :buildx, :inspect, builder_name unless docker_driver?
|
40
|
+
end
|
41
|
+
|
18
42
|
def build_options
|
19
|
-
[ *
|
43
|
+
[ *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh, *builder_provenance, *builder_sbom ]
|
20
44
|
end
|
21
45
|
|
22
46
|
def build_context
|
@@ -32,21 +56,19 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
32
56
|
)
|
33
57
|
end
|
34
58
|
|
35
|
-
def context_hosts
|
36
|
-
:true
|
37
|
-
end
|
38
|
-
|
39
|
-
def config_context_hosts
|
40
|
-
[]
|
41
|
-
end
|
42
|
-
|
43
59
|
def first_mirror
|
44
60
|
docker(:info, "--format '{{index .RegistryConfig.Mirrors 0}}'")
|
45
61
|
end
|
46
62
|
|
47
63
|
private
|
48
|
-
def
|
49
|
-
[
|
64
|
+
def build_tag_names(tag_as_dirty: false)
|
65
|
+
tag_names = [ config.absolute_image, config.latest_image ]
|
66
|
+
tag_names.map! { |t| "#{t}-dirty" } if tag_as_dirty
|
67
|
+
tag_names
|
68
|
+
end
|
69
|
+
|
70
|
+
def build_tag_options(tag_as_dirty: false)
|
71
|
+
build_tag_names(tag_as_dirty: tag_as_dirty).flat_map { |name| [ "-t", name ] }
|
50
72
|
end
|
51
73
|
|
52
74
|
def build_cache
|
@@ -65,7 +87,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
65
87
|
end
|
66
88
|
|
67
89
|
def build_secrets
|
68
|
-
argumentize "--secret", secrets.collect { |secret| [ "id", secret ] }
|
90
|
+
argumentize "--secret", secrets.keys.collect { |secret| [ "id", secret ] }
|
69
91
|
end
|
70
92
|
|
71
93
|
def build_dockerfile
|
@@ -84,11 +106,19 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
84
106
|
argumentize "--ssh", ssh if ssh.present?
|
85
107
|
end
|
86
108
|
|
109
|
+
def builder_provenance
|
110
|
+
argumentize "--provenance", provenance unless provenance.nil?
|
111
|
+
end
|
112
|
+
|
113
|
+
def builder_sbom
|
114
|
+
argumentize "--sbom", sbom unless sbom.nil?
|
115
|
+
end
|
116
|
+
|
87
117
|
def builder_config
|
88
118
|
config.builder
|
89
119
|
end
|
90
120
|
|
91
|
-
def
|
92
|
-
|
121
|
+
def platform_options(arches)
|
122
|
+
argumentize "--platform", arches.map { |arch| "linux/#{arch}" }.join(",") if arches.any?
|
93
123
|
end
|
94
124
|
end
|
@@ -1,29 +1,31 @@
|
|
1
1
|
module Kamal::Commands::Builder::Clone
|
2
|
-
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
included do
|
5
|
-
delegate :clone_directory, :build_directory, to: :"config.builder"
|
6
|
-
end
|
7
|
-
|
8
2
|
def clone
|
9
|
-
git :clone,
|
3
|
+
git :clone, escaped_root, "--recurse-submodules", path: config.builder.clone_directory.shellescape
|
10
4
|
end
|
11
5
|
|
12
6
|
def clone_reset_steps
|
13
7
|
[
|
14
|
-
git(:remote, "set-url", :origin,
|
15
|
-
git(:fetch, :origin, path:
|
16
|
-
git(:reset, "--hard", Kamal::Git.revision, path:
|
17
|
-
git(:clean, "-fdx", path:
|
18
|
-
git(:submodule, :update, "--init", path:
|
8
|
+
git(:remote, "set-url", :origin, escaped_root, path: escaped_build_directory),
|
9
|
+
git(:fetch, :origin, path: escaped_build_directory),
|
10
|
+
git(:reset, "--hard", Kamal::Git.revision, path: escaped_build_directory),
|
11
|
+
git(:clean, "-fdx", path: escaped_build_directory),
|
12
|
+
git(:submodule, :update, "--init", path: escaped_build_directory)
|
19
13
|
]
|
20
14
|
end
|
21
15
|
|
22
16
|
def clone_status
|
23
|
-
git :status, "--porcelain", path:
|
17
|
+
git :status, "--porcelain", path: escaped_build_directory
|
24
18
|
end
|
25
19
|
|
26
20
|
def clone_revision
|
27
|
-
git :"rev-parse", :HEAD, path:
|
21
|
+
git :"rev-parse", :HEAD, path: escaped_build_directory
|
22
|
+
end
|
23
|
+
|
24
|
+
def escaped_root
|
25
|
+
Kamal::Git.root.shellescape
|
26
|
+
end
|
27
|
+
|
28
|
+
def escaped_build_directory
|
29
|
+
config.builder.build_directory.shellescape
|
28
30
|
end
|
29
31
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Kamal::Commands::Builder::Cloud < Kamal::Commands::Builder::Base
|
2
|
+
# Expects `driver` to be of format "cloud docker-org-name/builder-name"
|
3
|
+
|
4
|
+
def create
|
5
|
+
docker :buildx, :create, "--driver", driver
|
6
|
+
end
|
7
|
+
|
8
|
+
def remove
|
9
|
+
docker :buildx, :rm, builder_name
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
def builder_name
|
14
|
+
driver.gsub(/[ \/]/, "-")
|
15
|
+
end
|
16
|
+
|
17
|
+
def inspect_buildx
|
18
|
+
pipe \
|
19
|
+
docker(:buildx, :inspect, builder_name),
|
20
|
+
grep("-q", "Endpoint:.*cloud://.*")
|
21
|
+
end
|
22
|
+
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, remote_context_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,46 @@
|
|
1
|
+
class Kamal::Commands::Builder::Pack < Kamal::Commands::Builder::Base
|
2
|
+
def push(export_action = "registry")
|
3
|
+
combine \
|
4
|
+
build,
|
5
|
+
export(export_action)
|
6
|
+
end
|
7
|
+
|
8
|
+
def remove;end
|
9
|
+
|
10
|
+
def info
|
11
|
+
pack :builder, :inspect, pack_builder
|
12
|
+
end
|
13
|
+
alias_method :inspect_builder, :info
|
14
|
+
|
15
|
+
private
|
16
|
+
def build
|
17
|
+
pack(:build,
|
18
|
+
config.repository,
|
19
|
+
"--platform", platform,
|
20
|
+
"--creation-time", "now",
|
21
|
+
"--builder", pack_builder,
|
22
|
+
buildpacks,
|
23
|
+
"-t", config.absolute_image,
|
24
|
+
"-t", config.latest_image,
|
25
|
+
"--env", "BP_IMAGE_LABELS=service=#{config.service}",
|
26
|
+
*argumentize("--env", args),
|
27
|
+
*argumentize("--env", secrets, sensitive: true),
|
28
|
+
"--path", build_context)
|
29
|
+
end
|
30
|
+
|
31
|
+
def export(export_action)
|
32
|
+
return unless export_action == "registry"
|
33
|
+
|
34
|
+
combine \
|
35
|
+
docker(:push, config.absolute_image),
|
36
|
+
docker(:push, config.latest_image)
|
37
|
+
end
|
38
|
+
|
39
|
+
def platform
|
40
|
+
"linux/#{local_arches.first}"
|
41
|
+
end
|
42
|
+
|
43
|
+
def buildpacks
|
44
|
+
(pack_buildpacks << "paketo-buildpacks/image-labels").map { |buildpack| [ "--buildpack", buildpack ] }
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,63 @@
|
|
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
|
+
def inspect_builder
|
21
|
+
combine \
|
22
|
+
combine inspect_buildx, inspect_remote_context,
|
23
|
+
[ "(echo no compatible builder && exit 1)" ],
|
24
|
+
by: "||"
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def builder_name
|
29
|
+
"kamal-remote-#{remote.gsub(/[^a-z0-9_-]/, "-")}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def remote_context_name
|
33
|
+
"#{builder_name}-context"
|
34
|
+
end
|
35
|
+
|
36
|
+
def inspect_buildx
|
37
|
+
pipe \
|
38
|
+
docker(:buildx, :inspect, builder_name),
|
39
|
+
grep("-q", "Endpoint:.*#{remote_context_name}")
|
40
|
+
end
|
41
|
+
|
42
|
+
def inspect_remote_context
|
43
|
+
pipe \
|
44
|
+
docker(:context, :inspect, remote_context_name, "--format", ENDPOINT_DOCKER_HOST_INSPECT),
|
45
|
+
grep("-xq", remote)
|
46
|
+
end
|
47
|
+
|
48
|
+
def create_remote_context
|
49
|
+
docker :context, :create, remote_context_name, "--description", "'#{builder_name} host'", "--docker", "'host=#{remote}'"
|
50
|
+
end
|
51
|
+
|
52
|
+
def remove_remote_context
|
53
|
+
docker :context, :rm, remote_context_name
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_buildx
|
57
|
+
docker :buildx, :create, "--name", builder_name, remote_context_name
|
58
|
+
end
|
59
|
+
|
60
|
+
def remove_buildx
|
61
|
+
docker :buildx, :rm, builder_name
|
62
|
+
end
|
63
|
+
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, :dev, :push, :clean, :pull, :info, :inspect_builder, :validate_image, :first_mirror, to: :target
|
5
|
+
delegate :local?, :remote?, :pack?, :cloud?, to: "config.builder"
|
6
6
|
|
7
7
|
include Clone
|
8
8
|
|
@@ -11,62 +11,38 @@ 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
|
20
|
+
elsif pack?
|
21
|
+
pack
|
22
|
+
elsif cloud?
|
23
|
+
cloud
|
24
24
|
else
|
25
|
-
|
26
|
-
native_cached
|
27
|
-
else
|
28
|
-
native
|
29
|
-
end
|
25
|
+
local
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
33
|
-
def
|
34
|
-
@
|
29
|
+
def remote
|
30
|
+
@remote ||= Kamal::Commands::Builder::Remote.new(config)
|
35
31
|
end
|
36
32
|
|
37
|
-
def
|
38
|
-
@
|
33
|
+
def local
|
34
|
+
@local ||= Kamal::Commands::Builder::Local.new(config)
|
39
35
|
end
|
40
36
|
|
41
|
-
def
|
42
|
-
@
|
37
|
+
def hybrid
|
38
|
+
@hybrid ||= Kamal::Commands::Builder::Hybrid.new(config)
|
43
39
|
end
|
44
40
|
|
45
|
-
def
|
46
|
-
@
|
41
|
+
def pack
|
42
|
+
@pack ||= Kamal::Commands::Builder::Pack.new(config)
|
47
43
|
end
|
48
44
|
|
49
|
-
def
|
50
|
-
@
|
45
|
+
def cloud
|
46
|
+
@cloud ||= Kamal::Commands::Builder::Cloud.new(config)
|
51
47
|
end
|
52
|
-
|
53
|
-
|
54
|
-
def ensure_local_dependencies_installed
|
55
|
-
if name.native?
|
56
|
-
ensure_local_docker_installed
|
57
|
-
else
|
58
|
-
combine \
|
59
|
-
ensure_local_docker_installed,
|
60
|
-
ensure_local_buildx_installed
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
private
|
65
|
-
def ensure_local_docker_installed
|
66
|
-
docker "--version"
|
67
|
-
end
|
68
|
-
|
69
|
-
def ensure_local_buildx_installed
|
70
|
-
docker :buildx, "version"
|
71
|
-
end
|
72
48
|
end
|
@@ -19,6 +19,10 @@ class Kamal::Commands::Docker < Kamal::Commands::Base
|
|
19
19
|
[ '[ "${EUID:-$(id -u)}" -eq 0 ] || command -v sudo >/dev/null || command -v su >/dev/null' ]
|
20
20
|
end
|
21
21
|
|
22
|
+
def create_network
|
23
|
+
docker :network, :create, :kamal
|
24
|
+
end
|
25
|
+
|
22
26
|
private
|
23
27
|
def get_docker
|
24
28
|
shell \
|
data/lib/kamal/commands/hook.rb
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
class Kamal::Commands::Hook < Kamal::Commands::Base
|
2
|
-
def run(hook
|
3
|
-
[ hook_file(hook)
|
2
|
+
def run(hook)
|
3
|
+
[ hook_file(hook) ]
|
4
|
+
end
|
5
|
+
|
6
|
+
def env(secrets: false, **details)
|
7
|
+
tags(**details).env.tap do |env|
|
8
|
+
env.merge!(config.secrets.to_h) if secrets
|
9
|
+
end
|
4
10
|
end
|
5
11
|
|
6
12
|
def hook_exists?(hook)
|
data/lib/kamal/commands/lock.rb
CHANGED
@@ -44,14 +44,10 @@ class Kamal::Commands::Lock < Kamal::Commands::Base
|
|
44
44
|
"/dev/null"
|
45
45
|
end
|
46
46
|
|
47
|
-
def locks_dir
|
48
|
-
File.join(config.run_directory, "locks")
|
49
|
-
end
|
50
|
-
|
51
47
|
def lock_dir
|
52
|
-
dir_name = [ config.service, config.destination ].compact.join("-")
|
48
|
+
dir_name = [ "lock", config.service, config.destination ].compact.join("-")
|
53
49
|
|
54
|
-
File.join(
|
50
|
+
File.join(config.run_directory, dir_name)
|
55
51
|
end
|
56
52
|
|
57
53
|
def lock_details_file
|
@@ -0,0 +1,127 @@
|
|
1
|
+
class Kamal::Commands::Proxy < Kamal::Commands::Base
|
2
|
+
delegate :argumentize, :optionize, to: Kamal::Utils
|
3
|
+
|
4
|
+
def run
|
5
|
+
pipe boot_config, xargs(docker_run)
|
6
|
+
end
|
7
|
+
|
8
|
+
def start
|
9
|
+
docker :container, :start, container_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def stop(name: container_name)
|
13
|
+
docker :container, :stop, name
|
14
|
+
end
|
15
|
+
|
16
|
+
def start_or_run
|
17
|
+
combine start, run, by: "||"
|
18
|
+
end
|
19
|
+
|
20
|
+
def info
|
21
|
+
docker :ps, "--filter", "name=^#{container_name}$"
|
22
|
+
end
|
23
|
+
|
24
|
+
def version
|
25
|
+
pipe \
|
26
|
+
docker(:inspect, container_name, "--format '{{.Config.Image}}'"),
|
27
|
+
[ :awk, "-F:", "'{print \$NF}'" ]
|
28
|
+
end
|
29
|
+
|
30
|
+
def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil)
|
31
|
+
pipe \
|
32
|
+
docker(:logs, container_name, ("--since #{since}" if since), ("--tail #{lines}" if lines), ("--timestamps" if timestamps), "2>&1"),
|
33
|
+
("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
|
34
|
+
end
|
35
|
+
|
36
|
+
def follow_logs(host:, timestamps: true, grep: nil, grep_options: nil)
|
37
|
+
run_over_ssh pipe(
|
38
|
+
docker(:logs, container_name, ("--timestamps" if timestamps), "--tail", "10", "--follow", "2>&1"),
|
39
|
+
(%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
|
40
|
+
).join(" "), host: host
|
41
|
+
end
|
42
|
+
|
43
|
+
def remove_container
|
44
|
+
docker :container, :prune, "--force", "--filter", "label=org.opencontainers.image.title=kamal-proxy"
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_image
|
48
|
+
docker :image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=kamal-proxy"
|
49
|
+
end
|
50
|
+
|
51
|
+
def cleanup_traefik
|
52
|
+
chain \
|
53
|
+
docker(:container, :stop, "traefik"),
|
54
|
+
combine(
|
55
|
+
docker(:container, :prune, "--force", "--filter", "label=org.opencontainers.image.title=Traefik"),
|
56
|
+
docker(:image, :prune, "--all", "--force", "--filter", "label=org.opencontainers.image.title=Traefik")
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
def ensure_proxy_directory
|
61
|
+
make_directory config.proxy_boot.host_directory
|
62
|
+
end
|
63
|
+
|
64
|
+
def remove_proxy_directory
|
65
|
+
remove_directory config.proxy_boot.host_directory
|
66
|
+
end
|
67
|
+
|
68
|
+
def ensure_apps_config_directory
|
69
|
+
make_directory config.proxy_boot.apps_directory
|
70
|
+
end
|
71
|
+
|
72
|
+
def boot_config
|
73
|
+
[ :echo, "#{substitute(read_boot_options)} #{substitute(read_image)}:#{substitute(read_image_version)} #{substitute(read_run_command)}" ]
|
74
|
+
end
|
75
|
+
|
76
|
+
def read_boot_options
|
77
|
+
read_file(config.proxy_boot.options_file, default: config.proxy_boot.default_boot_options.join(" "))
|
78
|
+
end
|
79
|
+
|
80
|
+
def read_image
|
81
|
+
read_file(config.proxy_boot.image_file, default: config.proxy_boot.image_default)
|
82
|
+
end
|
83
|
+
|
84
|
+
def read_image_version
|
85
|
+
read_file(config.proxy_boot.image_version_file, default: Kamal::Configuration::Proxy::Boot::MINIMUM_VERSION)
|
86
|
+
end
|
87
|
+
|
88
|
+
def read_run_command
|
89
|
+
read_file(config.proxy_boot.run_command_file)
|
90
|
+
end
|
91
|
+
|
92
|
+
def reset_boot_options
|
93
|
+
remove_file config.proxy_boot.options_file
|
94
|
+
end
|
95
|
+
|
96
|
+
def reset_image
|
97
|
+
remove_file config.proxy_boot.image_file
|
98
|
+
end
|
99
|
+
|
100
|
+
def reset_image_version
|
101
|
+
remove_file config.proxy_boot.image_version_file
|
102
|
+
end
|
103
|
+
|
104
|
+
def reset_run_command
|
105
|
+
remove_file config.proxy_boot.run_command_file
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
def container_name
|
110
|
+
config.proxy_boot.container_name
|
111
|
+
end
|
112
|
+
|
113
|
+
def read_file(file, default: nil)
|
114
|
+
combine [ :cat, file, "2>", "/dev/null" ], [ :echo, "\"#{default}\"" ], by: "||"
|
115
|
+
end
|
116
|
+
|
117
|
+
def docker_run
|
118
|
+
docker \
|
119
|
+
:run,
|
120
|
+
"--name", container_name,
|
121
|
+
"--network", "kamal",
|
122
|
+
"--detach",
|
123
|
+
"--restart", "unless-stopped",
|
124
|
+
"--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
|
125
|
+
*config.proxy_boot.apps_volume.docker_args
|
126
|
+
end
|
127
|
+
end
|