kontena-cli 1.4.0.pre6 → 1.4.0.pre7

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 (181) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/VERSION +1 -1
  4. data/bin/kontena +1 -1
  5. data/kontena-cli.gemspec +3 -3
  6. data/lib/kontena/cli/certificate/authorize_command.rb +67 -6
  7. data/lib/kontena/cli/certificate/get_command.rb +7 -0
  8. data/lib/kontena/cli/certificate/list_command.rb +75 -0
  9. data/lib/kontena/cli/certificate/register_command.rb +13 -2
  10. data/lib/kontena/cli/certificate/request_command.rb +20 -0
  11. data/lib/kontena/cli/certificate/show_command.rb +19 -0
  12. data/lib/kontena/cli/certificate_command.rb +4 -1
  13. data/lib/kontena/cli/cloud/master/add_command.rb +1 -1
  14. data/lib/kontena/cli/common.rb +21 -33
  15. data/lib/kontena/cli/etcd/health_command.rb +21 -27
  16. data/lib/kontena/cli/helpers/exec_helper.rb +15 -6
  17. data/lib/kontena/cli/helpers/health_helper.rb +12 -0
  18. data/lib/kontena/cli/helpers/log_helper.rb +2 -2
  19. data/lib/kontena/cli/helpers/time_helper.rb +29 -0
  20. data/lib/kontena/cli/master/init_cloud_command.rb +19 -0
  21. data/lib/kontena/cli/master/list_command.rb +1 -1
  22. data/lib/kontena/cli/master/ssh_command.rb +3 -1
  23. data/lib/kontena/cli/master/use_command.rb +1 -2
  24. data/lib/kontena/cli/node_command.rb +1 -0
  25. data/lib/kontena/cli/nodes/health_command.rb +28 -13
  26. data/lib/kontena/cli/nodes/list_command.rb +19 -3
  27. data/lib/kontena/cli/nodes/show_command.rb +4 -2
  28. data/lib/kontena/cli/nodes/ssh_command.rb +5 -2
  29. data/lib/kontena/cli/nodes/update_command.rb +2 -0
  30. data/lib/kontena/cli/plugins/install_command.rb +11 -8
  31. data/lib/kontena/cli/plugins/list_command.rb +5 -3
  32. data/lib/kontena/cli/plugins/search_command.rb +4 -2
  33. data/lib/kontena/cli/plugins/show_command.rb +17 -0
  34. data/lib/kontena/cli/plugins/uninstall_command.rb +9 -13
  35. data/lib/kontena/cli/registry/create_command.rb +1 -1
  36. data/lib/kontena/cli/services/create_command.rb +6 -0
  37. data/lib/kontena/cli/services/services_helper.rb +33 -6
  38. data/lib/kontena/cli/services/update_command.rb +6 -0
  39. data/lib/kontena/cli/stacks/build_command.rb +3 -3
  40. data/lib/kontena/cli/stacks/common.rb +105 -90
  41. data/lib/kontena/cli/stacks/deploy_command.rb +7 -3
  42. data/lib/kontena/cli/stacks/install_command.rb +39 -6
  43. data/lib/kontena/cli/stacks/list_command.rb +36 -4
  44. data/lib/kontena/cli/stacks/logs_command.rb +9 -2
  45. data/lib/kontena/cli/stacks/registry/pull_command.rb +2 -2
  46. data/lib/kontena/cli/stacks/registry/push_command.rb +20 -9
  47. data/lib/kontena/cli/stacks/registry/remove_command.rb +4 -4
  48. data/lib/kontena/cli/stacks/registry/show_command.rb +4 -4
  49. data/lib/kontena/cli/stacks/remove_command.rb +27 -1
  50. data/lib/kontena/cli/stacks/service_generator.rb +12 -2
  51. data/lib/kontena/cli/stacks/show_command.rb +35 -5
  52. data/lib/kontena/cli/stacks/stack_name.rb +71 -0
  53. data/lib/kontena/cli/stacks/upgrade_command.rb +127 -14
  54. data/lib/kontena/cli/stacks/validate_command.rb +38 -10
  55. data/lib/kontena/cli/stacks/yaml/custom_validators/certificates_validator.rb +22 -0
  56. data/lib/kontena/cli/stacks/yaml/opto/prompt_resolver.rb +1 -2
  57. data/lib/kontena/cli/stacks/yaml/reader.rb +211 -185
  58. data/lib/kontena/cli/stacks/yaml/service_extender.rb +6 -12
  59. data/lib/kontena/cli/stacks/yaml/stack_file_loader.rb +97 -0
  60. data/lib/kontena/cli/stacks/yaml/stack_file_loader/file_loader.rb +41 -0
  61. data/lib/kontena/cli/stacks/yaml/stack_file_loader/registry_loader.rb +24 -0
  62. data/lib/kontena/cli/stacks/yaml/stack_file_loader/uri_loader.rb +23 -0
  63. data/lib/kontena/cli/stacks/yaml/validations.rb +16 -0
  64. data/lib/kontena/cli/stacks/yaml/validator_v3.rb +25 -8
  65. data/lib/kontena/client.rb +2 -2
  66. data/lib/kontena/command.rb +11 -0
  67. data/lib/kontena/main_command.rb +3 -1
  68. data/lib/kontena/plugin_manager.rb +11 -198
  69. data/lib/kontena/plugin_manager/cleaner.rb +33 -0
  70. data/lib/kontena/plugin_manager/common.rb +86 -0
  71. data/lib/kontena/plugin_manager/installer.rb +54 -0
  72. data/lib/kontena/plugin_manager/loader.rb +93 -0
  73. data/lib/kontena/plugin_manager/rubygems_client.rb +42 -23
  74. data/lib/kontena/plugin_manager/uninstaller.rb +34 -0
  75. data/lib/kontena/util.rb +24 -0
  76. data/lib/kontena_cli.rb +1 -0
  77. data/omnibus/config/projects/kontena.rb +7 -1
  78. data/omnibus/config/software/{kontena.rb → kontena-cli.rb} +2 -0
  79. data/spec/fixtures/api/node.json +2 -1
  80. data/spec/fixtures/stack-internal-extend.yml +6 -1
  81. data/spec/fixtures/stack-with-dependencies-dep-1-1.yml +8 -0
  82. data/spec/fixtures/stack-with-dependencies-dep-1.yml +17 -0
  83. data/spec/fixtures/stack-with-dependencies-dep-2.yml +8 -0
  84. data/spec/fixtures/stack-with-dependencies-dep-3.yml +5 -0
  85. data/spec/fixtures/stack-with-dependencies-dep_2-removed.yml +17 -0
  86. data/spec/fixtures/stack-with-dependencies-dep_3-added.yml +25 -0
  87. data/spec/fixtures/stack-with-dependencies.yml +22 -0
  88. data/spec/fixtures/stack-with-variables.yml +3 -0
  89. data/spec/kontena/cli/etcd/health_command_spec.rb +45 -33
  90. data/spec/kontena/cli/helpers/exec_helper_spec.rb +2 -1
  91. data/spec/kontena/cli/master/init_cloud_command_spec.rb +14 -0
  92. data/spec/kontena/cli/nodes/health_command_spec.rb +74 -10
  93. data/spec/kontena/cli/nodes/list_command_spec.rb +381 -232
  94. data/spec/kontena/cli/nodes/show_command_spec.rb +31 -0
  95. data/spec/kontena/cli/nodes/ssh_command_spec.rb +18 -3
  96. data/spec/kontena/cli/plugins/install_command_spec.rb +1 -1
  97. data/spec/kontena/cli/stacks/build_command_spec.rb +6 -12
  98. data/spec/kontena/cli/stacks/common_spec.rb +42 -69
  99. data/spec/kontena/cli/stacks/install_command_spec.rb +57 -31
  100. data/spec/kontena/cli/stacks/list_command_spec.rb +44 -0
  101. data/spec/kontena/cli/stacks/logs_command_spec.rb +12 -1
  102. data/spec/kontena/cli/stacks/remove_command_spec.rb +39 -0
  103. data/spec/kontena/cli/stacks/show_command_spec.rb +16 -0
  104. data/spec/kontena/cli/stacks/stack_name_spec.rb +21 -0
  105. data/spec/kontena/cli/stacks/upgrade_command_spec.rb +73 -56
  106. data/spec/kontena/cli/stacks/validate_command_spec.rb +81 -0
  107. data/spec/kontena/cli/stacks/yaml/custom_validators/affinities_validator_spec.rb +22 -0
  108. data/spec/kontena/cli/stacks/yaml/reader_spec.rb +173 -169
  109. data/spec/kontena/cli/stacks/yaml/service_extender_spec.rb +12 -3
  110. data/spec/kontena/cli/stacks/yaml/stack_file_loader/file_loader_spec.rb +47 -0
  111. data/spec/kontena/cli/stacks/yaml/stack_file_loader/registry_loader_spec.rb +53 -0
  112. data/spec/kontena/cli/stacks/yaml/stack_file_loader/uri_loader_spec.rb +53 -0
  113. data/spec/kontena/cli/stacks/yaml/stack_file_loader_spec.rb +104 -0
  114. data/spec/kontena/cli/stacks/yaml/validator_v3_spec.rb +19 -0
  115. data/spec/kontena/plugin_manager/cleaner_spec.rb +20 -0
  116. data/spec/kontena/plugin_manager/common_spec.rb +39 -0
  117. data/spec/kontena/plugin_manager/installer_spec.rb +50 -0
  118. data/spec/kontena/plugin_manager/loader_spec.rb +5 -0
  119. data/spec/kontena/plugin_manager/rubygems_client_spec.rb +11 -25
  120. data/spec/kontena/plugin_manager/uninstaller_spec.rb +19 -0
  121. data/spec/kontena/plugin_manager_spec.rb +7 -7
  122. metadata +64 -97
  123. data/lib/kontena/cli/app_command.rb +0 -22
  124. data/lib/kontena/cli/apps/build_command.rb +0 -28
  125. data/lib/kontena/cli/apps/common.rb +0 -172
  126. data/lib/kontena/cli/apps/config_command.rb +0 -25
  127. data/lib/kontena/cli/apps/deploy_command.rb +0 -137
  128. data/lib/kontena/cli/apps/docker_compose_generator.rb +0 -61
  129. data/lib/kontena/cli/apps/docker_helper.rb +0 -80
  130. data/lib/kontena/cli/apps/dockerfile_generator.rb +0 -16
  131. data/lib/kontena/cli/apps/init_command.rb +0 -89
  132. data/lib/kontena/cli/apps/kontena_yml_generator.rb +0 -105
  133. data/lib/kontena/cli/apps/list_command.rb +0 -59
  134. data/lib/kontena/cli/apps/logs_command.rb +0 -37
  135. data/lib/kontena/cli/apps/monitor_command.rb +0 -93
  136. data/lib/kontena/cli/apps/remove_command.rb +0 -74
  137. data/lib/kontena/cli/apps/restart_command.rb +0 -39
  138. data/lib/kontena/cli/apps/scale_command.rb +0 -33
  139. data/lib/kontena/cli/apps/service_generator.rb +0 -114
  140. data/lib/kontena/cli/apps/service_generator_v2.rb +0 -27
  141. data/lib/kontena/cli/apps/show_command.rb +0 -23
  142. data/lib/kontena/cli/apps/start_command.rb +0 -40
  143. data/lib/kontena/cli/apps/stop_command.rb +0 -40
  144. data/lib/kontena/cli/apps/yaml/custom_validators/affinities_validator.rb +0 -19
  145. data/lib/kontena/cli/apps/yaml/custom_validators/build_validator.rb +0 -22
  146. data/lib/kontena/cli/apps/yaml/custom_validators/extends_validator.rb +0 -20
  147. data/lib/kontena/cli/apps/yaml/custom_validators/hooks_validator.rb +0 -54
  148. data/lib/kontena/cli/apps/yaml/custom_validators/secrets_validator.rb +0 -22
  149. data/lib/kontena/cli/apps/yaml/reader.rb +0 -213
  150. data/lib/kontena/cli/apps/yaml/service_extender.rb +0 -77
  151. data/lib/kontena/cli/apps/yaml/validations.rb +0 -71
  152. data/lib/kontena/cli/apps/yaml/validator.rb +0 -38
  153. data/lib/kontena/cli/apps/yaml/validator_v2.rb +0 -53
  154. data/spec/fixtures/app.json +0 -42
  155. data/spec/fixtures/health.yml +0 -26
  156. data/spec/fixtures/kontena-build.yml +0 -16
  157. data/spec/fixtures/kontena-internal-extend.yml +0 -8
  158. data/spec/fixtures/kontena-invalid.yml +0 -4
  159. data/spec/fixtures/kontena-with-env-file.yml +0 -18
  160. data/spec/fixtures/kontena-with-variables.yml +0 -19
  161. data/spec/fixtures/kontena.yml +0 -17
  162. data/spec/fixtures/kontena_build_v2.yml +0 -26
  163. data/spec/fixtures/kontena_numeric_version.yml +0 -9
  164. data/spec/fixtures/kontena_v2.yml +0 -35
  165. data/spec/fixtures/mysql.yml +0 -3
  166. data/spec/fixtures/wordpress-scaled.yml +0 -3
  167. data/spec/fixtures/wordpress.yml +0 -2
  168. data/spec/kontena/cli/app/build_command_spec.rb +0 -55
  169. data/spec/kontena/cli/app/common_spec.rb +0 -110
  170. data/spec/kontena/cli/app/config_command_spec.rb +0 -78
  171. data/spec/kontena/cli/app/deploy_command_spec.rb +0 -217
  172. data/spec/kontena/cli/app/docker_helper_spec.rb +0 -155
  173. data/spec/kontena/cli/app/init_command_spec.rb +0 -109
  174. data/spec/kontena/cli/app/logs_command_spec.rb +0 -131
  175. data/spec/kontena/cli/app/scale_spec.rb +0 -51
  176. data/spec/kontena/cli/app/service_generator_spec.rb +0 -384
  177. data/spec/kontena/cli/app/service_generator_v2_spec.rb +0 -73
  178. data/spec/kontena/cli/app/yaml/reader_spec.rb +0 -457
  179. data/spec/kontena/cli/app/yaml/service_extender_spec.rb +0 -127
  180. data/spec/kontena/cli/app/yaml/validator_spec.rb +0 -380
  181. data/spec/kontena/cli/app/yaml/validator_v2_spec.rb +0 -301
