Class: Kamal::Configuration

Inherits:
Object
  • Object
show all
Includes:
Validation
Defined in:
lib/kamal/configuration.rb

Defined Under Namespace

Modules: Validation Classes: Accessory, Alias, Boot, Builder, Env, Logging, Proxy, Registry, Role, Servers, Ssh, Sshkit, Validator, Volume

Constant Summary collapse

HOOKS_OUTPUT_LEVELS =
[ :quiet, :verbose ].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Validation

#validate!, #validation_yml

Constructor Details

#initialize(raw_config, destination: nil, version: nil, validate: true) ⇒ Configuration

Returns a new instance of Configuration.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/kamal/configuration.rb', line 54

def initialize(raw_config, destination: nil, version: nil, validate: true)
  @raw_config = ActiveSupport::InheritableOptions.new(raw_config)
  @destination = destination
  @declared_version = version

  validate! raw_config, example: validation_yml.symbolize_keys, context: "", with: Kamal::Configuration::Validator::Configuration

  @secrets = Kamal::Secrets.new(destination: destination, secrets_path: secrets_path)

  # Eager load config to validate it, these are first as they have dependencies later on
  @servers = Servers.new(config: self)
  @registry = Registry.new(config: @raw_config, secrets: secrets)

  @accessories = @raw_config.accessories&.keys&.collect { |name| Accessory.new(name, config: self) } || []
  @aliases = @raw_config.aliases&.keys&.to_h { |name| [ name, Alias.new(name, config: self) ] } || {}
  @boot = Boot.new(config: self)
  @builder = Builder.new(config: self)
  @env = Env.new(config: @raw_config.env || {}, secrets: secrets)

  @logging = Logging.new(logging_config: @raw_config.logging)
  @proxy = Proxy.new(config: self, proxy_config: @raw_config.proxy, secrets: secrets)
  @proxy_boot = Proxy::Boot.new(config: self)
  @ssh = Ssh.new(config: self)
  @sshkit = Sshkit.new(config: self)

  ensure_destination_if_required
  ensure_required_keys_present
  ensure_valid_kamal_version
  ensure_retain_containers_valid
  ensure_valid_service_name
  ensure_no_traefik_reboot_hooks
  ensure_one_host_for_ssl_roles
  ensure_unique_hosts_for_ssl_roles
  ensure_local_registry_remote_builder_has_ssh_url
  ensure_no_conflicting_proxy_runs
  ensure_valid_hooks_output!
end

Instance Attribute Details

#accessoriesObject (readonly)

Returns the value of attribute accessories.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def accessories
  @accessories
end

#aliasesObject (readonly)

Returns the value of attribute aliases.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def aliases
  @aliases
end

#bootObject (readonly)

Returns the value of attribute boot.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def boot
  @boot
end

#builderObject (readonly)

Returns the value of attribute builder.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def builder
  @builder
end

#destinationObject (readonly)

Returns the value of attribute destination.



14
15
16
# File 'lib/kamal/configuration.rb', line 14

def destination
  @destination
end

#envObject (readonly)

Returns the value of attribute env.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def env
  @env
end

#loggingObject (readonly)

Returns the value of attribute logging.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def logging
  @logging
end

#proxyObject (readonly)

Returns the value of attribute proxy.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def proxy
  @proxy
end

#proxy_bootObject (readonly)

Returns the value of attribute proxy_boot.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def proxy_boot
  @proxy_boot
end

#raw_configObject (readonly)

Returns the value of attribute raw_config.



14
15
16
# File 'lib/kamal/configuration.rb', line 14

def raw_config
  @raw_config
end

#registryObject (readonly)

Returns the value of attribute registry.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def registry
  @registry
end

#secretsObject (readonly)

Returns the value of attribute secrets.



14
15
16
# File 'lib/kamal/configuration.rb', line 14

def secrets
  @secrets
end

#serversObject (readonly)

Returns the value of attribute servers.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def servers
  @servers
end

#sshObject (readonly)

Returns the value of attribute ssh.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def ssh
  @ssh
end

#sshkitObject (readonly)

Returns the value of attribute sshkit.



15
16
17
# File 'lib/kamal/configuration.rb', line 15

def sshkit
  @sshkit
end

Class Method Details

.create_from(config_file:, destination: nil, version: nil) ⇒ Object



20
21
22
23
24
25
26
# File 'lib/kamal/configuration.rb', line 20

def create_from(config_file:, destination: nil, version: nil)
  ENV["KAMAL_DESTINATION"] = destination

  raw_config = load_raw_config(config_file: config_file, destination: destination)

  new raw_config, destination: destination, version: version
