kuber_kit 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dfc1d29b7283361acaed01c9ddd08a29d121020c75af2d6ec7e4245d347021fb
4
- data.tar.gz: 7e9063497954963223629beaa6d6ec914851c5e8c9633fa35d50986a95149aec
3
+ metadata.gz: da99b8b516e2fa2eb9090dc78084bc4b3d40f6d5856e4d3ecbbb993b1cbdef5d
4
+ data.tar.gz: 73c76c08809d116b0c5f317959b45e5fb513b518592f791d8a0d32a185a5d88c
5
5
  SHA512:
6
- metadata.gz: d0dd8904d21b8ca6648111856a6a5d8b4b3d1950a5db786f108f2906bdfc2388c6f515b4d833ce87f30f3c5098ebd1807aa0e3ef832903a4bec180b66788f3dc
7
- data.tar.gz: b9cb8446b31460a27571b8a91defbf7882ff0ecf1d8d97dd581edaa496d2f60dae58b4bd8bd6fad091c5448a16830cee48259821751211e4e6751d2128d88fe2
6
+ metadata.gz: 5953d83da7b07ebe1ee9be3ee803c6662c2a585bbc4b01a66ba9eb3232df86f11c6f9991e3e6ffd992828d25b5b9fc554bdb71ecd396026941b78f23448acb80
7
+ data.tar.gz: a36e8746b7caddea4fe4342df5be1bd7c5304856a613e42b805b119013b9f31cc40c5de9be8587b2f13850f8bc9aa1e1e0179f88904d9ec1b0d3617285261a9b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- kuber_kit (0.4.5)
4
+ kuber_kit (0.5.0)
5
5
  cli-ui
6
6
  contracts-lite
7
7
  dry-auto_inject
@@ -20,7 +20,7 @@ GEM
20
20
  docile (1.3.2)
21
21
  dry-auto_inject (0.7.0)
22
22
  dry-container (>= 0.3.4)
23
- dry-configurable (0.12.0)
23
+ dry-configurable (0.12.1)
24
24
  concurrent-ruby (~> 1.0)
25
25
  dry-core (~> 0.5, >= 0.5.0)
26
26
  dry-container (0.7.2)
data/TODO.md CHANGED
@@ -1,7 +1,8 @@
1
+ - do not show result for images list, if list is too large (Mikhail)
1
2
  - add kit get method for interactive kubernetes
2
- - do not show result for images list, if list is too large
3
3
  - kit status should show the list of services and their status, with ability to select & view logs
4
4
  - find a way to always deploy some service, e.g. for migrations and env_files
5
5
  - template should be able to set default attributes
6
6
  - template should be able to depend on image?
7
- - cleanup image builds older than some date
7
+ - cleanup image builds older than some date
8
+ - add some rotation for deploy log
@@ -2,5 +2,5 @@ KuberKit
2
2
  .define_configuration(:review)
3
3
  .use_registry(:review_default, as: :default)
4
4
  .use_artifact(:kuber_kit_repo, as: :kuber_kit_repo)
5
- .deployer_require_confirimation
5
+ #.deployer_require_confirimation
6
6
  #.use_build_server(:remote_bs)
@@ -8,4 +8,6 @@ COPY README.md README.md
8
8
 
9
9
  RUN ruby /app/source.rb
10
10
 
11
- COPY example_file.txt <%= build_vars.example_file_name %>
11
+ COPY example_file.txt <%= build_vars.example_file_name %>
12
+
13
+ CMD ["tail", "-f", "/dev/null"]
@@ -1,5 +1,5 @@
1
1
  KuberKit
2
- .define_service(:compose_app)
2
+ .define_service(:auth_app)
3
3
  .template(:docker_compose)
4
4
  .images(:ruby_app)
5
5
  .tags(:compose)
@@ -4,7 +4,7 @@ KuberKit
4
4
  .deployer_strategy(:docker)
