kuber_kit 0.5.5 → 0.5.10

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Gemfile.lock +5 -4
  4. data/TODO.md +2 -3
  5. data/example/app_data/service.yml +2 -1
  6. data/example/images/failing_app/Dockerfile +5 -0
  7. data/example/images/failing_app/image.rb +4 -0
  8. data/example/services/docker_app.rb +2 -1
  9. data/example/services/failing_app.rb +6 -0
  10. data/kuber_kit.gemspec +2 -1
  11. data/lib/kuber_kit.rb +11 -0
  12. data/lib/kuber_kit/actions/action_result.rb +32 -0
  13. data/lib/kuber_kit/actions/configuration_loader.rb +2 -1
  14. data/lib/kuber_kit/actions/image_compiler.rb +18 -12
  15. data/lib/kuber_kit/actions/service_deployer.rb +16 -15
  16. data/lib/kuber_kit/cli.rb +18 -24
  17. data/lib/kuber_kit/configs.rb +8 -5
  18. data/lib/kuber_kit/container.rb +16 -0
  19. data/lib/kuber_kit/core/artifacts/artifact_store.rb +3 -0
  20. data/lib/kuber_kit/core/env_files/abstract_env_file.rb +4 -0
  21. data/lib/kuber_kit/core/env_files/artifact_file.rb +4 -0
  22. data/lib/kuber_kit/core/env_files/env_file_store.rb +3 -0
  23. data/lib/kuber_kit/core/env_files/env_group.rb +12 -0
  24. data/lib/kuber_kit/core/registries/registry_store.rb +3 -0
  25. data/lib/kuber_kit/core/templates/template_store.rb +3 -0
  26. data/lib/kuber_kit/env_file_reader/env_file_parser.rb +51 -0
  27. data/lib/kuber_kit/env_file_reader/env_file_tempfile_creator.rb +17 -0
  28. data/lib/kuber_kit/env_file_reader/reader.rb +2 -0
  29. data/lib/kuber_kit/env_file_reader/strategies/artifact_file.rb +9 -65
  30. data/lib/kuber_kit/env_file_reader/strategies/env_group.rb +21 -0
  31. data/lib/kuber_kit/service_deployer/strategies/docker.rb +36 -12
  32. data/lib/kuber_kit/template_reader/strategies/artifact_file.rb +3 -3
  33. data/lib/kuber_kit/tools/logger_factory.rb +14 -0
  34. data/lib/kuber_kit/tools/workdir_detector.rb +33 -0
  35. data/lib/kuber_kit/version.rb +1 -1
  36. metadata +29 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87f41f4c189d1bb0420bc1db160dbd53c1b2769541b0ad0e772a9b74f20cd3ed
4
- data.tar.gz: d2b92edffabbe62b11801d09bd5f81cfd7a27be52aa0cea04ade796bc311f370
3
+ metadata.gz: 790b99f8456fde1e3c0f8f81308e6bcd7d6c8d6b4e274da4f667f0297f703b2a
4
+ data.tar.gz: 6102f785babd0ba638f46b9edc0d2d2740d60bcc7d3a4dd81a8a9e210aa2dc5a
5
5
  SHA512:
6
- metadata.gz: 0fcbdb08cf391d2ff480a7490261d7508f6e7d970b09091893fa4f6eb7338661df4f42349031303f16db404b74f3ca1f7fe9ec4f699f1c9052358cb661a2e4f8
7
- data.tar.gz: 922e179ff88f29dcb15f64a66a4e6fb43c7ee63b5a44be44a86ba401b64685997af1bf370281be36e332e729347e27e2f8f6d8f8f6a5b648bd3a2f6205c079d6
6
+ metadata.gz: c61ead9e24a6f88c1ae0e8a517eb030b035d8ce68c1babefcb0de9b4a36a8638f41f57a47000f75cd2f681c4e3086477a2afd9113d5e9850bce7ad3242c2c0aa
7
+ data.tar.gz: 96436dd5394baff8c2a8a2fe285909b4474df72f8548bfbecd0a2a9c28f2e6e763b0beec8b9d0ecaa6f12e69ca5c8c40974e16d1bf060911f6cf400f36a6eabc
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ **0.5.10**
2
+ - Fix a regression when deployment result would not be properly returned as json.
3
+
4
+ **0.5.9**
5
+ - Added an ability to set custom user
6
+ - Allow setting environment variable in docker strategy
7
+ - Properly stop deployment if image compilation is failed
8
+
9
+ **0.5.8**
10
+ - Update gemspec to support ruby 2.5
11
+
12
+ **0.5.7**
13
+ - Look for kuber_kit root path in parent folders, so kit command will work in sub-folders
14
+
15
+ **0.5.6**
16
+ - Pre-process env file if it has .erb extension
17
+ - Allow attaching env file from configuration to docker container
18
+ - Change default data paths to use home directory
19
+ - Add env groups support to combine multiple env files
20
+
1
21
  **0.5.5**
