kontena-cli 1.4.0.pre6 → 1.4.0.pre7

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,33 @@
1
+ require 'kontena/plugin_manager/common'
2
+ require 'rubygems/commands/cleanup_command'
3
+
4
+ module Kontena
5
+ module PluginManager
6
+ class Cleaner
7
+ include Common
8
+
9
+ attr_reader :plugin_name
10
+
11
+ def initialize(plugin_name)
12
+ @plugin_name = plugin_name
13
+ end
14
+
15
+ def command
16
+ @command ||= Gem::Commands::CleanupCommand.new
17
+ end
18
+
19
+ # Runs gem cleanup, removes remains from previous versions
20
+ # @param plugin_name [String]
21
+ def cleanup
22
+ options = []
23
+ options += ['-q', '--no-verbose'] unless ENV["DEBUG"]
24
+ command.handle_options options
25
+ command.execute
26
+ true
27
+ rescue Gem::SystemExitException => e
28
+ raise unless e.exit_code.zero?
29
+ true
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,86 @@
1
+ require 'kontena/plugin_manager'
2
+
3
+ module Kontena
4
+ module PluginManager
5
+ module Common
6
+ Gem.autoload :DefaultUserInteraction, 'rubygems/user_interaction'
7
+ Gem.autoload :StreamUI, 'rubygems/user_interaction'
8
+
9
+ # @return [Boolean] is the CLI in plugin debugging mode?
10
+ def plugin_debug?
11
+ @plugin_debug ||= ENV['DEBUG'] == 'plugin'
12
+ end
13
+ module_function :plugin_debug?
14
+
15
+ # @return [Gem::StreamUI] a rubygems user interaction module with minimal output
16
+ def dummy_ui
17
+ Gem::StreamUI.new(StringIO.new, StringIO.new, StringIO.new, false)
18
+ end
19
+ module_function :dummy_ui
20
+
21
+ # Tell rubygems to use the dummy ui as default user interaction
22
+ def use_dummy_ui
23
+ Gem::DefaultUserInteraction.ui = dummy_ui
24
+ end
25
+ module_function :use_dummy_ui
26
+
27
+ # Prefix a plugin name into a gem name (hello to kontena-plugin-hello)
28
+ def prefix(plugin_name)
29
+ return plugin_name if plugin_name.to_s.start_with?('kontena-plugin-')
30
+ "kontena-plugin-#{plugin_name}"
31
+ end
32
+ module_function :prefix
33
+
34
+ # Find a plugin by name from installed plugins
35
+ # @param plugin_name [String]
36
+ def installed(plugin_name)
37
+ search = prefix(plugin_name)
38
+ plugins.find {|plugin| plugin.name == search }
39
+ end
40
+ module_function :installed
41
+
42
+ def installed?(plugin_name)
43
+ !installed(plugin_name).nil?
44
+ end
45
+ module_function :installed?
46
+
47
+ # Gem installation directory
48
+ # @return [String]
49
+ def install_dir
50
+ return @install_dir if @install_dir
51
+ install_dir = File.join(Dir.home, '.kontena', 'gems', RUBY_VERSION)
52
+ unless File.directory?(install_dir)
53
+ require 'fileutils'
54
+ FileUtils.mkdir_p(install_dir, mode: 0700)
55
+ end
56
+ @install_dir = install_dir
57
+ end
58
+ module_function :install_dir
59
+
60
+ # @return [Kontena::PluginManager::RubygemsClient]
61
+ def rubygems_client
62
+ @rubygems_client ||= Kontena::PluginManager::RubygemsClient.new
63
+ end
64
+ module_function :rubygems_client
65
+
66
+ # Search rubygems for kontena plugins
67
+ # @param pattern [String] optional search pattern
68
+ def search_plugins(pattern = nil)
69
+ rubygems_client.search(prefix(pattern))
70
+ end
71
+ module_function :search_plugins
72
+
73
+ # Retrieve plugin versions from rubygems
74
+ # @param plugin_name [String]
75
+ def gem_versions(plugin_name)
76
+ rubygems_client.versions(prefix(plugin_name))
77
+ end
78
+ module_function :gem_versions
79
+
80
+ def plugins
81
+ Kontena::PluginManager.plugins
82
+ end
83
+ module_function :plugins
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,54 @@
1
+ require 'kontena/plugin_manager/common'
2
+ require 'rubygems/dependency_installer'
3
+ require 'rubygems/requirement'
4
+
5
+ module Kontena
6
+ module PluginManager
7
+ class Installer
8
+ include Common
9
+
10
+ attr_reader :plugin_name, :pre, :version
11
+
12
+ # Create a new instance of plugin installer
13
+ # @param plugin_name [String]
14
+ # @param pre [Boolean] install a prerelease version if available
15
+ # @param version [String] install a specific version
16
+ def initialize(plugin_name, pre: false, version: nil)
17
+ @plugin_name = plugin_name
18
+ @pre = pre
19
+ @version = version
20
+ end
21
+
22
+ def command
23
+ @command ||= Gem::DependencyInstaller.new(
24
+ document: false,
25
+ force: true,
26
+ prerelease: pre,
27
+ minimal_deps: true
28
+ )
29
+ end
30
+
31
+ # Install a plugin
32
+ def install
33
+ plugin_version = version.nil? ? Gem::Requirement.default : Gem::Requirement.new(version)
34
+ command.install(prefix(plugin_name), plugin_version)
35
+ command.installed_gems
36
+ end
37
+
38
+ # Upgrade an installed plugin
39
+ # @param plugin_name [String]
40
+ # @param pre [Boolean] upgrade to a prerelease version if available. Will happen always when the installed version is a prerelease version.
41
+ def upgrade
42
+ return install if version
43
+ installed = installed(plugin_name)
44
+ pre = installed.version.prerelease?
45
+
46
+ raise "Plugin #{plugin_name} not installed" unless installed
47
+ latest = rubygems_client.latest_version(prefix(plugin_name), pre: pre)
48
+ if latest > installed.version
49
+ Installer.new(plugin_name, version: latest.to_s).install
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,93 @@
1
+ require 'kontena_cli'
2
+ require 'kontena/plugin_manager/common'
3
+
4
+ module Kontena
5
+ module PluginManager
6
+ class Loader
7
+ include Common
8
+
9
+ CLI_GEM = 'kontena-cli'.freeze
10
+ MIN_CLI_VERSION = '0.15.99'.freeze
11
+
12
+ def loaded_plugins
13
+ @loaded_plugins ||= []
14
+ end
15
+
16
+ def load_plugins
17
+ Gem::Specification.to_a.each do |spec|
18
+ plugin_path = plugin_require_path(spec)
19
+ next unless plugin_path
20
+ next if loaded_plugins.find { |p| p.name == spec.name }
21
+ load_plugin(plugin_path, spec)
22
+ end
23
+ loaded_plugins
24
+ end
25
+
26
+ private
27
+
28
+ def load_plugin(path, spec)
29
+ unless spec_has_valid_dependency?(spec)
30
+ plugin_name = spec.name.sub('kontena-plugin-', '')
31
+ $stderr.puts " [#{Kontena.pastel.red('error')}] Plugin #{Kontena.pastel.cyan(plugin_name)} (#{spec.version}) is not compatible with the current cli version."
32
+ $stderr.puts " To update the plugin, run 'kontena plugin install #{plugin_name}'"
33
+ return false
34
+ end
35
+
36
+ start_tracking
37
+ activate(spec)
38
+
39
+ Kontena.logger.debug { "Loading plugin #{spec.name} from #{path}" }
40
+ require(path)
41
+ Kontena.logger.debug { "Loaded plugin #{spec.name}" } if plugin_debug?
42
+
43
+ report_tracking
44
+ true
45
+ rescue ScriptError, LoadError, StandardError => ex
46
+ warn " [#{Kontena.pastel.red('error')}] Failed to load plugin: #{spec.name} from #{spec.gem_dir}\n\tRerun the command with environment DEBUG=true set to get the full exception."
47
+ Kontena.logger.error(ex)
48
+ spec.description = spec.description + Kontena.pastel.red(" (broken)")
49
+ false
50
+ ensure
51
+ loaded_plugins << spec
52
+ end
53
+
54
+ def activate(spec)
55
+ Kontena.logger.debug { "Activating plugin #{spec.name}" } if plugin_debug?
56
+ spec.activate
57
+ spec.activate_dependencies
58
+ end
59
+
60
+ # @param [Gem::Specification] spec
61
+ # @return [Boolean]
62
+ def spec_has_valid_dependency?(spec)
63
+ kontena_cli = spec.runtime_dependencies.find{ |d| d.name == CLI_GEM }
64
+ !kontena_cli.match?(CLI_GEM, MIN_CLI_VERSION)
65
+ rescue
66
+ false
67
+ end
68
+
69
+ def plugin_require_path(spec)
70
+ paths = spec.require_paths.to_a.map do |require_path|
71
+ File.join(spec.gem_dir, require_path, 'kontena_cli_plugin.rb')
72
+ end
73
+ paths.find { |path| File.exist?(path) }
74
+ end
75
+
76
+ def start_tracking
77
+ return unless plugin_debug?
78
+ @loaded_features_before = $LOADED_FEATURES.dup
79
+ @load_path_before = $LOAD_PATH.dup
80
+ end
81
+
82
+ def report_tracking
83
+ return unless plugin_debug?
84
+ added_features = ($LOADED_FEATURES - @loaded_features_before).map {|feat| "- #{feat}"}
85
+ added_paths = ($LOAD_PATH - @load_path_before).map {|feat| "- #{feat}"}
86
+ Kontena.logger.debug { "Plugin manager loaded features for #{spec.name}:" } unless added_features.empty?
87
+ added_features.each { |feat| Kontena.logger.debug { feat } }
88
+ Kontena.logger.debug { "Plugin manager load paths added for #{spec.name}:" } unless added_paths.empty?
89
+ added_paths.each { |path| Kontena.logger.debug { path } }
90
+ end
91
+ end
92
+ end
93
+ end
@@ -1,40 +1,59 @@
1
- require 'excon'
1
+ require 'kontena_cli'
2
2
  require 'json'
