kuber_kit 0.5.4 → 0.5.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Gemfile.lock +7 -6
  4. data/example/app_data/service.yml +2 -1
  5. data/example/images/failing_app/Dockerfile +5 -0
  6. data/example/images/failing_app/image.rb +4 -0
  7. data/example/services/docker_app.rb +2 -1
  8. data/example/services/env_file.rb +1 -1
  9. data/example/services/failing_app.rb +6 -0
  10. data/example/services/ruby_app.rb +1 -1
  11. data/kuber_kit.gemspec +2 -1
  12. data/lib/kuber_kit.rb +11 -0
  13. data/lib/kuber_kit/actions/action_result.rb +32 -0
  14. data/lib/kuber_kit/actions/configuration_loader.rb +2 -1
  15. data/lib/kuber_kit/actions/image_compiler.rb +18 -12
  16. data/lib/kuber_kit/actions/service_deployer.rb +23 -17
  17. data/lib/kuber_kit/cli.rb +22 -26
  18. data/lib/kuber_kit/configs.rb +8 -5
  19. data/lib/kuber_kit/container.rb +16 -0
  20. data/lib/kuber_kit/core/artifacts/artifact_store.rb +3 -0
  21. data/lib/kuber_kit/core/env_files/abstract_env_file.rb +4 -0
  22. data/lib/kuber_kit/core/env_files/artifact_file.rb +4 -0
  23. data/lib/kuber_kit/core/env_files/env_file_store.rb +3 -0
  24. data/lib/kuber_kit/core/env_files/env_group.rb +12 -0
  25. data/lib/kuber_kit/core/registries/registry_store.rb +3 -0
  26. data/lib/kuber_kit/core/templates/template_store.rb +3 -0
  27. data/lib/kuber_kit/env_file_reader/env_file_parser.rb +51 -0
  28. data/lib/kuber_kit/env_file_reader/env_file_tempfile_creator.rb +17 -0
  29. data/lib/kuber_kit/env_file_reader/reader.rb +2 -0
  30. data/lib/kuber_kit/env_file_reader/strategies/artifact_file.rb +9 -65
  31. data/lib/kuber_kit/env_file_reader/strategies/env_group.rb +21 -0
  32. data/lib/kuber_kit/service_deployer/service_list_resolver.rb +2 -2
  33. data/lib/kuber_kit/service_deployer/strategies/docker.rb +36 -12
  34. data/lib/kuber_kit/template_reader/strategies/artifact_file.rb +3 -3
  35. data/lib/kuber_kit/tools/logger_factory.rb +14 -0
  36. data/lib/kuber_kit/tools/workdir_detector.rb +33 -0
  37. data/lib/kuber_kit/version.rb +1 -1
  38. metadata +29 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e99c1ae700ec8b59f9a832d3c9131e85c7d05a60548d8bca032d4ce2c9178b2
4
- data.tar.gz: e4233e8cf40a7980477d85f341320536725efd169ac4120e74de6c7ad651e436
3
+ metadata.gz: fa75f8b61926a3178d1592ceb81a35945a073b38d34c80c246872bae6b357d1f
4
+ data.tar.gz: fc41c9917961f9bff18ac03a60a16a77f094deae51abc6e28d80524fab793968
5
5
  SHA512:
6
- metadata.gz: 10a3f4b72a0d3a09c9a49842642e6f7a0457a5cb243d0c469c9792c7fcc70ff483b9ffbd6ecc7c278d20b3b7e22f603e45ad3360e701b1a9cf9696cff64d46ce
7
- data.tar.gz: f857ce1a307375486c51cfaa67c22a929826b54a1ad572dc5a5ac64fb4febfe680fa27f3adddadf2d2b3d68325cd5dee7ba47facdf672c427640d048c23c950f
6
+ metadata.gz: 7cb947b2cf303ef0f04a77364c0b6ea4043b2cf6f2b29cea0da1cd5d2808c7f2103799ad711e191e859bce59177372ac795460a1ed13589a6f62f536f4b23eb0
7
+ data.tar.gz: 324b1de9e8e762a5bce7bebf29ff9cc0317814f924be886fd10434f2ed2ffc8376025200f7ed2e35e2300bbbb2968061775c6e1f1c07f4a0ad2a61038225e66f
data/CHANGELOG.md CHANGED
@@ -1,3 +1,23 @@
1
+ **0.5.9**
2
+ - Added an ability to set custom user
3
+ - Allow setting environment variable in docker strategy
4
+ - Properly stop deployment if image compilation is failed
5
+
6
+ **0.5.8**
7
+ - Update gemspec to support ruby 2.5
8
+
9
+ **0.5.7**
10
+ - Look for kuber_kit root path in parent folders, so kit command will work in sub-folders
11
+
12
+ **0.5.6**
13
+ - Pre-process env file if it has .erb extension
14
+ - Allow attaching env file from configuration to docker container
15
+ - Change default data paths to use home directory
16
+ - Add env groups support to combine multiple env files
17
+
18
+ **0.5.5**
19
+ - Added ability to skip services during deployment using -S option
20
+
1
21
  **0.5.4**