2
22
  - Added ability to skip services during deployment using -S option
3
23
 
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kuber_kit (0.5.5)
4
+ kuber_kit (0.5.10)
5
5
  cli-ui
6
6
  contracts-lite
7
- dry-auto_inject
7
+ dry-auto_inject (~> 0.7.0)
8
+ dry-container (~> 0.7.2)
8
9
  net-ssh
9
10
  thor
10
11
  tty-prompt
@@ -14,7 +15,7 @@ GEM
14
15
  specs:
15
16
  cli-ui (1.5.1)
16
17
  coderay (1.1.3)
17
- concurrent-ruby (1.1.8)
18
+ concurrent-ruby (1.1.9)
18
19
  contracts-lite (0.15.0)
19
20
  diff-lcs (1.4.4)
20
21
  docile (1.3.2)
@@ -26,7 +27,7 @@ GEM
26
27
  dry-container (0.7.2)
27
28
  concurrent-ruby (~> 1.0)
28
29
  dry-configurable (~> 0.1, >= 0.1.3)
29
- dry-core (0.5.0)
30
+ dry-core (0.6.0)
30
31
  concurrent-ruby (~> 1.0)
31
32
  method_source (1.0.0)
32
33
  net-ssh (6.1.0)
data/TODO.md CHANGED
@@ -1,8 +1,7 @@
1
- - add kit get method for more interactive kubernetes
1
+ - cleanup image builds older than some date
2
+ - add some rotation for deploy log
2
3
  - env files should use a separate deployment method (with change detection)
3
4
  - add automatical confirmation support for service deployer
4
5
  - template should be able to set default attributes
5
6
  - template should be able to depend on image?
6
- - cleanup image builds older than some date
7
- - add some rotation for deploy log
8
7
  - kit status should show the list of services and their status, with ability to select & view logs
@@ -3,7 +3,8 @@ apiVersion: apps/v1
3
3
  kind: Deployment
4
4
  metadata:
5
5
  labels:
6
- app: <%= service_uri %>
6
+ app: <%= service_uri %>
7
+ user: <%= KuberKit.user %>
7
8
  name: <%= service_uri %>
8
9
  spec:
9
10
  replicas: 1
@@ -0,0 +1,5 @@
1
+ FROM <%= image_url(:ruby) %>
2
+
3
+ RUN not_existing_command
4
+
5
+ CMD ["tail", "-f", "/dev/null"]
@@ -0,0 +1,4 @@
1
+ KuberKit
2
+ .define_image(:failing_app)
3
+ .registry(:default)
4
+ .depends_on(:ruby, :app_sources)
@@ -7,6 +7,7 @@ KuberKit
7
7
  detached: false,
8
8
  image_name: :ruby_app,
9
9
  container_name: "test_docker_app",
10
- delete_if_exists: true
10
+ delete_if_exists: true,
11
+ env_file_names: [:test]
11
12
  }
12
13
  )
@@ -0,0 +1,6 @@
1
+ KuberKit
2
+ .define_service(:failing_app)
3
+ .depends_on(:env_file)
4
+ .template(:service)
5
+ .images(:failing_app)
6
+ .tags("app", "minimal")
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
@@ -54,6 +54,7 @@ module KuberKit
54
54
  autoload :EnvFileStore, 'core/env_files/env_file_store'
55
55
  autoload :AbstractEnvFile, 'core/env_files/abstract_env_file'
56
56
  autoload :ArtifactFile, 'core/env_files/artifact_file'
57
+ autoload :EnvGroup, 'core/env_files/env_group'
57
58
  end
58
59
 
59
60
  module ContextHelper
@@ -81,6 +82,7 @@ module KuberKit
81
82
  autoload :FilePresenceChecker, 'tools/file_presence_checker'
82
83
  autoload :LoggerFactory, 'tools/logger_factory'
83
84
  autoload :ProcessCleaner, 'tools/process_cleaner'
85
+ autoload :WorkdirDetector, 'tools/workdir_detector'
84
86
  end
85
87
 
86
88
  module Shell
@@ -127,10 +129,13 @@ module KuberKit
127
129
  module EnvFileReader
128
130
  autoload :ActionHandler, 'env_file_reader/action_handler'
129
131
  autoload :Reader, 'env_file_reader/reader'
132
+ autoload :EnvFileParser, 'env_file_reader/env_file_parser'
133
+ autoload :EnvFileTempfileCreator, 'env_file_reader/env_file_tempfile_creator'
130
134
 
131
135
  module Strategies
132
136
  autoload :Abstract, 'env_file_reader/strategies/abstract'
133
137
  autoload :ArtifactFile, 'env_file_reader/strategies/artifact_file'
138
+ autoload :EnvGroup, 'env_file_reader/strategies/env_group'
134
139
  end
135
140
  end
136
141
 
@@ -165,6 +170,7 @@ module KuberKit
165
170
  end
166
171
 
167
172
  module Actions
173
+ autoload :ActionResult, 'actions/action_result'
168
174
  autoload :ImageCompiler, 'actions/image_compiler'