3
+ require 'uri'
4
+ require 'net/https'
3
5
 
4
6
  module Kontena
5
- class PluginManager
7
+ module PluginManager
6
8
  class RubygemsClient
7
9
 
8
- RUBYGEMS_URL = 'https://rubygems.org'
9
- HEADERS = {
10
- 'Content-Type' => 'application/json',
11
- 'Accept' => 'application/json'
12
- }
10
+ JSON_MIME ='application/json'.freeze
11
+ ACCEPT = 'Accept'.freeze
12
+ HTTPOK = "200".freeze
13
13
 
14
- attr_reader :client
14
+ def search(pattern = nil)
15
+ get('/api/v1/search.json', query: pattern)
16
+ end
15
17
 
16
- def initialize
17
- @client = Excon.new(RUBYGEMS_URL)
18
+ def versions(gem_name)
19
+ response = get("/api/v1/versions/#{gem_name}.json")
20
+ response.map { |version| Gem::Version.new(version["number"]) }.sort.reverse
18
21
  end
19
22
 
20
- def search(pattern = nil)
21
- response = client.get(
22
- path: "/api/v1/search.json?query=#{pattern}",
23
- headers: HEADERS
24
- )
23
+ # Get the latest version number from rubygems
24
+ # @param plugin_name [String]
25
+ # @param pre [Boolean] include prerelease versions
26
+ def latest_version(gem_name, pre: false)
27
+ return versions(gem_name).first if pre
28
+ versions(gem_name).find { |version| !version.prerelease? }
29
+ end
25
30
 