2
22
  - Added disabled services support
3
23
 
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kuber_kit (0.5.4)
4
+ kuber_kit (0.5.9)
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
@@ -12,9 +13,9 @@ PATH
12
13
  GEM
13
14
  remote: https://rubygems.org/
14
15
  specs:
15
- cli-ui (1.4.0)
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)
@@ -58,7 +59,7 @@ GEM
58
59
  thor (1.1.0)
59
60
  tty-color (0.6.0)
60
61
  tty-cursor (0.7.1)
61
- tty-prompt (0.23.0)
62
+ tty-prompt (0.23.1)
62
63
  pastel (~> 0.8)
63
64
  tty-reader (~> 0.8)
64
65
  tty-reader (0.9.0)
@@ -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
  )
@@ -1,7 +1,7 @@
1
1
  KuberKit
2
2
  .define_service(:env_file)
3
3
  .template(:env_file)
4
- .tags("env_file")
4
+ .tags("env_file", "minimal")
5
5
  .attributes(
6
6
  deployer_restart_enabled: false
7
7
  )
@@ -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")
@@ -3,4 +3,4 @@ KuberKit
3
3
  .depends_on(:env_file)
4
4
  .template(:service)
5
5
  .images(:ruby_app)
6
- .tags("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, :result, :error
3
+
4
+ def initialize()
5
+ @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)
18
+ @mutex.synchronize do
19
+ @started_tasks.delete(task)
20
+ @finished_tasks.push(task)
21
+ @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
@@ -14,21 +14,27 @@ class KuberKit::Actions::ServiceDeployer
14
14
  Contract KeywordArgs[
15
15
  services: Maybe[ArrayOf[String]],
16
16
  tags: Maybe[ArrayOf[String]],
17
+ skip_services: Maybe[ArrayOf[String]],
17
18
  skip_compile: Maybe[Bool],
18
19
  require_confirmation: Maybe[Bool],
19
20
  ] => Any
20
- def call(services:, tags:, skip_compile: false, require_confirmation: false)
21
+ def call(services:, tags:, skip_services: nil, skip_compile: false, require_confirmation: false)
22
+ deployment_result = KuberKit::Actions::ActionResult.new()
21
23
  current_configuration = KuberKit.current_configuration
22
24
 
23
25
  if services.empty? && tags.empty?
24
26
  services, tags = show_tags_selection
25
27
  end
26
28
 
29
+
30
+ disabled_services = current_configuration.disabled_services.map(&:to_s)
31
+ disabled_services += skip_services if skip_services
32
+
27
33
  service_names = service_list_resolver.resolve(
28
34
  services: services || [],
29
35
  tags: tags || [],
30
36
  enabled_services: current_configuration.enabled_services.map(&:to_s),
31
- disabled_services: current_configuration.disabled_services.map(&:to_s)
37
+ disabled_services: disabled_services
32
38
  ).map(&:to_sym)
33
39
 
34
40
  # Return the list of services with all dependencies.
@@ -54,39 +60,41 @@ class KuberKit::Actions::ServiceDeployer
54
60
  images_names = services.map(&:images).flatten.uniq
55
61
 
56
62
  unless skip_compile
57
- compile_result = compile_images(images_names)
58
- return false unless compile_result
63
+ compilation_result = compile_images(images_names)
64
+
65
+ return false unless compilation_result && compilation_result.succeeded?
59
66
  end
60
67
 
61
- deployed_services = []
62
- deployment_result = {}
63
68
  service_dependency_resolver.each_with_deps(service_names) do |dep_service_names|
64
69
  ui.print_debug("ServiceDeployer", "Scheduling to compile: #{dep_service_names.inspect}. Limit: #{configs.deploy_simultaneous_limit}")
65
- result = deploy_simultaneously(dep_service_names)
66
- deployed_services += dep_service_names
67
- deployment_result = deployment_result.merge(result)
70
+
71
+ if deployment_result.succeeded?
72
+ deploy_simultaneously(dep_service_names, deployment_result)
73
+ end
68
74
  end
69
75
 
70
- { services: all_service_names, deployment: deployment_result }
76
+ deployment_result
71
77
  rescue KuberKit::Error => e
72
78
  ui.print_error("Error", e.message)
73
79
 
80
+ compilation_result.failed!(e.message)
81
+
74
82
  false
75
83
  rescue Interrupt => e
76
84
  process_cleaner.clean
77
85
  end
78
86
 
79
87
  private
80
- def deploy_simultaneously(service_names)
88
+ def deploy_simultaneously(service_names, deployment_result)
81
89
  task_group = ui.create_task_group
82
90
 
83
- deployer_result = {}
84
-
85
91
  service_names.each do |service_name|
86
92
 
87
93
  ui.print_debug("ServiceDeployer", "Started deploying: #{service_name.to_s.green}")
88
94
  task_group.add("Deploying #{service_name.to_s.yellow}") do |task|
89
- 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)
90
98
 