@@ -15,12 +15,12 @@ module Kontena::Cli::Helpers
15
15
  Kontena::Websocket::Logging.initialize_logger(STDERR, websocket_log_level)
16
16
 
17
17
  WEBSOCKET_CLIENT_OPTIONS = {
18
- connect_timeout: ENV["EXCON_CONNECT_TIMEOUT"] ? ENV["EXCON_CONNECT_TIMEOUT"].to_f : 5.0,
19
- open_timeout: ENV["EXCON_CONNECT_TIMEOUT"] ? ENV["EXCON_CONNECT_TIMEOUT"].to_f : 5.0,
18
+ connect_timeout: ENV["EXCON_CONNECT_TIMEOUT"] ? ENV["EXCON_CONNECT_TIMEOUT"].to_f : 10.0,
19
+ open_timeout: ENV["EXCON_CONNECT_TIMEOUT"] ? ENV["EXCON_CONNECT_TIMEOUT"].to_f : 10.0,
20
20
  ping_interval: ENV["EXCON_READ_TIMEOUT"] ? ENV["EXCON_READ_TIMEOUT"].to_f : 30.0,
21
- ping_timeout: ENV["EXCON_CONNECT_TIMEOUT"] ? ENV["EXCON_CONNECT_TIMEOUT"].to_f : 5.0,
22
- close_timeout: ENV["EXCON_CONNECT_TIMEOUT"] ? ENV["EXCON_CONNECT_TIMEOUT"].to_f : 5.0,
23
- write_timeout: ENV["EXCON_WRITE_TIMEOUT"] ? ENV["EXCON_WRITE_TIMEOUT"].to_f : 5.0,
21
+ ping_timeout: ENV["EXCON_CONNECT_TIMEOUT"] ? ENV["EXCON_CONNECT_TIMEOUT"].to_f : 10.0,
22
+ close_timeout: ENV["EXCON_CONNECT_TIMEOUT"] ? ENV["EXCON_CONNECT_TIMEOUT"].to_f : 10.0,
23
+ write_timeout: ENV["EXCON_WRITE_TIMEOUT"] ? ENV["EXCON_WRITE_TIMEOUT"].to_f : 10.0,
24
24
  }
