From 8eb78d45539df69c42ef0868a7aaaeced6807245 Mon Sep 17 00:00:00 2001 From: fabiosammy Date: Wed, 29 May 2024 22:16:10 -0300 Subject: [PATCH 1/8] Add a custom_env option --- lib/kamal/cli/base.rb | 3 +++ lib/kamal/cli/main.rb | 3 +++ 2 files changed, 6 insertions(+) diff --git a/lib/kamal/cli/base.rb b/lib/kamal/cli/base.rb index e648281ff..0ad4d8ff6 100644 --- a/lib/kamal/cli/base.rb +++ b/lib/kamal/cli/base.rb @@ -19,6 +19,7 @@ def self.exit_on_failure?() true end class_option :config_file, aliases: "-c", default: "config/deploy.yml", desc: "Path to config file" class_option :destination, aliases: "-d", desc: "Specify destination to be used for config file (staging -> deploy.staging.yml)" + class_option :custom_env, desc: "Specify a custom env to be used for upload the total environment (.env.custom_env)" class_option :skip_hooks, aliases: "-H", type: :boolean, default: false, desc: "Don't run hooks" @@ -33,6 +34,8 @@ def initialize(*) def load_envs if destination = options[:destination] Dotenv.load(".env.#{destination}", ".env") + elsif custom_env = options[:custom_env] + Dotenv.load(".env.#{custom_env}") else Dotenv.load(".env") end diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index c86418482..2fc488374 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -172,6 +172,9 @@ def envify if destination = options[:destination] env_template_path = ".env.#{destination}.erb" env_path = ".env.#{destination}" + elsif custom_env = options[:custom_env] + env_template_path = ".env.#{custom_env}.erb" + env_path = ".env.#{custom_env}" else env_template_path = ".env.erb" env_path = ".env" From 2250a2e2887e9e21d0fb27dcf2409b35646a8c51 Mon Sep 17 00:00:00 2001 From: fabiosammy Date: Wed, 29 May 2024 22:17:40 -0300 Subject: [PATCH 2/8] Add a for_node parameter on the env stuff to be able to detect with node is to force a environment there --- lib/kamal/commands/traefik.rb | 1 + lib/kamal/configuration/accessory.rb | 1 + lib/kamal/configuration/env.rb | 14 ++++++++++---- lib/kamal/configuration/env/tag.rb | 2 +- lib/kamal/configuration/role.rb | 3 ++- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/kamal/commands/traefik.rb b/lib/kamal/commands/traefik.rb index 569c2c2ca..6417b4086 100644 --- a/lib/kamal/commands/traefik.rb +++ b/lib/kamal/commands/traefik.rb @@ -74,6 +74,7 @@ def port def env Kamal::Configuration::Env.from_config \ config: config.traefik.fetch("env", {}), + for_node: "traefik", secrets_file: File.join(config.host_env_directory, "traefik", "traefik.env") end diff --git a/lib/kamal/configuration/accessory.rb b/lib/kamal/configuration/accessory.rb index 42b7754f2..7b742a0aa 100644 --- a/lib/kamal/configuration/accessory.rb +++ b/lib/kamal/configuration/accessory.rb @@ -44,6 +44,7 @@ def label_args def env Kamal::Configuration::Env.from_config \ config: specifics.fetch("env", {}), + for_node: @name, secrets_file: File.join(config.host_env_directory, "accessories", "#{service_name}.env") end diff --git a/lib/kamal/configuration/env.rb b/lib/kamal/configuration/env.rb index a78338493..531c617cf 100644 --- a/lib/kamal/configuration/env.rb +++ b/lib/kamal/configuration/env.rb @@ -2,17 +2,18 @@ class Kamal::Configuration::Env attr_reader :secrets_keys, :clear, :secrets_file delegate :argumentize, to: Kamal::Utils - def self.from_config(config:, secrets_file: nil) + def self.from_config(config:, secrets_file: nil, for_node: nil) secrets_keys = config.fetch("secret", []) clear = config.fetch("clear", config.key?("secret") || config.key?("tags") ? {} : config) - new clear: clear, secrets_keys: secrets_keys, secrets_file: secrets_file + new clear: clear, secrets_keys: secrets_keys, secrets_file: secrets_file, for_node: for_node end - def initialize(clear:, secrets_keys:, secrets_file:) + def initialize(clear:, secrets_keys:, secrets_file:, for_node:) @clear = clear @secrets_keys = secrets_keys @secrets_file = secrets_file + @for_node = for_node end def args @@ -24,7 +25,11 @@ def secrets_io end def secrets - @secrets ||= secrets_keys.to_h { |key| [ key, ENV.fetch(key) ] } + if @for_node == "ephemeral_node" + Dotenv::Environment.new('.env.ephemeral').keys.to_h { |key| [ key, ENV.fetch(key) ] } + else + secrets_keys.to_h { |key| [ key, ENV.fetch(key) ] } + end end def secrets_directory @@ -35,6 +40,7 @@ def merge(other) self.class.new \ clear: @clear.merge(other.clear), secrets_keys: @secrets_keys | other.secrets_keys, + for_node: @for_node, secrets_file: secrets_file end end diff --git a/lib/kamal/configuration/env/tag.rb b/lib/kamal/configuration/env/tag.rb index 2a6a13060..b992f1812 100644 --- a/lib/kamal/configuration/env/tag.rb +++ b/lib/kamal/configuration/env/tag.rb @@ -7,6 +7,6 @@ def initialize(name, config:) end def env - Kamal::Configuration::Env.from_config(config: config) + Kamal::Configuration::Env.from_config(config: config, for_node: @name) end end diff --git a/lib/kamal/configuration/role.rb b/lib/kamal/configuration/role.rb index f0df59244..12c35e8f2 100644 --- a/lib/kamal/configuration/role.rb +++ b/lib/kamal/configuration/role.rb @@ -239,13 +239,14 @@ def specializations end def specialized_env - Kamal::Configuration::Env.from_config config: specializations.fetch("env", {}) + Kamal::Configuration::Env.from_config config: specializations.fetch("env", {}), for_node: name end # Secrets are stored in an array, which won't merge by default, so have to do it by hand. def base_env Kamal::Configuration::Env.from_config \ config: config.env, + for_node: name, secrets_file: File.join(config.host_env_directory, "roles", "#{container_prefix}.env") end From 03df0a9ad58b8ded5015721b2fad2363556c73f4 Mon Sep 17 00:00:00 2001 From: fabiosammy Date: Wed, 29 May 2024 23:36:09 -0300 Subject: [PATCH 3/8] Add the env_file config --- lib/kamal/configuration/env.rb | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/kamal/configuration/env.rb b/lib/kamal/configuration/env.rb index 531c617cf..2d25173a3 100644 --- a/lib/kamal/configuration/env.rb +++ b/lib/kamal/configuration/env.rb @@ -5,15 +5,17 @@ class Kamal::Configuration::Env def self.from_config(config:, secrets_file: nil, for_node: nil) secrets_keys = config.fetch("secret", []) clear = config.fetch("clear", config.key?("secret") || config.key?("tags") ? {} : config) + env_file = config.fetch("env_file", nil) - new clear: clear, secrets_keys: secrets_keys, secrets_file: secrets_file, for_node: for_node + new clear: clear, secrets_keys: secrets_keys, secrets_file: secrets_file, for_node: for_node, env_file: env_file end - def initialize(clear:, secrets_keys:, secrets_file:, for_node:) + def initialize(clear:, secrets_keys:, secrets_file:, for_node:, env_file:) @clear = clear @secrets_keys = secrets_keys @secrets_file = secrets_file @for_node = for_node + @env_file = env_file end def args @@ -25,8 +27,10 @@ def secrets_io end def secrets - if @for_node == "ephemeral_node" - Dotenv::Environment.new('.env.ephemeral').keys.to_h { |key| [ key, ENV.fetch(key) ] } + # TODO: More than one @env_file + # TODO: Considerer a merge between env_file and env + if @env_file + Dotenv::Environment.new(@env_file) else secrets_keys.to_h { |key| [ key, ENV.fetch(key) ] } end @@ -41,6 +45,7 @@ def merge(other) clear: @clear.merge(other.clear), secrets_keys: @secrets_keys | other.secrets_keys, for_node: @for_node, + env_file: @env_file, secrets_file: secrets_file end end From d1bb836c2c666b989dd0dead65070ce4b0352b61 Mon Sep 17 00:00:00 2001 From: fabiosammy Date: Wed, 29 May 2024 23:36:29 -0300 Subject: [PATCH 4/8] Add the envify from config file --- lib/kamal/cli/base.rb | 1 + lib/kamal/cli/main.rb | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/kamal/cli/base.rb b/lib/kamal/cli/base.rb index 0ad4d8ff6..7cd0dec2a 100644 --- a/lib/kamal/cli/base.rb +++ b/lib/kamal/cli/base.rb @@ -32,6 +32,7 @@ def initialize(*) private def load_envs + # TODO: How can we load envs from configs? Is necessary? if destination = options[:destination] Dotenv.load(".env.#{destination}", ".env") elsif custom_env = options[:custom_env] diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index 2fc488374..19ccd854a 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -169,7 +169,10 @@ def init desc "envify", "Create .env by evaluating .env.erb (or .env.staging.erb -> .env.staging when using -d staging)" option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip .env file push" def envify - if destination = options[:destination] + if envify_from_config = KAMAL.config.raw_config["envify"] + env_template_path = ".env.#{envify_from_config}.erb" + env_path = ".env.#{envify_from_config}" + elsif destination = options[:destination] env_template_path = ".env.#{destination}.erb" env_path = ".env.#{destination}" elsif custom_env = options[:custom_env] From 8f21f7bb7b106ecaa0d66b7e703f8d5f8332a6d4 Mon Sep 17 00:00:00 2001 From: fabiosammy Date: Thu, 30 May 2024 00:21:52 -0300 Subject: [PATCH 5/8] Be able to upload a complete env_file --- lib/kamal/commands/traefik.rb | 2 +- lib/kamal/configuration/accessory.rb | 2 +- lib/kamal/configuration/env.rb | 12 +++++++----- lib/kamal/configuration/role.rb | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/kamal/commands/traefik.rb b/lib/kamal/commands/traefik.rb index 6417b4086..d20d377b5 100644 --- a/lib/kamal/commands/traefik.rb +++ b/lib/kamal/commands/traefik.rb @@ -73,7 +73,7 @@ def port def env Kamal::Configuration::Env.from_config \ - config: config.traefik.fetch("env", {}), + config: config.traefik, for_node: "traefik", secrets_file: File.join(config.host_env_directory, "traefik", "traefik.env") end diff --git a/lib/kamal/configuration/accessory.rb b/lib/kamal/configuration/accessory.rb index 7b742a0aa..5281ffce6 100644 --- a/lib/kamal/configuration/accessory.rb +++ b/lib/kamal/configuration/accessory.rb @@ -43,7 +43,7 @@ def label_args def env Kamal::Configuration::Env.from_config \ - config: specifics.fetch("env", {}), + config: specifics, for_node: @name, secrets_file: File.join(config.host_env_directory, "accessories", "#{service_name}.env") end diff --git a/lib/kamal/configuration/env.rb b/lib/kamal/configuration/env.rb index 2d25173a3..f2daef914 100644 --- a/lib/kamal/configuration/env.rb +++ b/lib/kamal/configuration/env.rb @@ -1,11 +1,13 @@ class Kamal::Configuration::Env - attr_reader :secrets_keys, :clear, :secrets_file + attr_reader :secrets_keys, :clear, :secrets_file, :env_file delegate :argumentize, to: Kamal::Utils def self.from_config(config:, secrets_file: nil, for_node: nil) - secrets_keys = config.fetch("secret", []) - clear = config.fetch("clear", config.key?("secret") || config.key?("tags") ? {} : config) - env_file = config.fetch("env_file", nil) + env_key_config = config.class == Kamal::Configuration ? config.env : config.fetch("env", {}) + secrets_keys = env_key_config.fetch("secret", []) + clear = env_key_config.fetch("clear", env_key_config.key?("secret") || env_key_config.key?("tags") ? {} : env_key_config) + # TODO: Support a wide env_file + env_file = config.class == Kamal::Configuration ? nil : config.fetch("env_file", nil) new clear: clear, secrets_keys: secrets_keys, secrets_file: secrets_file, for_node: for_node, env_file: env_file end @@ -45,7 +47,7 @@ def merge(other) clear: @clear.merge(other.clear), secrets_keys: @secrets_keys | other.secrets_keys, for_node: @for_node, - env_file: @env_file, + env_file: @env_file ? @env_file : other.env_file, secrets_file: secrets_file end end diff --git a/lib/kamal/configuration/role.rb b/lib/kamal/configuration/role.rb index 12c35e8f2..51d3975d6 100644 --- a/lib/kamal/configuration/role.rb +++ b/lib/kamal/configuration/role.rb @@ -239,13 +239,13 @@ def specializations end def specialized_env - Kamal::Configuration::Env.from_config config: specializations.fetch("env", {}), for_node: name + Kamal::Configuration::Env.from_config config: specializations, for_node: name end # Secrets are stored in an array, which won't merge by default, so have to do it by hand. def base_env Kamal::Configuration::Env.from_config \ - config: config.env, + config: config, for_node: name, secrets_file: File.join(config.host_env_directory, "roles", "#{container_prefix}.env") end From 2571da25df18d0f769ff70d13b09dd17ebb351e7 Mon Sep 17 00:00:00 2001 From: fabiosammy Date: Thu, 30 May 2024 00:28:03 -0300 Subject: [PATCH 6/8] remove the for_node approach --- lib/kamal/commands/traefik.rb | 1 - lib/kamal/configuration/accessory.rb | 1 - lib/kamal/configuration/env.rb | 8 +++----- lib/kamal/configuration/env/tag.rb | 2 +- lib/kamal/configuration/role.rb | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/kamal/commands/traefik.rb b/lib/kamal/commands/traefik.rb index d20d377b5..796131b36 100644 --- a/lib/kamal/commands/traefik.rb +++ b/lib/kamal/commands/traefik.rb @@ -74,7 +74,6 @@ def port def env Kamal::Configuration::Env.from_config \ config: config.traefik, - for_node: "traefik", secrets_file: File.join(config.host_env_directory, "traefik", "traefik.env") end diff --git a/lib/kamal/configuration/accessory.rb b/lib/kamal/configuration/accessory.rb index 5281ffce6..b62808841 100644 --- a/lib/kamal/configuration/accessory.rb +++ b/lib/kamal/configuration/accessory.rb @@ -44,7 +44,6 @@ def label_args def env Kamal::Configuration::Env.from_config \ config: specifics, - for_node: @name, secrets_file: File.join(config.host_env_directory, "accessories", "#{service_name}.env") end diff --git a/lib/kamal/configuration/env.rb b/lib/kamal/configuration/env.rb index f2daef914..45d48e57d 100644 --- a/lib/kamal/configuration/env.rb +++ b/lib/kamal/configuration/env.rb @@ -2,21 +2,20 @@ class Kamal::Configuration::Env attr_reader :secrets_keys, :clear, :secrets_file, :env_file delegate :argumentize, to: Kamal::Utils - def self.from_config(config:, secrets_file: nil, for_node: nil) + def self.from_config(config:, secrets_file: nil) env_key_config = config.class == Kamal::Configuration ? config.env : config.fetch("env", {}) secrets_keys = env_key_config.fetch("secret", []) clear = env_key_config.fetch("clear", env_key_config.key?("secret") || env_key_config.key?("tags") ? {} : env_key_config) # TODO: Support a wide env_file env_file = config.class == Kamal::Configuration ? nil : config.fetch("env_file", nil) - new clear: clear, secrets_keys: secrets_keys, secrets_file: secrets_file, for_node: for_node, env_file: env_file + new clear: clear, secrets_keys: secrets_keys, secrets_file: secrets_file, env_file: env_file end - def initialize(clear:, secrets_keys:, secrets_file:, for_node:, env_file:) + def initialize(clear:, secrets_keys:, secrets_file:, env_file:) @clear = clear @secrets_keys = secrets_keys @secrets_file = secrets_file - @for_node = for_node @env_file = env_file end @@ -46,7 +45,6 @@ def merge(other) self.class.new \ clear: @clear.merge(other.clear), secrets_keys: @secrets_keys | other.secrets_keys, - for_node: @for_node, env_file: @env_file ? @env_file : other.env_file, secrets_file: secrets_file end diff --git a/lib/kamal/configuration/env/tag.rb b/lib/kamal/configuration/env/tag.rb index b992f1812..2a6a13060 100644 --- a/lib/kamal/configuration/env/tag.rb +++ b/lib/kamal/configuration/env/tag.rb @@ -7,6 +7,6 @@ def initialize(name, config:) end def env - Kamal::Configuration::Env.from_config(config: config, for_node: @name) + Kamal::Configuration::Env.from_config(config: config) end end diff --git a/lib/kamal/configuration/role.rb b/lib/kamal/configuration/role.rb index 51d3975d6..5566ce70e 100644 --- a/lib/kamal/configuration/role.rb +++ b/lib/kamal/configuration/role.rb @@ -239,14 +239,13 @@ def specializations end def specialized_env - Kamal::Configuration::Env.from_config config: specializations, for_node: name + Kamal::Configuration::Env.from_config config: specializations end # Secrets are stored in an array, which won't merge by default, so have to do it by hand. def base_env Kamal::Configuration::Env.from_config \ config: config, - for_node: name, secrets_file: File.join(config.host_env_directory, "roles", "#{container_prefix}.env") end From 4959f3198c941b857940432e46cfd70e76cc0667 Mon Sep 17 00:00:00 2001 From: fabiosammy Date: Thu, 30 May 2024 00:28:46 -0300 Subject: [PATCH 7/8] Remove the custom_env approach --- lib/kamal/cli/base.rb | 3 --- lib/kamal/cli/main.rb | 3 --- 2 files changed, 6 deletions(-) diff --git a/lib/kamal/cli/base.rb b/lib/kamal/cli/base.rb index 7cd0dec2a..9ac7f4547 100644 --- a/lib/kamal/cli/base.rb +++ b/lib/kamal/cli/base.rb @@ -19,7 +19,6 @@ def self.exit_on_failure?() true end class_option :config_file, aliases: "-c", default: "config/deploy.yml", desc: "Path to config file" class_option :destination, aliases: "-d", desc: "Specify destination to be used for config file (staging -> deploy.staging.yml)" - class_option :custom_env, desc: "Specify a custom env to be used for upload the total environment (.env.custom_env)" class_option :skip_hooks, aliases: "-H", type: :boolean, default: false, desc: "Don't run hooks" @@ -35,8 +34,6 @@ def load_envs # TODO: How can we load envs from configs? Is necessary? if destination = options[:destination] Dotenv.load(".env.#{destination}", ".env") - elsif custom_env = options[:custom_env] - Dotenv.load(".env.#{custom_env}") else Dotenv.load(".env") end diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index 19ccd854a..ea46928ad 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -175,9 +175,6 @@ def envify elsif destination = options[:destination] env_template_path = ".env.#{destination}.erb" env_path = ".env.#{destination}" - elsif custom_env = options[:custom_env] - env_template_path = ".env.#{custom_env}.erb" - env_path = ".env.#{custom_env}" else env_template_path = ".env.erb" env_path = ".env" From de38809dc6021af59bca066578a000f7f1ad2a6f Mon Sep 17 00:00:00 2001 From: fabiosammy Date: Thu, 30 May 2024 01:00:25 -0300 Subject: [PATCH 8/8] First destination, then envify from config --- lib/kamal/cli/main.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index ea46928ad..2e7092bf5 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -169,12 +169,12 @@ def init desc "envify", "Create .env by evaluating .env.erb (or .env.staging.erb -> .env.staging when using -d staging)" option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip .env file push" def envify - if envify_from_config = KAMAL.config.raw_config["envify"] - env_template_path = ".env.#{envify_from_config}.erb" - env_path = ".env.#{envify_from_config}" - elsif destination = options[:destination] + if destination = options[:destination] env_template_path = ".env.#{destination}.erb" env_path = ".env.#{destination}" + elsif envify_from_config = KAMAL.config.raw_config["envify"] + env_template_path = ".env.#{envify_from_config}.erb" + env_path = ".env.#{envify_from_config}" else env_template_path = ".env.erb" env_path = ".env"