From 8af7e48a9008058cf7f372f4031bf39a1ce56564 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 23 Jan 2023 09:43:57 +0100 Subject: [PATCH] Add file mapping to accessories --- lib/mrsk/cli/accessory.rb | 17 ++++++++++++++++ lib/mrsk/commands/accessory.rb | 2 +- lib/mrsk/configuration/accessory.rb | 24 ++++++++++++++++++++++- test/cli/accessory_test.rb | 15 +++++++++----- test/configuration/accessory_test.rb | 10 +++++++--- test/fixtures/deploy_with_accessories.yml | 2 ++ test/fixtures/files/my.cnf | 1 + 7 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/files/my.cnf diff --git a/lib/mrsk/cli/accessory.rb b/lib/mrsk/cli/accessory.rb index be5bd777..16008fc8 100644 --- a/lib/mrsk/cli/accessory.rb +++ b/lib/mrsk/cli/accessory.rb @@ -3,10 +3,27 @@ require "mrsk/cli/base" class Mrsk::Cli::Accessory < Mrsk::Cli::Base desc "boot [NAME]", "Boot accessory service on host" def boot(name) + invoke :upload, [ name ] + accessory = MRSK.accessory(name) on(accessory.host) { execute *accessory.run } end + desc "upload [NAME]", "Upload accessory files to host" + def upload(name) + accessory = MRSK.accessory(name) + on(accessory.host) do + accessory.files.each do |(local, remote)| + if Pathname.new(local).exist? + execute :mkdir, "-p", Pathname.new(remote).dirname.to_s + upload! local.to_s, remote.to_s + else + raise "Missing file: #{local}" + end + end + end + end + desc "reboot [NAME]", "Reboot accessory on host (stop container, remove container, start new container)" def reboot(name) invoke :stop, [ name ] diff --git a/lib/mrsk/commands/accessory.rb b/lib/mrsk/commands/accessory.rb index cf828de1..3249a98a 100644 --- a/lib/mrsk/commands/accessory.rb +++ b/lib/mrsk/commands/accessory.rb @@ -2,7 +2,7 @@ require "mrsk/commands/base" class Mrsk::Commands::Accessory < Mrsk::Commands::Base attr_reader :accessory_config - delegate :service_name, :image, :host, :port, :env_args, :volume_args, :label_args, to: :accessory_config + delegate :service_name, :image, :host, :port, :files, :env_args, :volume_args, :label_args, to: :accessory_config def initialize(config, name:) super(config) diff --git a/lib/mrsk/configuration/accessory.rb b/lib/mrsk/configuration/accessory.rb index cd7c8fc0..a6396d5a 100644 --- a/lib/mrsk/configuration/accessory.rb +++ b/lib/mrsk/configuration/accessory.rb @@ -43,8 +43,15 @@ class Mrsk::Configuration::Assessory argumentize_env_with_secrets env end + def files + specifics["files"]&.to_h do |local_to_remote_mapping| + local_file, remote_file = local_to_remote_mapping.split(":") + [ expand_local_file_path(local_file), expand_remote_file_path(remote_file) ] + end || {} + end + def volumes - specifics["volumes"] || [] + (specifics["volumes"] || []) + remote_files_as_volumes end def volume_args @@ -57,4 +64,19 @@ class Mrsk::Configuration::Assessory def default_labels { "service" => service_name } end + + def expand_local_file_path(local_file) + Pathname.new(File.expand_path(local_file)) + end + + def expand_remote_file_path(remote_file) + service_name + remote_file + end + + def remote_files_as_volumes + specifics["files"]&.collect do |local_to_remote_mapping| + _, remote_file = local_to_remote_mapping.split(":") + "#{expand_remote_file_path(remote_file)}:#{remote_file}" + end || [] + end end diff --git a/test/cli/accessory_test.rb b/test/cli/accessory_test.rb index f2c1d931..a0b13c5b 100644 --- a/test/cli/accessory_test.rb +++ b/test/cli/accessory_test.rb @@ -5,13 +5,18 @@ require "mrsk/cli" class CliAccessoryTest < ActiveSupport::TestCase include ActiveSupport::Testing::Stream - test "boot" do - ENV["MYSQL_ROOT_PASSWORD"] = "secret123" + setup { ENV["MYSQL_ROOT_PASSWORD"] = "secret123" } + teardown { ENV["MYSQL_ROOT_PASSWORD"] = nil } + test "upload" do + command = stdouted { Mrsk::Cli::Accessory.start(["upload", "mysql", "-c", "test/fixtures/deploy_with_accessories.yml"]) } + + assert_match "test/fixtures/files/my.cnf app-mysql/etc/mysql/my.cnf", command + end + + test "boot" do command = stdouted { Mrsk::Cli::Accessory.start(["boot", "mysql", "-c", "test/fixtures/deploy_with_accessories.yml"]) } - assert_match "Running docker run --name app-mysql -d --restart unless-stopped -p 3306:3306 -e [REDACTED] -e MYSQL_ROOT_HOST=% --volume /var/lib/mysql:/var/lib/mysql --label service=app-mysql mysql:5.7 on 1.1.1.3", command - ensure - ENV["MYSQL_ROOT_PASSWORD"] = nil + assert_match "Running docker run --name app-mysql -d --restart unless-stopped -p 3306:3306 -e [REDACTED] -e MYSQL_ROOT_HOST=% --volume /var/lib/mysql:/var/lib/mysql --volume app-mysql/etc/mysql/my.cnf:/etc/mysql/my.cnf --label service=app-mysql mysql:5.7 on 1.1.1.3", command end end diff --git a/test/configuration/accessory_test.rb b/test/configuration/accessory_test.rb index c375bc6c..d3c837db 100644 --- a/test/configuration/accessory_test.rb +++ b/test/configuration/accessory_test.rb @@ -18,8 +18,12 @@ class ConfigurationAccessoryTest < ActiveSupport::TestCase }, "secret" => [ "MYSQL_ROOT_PASSWORD" - ] - } + ], + }, + "files" => [ + "config/mysql/my.cnf:/etc/mysql/my.cnf", + "db/structure.sql:/docker-entrypoint-initdb.d/structure.sql" + ] }, "redis" => { "image" => "redis:latest", @@ -83,7 +87,7 @@ class ConfigurationAccessoryTest < ActiveSupport::TestCase end test "volume args" do - assert_equal [], @config.accessory(:mysql).volume_args + assert_equal ["--volume", "app-mysql/etc/mysql/my.cnf:/etc/mysql/my.cnf", "--volume", "app-mysql/docker-entrypoint-initdb.d/structure.sql:/docker-entrypoint-initdb.d/structure.sql"], @config.accessory(:mysql).volume_args assert_equal ["--volume", "/var/lib/redis:/data"], @config.accessory(:redis).volume_args end end diff --git a/test/fixtures/deploy_with_accessories.yml b/test/fixtures/deploy_with_accessories.yml index e351d6e9..e4f82fce 100644 --- a/test/fixtures/deploy_with_accessories.yml +++ b/test/fixtures/deploy_with_accessories.yml @@ -19,6 +19,8 @@ accessories: - MYSQL_ROOT_PASSWORD volumes: - /var/lib/mysql:/var/lib/mysql + files: + - test/fixtures/files/my.cnf:/etc/mysql/my.cnf redis: image: redis:latest host: 1.1.1.4 diff --git a/test/fixtures/files/my.cnf b/test/fixtures/files/my.cnf new file mode 100644 index 00000000..40cb3236 --- /dev/null +++ b/test/fixtures/files/my.cnf @@ -0,0 +1 @@ +# MySQL Config