25
25
 
26
26
  # @param ws [Kontena::Websocket::Client]
@@ -59,6 +59,7 @@ module Kontena::Cli::Helpers
59
59
  end
60
60
 
61
61
  # @param ws [Kontena::Websocket::Client]
62
+ # @raise [RuntimeError] exec error
62
63
  # @return [Integer] exit code
63
64
  def websocket_exec_read(ws)
64
65
  ws.read do |msg|
@@ -66,7 +67,9 @@ module Kontena::Cli::Helpers
66
67
 
67
68
  logger.debug "websocket exec read: #{msg.inspect}"
68
69
 
69
- if msg.has_key?('exit')
70
+ if msg.has_key?('error')
71
+ raise msg['error']
72
+ elsif msg.has_key?('exit')
70
73
  # breaks the read loop
71
74
  return msg['exit'].to_i
72
75
  elsif msg.has_key?('stream')
@@ -96,6 +99,12 @@ module Kontena::Cli::Helpers
96
99
  def websocket_exec_write_thread(ws, tty: nil)
97
100
  Thread.new do
98
101
  begin
102
+ if tty
103
+ console_height, console_width = IO.console.winsize
104
+ websocket_exec_write(ws, 'tty_size' => {
105
+ width: console_width, height: console_height
106
+ })
107
+ end
99
108
  read_stdin(tty: tty) do |stdin|
