kamal 2.3.0 → 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/lib/kamal/cli/accessory.rb +42 -16
- data/lib/kamal/cli/alias/command.rb +1 -0
- data/lib/kamal/cli/app/{prepare_assets.rb → assets.rb} +1 -1
- data/lib/kamal/cli/app/boot.rb +3 -2
- 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 +94 -29
- data/lib/kamal/cli/base.rb +29 -4
- data/lib/kamal/cli/build.rb +60 -18
- data/lib/kamal/cli/main.rb +8 -10
- data/lib/kamal/cli/proxy.rb +58 -25
- data/lib/kamal/cli/registry.rb +2 -0
- data/lib/kamal/cli/secrets.rb +9 -3
- data/lib/kamal/cli/server.rb +4 -2
- data/lib/kamal/cli/templates/deploy.yml +6 -3
- 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/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.rb +1 -0
- data/lib/kamal/commander/specifics.rb +9 -1
- data/lib/kamal/commander.rb +18 -27
- data/lib/kamal/commands/accessory/proxy.rb +16 -0
- data/lib/kamal/commands/accessory.rb +9 -9
- data/lib/kamal/commands/app/assets.rb +4 -4
- 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 +6 -4
- data/lib/kamal/commands/app/images.rb +1 -1
- data/lib/kamal/commands/app/logging.rb +14 -4
- data/lib/kamal/commands/app/proxy.rb +17 -1
- data/lib/kamal/commands/app.rb +19 -10
- data/lib/kamal/commands/auditor.rb +11 -5
- data/lib/kamal/commands/base.rb +37 -1
- data/lib/kamal/commands/builder/base.rb +20 -7
- data/lib/kamal/commands/builder/cloud.rb +22 -0
- data/lib/kamal/commands/builder/pack.rb +46 -0
- data/lib/kamal/commands/builder.rb +11 -19
- data/lib/kamal/commands/proxy.rb +55 -15
- data/lib/kamal/commands/registry.rb +9 -7
- data/lib/kamal/configuration/accessory.rb +66 -11
- data/lib/kamal/configuration/builder.rb +20 -0
- data/lib/kamal/configuration/docs/accessory.yml +32 -4
- data/lib/kamal/configuration/docs/alias.yml +2 -2
- data/lib/kamal/configuration/docs/builder.yml +22 -0
- data/lib/kamal/configuration/docs/configuration.yml +6 -0
- data/lib/kamal/configuration/docs/env.yml +31 -0
- data/lib/kamal/configuration/docs/proxy.yml +78 -15
- data/lib/kamal/configuration/docs/registry.yml +4 -0
- data/lib/kamal/configuration/env.rb +13 -4
- data/lib/kamal/configuration/proxy/boot.rb +129 -0
- data/lib/kamal/configuration/proxy.rb +67 -5
- data/lib/kamal/configuration/registry.rb +6 -6
- data/lib/kamal/configuration/role.rb +11 -9
- data/lib/kamal/configuration/servers.rb +8 -1
- data/lib/kamal/configuration/validator/accessory.rb +6 -2
- data/lib/kamal/configuration/validator/builder.rb +2 -0
- data/lib/kamal/configuration/validator/proxy.rb +10 -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 +21 -1
- data/lib/kamal/configuration.rb +36 -57
- data/lib/kamal/docker.rb +30 -0
- 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 +13 -3
- data/lib/kamal/secrets/adapters/bitwarden.rb +2 -2
- 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 +3 -2
- data/lib/kamal/secrets/adapters/one_password.rb +47 -13
- data/lib/kamal/secrets/adapters/passbolt.rb +130 -0
- data/lib/kamal/secrets/adapters/test.rb +2 -2
- data/lib/kamal/secrets/adapters.rb +2 -0
- data/lib/kamal/secrets/dotenv/inline_command_substitution.rb +2 -1
- data/lib/kamal/secrets.rb +1 -1
- data/lib/kamal/version.rb +1 -1
- metadata +22 -10
@@ -1,8 +1,10 @@
|
|
1
1
|
class Kamal::Commands::Accessory < Kamal::Commands::Base
|
2
|
+
include Proxy
|
3
|
+
|
2
4
|
attr_reader :accessory_config
|
3
5
|
delegate :service_name, :image, :hosts, :port, :files, :directories, :cmd,
|
4
6
|
:network_args, :publish_args, :env_args, :volume_args, :label_args, :option_args,
|
5
|
-
:secrets_io, :secrets_path, :env_directory,
|
7
|
+
:secrets_io, :secrets_path, :env_directory, :proxy, :running_proxy?, :registry,
|
6
8
|
to: :accessory_config
|
7
9
|
|
8
10
|
def initialize(config, name:)
|
@@ -10,7 +12,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|
10
12
|
@accessory_config = config.accessory(name)
|
11
13
|
end
|
12
14
|
|
13
|
-
def run
|
15
|
+
def run(host: nil)
|
14
16
|
docker :run,
|
15
17
|
"--name", service_name,
|
16
18
|
"--detach",
|
@@ -18,6 +20,7 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|
18
20
|
*network_args,
|
19
21
|
*config.logging_args,
|
20
22
|
*publish_args,
|
23
|
+
*([ "--env", "KAMAL_HOST=\"#{host}\"" ] if host),
|
21
24
|
*env_args,
|
22
25
|
*volume_args,
|
23
26
|
*label_args,
|
@@ -34,11 +37,10 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|
34
37
|
docker :container, :stop, service_name
|
35
38
|
end
|
36
39
|
|
37
|
-
def info
|
38
|
-
docker :ps, *service_filter
|
40
|
+
def info(all: false, quiet: false)
|
41
|
+
docker :ps, *("-a" if all), *("-q" if quiet), *service_filter
|
39
42
|
end
|
40
43
|
|
41
|
-
|
42
44
|
def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil)
|
43
45
|
pipe \
|
44
46
|
docker(:logs, service_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), ("--timestamps" if timestamps), "2>&1"),
|
@@ -52,17 +54,16 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|
52
54
|
(%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
|
53
55
|
end
|
54
56
|
|
55
|
-
|
56
57
|
def execute_in_existing_container(*command, interactive: false)
|
57
58
|
docker :exec,
|
58
|
-
(
|
59
|
+
(docker_interactive_args if interactive),
|
59
60
|
service_name,
|
60
61
|
*command
|
61
62
|
end
|
62
63
|
|
63
64
|
def execute_in_new_container(*command, interactive: false)
|
64
65
|
docker :run,
|
65
|
-
(
|
66
|
+
(docker_interactive_args if interactive),
|
66
67
|
"--rm",
|
67
68
|
*network_args,
|
68
69
|
*env_args,
|
@@ -83,7 +84,6 @@ class Kamal::Commands::Accessory < Kamal::Commands::Base
|
|
83
84
|
super command, host: hosts.first
|
84
85
|
end
|
85
86
|
|
86
|
-
|
87
87
|
def ensure_local_file_present(local_file)
|
88
88
|
if !local_file.is_a?(StringIO) && !Pathname.new(local_file).exist?
|
89
89
|
raise "Missing file: #{local_file}"
|
@@ -4,10 +4,10 @@ module Kamal::Commands::App::Assets
|
|
4
4
|
|
5
5
|
combine \
|
6
6
|
make_directory(role.asset_extracted_directory),
|
7
|
-
[ *docker(:
|
8
|
-
docker(:
|
9
|
-
docker(:cp, "-L", "#{asset_container}:#{role.asset_path}/.", role.asset_extracted_directory),
|
10
|
-
docker(:
|
7
|
+
[ *docker(:container, :rm, asset_container, "2> /dev/null"), "|| true" ],
|
8
|
+
docker(:container, :create, "--name", asset_container, config.absolute_image),
|
9
|
+
docker(:container, :cp, "-L", "#{asset_container}:#{role.asset_path}/.", role.asset_extracted_directory),
|
10
|
+
docker(:container, :rm, asset_container),
|
11
11
|
by: "&&"
|
12
12
|
end
|
13
13
|
|
@@ -2,7 +2,7 @@ module Kamal::Commands::App::Containers
|
|
2
2
|
DOCKER_HEALTH_LOG_FORMAT = "'{{json .State.Health}}'"
|
3
3
|
|
4
4
|
def list_containers
|
5
|
-
docker :container, :ls, "--all", *
|
5
|
+
docker :container, :ls, "--all", *container_filter_args
|
6
6
|
end
|
7
7
|
|
8
8
|
def list_container_names
|
@@ -20,7 +20,7 @@ module Kamal::Commands::App::Containers
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def remove_containers
|
23
|
-
docker :container, :prune, "--force", *
|
23
|
+
docker :container, :prune, "--force", *container_filter_args
|
24
24
|
end
|
25
25
|
|
26
26
|
def container_health_log(version:)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module Kamal::Commands::App::ErrorPages
|
2
|
+
def create_error_pages_directory
|
3
|
+
make_directory(config.proxy_boot.error_pages_directory)
|
4
|
+
end
|
5
|
+
|
6
|
+
def clean_up_error_pages
|
7
|
+
[ :find, config.proxy_boot.error_pages_directory, "-mindepth", "1", "-maxdepth", "1", "!", "-name", KAMAL.config.version, "-exec", "rm", "-rf", "{} +" ]
|
8
|
+
end
|
9
|
+
end
|
@@ -1,19 +1,21 @@
|
|
1
1
|
module Kamal::Commands::App::Execution
|
2
2
|
def execute_in_existing_container(*command, interactive: false, env:)
|
3
3
|
docker :exec,
|
4
|
-
(
|
4
|
+
(docker_interactive_args if interactive),
|
5
5
|
*argumentize("--env", env),
|
6
6
|
container_name,
|
7
7
|
*command
|
8
8
|
end
|
9
9
|
|
10
|
-
def execute_in_new_container(*command, interactive: false, env:)
|
10
|
+
def execute_in_new_container(*command, interactive: false, detach: false, env:)
|
11
11
|
docker :run,
|
12
|
-
(
|
13
|
-
"--
|
12
|
+
(docker_interactive_args if interactive),
|
13
|
+
("--detach" if detach),
|
14
|
+
("--rm" unless detach),
|
14
15
|
"--network", "kamal",
|
15
16
|
*role&.env_args(host),
|
16
17
|
*argumentize("--env", env),
|
18
|
+
*role.logging_args,
|
17
19
|
*config.volume_args,
|
18
20
|
*role&.option_args,
|
19
21
|
config.absolute_image,
|
@@ -1,18 +1,28 @@
|
|
1
1
|
module Kamal::Commands::App::Logging
|
2
|
-
def logs(
|
2
|
+
def logs(container_id: nil, timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil)
|
3
3
|
pipe \
|
4
|
-
|
4
|
+
container_id_command(container_id),
|
5
5
|
"xargs docker logs#{" --timestamps" if timestamps}#{" --since #{since}" if since}#{" --tail #{lines}" if lines} 2>&1",
|
6
6
|
("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep)
|
7
7
|
end
|
8
8
|
|
9
|
-
def follow_logs(host:, timestamps: true, lines: nil, grep: nil, grep_options: nil)
|
9
|
+
def follow_logs(host:, container_id: nil, timestamps: true, lines: nil, grep: nil, grep_options: nil)
|
10
10
|
run_over_ssh \
|
11
11
|
pipe(
|
12
|
-
|
12
|
+
container_id_command(container_id),
|
13
13
|
"xargs docker logs#{" --timestamps" if timestamps}#{" --tail #{lines}" if lines} --follow 2>&1",
|
14
14
|
(%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep)
|
15
15
|
),
|
16
16
|
host: host
|
17
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def container_id_command(container_id)
|
22
|
+
case container_id
|
23
|
+
when Array then container_id
|
24
|
+
when String, Symbol then "echo #{container_id}"
|
25
|
+
else current_running_container_id
|
26
|
+
end
|
27
|
+
end
|
18
28
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Kamal::Commands::App::Proxy
|
2
|
-
delegate :
|
2
|
+
delegate :container_name, to: :"config.proxy_boot", prefix: :proxy
|
3
3
|
|
4
4
|
def deploy(target:)
|
5
5
|
proxy_exec :deploy, role.container_prefix, *role.proxy.deploy_command_args(target: target)
|
@@ -9,6 +9,22 @@ module Kamal::Commands::App::Proxy
|
|
9
9
|
proxy_exec :remove, role.container_prefix
|
10
10
|
end
|
11
11
|
|
12
|
+
def live
|
13
|
+
proxy_exec :resume, role.container_prefix
|
14
|
+
end
|
15
|
+
|
16
|
+
def maintenance(**options)
|
17
|
+
proxy_exec :stop, role.container_prefix, *role.proxy.stop_command_args(**options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def remove_proxy_app_directory
|
21
|
+
remove_directory config.proxy_boot.app_directory
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_ssl_directory
|
25
|
+
make_directory(File.join(config.proxy_boot.tls_directory, role.name))
|
26
|
+
end
|
27
|
+
|
12
28
|
private
|
13
29
|
def proxy_exec(*command)
|
14
30
|
docker :exec, proxy_container_name, "kamal-proxy", *command
|
data/lib/kamal/commands/app.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Kamal::Commands::App < Kamal::Commands::Base
|
2
|
-
include Assets, Containers, Execution, Images, Logging, Proxy
|
2
|
+
include Assets, Containers, ErrorPages, Execution, Images, Logging, Proxy
|
3
3
|
|
4
4
|
ACTIVE_DOCKER_STATUSES = [ :running, :restarting ]
|
5
5
|
|
@@ -20,8 +20,9 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
20
20
|
"--name", container_name,
|
21
21
|
"--network", "kamal",
|
22
22
|
*([ "--hostname", hostname ] if hostname),
|
23
|
-
"
|
24
|
-
"
|
23
|
+
"--env", "KAMAL_CONTAINER_NAME=\"#{container_name}\"",
|
24
|
+
"--env", "KAMAL_VERSION=\"#{config.version}\"",
|
25
|
+
"--env", "KAMAL_HOST=\"#{host}\"",
|
25
26
|
*role.env_args(host),
|
26
27
|
*role.logging_args,
|
27
28
|
*config.volume_args,
|
@@ -47,7 +48,7 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
47
48
|
end
|
48
49
|
|
49
50
|
def info
|
50
|
-
docker :ps, *
|
51
|
+
docker :ps, *container_filter_args
|
51
52
|
end
|
52
53
|
|
53
54
|
|
@@ -67,7 +68,7 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
67
68
|
|
68
69
|
def list_versions(*docker_args, statuses: nil)
|
69
70
|
pipe \
|
70
|
-
docker(:ps, *
|
71
|
+
docker(:ps, *container_filter_args(statuses: statuses), *docker_args, "--format", '"{{.Names}}"'),
|
71
72
|
extract_version_from_name
|
72
73
|
end
|
73
74
|
|
@@ -91,11 +92,15 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
91
92
|
end
|
92
93
|
|
93
94
|
def latest_container(format:, filters: nil)
|
94
|
-
docker :ps, "--latest", *format, *
|
95
|
+
docker :ps, "--latest", *format, *container_filter_args(statuses: ACTIVE_DOCKER_STATUSES), argumentize("--filter", filters)
|
95
96
|
end
|
96
97
|
|
97
|
-
def
|
98
|
-
argumentize "--filter",
|
98
|
+
def container_filter_args(statuses: nil)
|
99
|
+
argumentize "--filter", container_filters(statuses: statuses)
|
100
|
+
end
|
101
|
+
|
102
|
+
def image_filter_args
|
103
|
+
argumentize "--filter", image_filters
|
99
104
|
end
|
100
105
|
|
101
106
|
def extract_version_from_name
|
@@ -103,13 +108,17 @@ class Kamal::Commands::App < Kamal::Commands::Base
|
|
103
108
|
%(while read line; do echo ${line##{role.container_prefix}-}; done)
|
104
109
|
end
|
105
110
|
|
106
|
-
def
|
111
|
+
def container_filters(statuses: nil)
|
107
112
|
[ "label=service=#{config.service}" ].tap do |filters|
|
108
|
-
filters << "label=destination=#{config.destination}"
|
113
|
+
filters << "label=destination=#{config.destination}"
|
109
114
|
filters << "label=role=#{role}" if role
|
110
115
|
statuses&.each do |status|
|
111
116
|
filters << "status=#{status}"
|
112
117
|
end
|
113
118
|
end
|
114
119
|
end
|
120
|
+
|
121
|
+
def image_filters
|
122
|
+
[ "label=service=#{config.service}" ]
|
123
|
+
end
|
115
124
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
class Kamal::Commands::Auditor < Kamal::Commands::Base
|
2
2
|
attr_reader :details
|
3
|
+
delegate :escape_shell_value, to: Kamal::Utils
|
3
4
|
|
4
5
|
def initialize(config, **details)
|
5
6
|
super(config)
|
@@ -9,11 +10,8 @@ class Kamal::Commands::Auditor < Kamal::Commands::Base
|
|
9
10
|
# Runs remotely
|
10
11
|
def record(line, **details)
|
11
12
|
combine \
|
12
|
-
|
13
|
-
append(
|
14
|
-
[ :echo, audit_tags(**details).except(:version, :service_version, :service).to_s, line ],
|
15
|
-
audit_log_file
|
16
|
-
)
|
13
|
+
make_run_directory,
|
14
|
+
append([ :echo, escape_shell_value(audit_line(line, **details)) ], audit_log_file)
|
17
15
|
end
|
18
16
|
|
19
17
|
def reveal
|
@@ -30,4 +28,12 @@ class Kamal::Commands::Auditor < Kamal::Commands::Base
|
|
30
28
|
def audit_tags(**details)
|
31
29
|
tags(**self.details, **details)
|
32
30
|
end
|
31
|
+
|
32
|
+
def make_run_directory
|
33
|
+
[ :mkdir, "-p", config.run_directory ]
|
34
|
+
end
|
35
|
+
|
36
|
+
def audit_line(line, **details)
|
37
|
+
"#{audit_tags(**details).except(:version, :service_version, :service)} #{line}"
|
38
|
+
end
|
33
39
|
end
|
data/lib/kamal/commands/base.rb
CHANGED
@@ -11,7 +11,7 @@ module Kamal::Commands
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def run_over_ssh(*command, host:)
|
14
|
-
"ssh#{ssh_proxy_args} -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'"
|
14
|
+
"ssh#{ssh_proxy_args}#{ssh_keys_args} -t #{config.ssh.user}@#{host} -p #{config.ssh.port} '#{command.join(" ").gsub("'", "'\\\\''")}'"
|
15
15
|
end
|
16
16
|
|
17
17
|
def container_id_for(container_name:, only_running: false)
|
@@ -34,6 +34,12 @@ module Kamal::Commands
|
|
34
34
|
[ :rm, path ]
|
35
35
|
end
|
36
36
|
|
37
|
+
def ensure_docker_installed
|
38
|
+
combine \
|
39
|
+
ensure_local_docker_installed,
|
40
|
+
ensure_local_buildx_installed
|
41
|
+
end
|
42
|
+
|
37
43
|
private
|
38
44
|
def combine(*commands, by: "&&")
|
39
45
|
commands
|
@@ -62,6 +68,10 @@ module Kamal::Commands
|
|
62
68
|
combine *commands, by: "||"
|
63
69
|
end
|
64
70
|
|
71
|
+
def substitute(*commands)
|
72
|
+
"\$\(#{commands.join(" ")}\)"
|
73
|
+
end
|
74
|
+
|
65
75
|
def xargs(command)
|
66
76
|
[ :xargs, command ].flatten
|
67
77
|
end
|
@@ -74,6 +84,10 @@ module Kamal::Commands
|
|
74
84
|
args.compact.unshift :docker
|
75
85
|
end
|
76
86
|
|
87
|
+
def pack(*args)
|
88
|
+
args.compact.unshift :pack
|
89
|
+
end
|
90
|
+
|
77
91
|
def git(*args, path: nil)
|
78
92
|
[ :git, *([ "-C", path ] if path), *args.compact ]
|
79
93
|
end
|
@@ -94,5 +108,27 @@ module Kamal::Commands
|
|
94
108
|
" -o ProxyCommand='#{config.ssh.proxy.command_line_template}'"
|
95
109
|
end
|
96
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
|
97
133
|
end
|
98
134
|
end
|
@@ -6,20 +6,23 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
6
6
|
delegate :argumentize, to: Kamal::Utils
|
7
7
|
delegate \
|
8
8
|
:args, :secrets, :dockerfile, :target, :arches, :local_arches, :remote_arches, :remote,
|
9
|
-
:
|
9
|
+
:pack?, :pack_builder, :pack_buildpacks,
|
10
|
+
:cache_from, :cache_to, :ssh, :provenance, :sbom, :driver, :docker_driver?,
|
10
11
|
to: :builder_config
|
11
12
|
|
12
13
|
def clean
|
13
14
|
docker :image, :rm, "--force", config.absolute_image
|
14
15
|
end
|
15
16
|
|
16
|
-
def push
|
17
|
+
def push(export_action = "registry", tag_as_dirty: false)
|
17
18
|
docker :buildx, :build,
|
18
|
-
"--
|
19
|
+
"--output=type=#{export_action}",
|
19
20
|
*platform_options(arches),
|
20
21
|
*([ "--builder", builder_name ] unless docker_driver?),
|
22
|
+
*build_tag_options(tag_as_dirty: tag_as_dirty),
|
21
23
|
*build_options,
|
22
|
-
build_context
|
24
|
+
build_context,
|
25
|
+
"2>&1"
|
23
26
|
end
|
24
27
|
|
25
28
|
def pull
|
@@ -37,7 +40,7 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
37
40
|
end
|
38
41
|
|
39
42
|
def build_options
|
40
|
-
[ *
|
43
|
+
[ *build_cache, *build_labels, *build_args, *build_secrets, *build_dockerfile, *build_target, *build_ssh, *builder_provenance, *builder_sbom ]
|
41
44
|
end
|
42
45
|
|
43
46
|
def build_context
|
@@ -58,8 +61,14 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
58
61
|
end
|
59
62
|
|
60
63
|
private
|
61
|
-
def
|
62
|
-
[
|
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 ] }
|
63
72
|
end
|
64
73
|
|
65
74
|
def build_cache
|
@@ -101,6 +110,10 @@ class Kamal::Commands::Builder::Base < Kamal::Commands::Base
|
|
101
110
|
argumentize "--provenance", provenance unless provenance.nil?
|
102
111
|
end
|
103
112
|
|
113
|
+
def builder_sbom
|
114
|
+
argumentize "--sbom", sbom unless sbom.nil?
|
115
|
+
end
|
116
|
+
|
104
117
|
def builder_config
|
105
118
|
config.builder
|
106
119
|
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,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
|
@@ -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, :inspect_builder, :validate_image, :first_mirror, to: :target
|
5
|
-
delegate :local?, :remote?, to: "config.builder"
|
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
|
|
@@ -17,6 +17,10 @@ class Kamal::Commands::Builder < Kamal::Commands::Base
|
|
17
17
|
else
|
18
18
|
remote
|
19
19
|
end
|
20
|
+
elsif pack?
|
21
|
+
pack
|
22
|
+
elsif cloud?
|
23
|
+
cloud
|
20
24
|
else
|
21
25
|
local
|
22
26
|
end
|
@@ -34,23 +38,11 @@ class Kamal::Commands::Builder < Kamal::Commands::Base
|
|
34
38
|
@hybrid ||= Kamal::Commands::Builder::Hybrid.new(config)
|
35
39
|
end
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
if name.native?
|
40
|
-
ensure_local_docker_installed
|
41
|
-
else
|
42
|
-
combine \
|
43
|
-
ensure_local_docker_installed,
|
44
|
-
ensure_local_buildx_installed
|
45
|
-
end
|
41
|
+
def pack
|
42
|
+
@pack ||= Kamal::Commands::Builder::Pack.new(config)
|
46
43
|
end
|
47
44
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def ensure_local_buildx_installed
|
54
|
-
docker :buildx, "version"
|
55
|
-
end
|
45
|
+
def cloud
|
46
|
+
@cloud ||= Kamal::Commands::Builder::Cloud.new(config)
|
47
|
+
end
|
56
48
|
end
|
data/lib/kamal/commands/proxy.rb
CHANGED
@@ -2,14 +2,7 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base
|
|
2
2
|
delegate :argumentize, :optionize, to: Kamal::Utils
|
3
3
|
|
4
4
|
def run
|
5
|
-
|
6
|
-
"--name", container_name,
|
7
|
-
"--network", "kamal",
|
8
|
-
"--detach",
|
9
|
-
"--restart", "unless-stopped",
|
10
|
-
"--volume", "kamal-proxy-config:/home/kamal-proxy/.config/kamal-proxy",
|
11
|
-
"\$\(#{get_boot_options.join(" ")}\)",
|
12
|
-
config.proxy_image
|
5
|
+
pipe boot_config, xargs(docker_run)
|
13
6
|
end
|
14
7
|
|
15
8
|
def start
|
@@ -31,7 +24,7 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base
|
|
31
24
|
def version
|
32
25
|
pipe \
|
33
26
|
docker(:inspect, container_name, "--format '{{.Config.Image}}'"),
|
34
|
-
[ :
|
27
|
+
[ :awk, "-F:", "'{print \$NF}'" ]
|
35
28
|
end
|
36
29
|
|
37
30
|
def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil)
|
@@ -65,23 +58,70 @@ class Kamal::Commands::Proxy < Kamal::Commands::Base
|
|
65
58
|
end
|
66
59
|
|
67
60
|
def ensure_proxy_directory
|
68
|
-
make_directory config.
|
61
|
+
make_directory config.proxy_boot.host_directory
|
69
62
|
end
|
70
63
|
|
71
64
|
def remove_proxy_directory
|
72
|
-
remove_directory config.
|
65
|
+
remove_directory config.proxy_boot.host_directory
|
73
66
|
end
|
74
67
|
|
75
|
-
def
|
76
|
-
|
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)
|
77
90
|
end
|
78
91
|
|
79
92
|
def reset_boot_options
|
80
|
-
remove_file config.
|
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
|
81
106
|
end
|
82
107
|
|
83
108
|
private
|
84
109
|
def container_name
|
85
|
-
config.
|
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
|
86
126
|
end
|
87
127
|
end
|