end

.load_raw_config(config_file:, destination: nil) ⇒ Object



28
29
30
# File 'lib/kamal/configuration.rb', line 28

def load_raw_config(config_file:, destination: nil)
  load_config_files(config_file, *destination_config_file(config_file, destination))
end

Instance Method Details

#abbreviated_versionObject



100
101
102
103
104
105
106
107
108
109
# File 'lib/kamal/configuration.rb', line 100

def abbreviated_version
  if version
    # Don't abbreviate <sha>_uncommitted_<etc>
    if version.include?("_")
      version
    else
      version[0...7]
    end
  end
end

#absolute_imageObject



195
196
197
# File 'lib/kamal/configuration.rb', line 195

def absolute_image
  "#{repository}:#{version}"
end

#accessory(name) ⇒ Object



127
128
129
# File 'lib/kamal/configuration.rb', line 127

def accessory(name)
  accessories.detect { |a| a.name == name.to_s }
end

#all_hostsObject



131
132
133
# File 'lib/kamal/configuration.rb', line 131

def all_hosts
  (roles + accessories).flat_map(&:hosts).uniq
end

#allow_empty_roles?Boolean

Returns:

  • (Boolean)


159
160
161
# File 'lib/kamal/configuration.rb', line 159

def allow_empty_roles?
  raw_config.allow_empty_roles
end

#app_directoryObject



251
252
253
# File 'lib/kamal/configuration.rb', line 251

def app_directory
  File.join apps_directory, service_and_destination
end

#app_hostsObject



143
144
145
# File 'lib/kamal/configuration.rb', line 143

def app_hosts
  roles.flat_map(&:hosts).uniq
end

#apps_directoryObject



247
248
249
# File 'lib/kamal/configuration.rb', line 247

def apps_directory
  File.join run_directory, "apps"
end

#asset_pathObject



271
272
273
# File 'lib/kamal/configuration.rb', line 271

def asset_path
  raw_config.asset_path
end

#assets_directoryObject



259
260
261
# File 'lib/kamal/configuration.rb', line 259

def assets_directory
  File.join app_directory, "assets"
end

#deploy_timeoutObject



235
236
237
# File 'lib/kamal/configuration.rb', line 235

def deploy_timeout
  raw_config.deploy_timeout || 30
end

#drain_timeoutObject



239
240
241
# File 'lib/kamal/configuration.rb', line 239

def drain_timeout
  raw_config.drain_timeout || 30
end

#env_directoryObject



255
256
257
# File 'lib/kamal/configuration.rb', line 255

def env_directory
  File.join app_directory, "env"
end

#env_tag(name) ⇒ Object



287
288
289
# File 'lib/kamal/configuration.rb', line 287

def env_tag(name)
  env_tags.detect { |t| t.name == name.to_s }
end

#env_tagsObject



279
280
281
282
283
284
285
# File 'lib/kamal/configuration.rb', line 279

def env_tags
  @env_tags ||= if (tags = raw_config.env["tags"])
    tags.collect { |name, config| Env::Tag.new(name, config: config, secrets: secrets) }
  else
    []
  end
end

#error_pages_pathObject



275
276
277
# File 'lib/kamal/configuration.rb', line 275

def error_pages_path
  raw_config.error_pages_path
end

#hooks_output_for(hook) ⇒ Object



291
292
293
294
295
296
297
298
# File 'lib/kamal/configuration.rb', line 291

def hooks_output_for(hook)
  case raw_config.hooks_output
  when Symbol, String
    raw_config.hooks_output.to_sym
  when Hash
    raw_config.hooks_output[hook]&.to_sym
  end
end

#hooks_pathObject



263
264
265
# File 'lib/kamal/configuration.rb', line 263

def hooks_path
  raw_config.hooks_path || ".kamal/hooks"
end

#host_accessories(host) ⇒ Object



139
140
141
# File 'lib/kamal/configuration.rb', line 139

def host_accessories(host)
  accessories.select { |accessory| accessory.hosts.include?(host) }
end

#host_roles(host) ⇒ Object



135
136
137
# File 'lib/kamal/configuration.rb', line 135

def host_roles(host)
  roles.select { |role| role.hosts.include?(host) }
end

#imageObject



179
180
181
182
183
184
# File 'lib/kamal/configuration.rb', line 179

def image
  name = raw_config&.image.presence
  name ||= raw_config&.service if registry.local?

  name
end

#latest_imageObject



199
200
201
# File 'lib/kamal/configuration.rb', line 199