100
109
  websocket_exec_write(ws, 'stdin' => stdin)
101
110
  end
@@ -49,5 +49,17 @@ module Kontena::Cli::Helpers
49
49
  return node['connected'] ? :ok : :offline
50
50
  end
51
51
  end
52
+
53
+ # @param node_etcd_health [Hash{health: String, error: String}]
54
+ # @return [Symbol, String]
55
+ def node_etcd_health(node_etcd_health)
56
+ if node_etcd_health['health']
57
+ return :ok, "healthy"
58
+ elsif node_etcd_health['error']
59
+ return :error, "unhealthy: #{node_etcd_health['error']}"
60
+ else
61
+ return :error, "unhealthy"
62
+ end
63
+ end
52
64
  end
53
65
  end
@@ -3,8 +3,8 @@ module Kontena::Cli::Helpers
3
3
 
4
4
  def self.included(base)
5
5
  if base.respond_to?(:option)
6
- base.option ["-t", "--tail"], :flag, "Tail (follow) logs", default: false
7
- base.option "--lines", "LINES", "Number of lines to show from the end of the logs", default: 100 do |s|
6
+ base.option ["-f", "--follow"], :flag, "Follow log output", :attribute_name => :tail, default: false
7
+ base.option ['--tail', '--lines'], "LINES", "Number of lines to show from the end of the logs", :attribute_name => :lines, default: 100 do |s|
8
8
  Integer(s)