169
175
  autoload :EnvFileReader, 'actions/env_file_reader'
170
176
  autoload :TemplateReader, 'actions/template_reader'
@@ -270,6 +276,11 @@ module KuberKit
270
276
  KuberKit::Core::ContextHelper::BaseHelper.class_exec(&proc)
271
277
  end
272
278
 
279
+ def set_user(value)
280
+ @user = value
281
+ @user_id = nil
282
+ end
283
+
273
284
  def user
274
285
  @user ||= ENV["KUBER_KIT_USERNAME"] || `whoami`.chomp
275
286
  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 = options[:path] || File.join(Dir.pwd, configs.kuber_kit_dirname)
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
- result = compile_simultaneously(dep_image_names, build_id, build_server_pool)
21
- compiled_images += dep_image_names
22
- compilation_result = compilation_result.merge(result)
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
- { images: compiled_images, compilation: compilation_result }
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
- shell = build_server_pool.get_shell
43
-
44
- compiler_result[image_name] = image_compiler.call(shell, image_name, build_id)
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
- compiler_result
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
@@ -19,6 +19,7 @@ class KuberKit::Actions::ServiceDeployer
19
19
  require_confirmation: Maybe[Bool],
20
20
  ] => Any
21
21
  def call(services:, tags:, skip_services: nil, skip_compile: false, require_confirmation: false)
22
+ deployment_result = KuberKit::Actions::ActionResult.new()
22
23
  current_configuration = KuberKit.current_configuration
23
24
 
24
25
  if services.empty? && tags.empty?
@@ -59,39 +60,41 @@ class KuberKit::Actions::ServiceDeployer
59
60
  images_names = services.map(&:images).flatten.uniq
60
61
 
61
62
  unless skip_compile
62
- compile_result = compile_images(images_names)
63
- return false unless compile_result
63
+ compilation_result = compile_images(images_names)
64
+
65
+ return false unless compilation_result && compilation_result.succeeded?
64
66
  end
65
67
 
66
- deployed_services = []
67
- deployment_result = {}
68
68
  service_dependency_resolver.each_with_deps(service_names) do |dep_service_names|
69
69
  ui.print_debug("ServiceDeployer", "Scheduling to compile: #{dep_service_names.inspect}. Limit: #{configs.deploy_simultaneous_limit}")
70
- result = deploy_simultaneously(dep_service_names)
71
- deployed_services += dep_service_names
72
- deployment_result = deployment_result.merge(result)
70
+
71
+ if deployment_result.succeeded?
72
+ deploy_simultaneously(dep_service_names, deployment_result)
73
+ end
73
74
  end
74
75
 
75
- { services: all_service_names, deployment: deployment_result }
76
+ deployment_result
76
77
  rescue KuberKit::Error => e
77
78
  ui.print_error("Error", e.message)
78
79
 
80
+ compilation_result.failed!(e.message)
81
+
79
82
  false
80
83
  rescue Interrupt => e
81
84
  process_cleaner.clean
82
85
  end
83
86
 
84
87
  private
85
- def deploy_simultaneously(service_names)
88
+ def deploy_simultaneously(service_names, deployment_result)
86
89
  task_group = ui.create_task_group
87
90
 
88
- deployer_result = {}
89
-
90
91
  service_names.each do |service_name|
91
92
 
92
93
  ui.print_debug("ServiceDeployer", "Started deploying: #{service_name.to_s.green}")
93
94
  task_group.add("Deploying #{service_name.to_s.yellow}") do |task|
94
- deployer_result[service_name] = service_deployer.call(local_shell, service_name.to_sym)
95
+ deployment_result.start_task(service_name)
96
+ service_result = service_deployer.call(local_shell, service_name.to_sym)
97
+ deployment_result.finish_task(service_name, service_result)
95
98
 
96
99
  task.update_title("Deployed #{service_name.to_s.green}")
97
100
  ui.print_debug("ServiceDeployer", "Finished deploying: #{service_name.to_s.green}")
@@ -99,12 +102,10 @@ class KuberKit::Actions::ServiceDeployer
99
102
  end
100
103
 
101
104
  task_group.wait
102
-
103
- deployer_result
104
105
  end
105
106
 
106
107
  def compile_images(images_names)
107
- return true if images_names.empty?
108
+ return KuberKit::Actions::ActionResult.new if images_names.empty?
108
109
  image_compiler.call(images_names, {})
109
110
  end
110
111
 
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
- result = KuberKit::Container['actions.image_compiler'].call(image_names, options)
23
+ action_result = KuberKit::Container['actions.image_compiler'].call(image_names, options)
23
24
  end
24
25
 