26
- JSON.parse(response.body)
31
+ def client
32
+ return @client if @client
33
+ @client = Net::HTTP.new('rubygems.org', 443)
34
+ @client.use_ssl = true
35
+ @client
27
36
  end
28
37
 
29
- def versions(gem_name)
30
- response = client.get(
31
- path: "/api/v1/versions/#{gem_name}.json",
32
- headers: HEADERS
33
- )
34
- versions = JSON.parse(response.body)
35
- versions.map { |version| Gem::Version.new(version["number"]) }.sort.reverse
38
+ def request_path(path, query = nil)
39
+ uri = URI(path)
40
+ uri.query = URI.encode_www_form(query) if query
41
+ uri.to_s
42
+ end
43
+
44
+ def get_request(path)
45
+ request = Net::HTTP::Get.new(path)
46
+ request[ACCEPT] = JSON_MIME
47
+ request
36
48
  end
37
49
 
50
+ def get(path, query = nil)
51
+ Kontena.logger.debug { "Requesting GET #{path}" }
52
+ response = client.request(get_request(request_path(path, query)))
53
+ Kontena.logger.debug { "Response #{response.code}" }
54
+ raise "Server responded with #{response.code} (#{response.class.name})" unless response.code == HTTPOK
55
+ JSON.parse(response.body)
56
+ end
38
57
  end