9
9
  end
10
10
  base.option "--since", "SINCE", "Show logs since given timestamp"
@@ -0,0 +1,29 @@
1
+ module Kontena::Cli::Helpers
2
+ module TimeHelper
3
+ # Return an approximation of how long ago the given time was.
4
+ # @param time [String]
5
+ # @param terse [Boolean] very terse output (2-3 chars wide)
6
+ def time_since(time, terse: false)
7
+ return '' if time.nil? || time.empty?
8
+
9
+ dt = Time.now - Time.parse(time)
10
+
11
+ dt_s = dt.to_i
12
+ dt_m, dt_s = dt_s / 60, dt_s % 60
13
+ dt_h, dt_m = dt_m / 60, dt_m % 60
14
+ dt_d, dt_h = dt_h / 60, dt_h % 60
15
+
16
+ parts = []
17
+ parts << "%dd" % dt_d if dt_d > 0
18
+ parts << "%dh" % dt_h if dt_h > 0
19
+ parts << "%dm" % dt_m if dt_m > 0
20
+ parts << "%ds" % dt_s
21
+
22
+ if terse
23
+ return parts.first
24
+ else
25
+ return parts.join('')
26
+ end
27
+ end
28
+ end
29
+ end
@@ -14,7 +14,26 @@ module Kontena::Cli::Master
14
14
  requires_current_master_token
15
15
  requires_current_account_token
16
16
 
17
+ def master_config
18
+ @master_config ||= client.get('config')
19
+ end
20
+
21
+ def current_master_cloud_config
22
+ return @cloud_config if @cloud_config
23
+ master_client_id = master_config['oauth2.client_id']
24
+ @cloud_config = cloud_client.get('user/masters')['data'].find { |cm| cm['attributes']['client-id'] == master_client_id }
25
+ end
26
+
27
+ def current_master_cloud_name
28
+ @cloud_name ||= current_master_cloud_config.nil? ? nil : current_master_cloud_config['attributes']['name']
29
+ end
30
+
31
+ def already_cloud_enabled?
32
+ !current_master_cloud_config.nil?
33
+ end
34
+
17
35
  def execute
36
+ exit_with_error "Current master is already registered to use Kontena Cloud as #{pastel.cyan(current_master_cloud_name)}" if already_cloud_enabled?
18
37
  args = ["--current"]
19
38
  args << "--force" if self.force?
20
39
  args += ["--cloud-master-id", self.cloud_master_id.shellescape] if self.cloud_master_id
@@ -13,7 +13,7 @@ module Kontena::Cli::Master
13
13
 
14
14
  def mark_if_current(row)
15
15
  unless quiet?
16
- row.name.insert(0, pastel.yellow('* ')) if row.name == current_master_name
16
+ row.name.to_s.insert(0, pastel.yellow('* ')) if row.name == current_master_name
17
17
  end
18
18
  end
19
19
 
@@ -1,3 +1,5 @@
1
+ require 'kontena/plugin_manager'
2
+
1
3
  module Kontena::Cli::Master
2
4
  class SshCommand < Kontena::Command
3
5
 
@@ -25,7 +27,7 @@ module Kontena::Cli::Master
25
27
  end
26
28
 
27
29
  def vagrant_plugin_installed?
28
- Kontena::PluginManager.instance.plugins.any? { |plugin| plugin.name == 'kontena-plugin-vagrant' }
30
+ Kontena::PluginManager::Common.installed?('vagrant')
29
31
  end