91
99
  task.update_title("Deployed #{service_name.to_s.green}")
92
100
  ui.print_debug("ServiceDeployer", "Finished deploying: #{service_name.to_s.green}")
@@ -94,12 +102,10 @@ class KuberKit::Actions::ServiceDeployer
94
102
  end
95
103
 
96
104
  task_group.wait
97
-
98
- deployer_result
99
105
  end
100
106
 
101
107
  def compile_images(images_names)
102
- return true if images_names.empty?
108
+ return KuberKit::Actions::ActionResult.new if images_names.empty?
103
109
  image_compiler.call(images_names, {})
104
110
  end
105
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.result
31
+ })
28
32
  else
29
33
  exit 1
30
34
  end
@@ -33,6 +37,7 @@ class KuberKit::CLI < Thor
33
37
  desc "deploy -t TAG_NAME", "Deploy CONTEXT_NAME with kubectl"
34
38
  method_option :services, :type => :array, aliases: ["-s"], repeatable: true
35
39
  method_option :tags, :type => :array, aliases: ["-t"], repeatable: true
40
+ method_option :skip_services, :type => :array, aliases: ["-S"], repeatable: true
36
41
  method_option :skip_compile, :type => :boolean, aliases: ["-B"]
37
42
  method_option :require_confirmation, :type => :boolean, aliases: ["-r"]
38
43
  def deploy
@@ -43,24 +48,28 @@ class KuberKit::CLI < Thor
43
48
  KuberKit.current_configuration.deployer_require_confirimation ||
44
49
  false
45
50
  started_at = Time.now.to_i
46
- result = KuberKit::Container['actions.service_deployer'].call(
51
+ action_result = KuberKit::Container['actions.service_deployer'].call(
47
52
  services: (options[:services] || []).flatten.uniq,
48
53
  tags: (options[:tags] || []).flatten.uniq,
54
+ skip_services: (options[:skip_services] || []).flatten.uniq,
49
55
  skip_compile: options[:skip_compile] || false,
50
56
  require_confirmation: require_confirmation
51
57
  )
52
58
  end
53
59
 
54
- if result
60
+ if action_result && action_result.succeeded?
55
61
  time = (Time.now.to_i - started_at)
56
- 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.result
65
+ })
57
66
  else
58
67
  exit 1
59
68
  end
60
69
  end
61
70
 
62
- desc "env ENV_FILE_NAME", "Return content of Env File ENV_FILE_NAME"
63
- def env(env_file_name)
71
+ desc "envfile ENV_FILE_NAME", "Return content of Env File ENV_FILE_NAME"
72
+ def envfile(env_file_name)
64
73
  setup(options)
65
74
 
66
75
  if KuberKit::Container['actions.configuration_loader'].call(options)
@@ -176,8 +185,12 @@ class KuberKit::CLI < Thor
176
185
  KuberKit.set_ui_mode(options[:ui].to_sym)
177
186
  end
178
187
 
188
+ if options[:user]
189
+ KuberKit.set_user(options[:user])
190
+ end
191
+
179
192
  # We should load config before loading any bean, to make sure that bean won't be built with default config
180
- root_path = options[:path] || File.join(Dir.pwd, KuberKit::Container['configs'].kuber_kit_dirname)
193
+ root_path = KuberKit::Container['tools.workdir_detector'].call(options)
181
194
  config_file_path = File.join(root_path, APP_CONFIG_FILENAME)
182
195
  if File.exists?(config_file_path)
183
196
  require config_file_path
@@ -187,21 +200,4 @@ class KuberKit::CLI < Thor
187
200
  def print_result(message, data = {})
188
201
  KuberKit::Container['ui'].print_result(message, data)
189
202
  end
190
-
191
- def cleanup_processes
192
- # Stop all threads
193
- Thread.list.each do |t|
194
- t.abort_on_exception = false
195
- t.report_on_exception = false
196
- Thread.kill(t) if t != Thread.current
197
- end
198
-
199
- # Find all system calls
200
- child_pids_raw = `ps auxww | grep '[K]IT=#{Process.pid}' | awk '{print $2}'`
201
- child_pids = child_pids_raw.to_s.split("\n").reject(&:empty?)
202
- child_pids.each do |pid|
203
- puts "Killing child process: #{pid}"
204
- Process.kill("SIGHUP", pid.to_i)
205
- end
206
- end
207
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
@@ -46,9 +46,9 @@ class KuberKit::ServiceDeployer::ServiceListResolver
46
46
 
47
47
  Contract Array => Array
48
48
  def split_by_inclusion(array)
49
- excluded, included = array.partition{|e| e.start_with?('!') }
49
+ excluded, included = array.partition{|e| e.start_with?('^') }
50
50
 
51
- excluded.map!{ |item| item.gsub(/^\!/, "") }
51
+ excluded.map!{ |item| item.gsub(/^\^/, "") }
52
52
 
53
53
  [included, excluded]
54
54
  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.4"
2
+ VERSION = "0.5.9"
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.4
4
+ version: 0.5.9
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-03-18 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