39
58
  end
40
59
  end
@@ -0,0 +1,34 @@
1
+ require 'rubygems/uninstaller'
2
+
3
+ module Kontena
4
+ module PluginManager
5
+ class Uninstaller
6
+ include PluginManager::Common
7
+
8
+ attr_reader :plugin_name
9
+
10
+ def initialize(plugin_name)
11
+ @plugin_name = plugin_name
12
+ end
13
+
14
+ def command(spec)
15
+ @command ||= Gem::Uninstaller.new(
16
+ spec.name,
17
+ all: true,
18
+ executables: true,
19
+ force: true,
20
+ install_dir: spec.base_dir
21
+ )
22
+ end
23
+
24
+ # Uninstall a plugin
25
+ # @param plugin_name [String]
26
+ def uninstall
27
+ installed = installed(plugin_name)
28
+ raise "Plugin #{plugin_name} not installed" unless installed
29
+
30
+ command(installed).uninstall
31
+ end
32
+ end
33
+ end
34
+ end
@@ -28,6 +28,30 @@ module Kontena
28
28
  end
29
29
  module_function :symbolize_keys!
30
30
 
31
+ def stringify_keys(obj)
32
+ case obj
33
+ when Hash
34
+ obj.map { |k,v| [k.to_s, stringify_keys(v)] }.to_h
35
+ when Array
36
+ obj.map { |v| stringify_keys(v) }
37
+ else
38
+ obj
39
+ end
40
+ end
41
+ module_function :stringify_keys
42
+
43
+ def stringify_keys!(obj)
44
+ case obj
45
+ when Hash
46
+ obj.keys.each { |k| obj[k.to_s] = stringify_keys!(obj.delete(k)) }
47
+ when Array
48
+ obj.map! { |v| stringify_keys!(v) }
49
+ else
50
+ end
51
+ obj
52
+ end
53
+ module_function :stringify_keys!
54
+
31
55
  # @param [String] cmd
32
56
  def which(cmd)
33
57
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
@@ -21,6 +21,7 @@ module Kontena
21
21
  autoload :PluginManager, 'kontena/plugin_manager'
22
22
  autoload :MainCommand, 'kontena/main_command'
23
23
  autoload :Errors, 'kontena/errors'
24
+ autoload :Util, 'kontena/util'
24
25
 
25
26
  # Run a kontena command like it was launched from the command line. Re-raises any exceptions,
26
27
  # except a SystemExit with status 0, which is considered a success.
@@ -5,7 +5,9 @@
5
5
  #
6
6
 
7
7
  name "kontena"
8
+ package_name "kontena-cli"
8
9
  friendly_name "Kontena CLI"
10
+ description "Command-line tool for the Kontena Platform"
9
11
  maintainer "Kontena, Inc."
10
12
  homepage "https://kontena.io"
11
13
 
@@ -20,7 +22,7 @@ build_iteration 1
20
22
  dependency "preparation"
21
23
 
22
24
  # kontena dependencies/components
23
- dependency "kontena"
25
+ dependency "kontena-cli"
24
26
 
25
27
  # Version manifest file
26
28
  dependency "version-manifest"
@@ -32,3 +34,7 @@ package :pkg do
32
34
  identifier "io.kontena.cli.pkg.kontena"
33
35
  signing_identity "Developer ID Installer: Kontena Oy (JJ22T2W355)"
34
36
  end
37
+
38
+ package :deb do
39
+ vendor "Kontena, Inc <info@kontena.io>"
40
+ end