30
32
 
31
33
  def master_is_vagrant?
@@ -18,8 +18,7 @@ module Kontena::Cli::Master
18
18
 
19
19
  master = config.find_server(name)
20
20
  if master.nil?
21
- exit_with_error p"Could not resolve master by name '#{name}'." +
22
- "\nFor a list of known masters please run: kontena master list"
21
+ exit_with_error "Could not resolve master by name '#{name}'. For a list of known masters please run: kontena master list"
23
22
  else
24
23
  config.current_master = master['name']
25
24
  config.write
@@ -11,6 +11,7 @@ class Kontena::Cli::NodeCommand < Kontena::Command
11
11
  subcommand "health", "Check node health", load_subcommand('nodes/health_command')
12
12
  subcommand "env", "Generate kontena-agent.env configuration", load_subcommand('nodes/env_command')
13
13
 
14
+
14
15
  def execute
15
16
  end
16
17
  end
@@ -1,32 +1,47 @@
1
1
  require 'kontena/cli/helpers/health_helper'
2
+ require 'kontena/cli/helpers/time_helper'
2
3
 
3
4
  module Kontena::Cli::Nodes
4
5
  class HealthCommand < Kontena::Command
5
6
  include Kontena::Cli::Common
6
7
  include Kontena::Cli::GridOptions
7
8
  include Kontena::Cli::Helpers::HealthHelper
9
+ include Kontena::Cli::Helpers::TimeHelper
8
10
 
9
11
  parameter "NODE", "Node name"
10
12
 
11
- def execute
12
- require_api_url
13
- require_current_grid
14
- token = require_token
15
-
16
- node = client(token).get("nodes/#{current_grid}/#{self.node}")
13
+ requires_current_master
14
+ requires_current_grid
17
15
 
18
- return show_node_health(node)
16
+ def execute
17
+ return show_node_health("#{current_grid}/#{self.node}")
19
18
  end
20
19
 
20
+ # @param id [String] :grid/:node
21
21
  # @return [Boolean] true if healthy
22
- def show_node_health(node)
23
- if node['connected']
24
- puts "#{health_icon(:ok)} Node is online"
25
- return true
22
+ def show_node_health(id)
23
+ node_health = client.get("nodes/#{id}/health")
24
+
25
+ if node_health['status'] == 'online'
26
+ puts "#{health_icon(:ok)} Node is online for #{time_since(node_health['connected_at'])}"
26
27
  else
27
- puts "#{health_icon(:offline)} Node is offline"
28
- return false
28
+ puts "#{health_icon(:warning)} Node is #{node_health['status']}"
29
29
  end
30
+
31
+ etcd_health, etcd_status = node_etcd_health(node_health['etcd_health'])
32
+
33
+ puts "#{health_icon etcd_health} Node #{node_health['name']} etcd is #{etcd_status}"
34
+
35
+ return etcd_health == :ok
36
+
37
+ rescue Kontena::Errors::StandardErrorHash => exc
38
+ raise unless exc.status == 422
39
+
40
+ exc.errors.each do |what, error|
41
+ puts "#{health_icon :offline} Node #{id} #{what} error: #{error}"
42
+ end
43
+
44
+ return false
30
45
  end
31
46
  end
32
47
  end
@@ -1,10 +1,12 @@
1
1
  require_relative '../helpers/health_helper'
2
+ require_relative '../helpers/time_helper'
2
3
 
3
4
  module Kontena::Cli::Nodes
4
5
  class ListCommand < Kontena::Command
5
6
  include Kontena::Cli::Common
6
7
  include Kontena::Cli::GridOptions
7
8
  include Kontena::Cli::Helpers::HealthHelper
9
+ include Kontena::Cli::Helpers::TimeHelper
8
10
  include Kontena::Cli::TableGenerator::Helper
9
11
 
10
12
  option ['-a', '--all'], :flag, 'List nodes for all grids', default: false
@@ -19,7 +21,20 @@ module Kontena::Cli::Nodes
19
21
  end
20
22
 
21
23
  def node_status(node)
22
- node['connected'] ? pastel.green('online') : pastel.red('offline')
24
+ case node_status = node['status']
25
+ when 'created'
26
+ "#{pastel.dark('created')} #{time_since(node['created_at'], terse: true)}"
27
+ when 'connecting'
28
+ "#{pastel.cyan('connecting')} #{time_since(node['connected_at'], terse: true)}"
29
+ when 'online'
30
+ "#{pastel.green('online')} #{time_since(node['connected_at'], terse: true)}"
31
+ when 'drain'
32
+ "#{pastel.yellow('drain')}"
33
+ when 'offline'
34
+ "#{pastel.red('offline')} #{time_since(node['disconnected_at'], terse: true)}"
35
+ else
36
+ pastel.white(node_status.to_s)
37
+ end
23
38
  end