def latest_image
  "#{repository}:#{latest_tag}"
end

#latest_tagObject



203
204
205
# File 'lib/kamal/configuration.rb', line 203

def latest_tag
  [ "latest", *destination ].join("-")
end

#logging_argsObject



227
228
229
# File 'lib/kamal/configuration.rb', line 227

def logging_args
  logging.args
end

#minimum_versionObject



111
112
113
# File 'lib/kamal/configuration.rb', line 111

def minimum_version
  raw_config.minimum_version
end

#primary_hostObject



147
148
149
# File 'lib/kamal/configuration.rb', line 147

def primary_host
  primary_role&.primary_host
end

#primary_roleObject



155
156
157
# File 'lib/kamal/configuration.rb', line 155

def primary_role
  role(primary_role_name)
end

#primary_role_nameObject



151
152
153
# File 'lib/kamal/configuration.rb', line 151

def primary_role_name
  raw_config.primary_role || "web"
end

#proxy_accessoriesObject



171
172
173
# File 'lib/kamal/configuration.rb', line 171

def proxy_accessories
  accessories.select(&:running_proxy?)
end

#proxy_hostsObject



175
176
177
# File 'lib/kamal/configuration.rb', line 175

def proxy_hosts
  (proxy_roles.flat_map(&:hosts) + proxy_accessories.flat_map(&:hosts)).uniq
end

#proxy_role_namesObject



167
168
169
# File 'lib/kamal/configuration.rb', line 167

def proxy_role_names
  proxy_roles.flat_map(&:name)
end

#proxy_rolesObject



163
164
165
# File 'lib/kamal/configuration.rb', line 163

def proxy_roles
  roles.select(&:running_proxy?)
end

#proxy_run(host) ⇒ Object



186
187
188
189
# File 'lib/kamal/configuration.rb', line 186

def proxy_run(host)
  # We validate that all the config are identical for a host
  proxy_runs(host.to_s).first
end

#readiness_delayObject



231
232
233
# File 'lib/kamal/configuration.rb', line 231

def readiness_delay
  raw_config.readiness_delay || 7
end

#repositoryObject



191
192
193
# File 'lib/kamal/configuration.rb', line 191

def repository
  [ registry.server, image ].compact.join("/")
end

#require_destination?Boolean

Returns:

  • (Boolean)


211
212
213
# File 'lib/kamal/configuration.rb', line 211

def require_destination?
  raw_config.require_destination
end

#retain_containersObject



215
216
217
# File 'lib/kamal/configuration.rb', line 215

def retain_containers
  raw_config.retain_containers || 5
end

#role(name) ⇒ Object



123
124
125
# File 'lib/kamal/configuration.rb', line 123

def role(name)
  roles.detect { |r| r.name == name.to_s }
end

#rolesObject



119
120
121
# File 'lib/kamal/configuration.rb', line 119

def roles
  servers.roles
end

#run_directoryObject



243
244
245
# File 'lib/kamal/configuration.rb', line 243

def run_directory
  ".kamal"
end

#secrets_pathObject



267
268
269
# File 'lib/kamal/configuration.rb', line 267

def secrets_path
  raw_config.secrets_path || ".kamal/secrets"
end

#service_and_destinationObject



115
116
117
# File 'lib/kamal/configuration.rb', line 115

def service_and_destination
  [ service, destination ].compact.join("-")
end

#service_with_versionObject



207
208
209
# File 'lib/kamal/configuration.rb', line 207

def service_with_version
  "#{service}-#{version}"
end

#to_hObject



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/kamal/configuration.rb', line 300

def to_h
  {
    roles: role_names,
    hosts: all_hosts,
    primary_host: primary_host,
    version: version,
    repository: repository,
    absolute_image: absolute_image,
    service_with_version: service_with_version,
    volume_args: volume_args,
    ssh_options: ssh.to_h,
    sshkit: sshkit.to_h,
    builder: builder.to_h,
    accessories: raw_config.accessories,
    logging: logging_args
  }.compact
end

#versionObject



96
97
98
# File 'lib/kamal/configuration.rb', line 96

def version
  @declared_version.presence || ENV["VERSION"] || git_version
end

#version=(version) ⇒ Object



92
93
94
# File 'lib/kamal/configuration.rb', line 92

def version=(version)
  @declared_version = version
end

#volume_argsObject



219
220
221
222
223
224
225
# File 'lib/kamal/configuration.rb', line 219

def volume_args
  if raw_config.volumes.present?
    argumentize "--volume", raw_config.volumes
  else
    []
  end
end