kuber_kit 0.5.6 → 0.6.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 +4 -4
- data/CHANGELOG.md +18 -0
- data/Gemfile.lock +3 -2
- data/TODO.md +0 -3
- data/example/app_data/service.yml +2 -1
- data/example/images/failing_app/Dockerfile +5 -0
- data/example/images/failing_app/image.rb +4 -0
- data/example/services/failing_app.rb +6 -0
- data/kuber_kit.gemspec +2 -1
- data/lib/kuber_kit.rb +9 -0
- data/lib/kuber_kit/actions/action_result.rb +32 -0
- data/lib/kuber_kit/actions/configuration_loader.rb +2 -1
- data/lib/kuber_kit/actions/image_compiler.rb +18 -12
- data/lib/kuber_kit/actions/service_deployer.rb +37 -65
- data/lib/kuber_kit/cli.rb +18 -24
- data/lib/kuber_kit/container.rb +12 -0
- data/lib/kuber_kit/image_compiler/action_handler.rb +3 -0
- data/lib/kuber_kit/service_deployer/deployment_options_selector.rb +49 -0
- data/lib/kuber_kit/service_deployer/strategies/docker.rb +6 -1
- data/lib/kuber_kit/shell/local_shell.rb +12 -0
- data/lib/kuber_kit/tools/build_dir_cleaner.rb +26 -0
- data/lib/kuber_kit/tools/logger_factory.rb +6 -5
- data/lib/kuber_kit/tools/workdir_detector.rb +33 -0
- data/lib/kuber_kit/version.rb +1 -1
- metadata +27 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32c19efd73a0f79e6dd009a9e6700c184b78eacde4be6c7eb3e9571a6aa5977d
|
4
|
+
data.tar.gz: 6c66868a7a280ecaccc6dcb44ee75a929ecbb057545f412dab2f57e4e8c45bc9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b1316dd6e65c9f81db7450c4e86c398357cd429054965ddff80634744f1ab5b1acedb638cd51c9c65040edd0c09c67429d5f884eef6c443ddb0e6bf558bd878
|
7
|
+
data.tar.gz: dac99cdc86d70f8f9424f6cb9aee0e7f5630e5407f878266c6373740015a5664c3ea6c27a29c9f39985b738bc7665281f9f9ced846436f251598da16bc6517f8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
**0.6.0**
|
2
|
+
- Cleanup old image build dirs
|
3
|
+
- Add rotation to deployment log file
|
4
|
+
|
5
|
+
**0.5.10**
|
6
|
+
- Fix a regression when deployment result would not be properly returned as json.
|
7
|
+
|
8
|
+
**0.5.9**
|
9
|
+
- Added an ability to set custom user
|
10
|
+
- Allow setting environment variable in docker strategy
|
11
|
+
- Properly stop deployment if image compilation is failed
|
12
|
+
|
13
|
+
**0.5.8**
|
14
|
+
- Update gemspec to support ruby 2.5
|
15
|
+
|
16
|
+
**0.5.7**
|
17
|
+
- Look for kuber_kit root path in parent folders, so kit command will work in sub-folders
|
18
|
+
|
1
19
|
**0.5.6**
|
2
20
|
- Pre-process env file if it has .erb extension
|
3
21
|
- Allow attaching env file from configuration to docker container
|
data/Gemfile.lock
CHANGED
data/TODO.md
CHANGED
@@ -1,8 +1,5 @@
|
|
1
|
-
- add kit get method for more interactive kubernetes
|
2
1
|
- env files should use a separate deployment method (with change detection)
|
3
2
|
- add automatical confirmation support for service deployer
|
4
3
|
- template should be able to set default attributes
|
5
4
|
- template should be able to depend on image?
|
6
|
-
- cleanup image builds older than some date
|
7
|
-
- add some rotation for deploy log
|
8
5
|
- kit status should show the list of services and their status, with ability to select & view logs
|
data/kuber_kit.gemspec
CHANGED
@@ -24,11 +24,12 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.require_paths = ["lib"]
|
25
25
|
|
26
26
|
spec.add_dependency "contracts-lite"
|
27
|
-
spec.add_dependency "dry-auto_inject"
|
27
|
+
spec.add_dependency "dry-auto_inject", "~> 0.7.0"
|
28
28
|
spec.add_dependency "thor"
|
29
29
|
spec.add_dependency "cli-ui"
|
30
30
|
spec.add_dependency "net-ssh"
|
31
31
|
spec.add_dependency "tty-prompt"
|
32
|
+
spec.add_dependency "dry-container", "~> 0.7.2"
|
32
33
|
|
33
34
|
spec.add_development_dependency "bundler", "~> 1.17"
|
34
35
|
spec.add_development_dependency "rake", "~> 10.0"
|
data/lib/kuber_kit.rb
CHANGED
@@ -79,9 +79,11 @@ module KuberKit
|
|
79
79
|
end
|
80
80
|
|
81
81
|
module Tools
|
82
|
+
autoload :BuildDirCleaner, 'tools/build_dir_cleaner'
|
82
83
|
autoload :FilePresenceChecker, 'tools/file_presence_checker'
|
83
84
|
autoload :LoggerFactory, 'tools/logger_factory'
|
84
85
|
autoload :ProcessCleaner, 'tools/process_cleaner'
|
86
|
+
autoload :WorkdirDetector, 'tools/workdir_detector'
|
85
87
|
end
|
86
88
|
|
87
89
|
module Shell
|
@@ -152,6 +154,7 @@ module KuberKit
|
|
152
154
|
autoload :ActionHandler, 'service_deployer/action_handler'
|
153
155
|
autoload :StrategyDetector, 'service_deployer/strategy_detector'
|
154
156
|
autoload :Deployer, 'service_deployer/deployer'
|
157
|
+
autoload :DeploymentOptionsSelector, 'service_deployer/deployment_options_selector'
|
155
158
|
autoload :ServiceListResolver, 'service_deployer/service_list_resolver'
|
156
159
|
autoload :ServiceDependencyResolver, 'service_deployer/service_dependency_resolver'
|
157
160
|
|
@@ -169,6 +172,7 @@ module KuberKit
|
|
169
172
|
end
|
170
173
|
|
171
174
|
module Actions
|
175
|
+
autoload :ActionResult, 'actions/action_result'
|
172
176
|
autoload :ImageCompiler, 'actions/image_compiler'
|
173
177
|
autoload :EnvFileReader, 'actions/env_file_reader'
|
174
178
|
autoload :TemplateReader, 'actions/template_reader'
|
@@ -274,6 +278,11 @@ module KuberKit
|
|
274
278
|
KuberKit::Core::ContextHelper::BaseHelper.class_exec(&proc)
|
275
279
|
end
|
276
280
|
|
281
|
+
def set_user(value)
|
282
|
+
@user = value
|
283
|
+
@user_id = nil
|
284
|
+
end
|
285
|
+
|
277
286
|
def user
|
278
287
|
@user ||= ENV["KUBER_KIT_USERNAME"] || `whoami`.chomp
|
279
288
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class KuberKit::Actions::ActionResult
|
2
|
+
attr_reader :finished_tasks, :all_results, :error
|
3
|
+
|
4
|
+
def initialize()
|
5
|
+
@all_results = {}
|
6
|
+
@started_tasks = []
|
7
|
+
@finished_tasks = []
|
8
|
+
@mutex = Mutex.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def start_task(task)
|
12
|
+
@mutex.synchronize do
|
13
|
+
@started_tasks.push(task)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def finish_task(task, result = nil)
|
18
|
+
@mutex.synchronize do
|
19
|
+
@started_tasks.delete(task)
|
20
|
+
@finished_tasks.push(task)
|
21
|
+
@all_results[task] = result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def failed!(error)
|
26
|
+
@error = error
|
27
|
+
end
|
28
|
+
|
29
|
+
def succeeded?
|
30
|
+
@error.nil? && @started_tasks.empty?
|
31
|
+
end
|
32
|
+
end
|
@@ -4,6 +4,7 @@ class KuberKit::Actions::ConfigurationLoader
|
|
4
4
|
"core.image_store",
|
5
5
|
"core.service_store",
|
6
6
|
"core.configuration_store",
|
7
|
+
"tools.workdir_detector",
|
7
8
|
"artifacts_sync.artifacts_updater",
|
8
9
|
"shell.local_shell",
|
9
10
|
"ui",
|
@@ -12,7 +13,7 @@ class KuberKit::Actions::ConfigurationLoader
|
|
12
13
|
|
13
14
|
Contract Hash => Any
|
14
15
|
def call(options)
|
15
|
-
root_path =
|
16
|
+
root_path = workdir_detector.call(options)
|
16
17
|
images_path = options[:images_path] || File.join(root_path, configs.images_dirname)
|
17
18
|
services_path = options[:services_path] || File.join(root_path, configs.services_dirname)
|
18
19
|
infra_path = options[:infra_path] || File.join(root_path, configs.infra_dirname)
|
@@ -10,38 +10,40 @@ class KuberKit::Actions::ImageCompiler
|
|
10
10
|
|
11
11
|
Contract ArrayOf[Symbol], Hash => Any
|
12
12
|
def call(image_names, options)
|
13
|
+
compilation_result = KuberKit::Actions::ActionResult.new()
|
14
|
+
|
13
15
|
build_id = generate_build_id
|
14
16
|
build_server_pool = build_server_pool_factory.create()
|
15
17
|
|
16
|
-
compiled_images = []
|
17
|
-
compilation_result = {}
|
18
18
|
image_dependency_resolver.each_with_deps(image_names) do |dep_image_names|
|
19
19
|
ui.print_debug("ImageCompiler", "Scheduling to compile: #{dep_image_names.inspect}. Limit: #{configs.compile_simultaneous_limit}")
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
|
21
|
+
if compilation_result.succeeded?
|
22
|
+
compile_simultaneously(dep_image_names, build_id, build_server_pool, compilation_result)
|
23
|
+
end
|
23
24
|
end
|
24
25
|
|
25
26
|
build_server_pool.disconnect_all
|
26
27
|
|
27
|
-
|
28
|
+
compilation_result
|
28
29
|
rescue KuberKit::Error => e
|
29
30
|
ui.print_error("Error", e.message)
|
30
31
|
|
32
|
+
compilation_result.failed!(e.message)
|
33
|
+
|
31
34
|
false
|
32
35
|
end
|
33
36
|
|
34
37
|
private
|
35
|
-
def compile_simultaneously(image_names, build_id, build_server_pool)
|
38
|
+
def compile_simultaneously(image_names, build_id, build_server_pool, compilation_result)
|
36
39
|
task_group = ui.create_task_group
|
37
|
-
compiler_result = {}
|
38
40
|
image_names.map do |image_name|
|
39
41
|
|
40
42
|
ui.print_debug("ImageCompiler", "Started compiling: #{image_name.to_s.green}")
|
41
43
|
task_group.add("Compiling #{image_name.to_s.yellow}") do |task|
|
42
|
-
|
43
|
-
|
44
|
-
|
44
|
+
compilation_result.start_task(image_name)
|
45
|
+
image_result = compile_one(image_name, build_id, build_server_pool)
|
46
|
+
compilation_result.finish_task(image_name, image_result)
|
45
47
|
|
46
48
|
task.update_title("Compiled #{image_name.to_s.green}")
|
47
49
|
ui.print_debug("ImageCompiler", "Finished compiling: #{image_name}")
|
@@ -49,7 +51,11 @@ class KuberKit::Actions::ImageCompiler
|
|
49
51
|
|
50
52
|
end
|
51
53
|
task_group.wait
|
52
|
-
|
54
|
+
end
|
55
|
+
|
56
|
+
def compile_one(image_name, build_id, build_server_pool)
|
57
|
+
shell = build_server_pool.get_shell
|
58
|
+
image_compiler.call(shell, image_name, build_id)
|
53
59
|
end
|
54
60
|
|
55
61
|
def generate_build_id
|
@@ -3,6 +3,7 @@ class KuberKit::Actions::ServiceDeployer
|
|
3
3
|
"actions.image_compiler",
|
4
4
|
"service_deployer.service_list_resolver",
|
5
5
|
"service_deployer.service_dependency_resolver",
|
6
|
+
"service_deployer.deployment_options_selector",
|
6
7
|
"core.service_store",
|
7
8
|
"shell.local_shell",
|
8
9
|
"tools.process_cleaner",
|
@@ -19,13 +20,13 @@ class KuberKit::Actions::ServiceDeployer
|
|
19
20
|
require_confirmation: Maybe[Bool],
|
20
21
|
] => Any
|
21
22
|
def call(services:, tags:, skip_services: nil, skip_compile: false, require_confirmation: false)
|
23
|
+
deployment_result = KuberKit::Actions::ActionResult.new()
|
22
24
|
current_configuration = KuberKit.current_configuration
|
23
25
|
|
24
26
|
if services.empty? && tags.empty?
|
25
|
-
services, tags =
|
27
|
+
services, tags = deployment_options_selector.call()
|
26
28
|
end
|
27
29
|
|
28
|
-
|
29
30
|
disabled_services = current_configuration.disabled_services.map(&:to_s)
|
30
31
|
disabled_services += skip_services if skip_services
|
31
32
|
|
@@ -44,54 +45,50 @@ class KuberKit::Actions::ServiceDeployer
|
|
44
45
|
return false
|
45
46
|
end
|
46
47
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
if require_confirmation
|
51
|
-
result = ui.prompt("Please confirm to continue deployment", ["confirm".green, "cancel".red])
|
52
|
-
return false unless ["confirm".green, "confirm", "yes"].include?(result)
|
53
|
-
end
|
54
|
-
|
55
|
-
services = all_service_names.map do |service_name|
|
56
|
-
service_store.get_service(service_name.to_sym)
|
48
|
+
unless allow_deployment?(require_confirmation: require_confirmation, service_names: all_service_names)
|
49
|
+
return false
|
57
50
|
end
|
58
51
|
|
59
|
-
|
60
|
-
|
52
|
+
# Compile images for all services and dependencies
|
53
|
+
images_names = get_image_names(service_names: all_service_names)
|
61
54
|
unless skip_compile
|
62
|
-
|
63
|
-
|
55
|
+
compilation_result = compile_images(images_names)
|
56
|
+
|
57
|
+
return false unless compilation_result && compilation_result.succeeded?
|
64
58
|
end
|
65
59
|
|
66
|
-
deployed_services = []
|
67
|
-
deployment_result = {}
|
68
60
|
service_dependency_resolver.each_with_deps(service_names) do |dep_service_names|
|
69
61
|
ui.print_debug("ServiceDeployer", "Scheduling to compile: #{dep_service_names.inspect}. Limit: #{configs.deploy_simultaneous_limit}")
|
70
|
-
|
71
|
-
|
72
|
-
|
62
|
+
|
63
|
+
if deployment_result.succeeded?
|
64
|
+
deploy_simultaneously(dep_service_names, deployment_result)
|
65
|
+
end
|
73
66
|
end
|
74
67
|
|
75
|
-
|
68
|
+
deployment_result
|
76
69
|
rescue KuberKit::Error => e
|
77
70
|
ui.print_error("Error", e.message)
|
78
71
|
|
72
|
+
deployment_result.failed!(e.message)
|
73
|
+
|
79
74
|
false
|
80
75
|
rescue Interrupt => e
|
81
76
|
process_cleaner.clean
|
77
|
+
|
78
|
+
false
|
82
79
|
end
|
83
80
|
|
84
81
|
private
|
85
|
-
def deploy_simultaneously(service_names)
|
82
|
+
def deploy_simultaneously(service_names, deployment_result)
|
86
83
|
task_group = ui.create_task_group
|
87
84
|
|
88
|
-
deployer_result = {}
|
89
|
-
|
90
85
|
service_names.each do |service_name|
|
91
86
|
|
92
87
|
ui.print_debug("ServiceDeployer", "Started deploying: #{service_name.to_s.green}")
|
93
88
|
task_group.add("Deploying #{service_name.to_s.yellow}") do |task|
|
94
|
-
|
89
|
+
deployment_result.start_task(service_name)
|
90
|
+
service_result = service_deployer.call(local_shell, service_name.to_sym)
|
91
|
+
deployment_result.finish_task(service_name, service_result)
|
95
92
|
|
96
93
|
task.update_title("Deployed #{service_name.to_s.green}")
|
97
94
|
ui.print_debug("ServiceDeployer", "Finished deploying: #{service_name.to_s.green}")
|
@@ -99,55 +96,30 @@ class KuberKit::Actions::ServiceDeployer
|
|
99
96
|
end
|
100
97
|
|
101
98
|
task_group.wait
|
102
|
-
|
103
|
-
deployer_result
|
104
99
|
end
|
105
100
|
|
106
101
|
def compile_images(images_names)
|
107
|
-
return
|
102
|
+
return KuberKit::Actions::ActionResult.new if images_names.empty?
|
108
103
|
image_compiler.call(images_names, {})
|
109
104
|
end
|
110
105
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
tags = [specific_service_option, all_services_option]
|
116
|
-
tags += service_store
|
117
|
-
.all_definitions
|
118
|
-
.values
|
119
|
-
.map(&:to_service_attrs)
|
120
|
-
.map(&:tags)
|
121
|
-
.flatten
|
122
|
-
.uniq
|
123
|
-
.sort
|
124
|
-
.map(&:to_s)
|
125
|
-
|
126
|
-
selected_tag = ui.prompt("Please select which tag to deploy", tags)
|
127
|
-
|
128
|
-
if selected_tag == specific_service_option
|
129
|
-
show_service_selection
|
130
|
-
elsif selected_tag == all_services_option
|
131
|
-
[["*"], []]
|
132
|
-
else
|
133
|
-
[[], [selected_tag]]
|
106
|
+
def get_image_names(service_names:)
|
107
|
+
services = service_names.map do |service_name|
|
108
|
+
service_store.get_service(service_name.to_sym)
|
134
109
|
end
|
110
|
+
|
111
|
+
services.map(&:images).flatten.uniq
|
135
112
|
end
|
136
113
|
|
137
|
-
def
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
.sort
|
144
|
-
.map(&:to_s)
|
145
|
-
|
146
|
-
if services.empty?
|
147
|
-
return [[], []]
|
114
|
+
def allow_deployment?(require_confirmation:, service_names:)
|
115
|
+
services_list = service_names.map(&:to_s).map(&:yellow).join(", ")
|
116
|
+
ui.print_info "ServiceDeployer", "The following services will be deployed: #{services_list}"
|
117
|
+
|
118
|
+
unless require_confirmation
|
119
|
+
return true
|
148
120
|
end
|
149
121
|
|
150
|
-
|
151
|
-
[
|
122
|
+
result = ui.prompt("Please confirm to continue deployment", ["confirm".green, "cancel".red])
|
123
|
+
return ["confirm".green, "confirm", "yes"].include?(result)
|
152
124
|
end
|
153
125
|
end
|
data/lib/kuber_kit/cli.rb
CHANGED
@@ -10,6 +10,7 @@ class KuberKit::CLI < Thor
|
|
10
10
|
class_option :ui, :type => :string, :desc => "UI mode (interactive|debug|simple)"
|
11
11
|
class_option :debug, :type => :boolean, aliases: ["-d"]
|
12
12
|
class_option :configuration, :type => :string, aliases: ["-C"]
|
13
|
+
class_option :user, :type => :string, aliases: ["-u"]
|
13
14
|
|
14
15
|
desc "compile IMAGE_NAMES", "Compile image with IMAGE_NAMES (comma-separated)"
|
15
16
|
def compile(image_names_str)
|
@@ -19,12 +20,15 @@ class KuberKit::CLI < Thor
|
|
19
20
|
image_names = image_names_str.split(",").map(&:strip).map(&:to_sym)
|
20
21
|
|
21
22
|
if KuberKit::Container['actions.configuration_loader'].call(options)
|
22
|
-
|
23
|
+
action_result = KuberKit::Container['actions.image_compiler'].call(image_names, options)
|
23
24
|
end
|
24
25
|
|
25
|
-
if
|
26
|
+
if action_result && action_result.succeeded?
|
26
27
|
time = (Time.now.to_i - started_at)
|
27
|
-
print_result("Image compilation finished! (#{time}s)", result:
|
28
|
+
print_result("Image compilation finished! (#{time}s)", result: {
|
29
|
+
images: action_result.finished_tasks,
|
30
|
+
compilation: action_result.all_results
|
31
|
+
})
|
28
32
|
else
|
29
33
|
exit 1
|
30
34
|
end
|
@@ -44,7 +48,7 @@ class KuberKit::CLI < Thor
|
|
44
48
|
KuberKit.current_configuration.deployer_require_confirimation ||
|
45
49
|
false
|
46
50
|
started_at = Time.now.to_i
|
47
|
-
|
51
|
+
action_result = KuberKit::Container['actions.service_deployer'].call(
|
48
52
|
services: (options[:services] || []).flatten.uniq,
|
49
53
|
tags: (options[:tags] || []).flatten.uniq,
|
50
54
|
skip_services: (options[:skip_services] || []).flatten.uniq,
|
@@ -53,9 +57,12 @@ class KuberKit::CLI < Thor
|
|
53
57
|
)
|
54
58
|
end
|
55
59
|
|
56
|
-
if
|
60
|
+
if action_result && action_result.succeeded?
|
57
61
|
time = (Time.now.to_i - started_at)
|
58
|
-
print_result("Service deployment finished! (#{time}s)", result:
|
62
|
+
print_result("Service deployment finished! (#{time}s)", result: {
|
63
|
+
services: action_result.finished_tasks,
|
64
|
+
deployment: action_result.all_results
|
65
|
+
})
|
59
66
|
else
|
60
67
|
exit 1
|
61
68
|
end
|
@@ -178,8 +185,12 @@ class KuberKit::CLI < Thor
|
|
178
185
|
KuberKit.set_ui_mode(options[:ui].to_sym)
|
179
186
|
end
|
180
187
|
|
188
|
+
if options[:user]
|
189
|
+
KuberKit.set_user(options[:user])
|
190
|
+
end
|
191
|
+
|
181
192
|
# We should load config before loading any bean, to make sure that bean won't be built with default config
|
182
|
-
root_path
|
193
|
+
root_path = KuberKit::Container['tools.workdir_detector'].call(options)
|
183
194
|
config_file_path = File.join(root_path, APP_CONFIG_FILENAME)
|
184
195
|
if File.exists?(config_file_path)
|
185
196
|
require config_file_path
|
@@ -189,21 +200,4 @@ class KuberKit::CLI < Thor
|
|
189
200
|
def print_result(message, data = {})
|
190
201
|
KuberKit::Container['ui'].print_result(message, data)
|
191
202
|
end
|
192
|
-
|
193
|
-
def cleanup_processes
|
194
|
-
# Stop all threads
|
195
|
-
Thread.list.each do |t|
|
196
|
-
t.abort_on_exception = false
|
197
|
-
t.report_on_exception = false
|
198
|
-
Thread.kill(t) if t != Thread.current
|
199
|
-
end
|
200
|
-
|
201
|
-
# Find all system calls
|
202
|
-
child_pids_raw = `ps auxww | grep '[K]IT=#{Process.pid}' | awk '{print $2}'`
|
203
|
-
child_pids = child_pids_raw.to_s.split("\n").reject(&:empty?)
|
204
|
-
child_pids.each do |pid|
|
205
|
-
puts "Killing child process: #{pid}"
|
206
|
-
Process.kill("SIGHUP", pid.to_i)
|
207
|
-
end
|
208
|
-
end
|
209
203
|
end
|
data/lib/kuber_kit/container.rb
CHANGED
@@ -121,6 +121,10 @@ class KuberKit::Container
|
|
121
121
|
KuberKit::Core::ContextHelper::ContextHelperFactory.new
|
122
122
|
end
|
123
123
|
|
124
|
+
register "tools.build_dir_cleaner" do
|
125
|
+
KuberKit::Tools::BuildDirCleaner.new
|
126
|
+
end
|
127
|
+
|
124
128
|
register "tools.file_presence_checker" do
|
125
129
|
KuberKit::Tools::FilePresenceChecker.new
|
126
130
|
end
|
@@ -137,6 +141,10 @@ class KuberKit::Container
|
|
137
141
|
KuberKit::Tools::ProcessCleaner.new
|
138
142
|
end
|
139
143
|
|
144
|
+
register "tools.workdir_detector" do
|
145
|
+
KuberKit::Tools::WorkdirDetector.new
|
146
|
+
end
|
147
|
+
|
140
148
|
register "shell.bash_commands" do
|
141
149
|
KuberKit::Shell::Commands::BashCommands.new
|
142
150
|
end
|
@@ -269,6 +277,10 @@ class KuberKit::Container
|
|
269
277
|
KuberKit::ServiceDeployer::Deployer.new
|
270
278
|
end
|
271
279
|
|
280
|
+
register "service_deployer.deployment_options_selector" do
|
281
|
+
KuberKit::ServiceDeployer::DeploymentOptionsSelector.new
|
282
|
+
end
|
283
|
+
|
272
284
|
register "service_deployer.service_list_resolver" do
|
273
285
|
KuberKit::ServiceDeployer::ServiceListResolver.new
|
274
286
|
end
|
@@ -2,12 +2,15 @@ class KuberKit::ImageCompiler::ActionHandler
|
|
2
2
|
include KuberKit::Import[
|
3
3
|
"image_compiler.compiler",
|
4
4
|
"core.image_store",
|
5
|
+
"tools.build_dir_cleaner",
|
5
6
|
"configs",
|
6
7
|
]
|
7
8
|
|
8
9
|
Contract KuberKit::Shell::AbstractShell, Symbol, String => Any
|
9
10
|
def call(shell, image_name, build_id)
|
10
11
|
image = image_store.get_image(image_name)
|
12
|
+
|
13
|
+
build_dir_cleaner.call(parent_dir: configs.image_compile_dir)
|
11
14
|
|
12
15
|
compile_dir = generate_compile_dir(build_id: build_id)
|
13
16
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
class KuberKit::ServiceDeployer::DeploymentOptionsSelector
|
2
|
+
include KuberKit::Import[
|
3
|
+
"core.service_store",
|
4
|
+
"ui"
|
5
|
+
]
|
6
|
+
|
7
|
+
OPTION_SPECIFIC_SERVICE = "deploy specific service".freeze
|
8
|
+
OPTION_ALL_SERVICES = "deploy all services"
|
9
|
+
|
10
|
+
def call()
|
11
|
+
tags = [OPTION_SPECIFIC_SERVICE, OPTION_ALL_SERVICES]
|
12
|
+
tags += service_store
|
13
|
+
.all_definitions
|
14
|
+
.values
|
15
|
+
.map(&:to_service_attrs)
|
16
|
+
.map(&:tags)
|
17
|
+
.flatten
|
18
|
+
.uniq
|
19
|
+
.sort
|
20
|
+
.map(&:to_s)
|
21
|
+
|
22
|
+
selected_tag = ui.prompt("Please select which tag to deploy", tags)
|
23
|
+
|
24
|
+
if selected_tag == OPTION_SPECIFIC_SERVICE
|
25
|
+
show_service_selection
|
26
|
+
elsif selected_tag == OPTION_ALL_SERVICES
|
27
|
+
[["*"], []]
|
28
|
+
else
|
29
|
+
[[], [selected_tag]]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def show_service_selection()
|
34
|
+
services = service_store
|
35
|
+
.all_definitions
|
36
|
+
.values
|
37
|
+
.map(&:service_name)
|
38
|
+
.uniq
|
39
|
+
.sort
|
40
|
+
.map(&:to_s)
|
41
|
+
|
42
|
+
if services.empty?
|
43
|
+
return [[], []]
|
44
|
+
end
|
45
|
+
|
46
|
+
selected_service = ui.prompt("Please select which service to deploy", services)
|
47
|
+
[[selected_service], []]
|
48
|
+
end
|
49
|
+
end
|
@@ -20,7 +20,8 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
|
|
20
20
|
:networks,
|
21
21
|
:expose,
|
22
22
|
:publish,
|
23
|
-
:env_file_names
|
23
|
+
:env_file_names,
|
24
|
+
:env_vars
|
24
25
|
]
|
25
26
|
|
26
27
|
Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
|
@@ -44,6 +45,7 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
|
|
44
45
|
|
45
46
|
env_file_names = strategy_options.fetch(:env_file_names, [])
|
46
47
|
env_files = prepare_env_files(shell, env_file_names)
|
48
|
+
env_vars = strategy_options.fetch(:env_vars, {})
|
47
49
|
|
48
50
|
image_name = strategy_options.fetch(:image_name, nil)
|
49
51
|
if image_name.nil?
|
@@ -84,6 +86,9 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
|
|
84
86
|
Array(env_files).each do |env_file|
|
85
87
|
custom_args << "--env-file #{env_file}"
|
86
88
|
end
|
89
|
+
env_vars.each do |key, value|
|
90
|
+
custom_args << "--env #{key}=#{value}"
|
91
|
+
end
|
87
92
|
|
88
93
|
docker_commands.run(
|
89
94
|
shell, image.remote_registry_url,
|
@@ -100,6 +100,18 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
+
def list_dirs(path)
|
104
|
+
command = %Q{find -L #{path} -type f}
|
105
|
+
command += " -name '#{name}'" if name
|
106
|
+
exec!(command).split(/[\r\n]+/)
|
107
|
+
rescue => e
|
108
|
+
if e.message.include?("No such file or directory")
|
109
|
+
raise DirNotFoundError.new("Dir not found: #{path}")
|
110
|
+
else
|
111
|
+
raise e
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
103
115
|
def wrap_command_with_pid(command)
|
104
116
|
"KIT=#{Process.pid} #{command}"
|
105
117
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class KuberKit::Tools::BuildDirCleaner
|
2
|
+
include KuberKit::Import[
|
3
|
+
"shell.bash_commands",
|
4
|
+
"shell.local_shell",
|
5
|
+
]
|
6
|
+
|
7
|
+
KEEP_DIRS_COUNT = 10
|
8
|
+
|
9
|
+
def call(parent_dir:)
|
10
|
+
dirs_to_delete = get_ancient_builds_dirs(parent_dir: parent_dir)
|
11
|
+
|
12
|
+
dirs_to_delete.each do |dir|
|
13
|
+
bash_commands.rm_rf(local_shell, dir)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def get_ancient_builds_dirs(parent_dir:)
|
19
|
+
all_dirs = Dir.glob("#{parent_dir}/*")
|
20
|
+
skip_dirs = all_dirs
|
21
|
+
.sort_by{ |f| File.ctime(f) }
|
22
|
+
.reverse[0...KEEP_DIRS_COUNT]
|
23
|
+
|
24
|
+
all_dirs - skip_dirs
|
25
|
+
end
|
26
|
+
end
|
@@ -10,16 +10,17 @@ class KuberKit::Tools::LoggerFactory
|
|
10
10
|
Logger::FATAL => String::Colors::PURPLE,
|
11
11
|
}
|
12
12
|
|
13
|
+
MAX_LOGS_TO_KEEP = 3
|
14
|
+
MAX_LOG_FILE_SIZE = 512000
|
15
|
+
|
13
16
|
include KuberKit::Import[
|
14
17
|
"configs",
|
15
18
|
]
|
16
19
|
|
17
|
-
def create(
|
18
|
-
|
19
|
-
prepare_log_file(configs.log_file_path)
|
20
|
-
end
|
20
|
+
def create(level: nil)
|
21
|
+
prepare_log_file(configs.log_file_path)
|
21
22
|
|
22
|
-
logger = Logger.new(
|
23
|
+
logger = Logger.new(configs.log_file_path, MAX_LOGS_TO_KEEP, MAX_LOG_FILE_SIZE)
|
23
24
|
|
24
25
|
logger.level = level || Logger::DEBUG
|
25
26
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class KuberKit::Tools::WorkdirDetector
|
2
|
+
include KuberKit::Import[
|
3
|
+
"configs",
|
4
|
+
"tools.file_presence_checker"
|
5
|
+
]
|
6
|
+
|
7
|
+
def call(options, current_dir: nil)
|
8
|
+
current_dir ||= Dir.pwd
|
9
|
+
default_dir = File.join(current_dir, configs.kuber_kit_dirname)
|
10
|
+
workdir_path = options[:path] || ENV['KUBER_KIT_PATH'] || default_dir
|
11
|
+
|
12
|
+
unless file_presence_checker.dir_exists?(workdir_path)
|
13
|
+
workdir_in_ancestors = find_workdir_in_ancestors(current_dir)
|
14
|
+
workdir_path = workdir_in_ancestors if workdir_in_ancestors
|
15
|
+
end
|
16
|
+
|
17
|
+
workdir_path
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def find_workdir_in_ancestors(dir)
|
22
|
+
if dir == "/"
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
|
26
|
+
workdir_path = File.join(dir, configs.kuber_kit_dirname)
|
27
|
+
if file_presence_checker.dir_exists?(workdir_path)
|
28
|
+
return workdir_path
|
29
|
+
end
|
30
|
+
|
31
|
+
find_workdir_in_ancestors(File.dirname(dir))
|
32
|
+
end
|
33
|
+
end
|
data/lib/kuber_kit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kuber_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Iskander Khaziev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: contracts-lite
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: dry-auto_inject
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.7.0
|
34
34
|
type: :runtime
|
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:
|
40
|
+
version: 0.7.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: thor
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: dry-container
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.7.2
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.7.2
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: bundler
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,6 +198,8 @@ files:
|
|
184
198
|
- example/images/app_sources/Dockerfile
|
185
199
|
- example/images/app_sources/build_context/source.rb
|
186
200
|
- example/images/app_sources/image.rb
|
201
|
+
- example/images/failing_app/Dockerfile
|
202
|
+
- example/images/failing_app/image.rb
|
187
203
|
- example/images/ruby/Dockerfile
|
188
204
|
- example/images/ruby/image.rb
|
189
205
|
- example/images/ruby_app/Dockerfile
|
@@ -200,9 +216,11 @@ files:
|
|
200
216
|
- example/services/compose_app.rb
|
201
217
|
- example/services/docker_app.rb
|
202
218
|
- example/services/env_file.rb
|
219
|
+
- example/services/failing_app.rb
|
203
220
|
- example/services/ruby_app.rb
|
204
221
|
- kuber_kit.gemspec
|
205
222
|
- lib/kuber_kit.rb
|
223
|
+
- lib/kuber_kit/actions/action_result.rb
|
206
224
|
- lib/kuber_kit/actions/configuration_loader.rb
|
207
225
|
- lib/kuber_kit/actions/env_file_reader.rb
|
208
226
|
- lib/kuber_kit/actions/image_compiler.rb
|
@@ -288,6 +306,7 @@ files:
|
|
288
306
|
- lib/kuber_kit/preprocessing/text_preprocessor.rb
|
289
307
|
- lib/kuber_kit/service_deployer/action_handler.rb
|
290
308
|
- lib/kuber_kit/service_deployer/deployer.rb
|
309
|
+
- lib/kuber_kit/service_deployer/deployment_options_selector.rb
|
291
310
|
- lib/kuber_kit/service_deployer/service_dependency_resolver.rb
|
292
311
|
- lib/kuber_kit/service_deployer/service_list_resolver.rb
|
293
312
|
- lib/kuber_kit/service_deployer/strategies/abstract.rb
|
@@ -313,9 +332,11 @@ files:
|
|
313
332
|
- lib/kuber_kit/template_reader/reader.rb
|
314
333
|
- lib/kuber_kit/template_reader/strategies/abstract.rb
|
315
334
|
- lib/kuber_kit/template_reader/strategies/artifact_file.rb
|
335
|
+
- lib/kuber_kit/tools/build_dir_cleaner.rb
|
316
336
|
- lib/kuber_kit/tools/file_presence_checker.rb
|
317
337
|
- lib/kuber_kit/tools/logger_factory.rb
|
318
338
|
- lib/kuber_kit/tools/process_cleaner.rb
|
339
|
+
- lib/kuber_kit/tools/workdir_detector.rb
|
319
340
|
- lib/kuber_kit/ui.rb
|
320
341
|
- lib/kuber_kit/ui/api.rb
|
321
342
|
- lib/kuber_kit/ui/debug.rb
|