devkitkat 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.gitlab-ci.yml +15 -0
- data/.rspec +3 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +74 -0
- data/LICENSE.txt +21 -0
- data/README.md +250 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/devkitkat +6 -0
- data/bin/fast_rspec +3 -0
- data/bin/setup +8 -0
- data/devkitkat.gemspec +37 -0
- data/docs/READ.md +1 -0
- data/docs/config/READ.md +1 -0
- data/docs/machine/READ.md +1 -0
- data/docs/service/READ.md +1 -0
- data/lib/devkitkat.rb +14 -0
- data/lib/devkitkat/command.rb +65 -0
- data/lib/devkitkat/config.rb +87 -0
- data/lib/devkitkat/executor.rb +63 -0
- data/lib/devkitkat/executor/docker.rb +97 -0
- data/lib/devkitkat/executor/local.rb +25 -0
- data/lib/devkitkat/main.rb +46 -0
- data/lib/devkitkat/service.rb +243 -0
- data/lib/devkitkat/version.rb +3 -0
- metadata +225 -0
@@ -0,0 +1,46 @@
|
|
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
|
+
if command.tty? && target_services.count > 1
|
12
|
+
raise ArgumentError, 'TTY mode accepts only one service'
|
13
|
+
end
|
14
|
+
|
15
|
+
log_paths = target_services.map(&:log_path)
|
16
|
+
puts %Q{See the log at \n#{log_paths.join("\n")}}
|
17
|
+
|
18
|
+
if target_services.count == 1
|
19
|
+
# If the target is only one, it could be console access (TTY)
|
20
|
+
# so we can't run in parallel.
|
21
|
+
service = target_services.first
|
22
|
+
execute_for(service)
|
23
|
+
else
|
24
|
+
Parallel.map(target_services, progress: 'Executing', in_processes: 8) do |service|
|
25
|
+
execute_for(service)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def execute_for(service)
|
33
|
+
begin
|
34
|
+
service.execute!
|
35
|
+
rescue Devkitkat::Service::ScriptError => e
|
36
|
+
puts "Failure: #{e}".colorize(:red)
|
37
|
+
raise Parallel::Kill
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def target_services
|
42
|
+
@target_services ||= config.resolve!(command.target, exclude: command.options[:exclude])
|
43
|
+
.map { |name| Service.new(name, config, command) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Devkitkat
|
6
|
+
class Service
|
7
|
+
attr_reader :name, :config, :command, :executor
|
8
|
+
|
9
|
+
ScriptError = Class.new(StandardError)
|
10
|
+
|
11
|
+
DIVISIONS = %w[src script data cache log example dockerfile].freeze
|
12
|
+
SERVICE_PROPERTIES = %w[repo host port]
|
13
|
+
|
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
|
+
def initialize(name, config, command)
|
24
|
+
@name, @config, @command = name, config, command
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute!
|
28
|
+
executor.prepare
|
29
|
+
|
30
|
+
inject_global_variables
|
31
|
+
inject_public_variables
|
32
|
+
inject_private_variables
|
33
|
+
setup_logger
|
34
|
+
|
35
|
+
FileUtils.rm_f(log_path)
|
36
|
+
FileUtils.mkdir_p(log_dir)
|
37
|
+
|
38
|
+
method = script.tr('-', '_')
|
39
|
+
|
40
|
+
if File.exist?(script_path)
|
41
|
+
executor.write(%Q{echo "This script is a custom script provided by you."})
|
42
|
+
executor.write(script_path)
|
43
|
+
elsif respond_to?(method, true)
|
44
|
+
executor.write(%Q{echo "This script is a predefined script provided by devkitkat."})
|
45
|
+
send(method)
|
46
|
+
end
|
47
|
+
|
48
|
+
executor.commit.tap do |result|
|
49
|
+
raise ScriptError, process_error_message($?) unless result
|
50
|
+
end
|
51
|
+
ensure
|
52
|
+
executor.cleanup
|
53
|
+
end
|
54
|
+
|
55
|
+
def log_path
|
56
|
+
File.join(log_dir, "#{script}.log")
|
57
|
+
end
|
58
|
+
|
59
|
+
def container_name
|
60
|
+
"#{config.application}-#{name}"
|
61
|
+
end
|
62
|
+
|
63
|
+
DIVISIONS.each do |division|
|
64
|
+
define_method :"#{division}_dir" do
|
65
|
+
File.join(service_dir, division)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
SERVICE_PROPERTIES.each do |property|
|
70
|
+
define_method :"#{property}_defined?" do
|
71
|
+
config.service_hash(name).key?(property)
|
72
|
+
end
|
73
|
+
|
74
|
+
define_method :"#{property}" do
|
75
|
+
config.service_hash(name)[property]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def service_dir
|
80
|
+
File.join(kit_root, 'services', name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def shared_script_dir
|
84
|
+
File.join(script_dir, 'shared')
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def inject_global_variables
|
90
|
+
config.variables.each do |key, value|
|
91
|
+
executor.write("export #{key}=#{value}")
|
92
|
+
end
|
93
|
+
|
94
|
+
command.variables&.each do |key, value|
|
95
|
+
executor.write("export #{key}=#{value}")
|
96
|
+
end
|
97
|
+
|
98
|
+
executor.write("export MI_ROOT_DIR=#{kit_root}")
|
99
|
+
executor.write("export MI_ENVIRONMENT_TYPE=#{config.environment_type.to_s}")
|
100
|
+
executor.write("export MI_APPLICATION=#{config.application.to_s}")
|
101
|
+
end
|
102
|
+
|
103
|
+
def inject_public_variables
|
104
|
+
all_services.each do |service|
|
105
|
+
executor.write("export MI_#{service.name.upcase}_DIR=#{service.service_dir}")
|
106
|
+
|
107
|
+
DIVISIONS.each do |division|
|
108
|
+
executor.write("export MI_#{service.name.upcase}_#{division.upcase}_DIR=#{service.send("#{division}_dir")}")
|
109
|
+
end
|
110
|
+
|
111
|
+
executor.write("export MI_#{service.name.upcase}_SHARED_SCRIPT_DIR=#{service.shared_script_dir}")
|
112
|
+
|
113
|
+
config.service_hash(service.name).each do |key, value|
|
114
|
+
executor.write("export MI_#{service.name.upcase}_#{key.upcase}=#{value}")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def inject_private_variables
|
120
|
+
executor.write("export MI_SELF_DIR=#{service_dir}")
|
121
|
+
|
122
|
+
DIVISIONS.each do |division|
|
123
|
+
executor.write("export MI_SELF_#{division.upcase}_DIR=#{send("#{division}_dir")}")
|
124
|
+
end
|
125
|
+
|
126
|
+
config.service_hash(name).each do |key, value|
|
127
|
+
executor.write("export #{key}=#{value}")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def setup_logger
|
132
|
+
return if command.tty?
|
133
|
+
|
134
|
+
executor.write("exec > #{log_path} 2>&1")
|
135
|
+
end
|
136
|
+
|
137
|
+
def all_services
|
138
|
+
@all_services ||= config.all_services.map { |service| Service.new(service, config, command) }
|
139
|
+
end
|
140
|
+
|
141
|
+
def script_path
|
142
|
+
File.join(script_dir, script)
|
143
|
+
end
|
144
|
+
|
145
|
+
def system?
|
146
|
+
name == 'system'
|
147
|
+
end
|
148
|
+
|
149
|
+
def process_error_message(exit_code)
|
150
|
+
%Q[The command "#{script}" for "#{name}" exited with non-zero code: #{exit_code}.
|
151
|
+
See the log file: #{log_path}]
|
152
|
+
end
|
153
|
+
|
154
|
+
def add_script
|
155
|
+
names = command.args.any? ? command.args : %w[configure unconfigure start stop]
|
156
|
+
|
157
|
+
FileUtils.mkdir_p(script_dir)
|
158
|
+
|
159
|
+
names.each do |name|
|
160
|
+
file_path = File.join(script_dir, name)
|
161
|
+
|
162
|
+
next if File.exist?(file_path)
|
163
|
+
|
164
|
+
File.write(file_path, SCRIPT_TEMPLATE)
|
165
|
+
File.chmod(0777, file_path)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_example
|
170
|
+
names = command.args
|
171
|
+
|
172
|
+
raise ArgumentError, 'Please specify at least one example name' if names.empty?
|
173
|
+
|
174
|
+
FileUtils.mkdir_p(example_dir)
|
175
|
+
|
176
|
+
names.each do |name|
|
177
|
+
file_path = File.join(example_dir, name)
|
178
|
+
|
179
|
+
next if File.exist?(file_path)
|
180
|
+
|
181
|
+
FileUtils.touch(file_path)
|
182
|
+
File.chmod(0777, file_path)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def add_shared_script
|
187
|
+
raise ArgumentError, %Q{Shared script has to be added to "system"} unless name == 'system'
|
188
|
+
|
189
|
+
FileUtils.mkdir_p(script_dir)
|
190
|
+
|
191
|
+
file_path = File.join(script_dir, 'shared')
|
192
|
+
|
193
|
+
return if File.exist?(file_path)
|
194
|
+
|
195
|
+
FileUtils.touch(file_path)
|
196
|
+
File.chmod(0777, file_path)
|
197
|
+
end
|
198
|
+
|
199
|
+
def clone
|
200
|
+
return unless repo_defined?
|
201
|
+
|
202
|
+
options = []
|
203
|
+
|
204
|
+
if command.options[:git_depth]
|
205
|
+
options << "--depth #{command.options[:git_depth]}"
|
206
|
+
end
|
207
|
+
|
208
|
+
executor.write("git clone #{repo} #{src_dir} #{options.join(' ')}")
|
209
|
+
end
|
210
|
+
|
211
|
+
def pull
|
212
|
+
return unless repo_defined?
|
213
|
+
|
214
|
+
remote = command.options[:git_remote] || 'origin'
|
215
|
+
branch = command.options[:git_branch] || 'master'
|
216
|
+
|
217
|
+
executor.write("git pull #{remote} #{branch}")
|
218
|
+
end
|
219
|
+
|
220
|
+
def clean
|
221
|
+
executor.write("rm -rf #{src_dir}")
|
222
|
+
executor.write("rm -rf #{data_dir}")
|
223
|
+
executor.write("rm -rf #{cache_dir}")
|
224
|
+
executor.write("rm -rf #{log_dir}")
|
225
|
+
end
|
226
|
+
|
227
|
+
def reconfigure
|
228
|
+
unconfigure_path = File.join(script_dir, 'unconfigure')
|
229
|
+
configure_path = File.join(script_dir, 'configure')
|
230
|
+
|
231
|
+
executor.write(unconfigure_path) if File.exist?(unconfigure_path)
|
232
|
+
executor.write(configure_path) if File.exist?(configure_path)
|
233
|
+
end
|
234
|
+
|
235
|
+
def poop
|
236
|
+
executor.write(%Q{echo "💩"})
|
237
|
+
end
|
238
|
+
|
239
|
+
def executor
|
240
|
+
@executor ||= Executor.new(self)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
metadata
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: devkitkat
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Shinya Maeda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-10-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.17'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.17'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-temp_dir
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 1.1.0
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 1.1.0
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.12.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.12.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry-nav
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: activesupport
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 6.0.0
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 6.0.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: parallel
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.17.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.17.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: ruby-progressbar
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 1.10.1
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 1.10.1
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: colorize
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.8.1
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.8.1
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: docker-api
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 1.34.2
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 1.34.2
|
167
|
+
description: Make micro services easy
|
168
|
+
email:
|
169
|
+
- shinya@gitlab.com
|
170
|
+
executables:
|
171
|
+
- devkitkat
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- ".gitignore"
|
176
|
+
- ".gitlab-ci.yml"
|
177
|
+
- ".rspec"
|
178
|
+
- CODE_OF_CONDUCT.md
|
179
|
+
- Gemfile
|
180
|
+
- Gemfile.lock
|
181
|
+
- LICENSE.txt
|
182
|
+
- README.md
|
183
|
+
- Rakefile
|
184
|
+
- bin/console
|
185
|
+
- bin/devkitkat
|
186
|
+
- bin/fast_rspec
|
187
|
+
- bin/setup
|
188
|
+
- devkitkat.gemspec
|
189
|
+
- docs/READ.md
|
190
|
+
- docs/config/READ.md
|
191
|
+
- docs/machine/READ.md
|
192
|
+
- docs/service/READ.md
|
193
|
+
- lib/devkitkat.rb
|
194
|
+
- lib/devkitkat/command.rb
|
195
|
+
- lib/devkitkat/config.rb
|
196
|
+
- lib/devkitkat/executor.rb
|
197
|
+
- lib/devkitkat/executor/docker.rb
|
198
|
+
- lib/devkitkat/executor/local.rb
|
199
|
+
- lib/devkitkat/main.rb
|
200
|
+
- lib/devkitkat/service.rb
|
201
|
+
- lib/devkitkat/version.rb
|
202
|
+
homepage: https://gitlab.com/dosuken123/devkitkat
|
203
|
+
licenses:
|
204
|
+
- MIT
|
205
|
+
metadata: {}
|
206
|
+
post_install_message:
|
207
|
+
rdoc_options: []
|
208
|
+
require_paths:
|
209
|
+
- lib
|
210
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">="
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
216
|
+
requirements:
|
217
|
+
- - ">="
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
version: '0'
|
220
|
+
requirements: []
|
221
|
+
rubygems_version: 3.0.3
|
222
|
+
signing_key:
|
223
|
+
specification_version: 4
|
224
|
+
summary: Make micro services easy
|
225
|
+
test_files: []
|