24
39
 
25
40
  def node_initial(node, grid)
@@ -38,7 +53,7 @@ module Kontena::Cli::Nodes
38
53
  version: 'agent_version',
39
54
  status: 'status',
40
55
  initial: 'initial',
41
- labels: 'labels'
56
+ labels: 'labels',
42
57
  }
43
58
  end
44
59
 
@@ -58,6 +73,7 @@ module Kontena::Cli::Nodes
58
73
  node['name'] = node_name(node, grid)
59
74
  grid_nodes << node
60
75
  next if quiet?
76
+ node['agent_version'] ||= '-'
61
77
  node['initial'] = node_initial(node, grid)
62
78
  node['status'] = node_status(node)
63
79
  node['labels'] = node_labels(node)
@@ -66,7 +82,7 @@ module Kontena::Cli::Nodes
66
82
  unless quiet?
67
83
  grid_health = grid_health(grid, grid_nodes)
68
84
  grid_nodes.each do |node|
69
- node['name'] = health_icon(node_health(node, grid_health)) + " " + (node['name'] || '(initializing)')
85
+ node['name'] = health_icon(node_health(node, grid_health)) + " " + (node['name'] || node['node_id'])
70
86
  end
71
87
  end
72
88
 
@@ -19,6 +19,7 @@ module Kontena::Cli::Nodes
19
19
  puts " connected: #{node['connected'] ? 'yes': 'no'}"
20
20
  puts " last connect: #{node['connected_at']}"
21
21
  puts " last seen: #{node['last_seen_at']}"
22
+ puts " availability: #{node['availability']}"
22
23
  puts " public ip: #{node['public_ip']}"
23
24
  puts " private ip: #{node['private_ip']}"
24
25
  puts " overlay ip: #{node['overlay_ip']}"
@@ -43,9 +44,10 @@ module Kontena::Cli::Nodes
43
44
  mem_used = mem['used'] - (mem['cached'] + mem['buffers'])
44
45
  puts " memory: #{to_gigabytes(mem_used, 2)} of #{to_gigabytes(mem['total'], 2)} GB"
45
46
  end
46
- if node['resource_usage']['filesystem']
47
+ fs = node.dig('resource_usage','filesystem')
48
+ if fs
47
49
  puts " filesystem:"
48
- node['resource_usage']['filesystem'].each do |filesystem|
50
+ fs.each do |filesystem|
49
51
  puts " - #{filesystem['name']}: #{to_gigabytes(filesystem['used'], 2)} of #{to_gigabytes(filesystem['total'], 2)} GB"
50
52
  end
51
53
  end
@@ -1,3 +1,5 @@
1
+ require 'kontena/plugin_manager'
2
+
1
3
  module Kontena::Cli::Nodes
2
4
  class SshCommand < Kontena::Command
3
5
  include Kontena::Cli::Common
@@ -21,7 +23,8 @@ module Kontena::Cli::Nodes
21
23
  node = client.get("nodes/#{current_grid}/#{self.node}")
22
24
  elsif any?
23
25
  nodes = client.get("grids/#{current_grid}/nodes")['nodes']
24
- node = nodes.select{ |node| node['connected'] }.first
26
+ node = nodes.find{ |node| node['connected'] }
27
+ exit_with_error "There are no online nodes" if node.nil?
25
28
  else
26
29
  exit_with_error "No node name given. Use --any to connect to the first available node"
27
30
  end
@@ -29,7 +32,7 @@ module Kontena::Cli::Nodes
29
32
  provider = Array(node["labels"]).find{ |l| l.start_with?('provider=')}.to_s.split('=').last
30
33
 
31
34
  if provider == 'vagrant'
32
- unless Kontena::PluginManager.instance.plugins.find { |plugin| plugin.name == 'kontena-plugin-vagrant' }
35
+ unless Kontena::PluginManager::Common.installed?('vagrant')
33
36
  exit_with_error 'You need to install vagrant plugin to ssh into this node. Use kontena plugin install vagrant'
34
37
  end
35
38
  cmd = ['vagrant', 'node', 'ssh', node['name']] + commands_list
@@ -11,6 +11,7 @@ module Kontena::Cli::Nodes
11
11
 
12
12
  option ["-l", "--label"], "LABEL", "Node label", multivalued: true
13
13
  option "--clear-labels", :flag, "Clear node labels"
14
+ option "--availability", "active|drain", "Node scheduling availability"
14
15
 
