From 590dfd9e1ecfb5e4631070e3ec353f7188d7842f Mon Sep 17 00:00:00 2001 From: David Siaw Date: Fri, 31 May 2024 14:44:26 +0900 Subject: [PATCH] Service feature (#98) * add test and put up service feature * rubocop appease --- .rubocop.yml | 6 +++++- lib/kaiser/cli.rb | 12 ++++++----- lib/kaiser/kaiserfile.rb | 14 +++++++++++-- lib/kaiser/service.rb | 38 +++++++++++++++++++++++++++++++++++ lib/kaiser/version.rb | 2 +- spec/kaiserfile_spec.rb | 21 +++++++++++++++++--- spec/service_spec.rb | 43 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 124 insertions(+), 12 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 0c7a7df4..8ef93dcb 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -4,4 +4,8 @@ inherit_from: .rubocop_todo.yml # its basically what they do anyway Metrics/BlockLength: Exclude: - - 'spec/**/*.rb' \ No newline at end of file + - 'spec/**/*.rb' + +Layout/LineLength: + Exclude: + - 'spec/**/*' diff --git a/lib/kaiser/cli.rb b/lib/kaiser/cli.rb index d7db189a..a930c537 100644 --- a/lib/kaiser/cli.rb +++ b/lib/kaiser/cli.rb @@ -110,11 +110,7 @@ def start_services services.each do |service| Config.info_out.puts "Starting service: #{service.name}" run_if_dead( - service.shared_name, - "docker run -d - --name #{service.shared_name} - --network #{Config.config[:networkname]} - #{service.image}" + service.shared_name, service.start_docker_command ) end end @@ -246,6 +242,10 @@ def default_db_image end def attach_app + start_services + + puts 'Attaching to app...' + cmd = (ARGV || []).join(' ') killrm app_container_name @@ -265,6 +265,8 @@ def attach_app #{app_params} kaiser:#{envname}-#{current_branch} #{cmd}".tr("\n", ' ') + stop_services + Config.out.puts 'Cleaning up...' end diff --git a/lib/kaiser/kaiserfile.rb b/lib/kaiser/kaiserfile.rb index e2f74f3a..1ceb7f4b 100644 --- a/lib/kaiser/kaiserfile.rb +++ b/lib/kaiser/kaiserfile.rb @@ -102,10 +102,20 @@ def type(value) @server_type = value end - def service(name, image: name) + def service(name, + image: name, + command: nil, + binds: {}, + env: {}) + raise "duplicate service #{name.inspect}" if @services.key?(name) - @services[name] = { image: image } + @services[name] = { + image: image, + command: command, + binds: binds, + env: env + } end end end diff --git a/lib/kaiser/service.rb b/lib/kaiser/service.rb index 8e0004c6..32f48e41 100644 --- a/lib/kaiser/service.rb +++ b/lib/kaiser/service.rb @@ -18,5 +18,43 @@ def shared_name def image @service_info[:image] end + + def command + @service_info[:command].to_s + end + + def binds + @service_info[:binds] || {} + end + + def env + @service_info[:env] || {} + end + + def start_docker_command + envstring = env.map do |k, v| + "-e #{k}=#{v}" + end.join(' ') + + bindstring = binds.map do |k, v| + "-v #{k}:#{v}" + end.join(' ') + + commandstring = command + + cmd_array = [ + 'docker run -d', + "--name #{shared_name}", + "--network #{Config.config[:networkname]}", + envstring, + bindstring, + image, + commandstring + ] + + cmd_array.filter! { |x| !x.empty? } + + cmd_array.join(' ') + end end end diff --git a/lib/kaiser/version.rb b/lib/kaiser/version.rb index 9e6c5496..b2478ced 100644 --- a/lib/kaiser/version.rb +++ b/lib/kaiser/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module Kaiser - VERSION = '0.7.1' + VERSION = '0.8.0' end diff --git a/spec/kaiserfile_spec.rb b/spec/kaiserfile_spec.rb index 6075789d..5bcba812 100644 --- a/spec/kaiserfile_spec.rb +++ b/spec/kaiserfile_spec.rb @@ -197,7 +197,12 @@ it 'adds a service' do kaiserfile = Kaiser::Kaiserfile.new('Kaiserfile') - expect(kaiserfile.services).to eq('santaclaus' => { image: 'santaclaus' }) + expect(kaiserfile.services).to eq('santaclaus' => { + image: 'santaclaus', + command: nil, + binds: {}, + env: {} + }) end end @@ -206,7 +211,12 @@ it 'adds a service with the image name' do kaiserfile = Kaiser::Kaiserfile.new('Kaiserfile') - expect(kaiserfile.services).to eq('santaclaus' => { image: 'northpole/santaclaus' }) + expect(kaiserfile.services).to eq('santaclaus' => { + image: 'northpole/santaclaus', + command: nil, + binds: {}, + env: {} + }) end end @@ -215,7 +225,12 @@ it 'adds a service with the image name' do kaiserfile = Kaiser::Kaiserfile.new('Kaiserfile') - expect(kaiserfile.services).to eq('santaclaus' => { image: 'northpole/santaclaus:last_christmas' }) + expect(kaiserfile.services).to eq('santaclaus' => { + image: 'northpole/santaclaus:last_christmas', + command: nil, + binds: {}, + env: {} + }) end end end diff --git a/spec/service_spec.rb b/spec/service_spec.rb index 73c7c0c0..4c708f90 100644 --- a/spec/service_spec.rb +++ b/spec/service_spec.rb @@ -20,4 +20,47 @@ expect(s.name).to eq 'santa' end + + describe '#start_docker_command' do + before do + allow(Kaiser::Config).to receive(:config).and_return({ networkname: 'testnet' }) + end + + it 'provides a proper docker command' do + s = Kaiser::Service.new('meow', 'santa', { image: 'np/santa:lol' }) + + expect(s.start_docker_command).to eq 'docker run -d --name meow-santa --network testnet np/santa:lol' + end + + it 'provides a command with envs' do + s = Kaiser::Service.new('meow', 'santa', { + image: 'np/santa:lol', + env: { + 'HELLO' => 'world' + } + }) + + expect(s.start_docker_command).to eq 'docker run -d --name meow-santa --network testnet -e HELLO=world np/santa:lol' + end + + it 'provides a command with binds' do + s = Kaiser::Service.new('meow', 'santa', { + image: 'np/santa:lol', + binds: { + '/home/user' => '/home/inside/container' + } + }) + + expect(s.start_docker_command).to eq 'docker run -d --name meow-santa --network testnet -v /home/user:/home/inside/container np/santa:lol' + end + + it 'provides a command with command' do + s = Kaiser::Service.new('meow', 'santa', { + image: 'np/santa:lol', + command: 'hohoho' + }) + + expect(s.start_docker_command).to eq 'docker run -d --name meow-santa --network testnet np/santa:lol hohoho' + end + end end