5
5
  .attributes(
6
6
  deployer: {
7
- detached: true,
7
+ detached: false,
8
8
  image_name: :ruby_app,
9
9
  container_name: "test_docker_app",
10
10
  delete_if_exists: true
data/lib/kuber_kit.rb CHANGED
@@ -76,6 +76,7 @@ module KuberKit
76
76
  module Tools
77
77
  autoload :FilePresenceChecker, 'tools/file_presence_checker'
78
78
  autoload :LoggerFactory, 'tools/logger_factory'
79
+ autoload :ProcessCleaner, 'tools/process_cleaner'
79
80
  end
80
81
 
81
82
  module Shell
@@ -92,6 +93,7 @@ module KuberKit
92
93
  autoload :GitCommands, 'shell/commands/git_commands'
93
94
  autoload :RsyncCommands, 'shell/commands/rsync_commands'
94
95
  autoload :KubectlCommands, 'shell/commands/kubectl_commands'
96
+ autoload :SystemCommands, 'shell/commands/system_commands'
95
97
  end
96
98
  end
97
99
 
@@ -163,18 +165,25 @@ module KuberKit
163
165
  autoload :TemplateReader, 'actions/template_reader'
164
166
  autoload :ServiceReader, 'actions/service_reader'
165
167
  autoload :ServiceDeployer, 'actions/service_deployer'
168
+ autoload :ServiceChecker, 'actions/service_checker'
166
169
  autoload :ConfigurationLoader, 'actions/configuration_loader'
167
170
  autoload :KubectlApplier, 'actions/kubectl_applier'
168
171
  autoload :KubectlAttacher, 'actions/kubectl_attacher'
169
172
  autoload :KubectlConsole, 'actions/kubectl_console'
170
173
  autoload :KubectlDescribe, 'actions/kubectl_describe'
171
174
  autoload :KubectlLogs, 'actions/kubectl_logs'
175
+ autoload :KubectlEnv, 'actions/kubectl_env'
172
176
  end
173
177
 
174
178
  module Extensions
175
179
  autoload :Inspectable, 'extensions/inspectable'
176
180
  end
177
181
 
182
+ module Kubernetes
183
+ autoload :ResourceSelector, 'kubernetes/resource_selector'
184
+ autoload :ResourcesFetcher, 'kubernetes/resources_fetcher'
185
+ end
186
+
178
187
  module UI
179
188
  autoload :Interactive, 'ui/interactive'
180
189
  autoload :Simple, 'ui/simple'
@@ -2,6 +2,7 @@ class KuberKit::Actions::KubectlAttacher
2
2
  include KuberKit::Import[
3
3
  "shell.kubectl_commands",
4
4
  "shell.local_shell",
5
+ "kubernetes.resources_fetcher",
5
6
  "ui"
6
7
  ]
7
8
 
@@ -10,10 +11,8 @@ class KuberKit::Actions::KubectlAttacher
10
11
  kubeconfig_path = KuberKit.current_configuration.kubeconfig_path
11
12
  deployer_namespace = KuberKit.current_configuration.deployer_namespace
12
13
 
13
- if !pod_name
14
- resources = kubectl_commands.get_resources(local_shell, "deployments", jsonpath: ".items[*].metadata.name")
15
- options = resources.split(" ").map{|d| "deploy/#{d}" }
16
- pod_name = ui.prompt("Please select deployment to attach", options)
14
+ if !pod_name
15
+ pod_name = resources_fetcher.call("attach")
17
16
  end
18
17
 
19
18
  kubectl_commands.exec(
@@ -2,6 +2,7 @@ class KuberKit::Actions::KubectlConsole
2
2
  include KuberKit::Import[
3
3
  "shell.kubectl_commands",
4
4
  "shell.local_shell",
5
+ "kubernetes.resources_fetcher",
5
6
  "ui"
6
7
  ]
7
8
 
@@ -11,9 +12,7 @@ class KuberKit::Actions::KubectlConsole
11
12
  deployer_namespace = KuberKit.current_configuration.deployer_namespace
12
13
 
13
14
  if !pod_name
14
- resources = kubectl_commands.get_resources(local_shell, "deployments", jsonpath: ".items[*].metadata.name")
15
- options = resources.split(" ").map{|d| "deploy/#{d}" }
16
- pod_name = ui.prompt("Please select deployment to attach", options)
15
+ pod_name = resources_fetcher.call("attach")
17
16
  end
18
17
 
19
18
  kubectl_commands.exec(
@@ -2,6 +2,7 @@ class KuberKit::Actions::KubectlDescribe
2
2
  include KuberKit::Import[
3
3
  "shell.kubectl_commands",
4
4
  "shell.local_shell",
5
+ "kubernetes.resources_fetcher",
5
6
  "ui"
6
7
  ]
7
8
 
@@ -11,7 +12,7 @@ class KuberKit::Actions::KubectlDescribe
11
12
  deployer_namespace = KuberKit.current_configuration.deployer_namespace
12
13
 
13
14
  if !resource_name
14
- resource_name = get_resource_name
15
+ resource_name = resources_fetcher.call("describe", include_ingresses: true, include_pods: true)
15
16
  end
16
17
 
17
18
  args = nil
@@ -32,25 +33,4 @@ class KuberKit::Actions::KubectlDescribe
32
33
 
33
34
  false
34
35
  end
35
-
36
- def get_resource_name
37
- deployments = kubectl_commands.get_resources(local_shell, "deployments", jsonpath: ".items[*].metadata.name")
38
- options = deployments.split(" ").map{|d| "deploy/#{d}" }
39
- options += ["ingresses", "pods"]
40
- option = ui.prompt("Please select resource to describe", options)
41
-
42
- if option == "ingresses"
43
- ingresses = kubectl_commands.get_resources(local_shell, "ingresses", jsonpath: ".items[*].metadata.name")
44
- options = ingresses.split(" ").map{|d| "ingresses/#{d}" }
45
- return ui.prompt("Please select ingress to describe", options)
46
- end
47
-
48
- if option == "pods"
49
- ingresses = kubectl_commands.get_resources(local_shell, "pods", jsonpath: ".items[*].metadata.name")
50
- options = ingresses.split(" ").map{|d| "pods/#{d}" }
51
- return ui.prompt("Please select pod to describe", options)
52
- end
53
-
54
- option
55
- end
56
36
  end
@@ -0,0 +1,19 @@
1
+ class KuberKit::Actions::KubectlEnv
2
+ include KuberKit::Import[
3
+ "shell.local_shell",
4
+ "ui"
5
+ ]
6
+
7
+ Contract Hash => Any
8
+ def call(options)
9
+ configuration = KuberKit.current_configuration
10
+ kubeconfig_path = configuration.kubeconfig_path
11
+ ui.print_info("ENV", "export KUBECONFIG=#{kubeconfig_path}")
12
+
13
+ true
14
+ rescue KuberKit::Error => e
15
+ ui.print_error("Error", e.message)
16
+
17
+ false
18
+ end
19
+ end
@@ -2,6 +2,7 @@ class KuberKit::Actions::KubectlLogs
2
2
  include KuberKit::Import[
3
3
  "shell.kubectl_commands",
4
4
  "shell.local_shell",
5
+ "kubernetes.resources_fetcher",
5
6
  "ui"
6
7
  ]
7
8
 
@@ -11,9 +12,7 @@ class KuberKit::Actions::KubectlLogs
11
12
  deployer_namespace = KuberKit.current_configuration.deployer_namespace
12
13
 
13
14
  if !pod_name
14
- deployments = kubectl_commands.get_resources(local_shell, "deployments", jsonpath: ".items[*].metadata.name")
15
- deploy_options = deployments.split(" ").map{|d| "deploy/#{d}" }
16
- pod_name = ui.prompt("Please select deployment to attach", deploy_options)
15
+ pod_name = resources_fetcher.call("attach")
17
16
  end
18
17
 
19
18
  args = nil
@@ -0,0 +1,32 @@
1
+ class KuberKit::Actions::ServiceChecker
2
+ include KuberKit::Import[
3
+ "kubernetes.resources_fetcher",
4
+ "shell.local_shell",
5
+ "core.service_store",
6
+ "ui",
7
+ ]
8
+
9
+ Contract Hash => Any
10
+ def call(options)
11
+ services = service_store.all_definitions.values.map(&:service_name).map(&:to_s)
12
+
13
+ enabled_services = KuberKit.current_configuration.enabled_services.map(&:to_s)
14
+ if enabled_services.any?
15
+ services = services.select{ |s| enabled_services.include?(s) }
16
+ end
17
+
18
+ deployments = resources_fetcher.call("deployments")
19
+
20
+ missing_services = services.select{ |s| !deployments.include?(s.gsub("_", "-")) }
21
+
22
+ ui.print_warning("Warning", "This command will only check services deployed using k8s")
23
+
24
+ ui.print_info("Missing", missing_services.inspect)
25
+
26
+ {}
27
+ rescue KuberKit::Error => e
28
+ ui.print_error("Error", e.message)
29
+
30
+ false
31
+ end
32
+ end
@@ -4,6 +4,7 @@ class KuberKit::Actions::ServiceDeployer
4
4
  "service_deployer.service_list_resolver",
5
5
  "core.service_store",
6
6
  "shell.local_shell",
7
+ "tools.process_cleaner",
7
8
  "ui",
8
9
  service_deployer: "service_deployer.action_handler",
9
10
  ]
@@ -56,6 +57,8 @@ class KuberKit::Actions::ServiceDeployer
56
57
  ui.print_error("Error", e.message)
57
58
 
58
59
  false
60
+ rescue Interrupt => e
61
+ process_cleaner.clean
59
62
  end
60
63
 
61
64
  def deploy_services(service_names)
data/lib/kuber_kit/cli.rb CHANGED
@@ -86,6 +86,15 @@ class KuberKit::CLI < Thor
86
86
  end
87
87
  end
88
88
 
89
+ desc "check", "Check to make sure that all services are deployed"
90
+ def check()
91
+ setup(options)
92
+
93
+ if KuberKit::Container['actions.configuration_loader'].call(options)
94
+ KuberKit::Container['actions.service_checker'].call(options)
95
+ end
96
+ end
97
+
89
98
  desc "apply FILE_PATH", "Apply FILE_PATH with kubectl"
90
99
  def apply(file_path)
91
100
  setup(options)
@@ -132,6 +141,15 @@ class KuberKit::CLI < Thor
132
141
  end
133
142
  end
134
143
 
144
+ desc "env", "Show environment variables for given configuration"
145
+ def env()
146
+ setup(options)
147
+
148
+ if KuberKit::Container['actions.configuration_loader'].call(options.merge(load_inventory: false))
149
+ KuberKit::Container['actions.kubectl_env'].call(options)
150
+ end
151
+ end
152
+
135
153
  desc "version", "Print current version"
136
154
  def version
137
155
  puts KuberKit::VERSION
@@ -160,4 +178,21 @@ class KuberKit::CLI < Thor
160
178
  def print_result(message, data = {})
161
179
  KuberKit::Container['ui'].print_result(message, data)
162
180
  end
181
+
182
+ def cleanup_processes
183
+ # Stop all threads
184
+ Thread.list.each do |t|
185
+ t.abort_on_exception = false
186
+ t.report_on_exception = false
187
+ Thread.kill(t) if t != Thread.current
188
+ end
189
+
190
+ # Find all system calls
191
+ child_pids_raw = `ps auxww | grep '[K]IT=#{Process.pid}' | awk '{print $2}'`
192
+ child_pids = child_pids_raw.to_s.split("\n").reject(&:empty?)
193
+ child_pids.each do |pid|
194
+ puts "Killing child process: #{pid}"
195
+ Process.kill("SIGHUP", pid.to_i)
196
+ end
197
+ end
163
198
  end
@@ -21,6 +21,10 @@ class KuberKit::Container
21
21
  KuberKit::Actions::ServiceDeployer.new
22
22
  end
23
23
 
24
+ register "actions.service_checker" do
25
+ KuberKit::Actions::ServiceChecker.new
26
+ end
27
+
24
28
  register "actions.configuration_loader" do
25
29
  KuberKit::Actions::ConfigurationLoader.new
26
30
  end
@@ -45,6 +49,10 @@ class KuberKit::Container
45
49
  KuberKit::Actions::KubectlLogs.new
46
50
  end
47
51
 
52
+ register "actions.kubectl_env" do
53
+ KuberKit::Actions::KubectlEnv.new
54
+ end
55
+
48
56
  register "configs" do
49
57
  KuberKit::Configs.new
50
58
  end
@@ -121,6 +129,10 @@ class KuberKit::Container
121
129
  KuberKit::Container["tools.logger_factory"].create()
122
130
  end
123
131
 
132
+ register "tools.process_cleaner" do
133
+ KuberKit::Tools::ProcessCleaner.new
134
+ end
135
+
124
136
  register "shell.bash_commands" do
125
137
  KuberKit::Shell::Commands::BashCommands.new
126
138
  end
@@ -145,6 +157,10 @@ class KuberKit::Container
145
157
  KuberKit::Shell::Commands::KubectlCommands.new
146
158
  end
147
159
 
160
+ register "shell.system_commands" do
161
+ KuberKit::Shell::Commands::SystemCommands.new
162
+ end
163
+
148
164
  register "shell.local_shell" do
149
165
  KuberKit::Shell::LocalShell.new
150
166
  end
@@ -261,6 +277,14 @@ class KuberKit::Container
261
277
  KuberKit::ServiceReader::Reader.new
262
278
  end
263
279
 
280
+ register "kubernetes.resource_selector" do
281
+ KuberKit::Kubernetes::ResourceSelector.new
282
+ end
283
+
284
+ register "kubernetes.resources_fetcher" do
285
+ KuberKit::Kubernetes::ResourcesFetcher.new
286
+ end
287
+
264
288
  register "ui" do
265
289
  if KuberKit.ui_mode == :debug
266
290
  KuberKit::UI::Debug.new
@@ -0,0 +1,33 @@
1
+ class KuberKit::Kubernetes::ResourceSelector
2
+ include KuberKit::Import[
3
+ "kubernetes.resources_fetcher",
4
+ "shell.local_shell",
5
+ "ui"
6
+ ]
7
+
8
+ Contract String, KeywordArgs[
9
+ include_ingresses: Optional[Bool],
10
+ include_pods: Optional[Bool]
11
+ ] => Any
12
+ def call(action_name, include_ingresses: false, include_pods: false)
13
+ deployments = resources_fetcher.call("deployments")
14
+ options = deployments.map{|d| "deploy/#{d}" }
15
+ options << "ingresses" if include_ingresses
16
+ options << "pods" if include_pods
17
+ option = ui.prompt("Please select resource to #{action_name}", options)
18
+
19
+ if option == "ingresses" && include_ingresses
20
+ ingresses = resources_fetcher.call("ingresses")
21
+ options = ingresses.map{|d| "ingresses/#{d}" }
22
+ return ui.prompt("Please select ingress to #{action_name}", options)
23
+ end
24
+
25
+ if option == "pods" && include_pods
26
+ ingresses = resources_fetcher.call("pods")
27
+ options = ingresses.map{|d| "pods/#{d}" }
28
+ return ui.prompt("Please select pod to #{action_name}", options)
29
+ end
30
+
31
+ option
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ class KuberKit::Kubernetes::ResourcesFetcher
2
+ include KuberKit::Import[
3
+ "shell.kubectl_commands",
4
+ "shell.local_shell",
5
+ ]
6
+
7
+ Contract String => ArrayOf[String]
8
+ def call(resource_type)
9
+ current_configuration = KuberKit.current_configuration
10
+
11
+ kubectl_commands.get_resources(
12
+ local_shell, resource_type,
13
+ jsonpath: ".items[*].metadata.name",
14
+ kubeconfig_path: current_configuration.kubeconfig_path,
15
+ namespace: current_configuration.deployer_namespace
16
+ )
17
+ end
18
+ end
@@ -6,7 +6,9 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
6
6
  ]
7
7
 
8
8
  STRATEGY_OPTIONS = [
9
+ :namespace,
9
10
  :container_name,
11
+ :env_file,
10
12
  :image_name,
11
13
  :detached,
12
14
  :command_name,
@@ -14,6 +16,8 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
14
16
  :delete_if_exists,
15
17
  :volumes,
16
18
  :networks,
19
+ :expose,
20
+ :publish,
17
21
  ]
18
22
 
19
23
  Contract KuberKit::Shell::AbstractShell, KuberKit::Core::Service => Any
@@ -24,11 +28,15 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
24
28
  raise KuberKit::Error, "Unknow options for deploy strategy: #{unknown_options}. Available options: #{STRATEGY_OPTIONS}"
25
29
  end
26
30
 
27
- container_name = strategy_options.fetch(:container_name, service.uri)
31
+ namespace = strategy_options.fetch(:namespace, nil)
32
+ container_name = strategy_options.fetch(:container_name, [namespace, service.name].compact.join("_"))
28
33
  command_name = strategy_options.fetch(:command_name, nil)
34
+ env_file = strategy_options.fetch(:env_file, nil)
29
35
  custom_args = strategy_options.fetch(:custom_args, nil)
30
36
  networks = strategy_options.fetch(:networks, [])
31
37
  volumes = strategy_options.fetch(:volumes, [])
38
+ expose_ports = strategy_options.fetch(:expose, [])
39
+ publish_ports = strategy_options.fetch(:publish, [])
32
40
  hostname = strategy_options.fetch(:hostname, container_name)
33
41
 
34
42
  image_name = strategy_options.fetch(:image_name, nil)
@@ -46,6 +54,9 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
46
54
  if container_name
47
55
  custom_args << "--name #{container_name}"
48
56
  end
57
+ if env_file
58
+ custom_args << "--env-file #{env_file}"
59
+ end
49
60
  if hostname
50
61
  custom_args << "--hostname #{hostname}"
51
62
  end
@@ -58,12 +69,19 @@ class KuberKit::ServiceDeployer::Strategies::Docker < KuberKit::ServiceDeployer:
58
69
  docker_commands.create_volume(shell, volume_name) unless volume_name.start_with?("/")
59
70
  custom_args << "--volume #{volume}"
60
71
  end
72
+ Array(expose_ports).each do |expose_port|
73
+ custom_args << "--expose #{expose_port}"
74
+ end
75
+ Array(publish_ports).each do |publish_port|
76
+ custom_args << "--publish #{publish_port}"
77
+ end
61
78
 
62
79
  docker_commands.run(
63
80
  shell, image.remote_registry_url,
64
- command: command_name,
65
- args: custom_args,
66
- detached: !!strategy_options[:detached]
81
+ command: command_name,
82
+ args: custom_args,
83
+ detached: !!strategy_options[:detached],
84
+ interactive: !strategy_options[:detached]
67
85
  )
68
86
  end
69
87
  end
@@ -29,10 +29,11 @@ class KuberKit::ServiceDeployer::Strategies::DockerCompose < KuberKit::ServiceDe
29
29
  custom_args = strategy_options.fetch(:custom_args, nil)
30
30
 
31
31
  docker_compose_commands.run(shell, config_path,
32
- service: service_name,
33
- command: command_name,
34
- args: custom_args,
35
- detached: !!strategy_options[:detached]
32
+ service: service_name,
33
+ command: command_name,
34
+ args: custom_args,
35
+ detached: !!strategy_options[:detached],
36
+ interactive: !strategy_options[:detached]
36
37
  )
37
38
  end
38
39
  end
@@ -60,19 +60,19 @@ class KuberKit::Shell::Commands::KubectlCommands
60
60
  command_parts << "-o jsonpath='{#{jsonpath}}'"
61
61
  end
62
62
 
63
- result = kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, namespace: namespace)
63
+ result = kubectl_run(shell, command_parts, kubeconfig_path: kubeconfig_path, namespace: namespace).to_s
64
64
 
65
65
  # Hide warnings manually, until appropriate kubectl option will be available
66
- result = result.split("\n").reject{|n| n.start_with?("Warning:") }.join("\n") if result.is_a?(String)
66
+ result = result.split("\n").reject{|n| n.start_with?("Warning:") }.join("\n")
67
67
 
68
- result
68
+ Array(result.split(" ")).reject(&:empty?)
69
69
  end
70
70
 
71
71
  def resource_exists?(shell, resource_type, resource_name, kubeconfig_path: nil, namespace: nil)
72
72
  result = get_resources(shell, resource_type,
73
73
  field_selector: "metadata.name=#{resource_name}", kubeconfig_path: kubeconfig_path, namespace: namespace
74
74
  )
75
- result && result != ""
75
+ result.any?
76
76
  end
77
77
 
78
78
  def delete_resource(shell, resource_type, resource_name, kubeconfig_path: nil, namespace: nil)
@@ -0,0 +1,32 @@
1
+ class KuberKit::Shell::Commands::SystemCommands
2
+ def kill_process(shell, pid)
3
+ # we need to use kill command directly sometimes,
4
+ # because Process.kill doesn't kill processes created by system() call
5
+ shell.exec!("kill -9 #{pid}")
6
+ true
7
+ rescue
8
+ false
9
+ end
10
+
11
+ def find_pids_by_name(shell, name)
12
+ shell
13
+ .exec!("ps auxww | grep '#{name}' | grep -v 'grep' | awk '{print $2}'")
14
+ .split("\n")
15
+ .reject(&:empty?)
16
+ .map(&:chomp)
17
+ .map(&:to_i)
18
+ rescue
19
+ []
20
+ end
21
+
22
+ def get_child_pids(shell, pid)
23
+ shell
24
+ .exec!("pgrep -P #{pid}")
25
+ .split("\n")
26
+ .reject(&:empty?)
27
+ .map(&:chomp)
28
+ .map(&:to_i)
29
+ rescue
30
+ []
31
+ end
32
+ end
@@ -15,7 +15,7 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
15
15
  end
16
16
 
17
17
  result = nil
18
- IO.popen(command, err: [:child, :out]) do |io|
18
+ IO.popen(wrap_command_with_pid(command), err: [:child, :out]) do |io|
19
19
  result = io.read.chomp.strip
20
20
  end
21
21
 
@@ -37,7 +37,7 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
37
37
  ui.print_debug("LocalShell", "Interactive: [#{command_number}]: #{command.to_s.cyan}")
38
38
  end
39
39
 
40
- result = system(command)
40
+ result = system(wrap_command_with_pid(command))
41
41
 
42
42
  if !$?.success?
43
43
  raise ShellError, "Shell command failed: #{command}\r\n#{result}"
@@ -86,6 +86,10 @@ class KuberKit::Shell::LocalShell < KuberKit::Shell::AbstractShell
86
86
  end
87
87
  end
88
88
 
89
+ def wrap_command_with_pid(command)
90
+ "KIT=#{Process.pid} #{command}"
91
+ end
92
+
89
93
  private
90
94
  def ensure_directory_exists(file_path)
91
95
  dir_path = File.dirname(file_path)
@@ -27,7 +27,7 @@ class KuberKit::Shell::SshShell < KuberKit::Shell::LocalShell
27
27
  ui.print_debug("SshShell", "#{ssh_session.host.green} > Execute: [#{command_number}]: #{command.to_s.cyan}")
28
28
  end
29
29
 
30
- result = ssh_session.exec!(command)
30
+ result = ssh_session.exec!(wrap_command_with_pid(command))
31
31
 
32
32
  if result && result != "" && log_command
33
33
  ui.print_debug("SshShell", "#{ssh_session.host.green} > Finished [#{command_number}] with result: \n#{result.grey}")
@@ -0,0 +1,38 @@
1
+ class KuberKit::Tools::ProcessCleaner
2
+ include KuberKit::Import[
3
+ "shell.system_commands",
4
+ "shell.local_shell"
5
+ ]
6
+
7
+ def clean
8
+ stop_threads
9
+ stop_child_proceses
10
+ end
11
+
12
+ def stop_threads
13
+ Thread.list.each do |t|
14
+ t.abort_on_exception = false
15
+ t.report_on_exception = false
16
+ Thread.kill(t) if t != Thread.current
17
+ end
18
+ end
19
+
20
+ def stop_child_proceses
21
+ find_all_child_processes.each do |pid|
22
+ system_commands.kill_process(local_shell, pid)
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def find_all_child_processes
29
+ pids = system_commands.find_pids_by_name(local_shell, "KIT=#{Process.pid}")
30
+ pids + get_child_pids(pids)
31
+ end
32
+
33
+ def get_child_pids(pids)
34
+ pids
35
+ .map{ |p| system_commands.get_child_pids(local_shell, p) }
36
+ .flatten
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  module KuberKit
2
- VERSION = "0.4.5"
2
+ VERSION = "0.5.0"
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.4.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Iskander Khaziev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-09 00:00:00.000000000 Z
11
+ date: 2021-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: contracts-lite
@@ -209,7 +209,9 @@ files:
209
209
  - lib/kuber_kit/actions/kubectl_attacher.rb
210
210
  - lib/kuber_kit/actions/kubectl_console.rb
211
211
  - lib/kuber_kit/actions/kubectl_describe.rb
212
+ - lib/kuber_kit/actions/kubectl_env.rb
212
213
  - lib/kuber_kit/actions/kubectl_logs.rb
214
+ - lib/kuber_kit/actions/service_checker.rb
213
215
  - lib/kuber_kit/actions/service_deployer.rb
214
216
  - lib/kuber_kit/actions/service_reader.rb
215
217
  - lib/kuber_kit/actions/template_reader.rb
@@ -273,6 +275,8 @@ files:
273
275
  - lib/kuber_kit/image_compiler/image_builder.rb
274
276
  - lib/kuber_kit/image_compiler/image_dependency_resolver.rb
275
277
  - lib/kuber_kit/image_compiler/version_tag_builder.rb
278
+ - lib/kuber_kit/kubernetes/resource_selector.rb
279
+ - lib/kuber_kit/kubernetes/resources_fetcher.rb
276
280
  - lib/kuber_kit/preprocessing/file_preprocessor.rb
277
281
  - lib/kuber_kit/preprocessing/text_preprocessor.rb
278
282
  - lib/kuber_kit/service_deployer/action_handler.rb
@@ -293,6 +297,7 @@ files:
293
297
  - lib/kuber_kit/shell/commands/git_commands.rb
294
298
  - lib/kuber_kit/shell/commands/kubectl_commands.rb
295
299
  - lib/kuber_kit/shell/commands/rsync_commands.rb
300
+ - lib/kuber_kit/shell/commands/system_commands.rb
296
301
  - lib/kuber_kit/shell/local_shell.rb
297
302
  - lib/kuber_kit/shell/ssh_session.rb
298
303
  - lib/kuber_kit/shell/ssh_shell.rb
@@ -302,6 +307,7 @@ files:
302
307
  - lib/kuber_kit/template_reader/strategies/artifact_file.rb
303
308
  - lib/kuber_kit/tools/file_presence_checker.rb
304
309
  - lib/kuber_kit/tools/logger_factory.rb
310
+ - lib/kuber_kit/tools/process_cleaner.rb
305
311
  - lib/kuber_kit/ui.rb
306
312
  - lib/kuber_kit/ui/api.rb
307
313
  - lib/kuber_kit/ui/debug.rb