15
16
  def execute
16
17
  data = {}
@@ -18,6 +19,7 @@ module Kontena::Cli::Nodes
18
19
  data[:labels] = self.label_list unless self.label_list.empty?
19
20
  data[:labels] = [] if self.clear_labels?
20
21
 
22
+ data[:availability] = availability if availability
21
23
  spinner "Updating #{self.node.colorize(:cyan)} node " do
22
24
  client.put("nodes/#{current_grid}/#{self.node}", data)
23
25
  end
@@ -1,29 +1,32 @@
1
- require 'open3'
1
+ require 'kontena/plugin_manager'
2
2
 
3
3
  module Kontena::Cli::Plugins
4
4
  class InstallCommand < Kontena::Command
5
5
  include Kontena::Util
6
6
  include Kontena::Cli::Common
7
+ include Kontena::PluginManager::Common
7
8
 
8
9
  parameter 'NAME', 'Plugin name'
9
10
 
10
11
  option ['-v', '--version'], 'VERSION', 'Specify version of plugin to install'
11
12
  option '--pre', :flag, 'Allow pre-release of a plugin to be installed', default: false
12
13
 
13
- def execute
14
- installed_version = Kontena::PluginManager.instance.installed(name)
14
+ def installer
15
+ Kontena::PluginManager::Installer.new(name, pre: pre?, version: version)
16
+ end
15
17
 
16
- if installed_version
18
+ def execute
19
+ if installed?(name)
17
20
  installed = spinner "Upgrading plugin #{name.colorize(:cyan)}" do
18
- Kontena::PluginManager.instance.upgrade_plugin(name, pre: pre?)
21
+ installer.upgrade
19
22
  end
20
23
 
21
- spinner "Running cleanup" do
22
- Kontena::PluginManager.instance.cleanup_plugin(name)
24
+ spinner "Running cleanup" do |spin|
25
+ Kontena::PluginManager::Cleaner.new(name).cleanup
23
26
  end
24
27
  else
25
28
  installed = spinner "Installing plugin #{name.colorize(:cyan)}" do
26
- Kontena::PluginManager.instance.install_plugin(name, pre: pre?, version: version)
29
+ installer.install
27
30
  end
28
31
  end
29
32
 
@@ -1,3 +1,4 @@
1
+ require 'kontena/plugin_manager'
1
2
  require_relative 'common'
2
3
 
3
4
  module Kontena::Cli::Plugins
@@ -5,6 +6,7 @@ module Kontena::Cli::Plugins
5
6
  include Kontena::Cli::Common
6
7
  include Kontena::Cli::TableGenerator::Helper
7
8
  include Common
9
+ include Kontena::PluginManager::Common
8
10
 
9
11
  banner "List installed plugins"
10
12
 
@@ -12,8 +14,8 @@ module Kontena::Cli::Plugins
12
14
  quiet? ? [:name] : %i(name version description)
13
15
  end
14
16
 
15
- def plugins
16
- Kontena::PluginManager.instance.plugins.map do |plugin|
17
+ def plugin_list
18
+ plugins.map do |plugin|
17
19
  {
18
20
  name: short_name(plugin.name),
19
21
  version: plugin.version,
@@ -23,7 +25,7 @@ module Kontena::Cli::Plugins
23
25
  end
24
26
 
25
27
  def execute
26
- print_table(plugins)
28
+ print_table(plugin_list)
27
29
  end
28
30
  end
29
31
  end
@@ -1,19 +1,21 @@
1
1
  require_relative 'common'
2
+ require 'kontena/plugin_manager'
2
3
 
3
4
  module Kontena::Cli::Plugins
4
5
  class SearchCommand < Kontena::Command
5
6
  include Common
7
+ include Kontena::PluginManager::Common
6
8
 
7
9
  parameter '[NAME]', 'Search text'
8
10
  option '--pre', :flag, 'Include pre-release versions'
9
11
 
10
12
  def execute
11
- results = Kontena::PluginManager.instance.search_plugins(name)
13
+ results = search_plugins(name)
12
14
  exit_with_error("Cannot access plugin server") unless results
13
15
  puts "%-50s %-10s %-60s" % ['NAME', 'VERSION', 'DESCRIPTION']
14
16
  results.each do |item|
15
17
  if pre?
16
- latest = Kontena::PluginManager.instance.latest_version(item['name'], pre: true)
18
+ latest = rubygems_client.latest_version(item['name'], pre: true)
17
19
  item['version'] = latest.version.to_s
18
20
  end
19
21
  puts "%-50s %-10s %-60s" % [short_name(item['name']), item['version'], item['info']]