25
- if result
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: 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
- result = KuberKit::Container['actions.service_deployer'].call(
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 result
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: 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 = options[:path] || File.join(Dir.pwd, KuberKit::Container['configs'].kuber_kit_dirname)
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
@@ -5,7 +5,7 @@ class KuberKit::Configs
5
5
  :image_dockerfile_name, :image_build_context_dir, :image_tag, :docker_ignore_list, :image_compile_dir,
6
6
  :kuber_kit_dirname, :kuber_kit_min_version, :images_dirname, :services_dirname, :infra_dirname, :configurations_dirname,
7
7
  :artifact_clone_dir, :service_config_dir, :deployer_strategy, :compile_simultaneous_limit, :deploy_simultaneous_limit,
8
- :additional_images_paths, :deprecation_warnings_disabled, :log_file_path
8
+ :additional_images_paths, :deprecation_warnings_disabled, :log_file_path, :env_file_compile_dir
9
9
  ]
10
10
  DOCKER_IGNORE_LIST = [
11
11
  'Dockerfile',
@@ -34,10 +34,12 @@ class KuberKit::Configs
34
34
  end
35
35
 
36
36
  def add_default_configs
37
+ home_kuber_kit_path = File.expand_path(File.join("~", ".kuber_kit"))
38
+
37
39
  set :image_dockerfile_name, "Dockerfile"
38
40
  set :image_build_context_dir, "build_context"
39
41
  set :image_tag, 'latest'
40
- set :image_compile_dir, "/tmp/kuber_kit/image_builds"
42
+ set :image_compile_dir, File.join(home_kuber_kit_path, "image_builds")
41
43
  set :docker_ignore_list, DOCKER_IGNORE_LIST
42
44
  set :kuber_kit_dirname, "kuber_kit"
43
45
  set :kuber_kit_min_version, KuberKit::VERSION
@@ -45,14 +47,15 @@ class KuberKit::Configs
45
47
  set :services_dirname, "services"
46
48
  set :infra_dirname, "infrastructure"
47
49
  set :configurations_dirname, "configurations"
48
- set :artifact_clone_dir, "/tmp/kuber_kit/artifacts"
49
- set :service_config_dir, "/tmp/kuber_kit/services"
50
+ set :artifact_clone_dir, File.join(home_kuber_kit_path, "artifacts")
51
+ set :service_config_dir, File.join(home_kuber_kit_path, "services")
50
52
  set :deployer_strategy, :kubernetes
51
53
  set :compile_simultaneous_limit, 5
52
54
  set :deploy_simultaneous_limit, 5
53
55
  set :additional_images_paths, []
54
56
  set :deprecation_warnings_disabled, false
55
- set :log_file_path, "/tmp/kuber_kit.log"
57
+ set :log_file_path, File.join(home_kuber_kit_path, "deploy.log")
58
+ set :env_file_compile_dir, File.join(home_kuber_kit_path, "env_files")
56
59
  end
57
60
 
58
61
  def items
@@ -137,6 +137,10 @@ class KuberKit::Container
137
137
  KuberKit::Tools::ProcessCleaner.new
138
138
  end
139
139
 
140
+ register "tools.workdir_detector" do
141
+ KuberKit::Tools::WorkdirDetector.new
142
+ end
143
+
140
144
  register "shell.bash_commands" do
141
145
  KuberKit::Shell::Commands::BashCommands.new
142
146
  end
@@ -229,10 +233,22 @@ class KuberKit::Container
229
233
  KuberKit::EnvFileReader::Reader.new
230
234
  end
231
235
 
236
+ register "env_file_reader.env_file_parser" do
237
+ KuberKit::EnvFileReader::EnvFileParser.new
238
+ end
239
+
240
+ register "env_file_reader.env_file_tempfile_creator" do
241
+ KuberKit::EnvFileReader::EnvFileTempfileCreator.new
242
+ end
243
+
232
244
  register "env_file_reader.strategies.artifact_file" do
233
245
  KuberKit::EnvFileReader::Strategies::ArtifactFile.new
234
246
  end
235
247
 
248
+ register "env_file_reader.strategies.env_group" do
249
+ KuberKit::EnvFileReader::Strategies::EnvGroup.new
250
+ end
251
+
236
252
  register "template_reader.action_handler" do
237
253
  KuberKit::TemplateReader::ActionHandler.new
238
254
  end
@@ -3,6 +3,7 @@ class KuberKit::Core::Artifacts::ArtifactStore
3
3
  store.add(artifact.name, artifact)
4
4
  end
5
5
 
6
+ Contract Symbol => Maybe[KuberKit::Core::Artifacts::AbstractArtifact]
6
7
  def get(artifact_name)
7
8
  artifact = get_from_configuration(artifact_name) ||
8
9
  get_global(artifact_name)
@@ -10,10 +11,12 @@ class KuberKit::Core::Artifacts::ArtifactStore
10
11
  artifact
11
12
  end
12
13
 
14
+ Contract Symbol => Maybe[KuberKit::Core::Artifacts::AbstractArtifact]
13
15
  def get_global(artifact_name)
14
16
  store.get(artifact_name)
15
17
  end
16
18
 
19
+ Contract Symbol => Maybe[KuberKit::Core::Artifacts::AbstractArtifact]
17
20
  def get_from_configuration(artifact_name)
18
21
  artifacts = KuberKit.current_configuration.artifacts
19
22
  artifacts[artifact_name]
@@ -6,4 +6,8 @@ class KuberKit::Core::EnvFiles::AbstractEnvFile
6
6
  def initialize(env_file_name)
7
7
  @name = env_file_name
8
8
  end
9
+
10
+ def uniq_name
11
+ @name.to_s
12
+ end
9
13
  end
@@ -6,4 +6,8 @@ class KuberKit::Core::EnvFiles::ArtifactFile < KuberKit::Core::EnvFiles::Abstrac
6
6
  @artifact_name = artifact_name
7
7
  @file_path = file_path
8
8
  end
9
+
10
+ def uniq_name
11
+ [@artifact_name.to_s, @name.to_s].join("-")
12
+ end
9
13
  end
@@ -3,6 +3,7 @@ class KuberKit::Core::EnvFiles::EnvFileStore
3
3
  store.add(env_file.name, env_file)
4
4
  end
5
5
 
6
+ Contract Symbol => Maybe[KuberKit::Core::EnvFiles::AbstractEnvFile]
6
7
  def get(env_file_name)
7
8
  env_file = get_from_configuration(env_file_name) ||
8
9
  get_global(env_file_name)
@@ -10,10 +11,12 @@ class KuberKit::Core::EnvFiles::EnvFileStore
10
11
  env_file
11
12
  end
12
13
 
14
+ Contract Symbol => Maybe[KuberKit::Core::EnvFiles::AbstractEnvFile]
13
15
  def get_global(env_file_name)
14
16
  store.get(env_file_name)
15
17
  end
16
18
 
19
+ Contract Symbol => Maybe[KuberKit::Core::EnvFiles::AbstractEnvFile]
17
20
  def get_from_configuration(env_file_name)
18
21
  env_files = KuberKit.current_configuration.env_files
19
22
  env_files[env_file_name]
@@ -0,0 +1,12 @@
1
+ class KuberKit::Core::EnvFiles::EnvGroup < KuberKit::Core::EnvFiles::AbstractEnvFile
2
+ attr_reader :env_files
3
+
4
+ def initialize(env_group_name, env_files:)
5
+ super(env_group_name)
6
+ @env_files = env_files
7
+ end
8
+
9
+ def uniq_name
10
+ "env-group-#{@name.to_s}"
11
+ end
12
+ end
@@ -3,6 +3,7 @@ class KuberKit::Core::Registries::RegistryStore
3
3
  store.add(registry.name, registry)
4
4
  end
5
5
 
6
+ Contract Symbol => Maybe[KuberKit::Core::Registries::AbstractRegistry]
6
7
  def get(registry_name)
7
8
  registry = get_from_configuration(registry_name) ||
8
9
  get_global(registry_name)
@@ -10,10 +11,12 @@ class KuberKit::Core::Registries::RegistryStore
10
11
  registry
11
12
  end
12
13
 
14
+ Contract Symbol => Maybe[KuberKit::Core::Registries::AbstractRegistry]
13
15
  def get_global(registry_name)
14
16
  store.get(registry_name)
15
17
  end
16
18
 
19
+ Contract Symbol => Maybe[KuberKit::Core::Registries::AbstractRegistry]
17
20
  def get_from_configuration(registry_name)
18
21
  registries = KuberKit.current_configuration.registries
19
22
  registries[registry_name]
@@ -3,6 +3,7 @@ class KuberKit::Core::Templates::TemplateStore
3
3
  store.add(template.name, template)
4
4
  end
5
5
 
6
+ Contract Symbol => Maybe[KuberKit::Core::Templates::AbstractTemplate]
6
7
  def get(template_name)
7
8
  template = get_from_configuration(template_name) ||
8
9
  get_global(template_name)
@@ -10,10 +11,12 @@ class KuberKit::Core::Templates::TemplateStore
10
11
  template
11
12
  end
12
13
 
14
+ Contract Symbol => Maybe[KuberKit::Core::Templates::AbstractTemplate]
13
15
  def get_global(template_name)
14
16
  store.get(template_name)
15
17
  end
16
18
 
19
+ Contract Symbol => Maybe[KuberKit::Core::Templates::AbstractTemplate]
17
20
  def get_from_configuration(template_name)
18
21
  templates = KuberKit.current_configuration.templates
19
22
  templates[template_name]
@@ -0,0 +1,51 @@
1
+ class KuberKit::EnvFileReader::EnvFileParser
2
+ # Parser is based on:
3
+ # https://github.com/bkeepers/dotenv/blob/master/lib/dotenv/parser.rb
4
+ LINE = /
5
+ (?:^|\A) # beginning of line
6
+ \s* # leading whitespace
7
+ (?:export\s+)? # optional export
8
+ ([\w\.]+) # key
9
+ (?:\s*=\s*?|:\s+?) # separator
10
+ ( # optional value begin
11
+ \s*'(?:\\'|[^'])*' # single quoted value
12
+ | # or
13
+ \s*"(?:\\"|[^"])*" # double quoted value
14
+ | # or
15
+ [^\#\r\n]+ # unquoted value
16
+ )? # value end
17
+ \s* # trailing whitespace
18
+ (?:\#.*)? # optional comment
19
+ (?:$|\z) # end of line
20
+ /x
21
+
22
+ Contract String => Hash
23
+ def call(string)
24
+ hash = {}
25
+ string.gsub(/\r\n?/, "\n").scan(LINE).each do |key, value|
26
+ hash[key] = parse_value(value || "")
27
+ end
28
+ hash
29
+ end
30
+
31
+ private
32
+
33
+ def parse_value(value)
34
+ # Remove surrounding quotes
35
+ value = value.strip.sub(/\A(['"])(.*)\1\z/m, '\2')
36
+
37
+ if Regexp.last_match(1) == '"'
38
+ value = unescape_characters(expand_newlines(value))
39
+ end
40
+
41
+ value
42
+ end
43
+
44
+ def unescape_characters(value)
45
+ value.gsub(/\\([^$])/, '\1')
46
+ end
47
+
48
+ def expand_newlines(value)
49
+ value.gsub('\n', "\n").gsub('\r', "\r")
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ class KuberKit::EnvFileReader::EnvFileTempfileCreator
2
+ include KuberKit::Import[
3
+ "env_file_reader.reader",
4
+ "configs"
5
+ ]
6
+
7
+ Contract KuberKit::Shell::AbstractShell, KuberKit::Core::EnvFiles::AbstractEnvFile => String
8
+ def call(shell, env_file)
9
+ env_file_hash = reader.read(shell, env_file)
10
+ env_file_raw = env_file_hash.to_a.map{|k,v| "#{k}=#{v}"}.join("\r\n")
11
+ temp_file_path = File.join(configs.env_file_compile_dir, env_file.uniq_name)
12
+
13
+ shell.write(temp_file_path, env_file_raw)
14
+
15
+ temp_file_path
16
+ end
17
+ end
@@ -3,6 +3,7 @@ class KuberKit::EnvFileReader::Reader
3
3
 
4
4
  include KuberKit::Import[
5
5
  "env_file_reader.strategies.artifact_file",
6
+ "env_file_reader.strategies.env_group",
6
7
  ]
7
8
 
8
9
  def initialize(**injected_deps)
@@ -35,5 +36,6 @@ class KuberKit::EnvFileReader::Reader
35
36
  private
36
37
  def add_default_strategies
37
38
  use_reader(artifact_file, env_file_class: KuberKit::Core::EnvFiles::ArtifactFile)
39
+ use_reader(env_group, env_file_class: KuberKit::Core::EnvFiles::EnvGroup)
38
40
  end
39
41
  end
@@ -1,8 +1,12 @@
1
1
  class KuberKit::EnvFileReader::Strategies::ArtifactFile < KuberKit::EnvFileReader::Strategies::Abstract
2
2
  include KuberKit::Import[
3
- "core.artifact_store"
3
+ "core.artifact_store",
4
+ "env_file_reader.env_file_parser",
5
+ "preprocessing.text_preprocessor"
4
6
  ]
5
7
 
8
+ PREPROCESS_EXTENSIONS = [".erb"]
9
+
6
10
  def read(shell, env_file)
7
11
  artifact = artifact_store.get(env_file.artifact_name)
8
12
 
@@ -16,71 +20,11 @@ class KuberKit::EnvFileReader::Strategies::ArtifactFile < KuberKit::EnvFileReade
16
20
  def read_file(shell, file_path)
17
21
  result = {}
18
22
  content = shell.read(file_path)
19
- Parser.call(content)
20
- end
21
-
22
- # Parser is based on:
23
- # https://github.com/bkeepers/dotenv/blob/master/lib/dotenv/parser.rb
24
- class Parser
25
- LINE = /
26
- (?:^|\A) # beginning of line
27
- \s* # leading whitespace
28
- (?:export\s+)? # optional export
29
- ([\w\.]+) # key
30
- (?:\s*=\s*?|:\s+?) # separator
31
- ( # optional value begin
32
- \s*'(?:\\'|[^'])*' # single quoted value
33
- | # or
34
- \s*"(?:\\"|[^"])*" # double quoted value
35
- | # or
36
- [^\#\r\n]+ # unquoted value
37
- )? # value end
38
- \s* # trailing whitespace
39
- (?:\#.*)? # optional comment
40
- (?:$|\z) # end of line
41
- /x
42
-
43
- class << self
44
- def call(string, is_load = false)
45
- new(string, is_load).call
23
+ enable_preprocessing = PREPROCESS_EXTENSIONS.any?{ |e| e == File.extname(file_path) }
24
+ if enable_preprocessing
25
+ content = text_preprocessor.compile(content)
46
26
  end
47
- end
48
27
 
49
- def initialize(string, is_load = false)
50
- @string = string
51
- @hash = {}
52
- @is_load = is_load
28
+ env_file_parser.call(content)
53
29
  end
54
-
55
- def call
56
- # Convert line breaks to same format
57
- lines = @string.gsub(/\r\n?/, "\n")
58
- # Process matches
59
- lines.scan(LINE).each do |key, value|
60
- @hash[key] = parse_value(value || "")
61
- end
62
- @hash
63
- end
64
-
65
- private
66
-
67
- def parse_value(value)
68
- # Remove surrounding quotes
69
- value = value.strip.sub(/\A(['"])(.*)\1\z/m, '\2')
70
-
71
- if Regexp.last_match(1) == '"'
72
- value = unescape_characters(expand_newlines(value))
73
- end
74
-
75
- value
76
- end
77
-
78
- def unescape_characters(value)
79
- value.gsub(/\\([^$])/, '\1')
80
- end
81
-
82
- def expand_newlines(value)
83
- value.gsub('\n', "\n").gsub('\r', "\r")
84
- end
85
- end
86
30
  end
@@ -0,0 +1,21 @@
1
+ class KuberKit::EnvFileReader::Strategies::EnvGroup < KuberKit::EnvFileReader::Strategies::Abstract
2
+ include KuberKit::Import[
3
+ "env_file_reader.strategies.artifact_file",
4
+ "core.env_file_store",
5
+ ]
6
+
7
+ def read(shell, env_group)
8
+ content = {}
9
+ env_group.env_files.each do |env_file_name|
10
+ env_file = env_file_store.get(env_file_name)
11
+
12
+ if env_file.is_a?(KuberKit::Core::EnvFiles::EnvGroup)
13
+ raise "EnvGroup inside another EnvGroup is not supported"
14
+ end
15
+
16
+ result = artifact_file.read(shell, env_file)
17
+ content = content.merge(result)
18
+ end
19
+ content
20
+ end
21
+ end
@@ -1,6 +1,8 @@
1
1
  class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer::Strategies::Abstract
2
2
  include KuberKit::Import[
3
+ "env_file_reader.env_file_tempfile_creator",
3
4
  "shell.docker_commands",
5
+ "core.env_file_store",
4
6
  "core.image_store",
5
7
  "configs",
6
8
  ]
@@ -18,6 +20,8 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
18
20
  :networks,
19
21
  :expose,
20
22
  :publish,
23
+ :env_file_names,
24
+ :env_vars
21
25
  ]
22
26
 
23
27
  Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
@@ -28,16 +32,20 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
28
32
  raise KuberKit::Error, "Unknow options for deploy strategy: #{unknown_options}. Available options: #{STRATEGY_OPTIONS}"
29
33
  end
30
34
 
31
- namespace = strategy_options.fetch(:namespace, nil)
32
- container_name = strategy_options.fetch(:container_name, [namespace, service.name].compact.join("_"))
33
- command_name = strategy_options.fetch(:command_name, nil)
34
- env_file = strategy_options.fetch(:env_file, nil)
35
- custom_args = strategy_options.fetch(:custom_args, nil)
36
- networks = strategy_options.fetch(:networks, [])
37
- volumes = strategy_options.fetch(:volumes, [])
38
- expose_ports = strategy_options.fetch(:expose, [])
39
- publish_ports = strategy_options.fetch(:publish, [])
40
- hostname = strategy_options.fetch(:hostname, container_name)
35
+ namespace = strategy_options.fetch(:namespace, nil)
36
+ container_name = strategy_options.fetch(:container_name, [namespace, service.name].compact.join("_"))
37
+ command_name = strategy_options.fetch(:command_name, nil)
38
+ custom_env_file = strategy_options.fetch(:env_file, nil)
39
+ custom_args = strategy_options.fetch(:custom_args, nil)
40
+ networks = strategy_options.fetch(:networks, [])
41
+ volumes = strategy_options.fetch(:volumes, [])
42
+ expose_ports = strategy_options.fetch(:expose, [])
43
+ publish_ports = strategy_options.fetch(:publish, [])
44
+ hostname = strategy_options.fetch(:hostname, container_name)
45
+
46
+ env_file_names = strategy_options.fetch(:env_file_names, [])
47
+ env_files = prepare_env_files(shell, env_file_names)
48
+ env_vars = strategy_options.fetch(:env_vars, {})
41
49
 
42
50
  image_name = strategy_options.fetch(:image_name, nil)
43
51
  if image_name.nil?
@@ -54,8 +62,8 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
54
62
  if container_name
55
63
  custom_args << "--name #{container_name}"
56
64
  end
57
- if env_file
58
- custom_args << "--env-file #{env_file}"
65
+ if custom_env_file
66
+ custom_args << "--env-file #{custom_env_file}"
59
67
  end
60
68
  if hostname
61
69
  custom_args << "--hostname #{hostname}"
@@ -75,6 +83,12 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
75
83
  Array(publish_ports).each do |publish_port|
76
84
  custom_args << "--publish #{publish_port}"
77
85
  end
86
+ Array(env_files).each do |env_file|
87
+ custom_args << "--env-file #{env_file}"
88
+ end
89
+ env_vars.each do |key, value|
90
+ custom_args << "--env #{key}=#{value}"
91
+ end
78
92
 
79
93
  docker_commands.run(
80
94
  shell, image.remote_registry_url,
@@ -84,4 +98,14 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
84
98
  interactive: !strategy_options[:detached]
85
99
  )
86
100
  end
101
+
102
+ private
103
+ def prepare_env_files(shell, env_file_names)
104
+ env_files = env_file_names.map do |env_file_name|
105
+ env_file_store.get(env_file_name)
106
+ end
107
+ env_files.map do |env_file|
108
+ env_file_tempfile_creator.call(shell, env_file)
109
+ end
110
+ end
87
111
  end
@@ -3,10 +3,10 @@ class KuberKit::TemplateReader::Strategies::ArtifactFile < KuberKit::TemplateRea
3
3
  "core.artifact_store"
4
4
  ]
5
5
 
6
- def read(shell, env_file)
7
- artifact = artifact_store.get(env_file.artifact_name)
6
+ def read(shell, template)
7
+ artifact = artifact_store.get(template.artifact_name)
8
8
 
9
- file_parts = [artifact.cloned_path, env_file.file_path].compact
9
+ file_parts = [artifact.cloned_path, template.file_path].compact
10
10
  file_path = File.join(*file_parts)
11
11
 
12
12
  shell.read(file_path)
@@ -1,4 +1,5 @@
1
1
  require 'logger'
2
+ require 'fileutils'
2
3
 
3
4
  class KuberKit::Tools::LoggerFactory
4
5
  SEVERITY_COLORS_BY_LEVEL = {
@@ -14,6 +15,10 @@ class KuberKit::Tools::LoggerFactory
14
15
  ]
15
16
 
16
17
  def create(stdout = nil, level = nil)
18
+ if !stdout
19
+ prepare_log_file(configs.log_file_path)
20
+ end
21
+
17
22
  logger = Logger.new(stdout || configs.log_file_path)
18
23
 
19
24
  logger.level = level || Logger::DEBUG
@@ -35,4 +40,13 @@ class KuberKit::Tools::LoggerFactory
35
40
 
36
41
  logger
37
42
  end
43
+
44
+ private
45
+ def prepare_log_file(file_path)
46
+ dir_path = File.dirname(file_path)
47
+ unless Dir.exists?(dir_path)
48
+ FileUtils.mkdir_p(dir_path)
49
+ end
50
+ FileUtils.touch(file_path)
51
+ end
38
52
  end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module KuberKit
2
- VERSION = "0.5.5"
2
+ VERSION = "0.5.10"
3
3
  end
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.5.5
4
+ version: 0.5.10
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-05-12 00:00:00.000000000 Z
11
+ date: 2021-06-21 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: '0'
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: '0'
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
@@ -245,6 +263,7 @@ files:
245
263
  - lib/kuber_kit/core/env_files/abstract_env_file.rb
246
264
  - lib/kuber_kit/core/env_files/artifact_file.rb
247
265
  - lib/kuber_kit/core/env_files/env_file_store.rb
266
+ - lib/kuber_kit/core/env_files/env_group.rb
248
267
  - lib/kuber_kit/core/image.rb
249
268
  - lib/kuber_kit/core/image_definition.rb
250
269
  - lib/kuber_kit/core/image_definition_factory.rb
@@ -263,9 +282,12 @@ files:
263
282
  - lib/kuber_kit/core/templates/artifact_file.rb
264
283
  - lib/kuber_kit/core/templates/template_store.rb
265
284
  - lib/kuber_kit/env_file_reader/action_handler.rb
285
+ - lib/kuber_kit/env_file_reader/env_file_parser.rb
286
+ - lib/kuber_kit/env_file_reader/env_file_tempfile_creator.rb
266
287
  - lib/kuber_kit/env_file_reader/reader.rb
267
288
  - lib/kuber_kit/env_file_reader/strategies/abstract.rb
268
289
  - lib/kuber_kit/env_file_reader/strategies/artifact_file.rb
290
+ - lib/kuber_kit/env_file_reader/strategies/env_group.rb
269
291
  - lib/kuber_kit/extensions/colored_string.rb
270
292
  - lib/kuber_kit/extensions/contracts.rb
271
293
  - lib/kuber_kit/extensions/indocker_compat.rb
@@ -312,6 +334,7 @@ files:
312
334
  - lib/kuber_kit/tools/file_presence_checker.rb
313
335
  - lib/kuber_kit/tools/logger_factory.rb
314
336
  - lib/kuber_kit/tools/process_cleaner.rb
337
+ - lib/kuber_kit/tools/workdir_detector.rb
315
338
  - lib/kuber_kit/ui.rb
316
339
  - lib/kuber_kit/ui/api.rb
317
340
  - lib/kuber_kit/ui/debug.rb