devkitkat 0.1.21 → 0.1.22

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +13 -11
  3. data/README.md +2 -2
  4. data/bin/devkitkat +1 -1
  5. data/devkitkat.gemspec +2 -1
  6. data/lib/devkitkat/command.rb +6 -8
  7. data/lib/devkitkat/config.rb +33 -20
  8. data/lib/devkitkat/processor.rb +48 -0
  9. data/lib/devkitkat/service/concerns/service_initializer.rb +17 -0
  10. data/lib/devkitkat/service/driver/base.rb +23 -0
  11. data/lib/devkitkat/service/driver/docker/container.rb +163 -0
  12. data/lib/devkitkat/service/driver/docker/image.rb +33 -0
  13. data/lib/devkitkat/service/driver/docker.rb +45 -0
  14. data/lib/devkitkat/service/driver/none.rb +19 -0
  15. data/lib/devkitkat/service/executor/logger.rb +22 -0
  16. data/lib/devkitkat/service/executor/scripter.rb +48 -0
  17. data/lib/devkitkat/service/executor/variables.rb +82 -0
  18. data/lib/devkitkat/service/executor.rb +102 -0
  19. data/lib/devkitkat/service/predefined_command/add_example.rb +33 -0
  20. data/lib/devkitkat/service/predefined_command/add_git_ignore.rb +29 -0
  21. data/lib/devkitkat/service/predefined_command/add_script.rb +35 -0
  22. data/lib/devkitkat/service/predefined_command/add_shared_script.rb +21 -0
  23. data/lib/devkitkat/service/predefined_command/base.rb +17 -0
  24. data/lib/devkitkat/service/predefined_command/clean.rb +22 -0
  25. data/lib/devkitkat/service/predefined_command/clone.rb +25 -0
  26. data/lib/devkitkat/service/predefined_command/exec.rb +18 -0
  27. data/lib/devkitkat/service/predefined_command/poop.rb +17 -0
  28. data/lib/devkitkat/service/predefined_command/pull.rb +19 -0
  29. data/lib/devkitkat/service/predefined_command/reconfigure.rb +26 -0
  30. data/lib/devkitkat/service/predefined_command/show_variables.rb +17 -0
  31. data/lib/devkitkat/service.rb +13 -214
  32. data/lib/devkitkat/version.rb +1 -1
  33. data/lib/devkitkat.rb +12 -5
  34. metadata +41 -12
  35. data/docs/READ.md +0 -1
  36. data/docs/config/READ.md +0 -1
  37. data/docs/machine/READ.md +0 -1
  38. data/docs/service/READ.md +0 -1
  39. data/lib/devkitkat/executor/docker.rb +0 -154
  40. data/lib/devkitkat/executor/local.rb +0 -25
  41. data/lib/devkitkat/executor.rb +0 -62
  42. data/lib/devkitkat/main.rb +0 -50
@@ -1,79 +1,26 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  require 'fileutils'
4
+ require "devkitkat/service/executor"
4
5
 
5
6
  module Devkitkat
6
7
  class Service
7
8
  attr_reader :name, :config, :command, :executor
8
9
 
9
- ScriptError = Class.new(StandardError)
10
-
11
10
  DIVISIONS = %w[src script data cache log example dockerfile].freeze
12
11
  SERVICE_PROPERTIES = %w[repo host port]
13
12
 
14
- SCRIPT_TEMPLATE = <<-EOS
15
- #!/bin/bash
16
- set -e
17
-
18
- # TODO: Define scripts
19
- EOS
20
-
21
- delegate :options, :script, :args, :kit_root, to: :command
22
-
23
13
  def initialize(name, config, command)
24
14
  @name, @config, @command = name, config, command
25
15
  end
26
16
 
27
17
  def execute
