kuber_kit 0.5.4 → 0.5.9

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 (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