28
- execute!
29
-
30
- true
31
- rescue ScriptError => e
32
- puts "Failure: #{e}".colorize(:red)
33
-
34
- false
35
- end
36
-
37
- def execute!
38
- executor.prepare
39
-
40
- inject_global_variables
41
- inject_public_variables
42
- inject_private_variables
43
- setup_logger
44
-
45
- FileUtils.rm_f(log_path)
46
- FileUtils.mkdir_p(log_dir)
47
-
48
- method = script.tr('-', '_')
49
-
50
- if File.exist?(script_path)
51
- executor.write(%Q{echo "This script is a custom script provided by you."})
52
- executor.write(script_path)
53
- elsif respond_to?(method, true)
54
- executor.write(%Q{echo "This script is a predefined script provided by devkitkat."})
55
- executor.write("set -e")
56
- send(method)
57
- end
58
-
59
- executor.commit.tap do |result|
60
- raise ScriptError, process_error_message($?) unless result
61
- end
62
- ensure
63
- executor.cleanup
64
- end
65
-
66
- def log_path
67
- File.join(log_dir, "#{script}.log")
68
- end
69
-
70
- def container_name
71
- "#{config.application}-#{name}"
18
+ Executor.new(self).execute
72
19
  end
73
20
 
74
21
  DIVISIONS.each do |division|
75
22
  define_method :"#{division}_dir" do
76
- File.join(service_dir, division)
23
+ File.join(dir, division)
77
24
  end
78
25
  end
79
26
 
@@ -87,178 +34,30 @@ set -e
87
34
  end
88
35
  end
89
36
 
90
- def service_dir
91
- File.join(kit_root, 'services', name)
37
+ def root_dir
38
+ File.join(command.kit_root, 'services')
92
39
  end
93
40
 
94
- def shared_script_dir
95
- File.join(script_dir, 'shared')
96
- end
97
-
98
- private
99
-
100
- def inject_global_variables
101
- config.variables.each do |key, value|
102
- executor.write("export #{key}=#{value}")
103
- end
104
-
105
- command.variables&.each do |key, value|
106
- executor.write("export #{key}=#{value}")
107
- end
108
-
109
- executor.write("export DK_ROOT_DIR=#{kit_root}")
110
- executor.write("export DK_ENVIRONMENT_TYPE=#{config.environment_type.to_s}")
111
- executor.write("export DK_APPLICATION=#{config.application.to_s}")
112
- end
113
-
114
- def inject_public_variables
115
- all_services.each do |service|
116
- executor.write("export DK_#{service.name.upcase}_DIR=#{service.service_dir}")
117
-
118
- DIVISIONS.each do |division|
119
- executor.write("export DK_#{service.name.upcase}_#{division.upcase}_DIR=#{service.send("#{division}_dir")}")
120
- end
121
-
122
- executor.write("export DK_#{service.name.upcase}_SHARED_SCRIPT_DIR=#{service.shared_script_dir}")
123
-
124
- config.service_hash(service.name).each do |key, value|
125
- executor.write("export DK_#{service.name.upcase}_#{key.upcase}=#{value}")
126
- end
127
- end
128
- end
129
-
130
- def inject_private_variables
131
- executor.write("export DK_SELF_DIR=#{service_dir}")
132
-
133
- DIVISIONS.each do |division|
134
- executor.write("export DK_SELF_#{division.upcase}_DIR=#{send("#{division}_dir")}")
135
- end
136
-
137
- config.service_hash(name).each do |key, value|
138
- executor.write("export #{key}=#{value}")
139
- end
140
- end
141
-
142
- def setup_logger
143
- return if command.interactive?
144
-
145
- executor.write("exec > #{log_path} 2>&1")
41
+ def dir
42
+ File.join(root_dir, name)
146
43
  end
147
44
 
148
- def all_services
149
- @all_services ||= config.all_services.map { |service| Service.new(service, config, command) }
45
+ def log_path
46
+ File.join(log_dir, "#{command.script}.log")
150
47
  end
151
48
 
152
49
  def script_path
153
- File.join(script_dir, script)
50
+ File.join(script_dir, command.script)
154
51
  end
155
52
 
156
53
  def system?
157
54
  name == 'system'
158
55
  end
159
56
 
160
- def process_error_message(exit_code)
161
- %Q[The command "#{script}" for "#{name}" exited with non-zero code: #{exit_code}.
162
- See the log file: #{log_path}]
163
- end
164
-
165
- def add_script
166
- names = command.args.any? ? command.args : %w[configure unconfigure start]
167
-
168
- FileUtils.mkdir_p(script_dir)
169
-
170
- names.each do |name|
171
- file_path = File.join(script_dir, name)
172
-
173
- next if File.exist?(file_path)
174
-
175
- File.write(file_path, SCRIPT_TEMPLATE)
176
- File.chmod(0777, file_path)
177
- end
178
- end
179
-
180
- def add_example
181
- names = command.args
182
-
183
- raise ArgumentError, 'Please specify at least one example name' if names.empty?
184
-
185
- FileUtils.mkdir_p(example_dir)
186
-
187
- names.each do |name|
188
- file_path = File.join(example_dir, name)
189
-
190
- next if File.exist?(file_path)
191
-
192
- FileUtils.touch(file_path)
193
- File.chmod(0777, file_path)
194
- end
195
- end
196
-
197
- def add_shared_script
198
- raise ArgumentError, %Q{Shared script has to be added to "system"} unless name == 'system'
199
-
200
- FileUtils.mkdir_p(script_dir)
201
-
202
- file_path = File.join(script_dir, 'shared')
203
-
204
- return if File.exist?(file_path)
205
-
206
- FileUtils.touch(file_path)
207
- File.chmod(0777, file_path)
208
- end
209
-
210
- def clone
211
- return unless repo_defined?
212
-
213
- cmd = <<-EOS
214
- if [ -n "$GIT_DEPTH" ]; then
215
- git clone #{repo} #{src_dir} --depth $GIT_DEPTH
216
- else
217
- git clone #{repo} #{src_dir}
218
- fi
219
- EOS
220
-
221
- executor.write(cmd)
222
- end
223
-
224
- def pull
225
- return unless repo_defined?
226
-
227
- executor.write("cd #{src_dir}")
228
- executor.write("git checkout master")
229
- executor.write("git pull origin master")
230
- end
231
-
232
- def clean
233
- executor.write("rm -rf #{src_dir}")
234
- executor.write("rm -rf #{data_dir}")
235
- executor.write("rm -rf #{cache_dir}")
236
- executor.write("rm -rf #{log_dir}")
237
- end
57
+ def shared_script_path
58
+ return unless system?
238
59
 
239
- def reconfigure
240
- unconfigure_path = File.join(script_dir, 'unconfigure')
241
- configure_path = File.join(script_dir, 'configure')
242
-
243
- executor.write(unconfigure_path) if File.exist?(unconfigure_path)
244
- executor.write(configure_path) if File.exist?(configure_path)
245
- end
246
-
247
- def poop
248
- executor.write(%Q{echo "💩"})
249
- end
250
-
251
- def exec
252
- executor.write(%Q{cd #{src_dir}})
253
- executor.write(%Q{#{args.join(' ')}})
254
- end
255
-
256
- def show_variables
257
- executor.write(%Q{export})
258
- end
259
-
260
- def executor
261
- @executor ||= Executor.new(self)
60
+ File.join(script_dir, 'shared')
262
61
  end
263
62
  end
264
63
  end
@@ -1,3 +1,3 @@
1
1
  module Devkitkat
2
- VERSION = "0.1.21"
2
+ VERSION = "0.1.22"
3
3
  end
data/lib/devkitkat.rb CHANGED
@@ -1,14 +1,21 @@
1
1
  require "devkitkat/version"
2
- require "devkitkat/main"
3
- require "devkitkat/executor"
4
2
  require "devkitkat/command"
5
3
  require "devkitkat/config"
6
4
  require "devkitkat/service"
7
- require 'yaml'
8
- require 'optparse'
9
- require 'parallel'
5
+ require "devkitkat/processor"
10
6
  require 'colorize'
11
7
  require 'active_support/core_ext/array/conversions'
12
8
 
13
9
  module Devkitkat
10
+ class Main
11
+ def self.execute
12
+ command = Command.new
13
+ config = Config.new(command.kit_root)
14
+
15
+ target_services = config.resolve!(command.target, exclude: command.options[:exclude])
16
+ .map { |name| Service.new(name, config, command) }
17
+
18
+ Processor.new(target_services, command, config).execute
19
+ end
20
+ end
14
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devkitkat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.21
4
+ version: 0.1.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shinya Maeda
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-29 00:00:00.000000000 Z
11
+ date: 2020-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: 1.34.2
167
+ - !ruby/object:Gem::Dependency
168
+ name: require_all
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 3.0.0
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 3.0.0
167
181
  description: Make micro services easy
168
182
  email:
169
183
  - shinya@gitlab.com
@@ -188,18 +202,33 @@ files:
188
202
  - bin/release
189
203
  - bin/setup
190
204
  - devkitkat.gemspec
191
- - docs/READ.md
192
- - docs/config/READ.md
193
- - docs/machine/READ.md
194
- - docs/service/READ.md
195
205
  - lib/devkitkat.rb
196
206
  - lib/devkitkat/command.rb
197
207
  - lib/devkitkat/config.rb
198
- - lib/devkitkat/executor.rb
199
- - lib/devkitkat/executor/docker.rb
200
- - lib/devkitkat/executor/local.rb
201
- - lib/devkitkat/main.rb
208
+ - lib/devkitkat/processor.rb
202
209
  - lib/devkitkat/service.rb
210
+ - lib/devkitkat/service/concerns/service_initializer.rb
211
+ - lib/devkitkat/service/driver/base.rb
212
+ - lib/devkitkat/service/driver/docker.rb
213
+ - lib/devkitkat/service/driver/docker/container.rb
214
+ - lib/devkitkat/service/driver/docker/image.rb
215
+ - lib/devkitkat/service/driver/none.rb
216
+ - lib/devkitkat/service/executor.rb
217
+ - lib/devkitkat/service/executor/logger.rb
218
+ - lib/devkitkat/service/executor/scripter.rb
219
+ - lib/devkitkat/service/executor/variables.rb
220
+ - lib/devkitkat/service/predefined_command/add_example.rb
221
+ - lib/devkitkat/service/predefined_command/add_git_ignore.rb
222
+ - lib/devkitkat/service/predefined_command/add_script.rb
223
+ - lib/devkitkat/service/predefined_command/add_shared_script.rb
224
+ - lib/devkitkat/service/predefined_command/base.rb
225
+ - lib/devkitkat/service/predefined_command/clean.rb
226
+ - lib/devkitkat/service/predefined_command/clone.rb
227
+ - lib/devkitkat/service/predefined_command/exec.rb
228
+ - lib/devkitkat/service/predefined_command/poop.rb
229
+ - lib/devkitkat/service/predefined_command/pull.rb
230
+ - lib/devkitkat/service/predefined_command/reconfigure.rb
231
+ - lib/devkitkat/service/predefined_command/show_variables.rb
203
232
  - lib/devkitkat/version.rb
204
233
  homepage: https://gitlab.com/dosuken123/devkitkat
205
234
  licenses:
data/docs/READ.md DELETED
@@ -1 +0,0 @@
1
- # Devkitkat
data/docs/config/READ.md DELETED
@@ -1 +0,0 @@
1
- # Config
data/docs/machine/READ.md DELETED
@@ -1 +0,0 @@
1
- # Machine
data/docs/service/READ.md DELETED
@@ -1 +0,0 @@
1
- # Service
@@ -1,154 +0,0 @@
1
- require 'active_support/core_ext/module/delegation'
2
- require 'docker'
3
-
4
- module Devkitkat
5
- class Executor
6
- class Docker
7
- PreparationError = Class.new(StandardError)
8
-
9
- attr_reader :service, :script_file
10
-
11
- delegate :config, :command, to: :service
12
-
13
- ROOT_IN_CONTAINER = '/devkitkat'
14
-
15
- def initialize(service)
16
- @service = service
17
- end
18
-
19
- def prepare
20
- pull_image unless image_exist?
21
- start_container
22
- sync_user_with_host
23
- end
24
-
25
- def cleanup
26
- stop_container
27
- end
28
-
29
- def commit(script_file)
30
- @script_file = script_file
31
-
32
- rewrite_root_path!
33
- new_path = script_path_in_container
34
-
35
- exec([new_path], user: user_name)
36
- end
37
-
38
- private
39
-
40
- def rewrite_root_path!
41
- content = File.read(script_file)
42
- new_content = content.gsub(command.kit_root, ROOT_IN_CONTAINER)
43
- File.write(script_file, new_content)
44
- end
45
-
46
- def script_path_in_container
47
- relative_path = script_file.delete_prefix(command.kit_root)
48
- File.join(ROOT_IN_CONTAINER, relative_path)
49
- end
50
-
51
- def log_path_in_container
52
- relative_path = service.log_path.delete_prefix(command.kit_root)
53
- File.join(ROOT_IN_CONTAINER, relative_path)
54
- end
55
-
56
- def docker_image
57
- config.image
58
- end
59
-
60
- def container
61
- @container ||= ::Docker::Container.create(container_parameter)
62
- end
63
-
64
- def container_parameter
65
- params = {
66
- 'Cmd' => %w[tail -f],
67
- 'Image' => docker_image,
68
- 'name' => service.container_name,
69
- 'HostConfig' => {
70
- 'Binds' => ["#{command.kit_root}:#{ROOT_IN_CONTAINER}"]
71
- }
72
- }
73
-
74
- if service.port
75
- params.deep_merge!(
76
- 'ExposedPorts' => { "#{service.port}/tcp" => {} },
77
- 'HostConfig' => {
78
- 'PortBindings' => {
79
- "#{service.port}/tcp" => [{ 'HostPort' => service.port.to_s }]
80
- }
81
- }
82
- )
83
- end
84
-
85
- params
86
- end
87
-
88
- def pull_image
89
- puts "Pulling image #{docker_image}..."
90
- ::Docker::Image.create('fromImage' => docker_image)
91
- puts "Pulled image #{docker_image}..."
92
- end
93
-
94
- def image_exist?
95
- ::Docker::Image.get(docker_image)
96
- rescue
97
- false
98
- end
99
-
100
- def start_container
101
- container.start
102
- end
103
-
104
- def user_name
105
- 'devkitkat'
106
- end
107
-
108
- def group_id
109
- @group_id ||= `id -u`.delete("\n")
110
- end
111
-
112
- def user_id
113
- @user_id ||= `id -g`
114
- end
115
-
116
- def exec(cmds, params = {})
117
- stdout_messages, stderr_messages, exit_code =
118
- container.exec(cmds, params)
119
-
120
- if command.debug?
121
- puts "#{self.class.name} - #{__callee__}: stdout_messages: #{stdout_messages} stderr_messages: #{stderr_messages}"
122
- end
123
-
124
- exit_code == 0 ? true : false
125
- end
126
-
127
- def exec!(cmds, params = {})
128
- unless exec(cmds, params)
129
- raise PreparationError, "Failed to execute command in container. cmds: #{cmds}"
130
- end
131
- end
132
-
133
- def sync_user_with_host
134
- exec!(['addgroup', '--gid', group_id, user_name])
135
-
136
- exec!(['adduser',
137
- '--uid', user_id,
138
- '--gid', group_id,
139
- '--shell', '/bin/bash',
140
- '--home', ROOT_IN_CONTAINER,
141
- '--gecos', '',
142
- '--disabled-password',
143
- user_name])
144
-
145
- exec!(['chown', '-R', "#{user_name}:#{user_name}", ROOT_IN_CONTAINER])
146
- end
147
-
148
- def stop_container
149
- # container.stop
150
- container.remove(force: true)
151
- end
152
- end
153
- end
154
- end
@@ -1,25 +0,0 @@
1
- module Devkitkat
2
- class Executor
3
- class Local
4
- attr_reader :service
5
-
6
- delegate :config, :command, to: :service
7
-
8
- def initialize(service)
9
- @service = service
10
- end
11
-
12
- def prepare
13
- # no-op
14
- end
15
-
16
- def cleanup
17
- # no-op
18
- end
19
-
20
- def commit(script_file)
21
- system(script_file)
22
- end
23
- end
24
- end
25
- end
@@ -1,62 +0,0 @@
1
- require "devkitkat/executor/docker"
2
- require "devkitkat/executor/local"
3
-
4
- module Devkitkat
5
- class Executor
6
- attr_reader :service, :scripts
7
-
8
- delegate :config, :command, to: :service
9
- delegate :prepare, :cleanup, to: :executor
10
-
11
- SCRIPT_HEADER = <<-EOS
12
- #!/bin/bash
13
- EOS
14
-
15
- def initialize(service)
16
- @service = service
17
- delete_script_file
18
- end
19
-
20
- def write(cmd)
21
- ensure_script_file
22
-
23
- File.open(script_file, 'a') do |stream|
24
- stream.write(cmd + "\n")
25
- end
26
- end
27
-
28
- def commit
29
- executor.commit(script_file)
30
- ensure
31
- delete_script_file
32
- end
33
-
34
- private
35
-
36
- def executor
37
- @executor ||= klass.new(service)
38
- end
39
-
40
- def klass
41
- Object.const_get("Devkitkat::Executor::#{config.environment_type.capitalize}")
42
- end
43
-
44
- def script_file
45
- File.join(command.tmp_dir, "script-#{service.name}-#{command.script}")
46
- end
47
-
48
- def ensure_script_file
49
- create_script_file unless File.exist?(script_file)
50
- end
51
-
52
- def create_script_file
53
- command.create_tmp_dir
54
- File.write(script_file, SCRIPT_HEADER)
55
- File.chmod(0777, script_file)
56
- end
57
-
58
- def delete_script_file
59
- FileUtils.rm_f(script_file)
60
- end
61
- end
62
- end
@@ -1,50 +0,0 @@
1
- module Devkitkat
2
- class Main
3
- attr_reader :config, :command
4
-
5
- def initialize
6
- @command = Command.new
7
- @config = Config.new(command.kit_root)
8
- end
9
-
10
- def execute
11
- results = []
12
-
13
- print_log_paths
14
-
15
- if target_services.count == 1
16
- # If the target is only one, it could be console access (TTY)
17
- # so we can't run in parallel.
18
- results << target_services.first.execute
19
- else
20
- results = Parallel.map(target_services, progress: 'Executing', in_processes: 8) do |service|
21
- service.execute.tap do |success|
22
- raise Parallel::Kill unless success
23
- end
24
- end
25
- end
26
-
27
- terminate_process_group! unless results&.all? { |result| result == true }
28
- end
29
-
30
- private
31
-
32
- def terminate_process_group!
33
- pgid = Process.getpgid(Process.pid)
34
-
35
- Process.kill('TERM', -pgid)
36
- end
37
-
38
- def target_services
39
- @target_services ||= config.resolve!(command.target, exclude: command.options[:exclude])
40
- .map { |name| Service.new(name, config, command) }
41
- end
42
-
43
- def print_log_paths
44
- return if command.interactive? || command.quiet?
45
-
46
- log_paths = target_services.map(&:log_path)
47
- puts %Q{See the log at \n#{log_paths.join("\n")}}
48
- end
49
- end
50
- end