krates 1.6.0

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 (293) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +212 -0
  3. data/LOGO +10 -0
  4. data/VERSION +1 -0
  5. data/bin/krates +23 -0
  6. data/lib/kontena/autoload_core.rb +19 -0
  7. data/lib/kontena/callback.rb +60 -0
  8. data/lib/kontena/callbacks/.gitkeep +0 -0
  9. data/lib/kontena/callbacks/auth/01_list_and_select_grid_after_master_auth.rb +26 -0
  10. data/lib/kontena/callbacks/master/01_clear_current_master_after_terminate.rb +19 -0
  11. data/lib/kontena/callbacks/master/deploy/01_show_logo_before_deploy.rb +14 -0
  12. data/lib/kontena/callbacks/master/deploy/04_default_master_version.rb +18 -0
  13. data/lib/kontena/callbacks/master/deploy/05_before_deploy_configuration_wizard.rb +105 -0
  14. data/lib/kontena/callbacks/master/deploy/40_install_ssl_certificate_after_deploy.rb +32 -0
  15. data/lib/kontena/callbacks/master/deploy/50_authenticate_after_deploy.rb +66 -0
  16. data/lib/kontena/callbacks/master/deploy/55_create_initial_grid_after_deploy.rb +21 -0
  17. data/lib/kontena/callbacks/master/deploy/56_set_server_provider_after_deploy.rb +24 -0
  18. data/lib/kontena/callbacks/master/deploy/60_configure_auth_provider_after_deploy.rb +31 -0
  19. data/lib/kontena/callbacks/master/deploy/70_invite_self_after_deploy.rb +95 -0
  20. data/lib/kontena/callbacks/master/deploy/90_proptip_after_deploy.rb +33 -0
  21. data/lib/kontena/cli/browser_launcher.rb +61 -0
  22. data/lib/kontena/cli/bytes_helper.rb +40 -0
  23. data/lib/kontena/cli/certificate/authorize_command.rb +107 -0
  24. data/lib/kontena/cli/certificate/common.rb +16 -0
  25. data/lib/kontena/cli/certificate/domain_authorization/list_command.rb +24 -0
  26. data/lib/kontena/cli/certificate/domain_authorization/remove_authorization_command.rb +25 -0
  27. data/lib/kontena/cli/certificate/domain_authorize_command.rb +7 -0
  28. data/lib/kontena/cli/certificate/export_command.rb +28 -0
  29. data/lib/kontena/cli/certificate/get_command.rb +33 -0
  30. data/lib/kontena/cli/certificate/import_command.rb +61 -0
  31. data/lib/kontena/cli/certificate/list_command.rb +75 -0
  32. data/lib/kontena/cli/certificate/register_command.rb +30 -0
  33. data/lib/kontena/cli/certificate/remove_command.rb +23 -0
  34. data/lib/kontena/cli/certificate/request_command.rb +20 -0
  35. data/lib/kontena/cli/certificate/show_command.rb +22 -0
  36. data/lib/kontena/cli/certificate_command.rb +18 -0
  37. data/lib/kontena/cli/cloud/login_command.rb +186 -0
  38. data/lib/kontena/cli/cloud/logout_command.rb +14 -0
  39. data/lib/kontena/cli/cloud/master/add_command.rb +156 -0
  40. data/lib/kontena/cli/cloud/master/list_command.rb +35 -0
  41. data/lib/kontena/cli/cloud/master/remove_command.rb +68 -0
  42. data/lib/kontena/cli/cloud/master/show_command.rb +21 -0
  43. data/lib/kontena/cli/cloud/master/update_command.rb +52 -0
  44. data/lib/kontena/cli/cloud/master_command.rb +14 -0
  45. data/lib/kontena/cli/cloud_command.rb +13 -0
  46. data/lib/kontena/cli/common.rb +360 -0
  47. data/lib/kontena/cli/config.rb +662 -0
  48. data/lib/kontena/cli/container_command.rb +10 -0
  49. data/lib/kontena/cli/containers/exec_command.rb +31 -0
  50. data/lib/kontena/cli/containers/inspect_command.rb +16 -0
  51. data/lib/kontena/cli/containers/list_command.rb +51 -0
  52. data/lib/kontena/cli/containers/logs_command.rb +19 -0
  53. data/lib/kontena/cli/etcd/common.rb +8 -0
  54. data/lib/kontena/cli/etcd/get_command.rb +26 -0
  55. data/lib/kontena/cli/etcd/health_command.rb +53 -0
  56. data/lib/kontena/cli/etcd/list_command.rb +36 -0
  57. data/lib/kontena/cli/etcd/mkdir_command.rb +23 -0
  58. data/lib/kontena/cli/etcd/remove_command.rb +29 -0
  59. data/lib/kontena/cli/etcd/set_command.rb +24 -0
  60. data/lib/kontena/cli/etcd_command.rb +12 -0
  61. data/lib/kontena/cli/external_registries/add_command.rb +25 -0
  62. data/lib/kontena/cli/external_registries/list_command.rb +23 -0
  63. data/lib/kontena/cli/external_registries/remove_command.rb +17 -0
  64. data/lib/kontena/cli/external_registry_command.rb +9 -0
  65. data/lib/kontena/cli/grid_command.rb +21 -0
  66. data/lib/kontena/cli/grid_options.rb +12 -0
  67. data/lib/kontena/cli/grids/audit_log_command.rb +22 -0
  68. data/lib/kontena/cli/grids/cloud_config_command.rb +53 -0
  69. data/lib/kontena/cli/grids/common.rb +182 -0
  70. data/lib/kontena/cli/grids/create_command.rb +48 -0
  71. data/lib/kontena/cli/grids/current_command.rb +25 -0
  72. data/lib/kontena/cli/grids/env_command.rb +32 -0
  73. data/lib/kontena/cli/grids/events_command.rb +50 -0
  74. data/lib/kontena/cli/grids/health_command.rb +69 -0
  75. data/lib/kontena/cli/grids/list_command.rb +59 -0
  76. data/lib/kontena/cli/grids/logs_command.rb +35 -0
  77. data/lib/kontena/cli/grids/remove_command.rb +31 -0
  78. data/lib/kontena/cli/grids/show_command.rb +25 -0
  79. data/lib/kontena/cli/grids/trusted_subnet_command.rb +10 -0
  80. data/lib/kontena/cli/grids/trusted_subnets/add_command.rb +18 -0
  81. data/lib/kontena/cli/grids/trusted_subnets/list_command.rb +18 -0
  82. data/lib/kontena/cli/grids/trusted_subnets/remove_command.rb +26 -0
  83. data/lib/kontena/cli/grids/update_command.rb +35 -0
  84. data/lib/kontena/cli/grids/use_command.rb +26 -0
  85. data/lib/kontena/cli/grids/user_command.rb +9 -0
  86. data/lib/kontena/cli/grids/users/add_command.rb +18 -0
  87. data/lib/kontena/cli/grids/users/list_command.rb +20 -0
  88. data/lib/kontena/cli/grids/users/remove_command.rb +20 -0
  89. data/lib/kontena/cli/helpers/exec_helper.rb +209 -0
  90. data/lib/kontena/cli/helpers/health_helper.rb +65 -0
  91. data/lib/kontena/cli/helpers/log_helper.rb +113 -0
  92. data/lib/kontena/cli/helpers/time_helper.rb +29 -0
  93. data/lib/kontena/cli/localhost_web_server.rb +113 -0
  94. data/lib/kontena/cli/log_formatters/compact.rb +65 -0
  95. data/lib/kontena/cli/log_formatters/strip_color.rb +13 -0
  96. data/lib/kontena/cli/logout_command.rb +10 -0
  97. data/lib/kontena/cli/master/audit_log_command.rb +19 -0
  98. data/lib/kontena/cli/master/config/export_command.rb +46 -0
  99. data/lib/kontena/cli/master/config/get_command.rb +26 -0
  100. data/lib/kontena/cli/master/config/import_command.rb +67 -0
  101. data/lib/kontena/cli/master/config/set_command.rb +19 -0
  102. data/lib/kontena/cli/master/config/unset_command.rb +20 -0
  103. data/lib/kontena/cli/master/config_command.rb +17 -0
  104. data/lib/kontena/cli/master/create_command.rb +74 -0
  105. data/lib/kontena/cli/master/current_command.rb +25 -0
  106. data/lib/kontena/cli/master/init_cloud_command.rb +45 -0
  107. data/lib/kontena/cli/master/join_command.rb +22 -0
  108. data/lib/kontena/cli/master/list_command.rb +24 -0
  109. data/lib/kontena/cli/master/login_command.rb +331 -0
  110. data/lib/kontena/cli/master/logout_command.rb +25 -0
  111. data/lib/kontena/cli/master/remove_command.rb +55 -0
  112. data/lib/kontena/cli/master/ssh_command.rb +72 -0
  113. data/lib/kontena/cli/master/token/common.rb +29 -0
  114. data/lib/kontena/cli/master/token/create_command.rb +50 -0
  115. data/lib/kontena/cli/master/token/current_command.rb +45 -0
  116. data/lib/kontena/cli/master/token/list_command.rb +39 -0
  117. data/lib/kontena/cli/master/token/remove_command.rb +19 -0
  118. data/lib/kontena/cli/master/token/show_command.rb +34 -0
  119. data/lib/kontena/cli/master/token_command.rb +13 -0
  120. data/lib/kontena/cli/master/use_command.rb +31 -0
  121. data/lib/kontena/cli/master/user/invite_command.rb +51 -0
  122. data/lib/kontena/cli/master/user/list_command.rb +29 -0
  123. data/lib/kontena/cli/master/user/remove_command.rb +24 -0
  124. data/lib/kontena/cli/master/user/role/add_command.rb +29 -0
  125. data/lib/kontena/cli/master/user/role/remove_command.rb +27 -0
  126. data/lib/kontena/cli/master/user/role_command.rb +6 -0
  127. data/lib/kontena/cli/master/user_command.rb +9 -0
  128. data/lib/kontena/cli/master_command.rb +21 -0
  129. data/lib/kontena/cli/node_command.rb +17 -0
  130. data/lib/kontena/cli/nodes/create_command.rb +25 -0
  131. data/lib/kontena/cli/nodes/env_command.rb +37 -0
  132. data/lib/kontena/cli/nodes/health_command.rb +47 -0
  133. data/lib/kontena/cli/nodes/label_command.rb +10 -0
  134. data/lib/kontena/cli/nodes/labels/add_command.rb +18 -0
  135. data/lib/kontena/cli/nodes/labels/list_command.rb +19 -0
  136. data/lib/kontena/cli/nodes/labels/remove_command.rb +32 -0
  137. data/lib/kontena/cli/nodes/list_command.rb +97 -0
  138. data/lib/kontena/cli/nodes/remove_command.rb +34 -0
  139. data/lib/kontena/cli/nodes/reset_token_command.rb +34 -0
  140. data/lib/kontena/cli/nodes/show_command.rb +56 -0
  141. data/lib/kontena/cli/nodes/ssh_command.rb +63 -0
  142. data/lib/kontena/cli/nodes/update_command.rb +31 -0
  143. data/lib/kontena/cli/plugin_command.rb +12 -0
  144. data/lib/kontena/cli/plugins/common.rb +8 -0
  145. data/lib/kontena/cli/plugins/install_command.rb +42 -0
  146. data/lib/kontena/cli/plugins/list_command.rb +31 -0
  147. data/lib/kontena/cli/plugins/search_command.rb +25 -0
  148. data/lib/kontena/cli/plugins/show_command.rb +17 -0
  149. data/lib/kontena/cli/plugins/uninstall_command.rb +31 -0
  150. data/lib/kontena/cli/plugins/upgrade_command.rb +60 -0
  151. data/lib/kontena/cli/registry/create_command.rb +151 -0
  152. data/lib/kontena/cli/registry/remove_command.rb +21 -0
  153. data/lib/kontena/cli/registry_command.rb +8 -0
  154. data/lib/kontena/cli/service_command.rb +28 -0
  155. data/lib/kontena/cli/services/container_command.rb +8 -0
  156. data/lib/kontena/cli/services/containers_command.rb +39 -0
  157. data/lib/kontena/cli/services/create_command.rb +105 -0
  158. data/lib/kontena/cli/services/deploy_command.rb +25 -0
  159. data/lib/kontena/cli/services/env_command.rb +9 -0
  160. data/lib/kontena/cli/services/envs/add_command.rb +21 -0
  161. data/lib/kontena/cli/services/envs/list_command.rb +22 -0
  162. data/lib/kontena/cli/services/envs/remove_command.rb +22 -0
  163. data/lib/kontena/cli/services/events_command.rb +36 -0
  164. data/lib/kontena/cli/services/exec_command.rb +107 -0
  165. data/lib/kontena/cli/services/link_command.rb +35 -0
  166. data/lib/kontena/cli/services/list_command.rb +66 -0
  167. data/lib/kontena/cli/services/logs_command.rb +33 -0
  168. data/lib/kontena/cli/services/monitor_command.rb +58 -0
  169. data/lib/kontena/cli/services/remove_command.rb +60 -0
  170. data/lib/kontena/cli/services/restart_command.rb +19 -0
  171. data/lib/kontena/cli/services/scale_command.rb +21 -0
  172. data/lib/kontena/cli/services/secret_command.rb +8 -0
  173. data/lib/kontena/cli/services/secrets/link_command.rb +26 -0
  174. data/lib/kontena/cli/services/secrets/unlink_command.rb +28 -0
  175. data/lib/kontena/cli/services/services_helper.rb +579 -0
  176. data/lib/kontena/cli/services/show_command.rb +26 -0
  177. data/lib/kontena/cli/services/start_command.rb +21 -0
  178. data/lib/kontena/cli/services/stats_command.rb +87 -0
  179. data/lib/kontena/cli/services/stop_command.rb +21 -0
  180. data/lib/kontena/cli/services/unlink_command.rb +30 -0
  181. data/lib/kontena/cli/services/update_command.rb +94 -0
  182. data/lib/kontena/cli/spinner.rb +205 -0
  183. data/lib/kontena/cli/stack_command.rb +21 -0
  184. data/lib/kontena/cli/stacks/build_command.rb +125 -0
  185. data/lib/kontena/cli/stacks/common.rb +209 -0
  186. data/lib/kontena/cli/stacks/deploy_command.rb +37 -0
  187. data/lib/kontena/cli/stacks/events_command.rb +33 -0
  188. data/lib/kontena/cli/stacks/inspect_command.rb +17 -0
  189. data/lib/kontena/cli/stacks/install_command.rb +95 -0
  190. data/lib/kontena/cli/stacks/label_command.rb +10 -0
  191. data/lib/kontena/cli/stacks/labels/add_command.rb +21 -0
  192. data/lib/kontena/cli/stacks/labels/common.rb +19 -0
  193. data/lib/kontena/cli/stacks/labels/list_command.rb +21 -0
  194. data/lib/kontena/cli/stacks/labels/remove_command.rb +21 -0
  195. data/lib/kontena/cli/stacks/list_command.rb +154 -0
  196. data/lib/kontena/cli/stacks/logs_command.rb +35 -0
  197. data/lib/kontena/cli/stacks/monitor_command.rb +93 -0
  198. data/lib/kontena/cli/stacks/registry/create_command.rb +24 -0
  199. data/lib/kontena/cli/stacks/registry/make_private_command.rb +24 -0
  200. data/lib/kontena/cli/stacks/registry/make_public_command.rb +24 -0
  201. data/lib/kontena/cli/stacks/registry/pull_command.rb +28 -0
  202. data/lib/kontena/cli/stacks/registry/push_command.rb +40 -0
  203. data/lib/kontena/cli/stacks/registry/remove_command.rb +30 -0
  204. data/lib/kontena/cli/stacks/registry/search_command.rb +42 -0
  205. data/lib/kontena/cli/stacks/registry/show_command.rb +65 -0
  206. data/lib/kontena/cli/stacks/registry_command.rb +12 -0
  207. data/lib/kontena/cli/stacks/remove_command.rb +80 -0
  208. data/lib/kontena/cli/stacks/restart_command.rb +24 -0
  209. data/lib/kontena/cli/stacks/service_generator.rb +131 -0
  210. data/lib/kontena/cli/stacks/service_generator_v2.rb +27 -0
  211. data/lib/kontena/cli/stacks/show_command.rb +168 -0
  212. data/lib/kontena/cli/stacks/stack_name.rb +71 -0
  213. data/lib/kontena/cli/stacks/stacks_helper.rb +83 -0
  214. data/lib/kontena/cli/stacks/stop_command.rb +24 -0
  215. data/lib/kontena/cli/stacks/upgrade_command.rb +264 -0
  216. data/lib/kontena/cli/stacks/validate_command.rb +75 -0
  217. data/lib/kontena/cli/stacks/yaml/custom_validators/affinities_validator.rb +19 -0
  218. data/lib/kontena/cli/stacks/yaml/custom_validators/build_validator.rb +22 -0
  219. data/lib/kontena/cli/stacks/yaml/custom_validators/certificates_validator.rb +22 -0
  220. data/lib/kontena/cli/stacks/yaml/custom_validators/extends_validator.rb +22 -0
  221. data/lib/kontena/cli/stacks/yaml/custom_validators/hooks_validator.rb +102 -0
  222. data/lib/kontena/cli/stacks/yaml/custom_validators/secrets_validator.rb +22 -0
  223. data/lib/kontena/cli/stacks/yaml/opto/certificates_resolver.rb +37 -0
  224. data/lib/kontena/cli/stacks/yaml/opto/prompt_resolver.rb +78 -0
  225. data/lib/kontena/cli/stacks/yaml/opto/service_instances_resolver.rb +25 -0
  226. data/lib/kontena/cli/stacks/yaml/opto/service_link_resolver.rb +80 -0
  227. data/lib/kontena/cli/stacks/yaml/opto/vault_cert_prompt_resolver.rb +39 -0
  228. data/lib/kontena/cli/stacks/yaml/opto/vault_resolver.rb +13 -0
  229. data/lib/kontena/cli/stacks/yaml/opto/vault_setter.rb +12 -0
  230. data/lib/kontena/cli/stacks/yaml/opto.rb +16 -0
  231. data/lib/kontena/cli/stacks/yaml/reader.rb +525 -0
  232. data/lib/kontena/cli/stacks/yaml/service_extender.rb +65 -0
  233. data/lib/kontena/cli/stacks/yaml/stack_file_loader/file_loader.rb +41 -0
  234. data/lib/kontena/cli/stacks/yaml/stack_file_loader/registry_loader.rb +24 -0
  235. data/lib/kontena/cli/stacks/yaml/stack_file_loader/uri_loader.rb +23 -0
  236. data/lib/kontena/cli/stacks/yaml/stack_file_loader.rb +152 -0
  237. data/lib/kontena/cli/stacks/yaml/validations.rb +119 -0
  238. data/lib/kontena/cli/stacks/yaml/validator_v3.rb +164 -0
  239. data/lib/kontena/cli/subcommand_loader.rb +83 -0
  240. data/lib/kontena/cli/table_generator.rb +128 -0
  241. data/lib/kontena/cli/vault/export_command.rb +24 -0
  242. data/lib/kontena/cli/vault/import_command.rb +75 -0
  243. data/lib/kontena/cli/vault/list_command.rb +37 -0
  244. data/lib/kontena/cli/vault/read_command.rb +27 -0
  245. data/lib/kontena/cli/vault/remove_command.rb +23 -0
  246. data/lib/kontena/cli/vault/update_command.rb +24 -0
  247. data/lib/kontena/cli/vault/write_command.rb +23 -0
  248. data/lib/kontena/cli/vault_command.rb +13 -0
  249. data/lib/kontena/cli/version.rb +10 -0
  250. data/lib/kontena/cli/version_command.rb +20 -0
  251. data/lib/kontena/cli/volume_command.rb +9 -0
  252. data/lib/kontena/cli/volumes/create_command.rb +42 -0
  253. data/lib/kontena/cli/volumes/list_command.rb +29 -0
  254. data/lib/kontena/cli/volumes/remove_command.rb +29 -0
  255. data/lib/kontena/cli/volumes/show_command.rb +38 -0
  256. data/lib/kontena/cli/vpn/config_command.rb +27 -0
  257. data/lib/kontena/cli/vpn/create_command.rb +99 -0
  258. data/lib/kontena/cli/vpn/remove_command.rb +22 -0
  259. data/lib/kontena/cli/vpn_command.rb +9 -0
  260. data/lib/kontena/cli/whoami_command.rb +38 -0
  261. data/lib/kontena/client.rb +574 -0
  262. data/lib/kontena/command.rb +251 -0
  263. data/lib/kontena/debug_instrumentor.rb +80 -0
  264. data/lib/kontena/errors.rb +50 -0
  265. data/lib/kontena/light_prompt.rb +103 -0
  266. data/lib/kontena/machine/cert_helper.rb +43 -0
  267. data/lib/kontena/machine/cloud_config/cloudinit.yml +82 -0
  268. data/lib/kontena/machine/cloud_config/node_generator.rb +28 -0
  269. data/lib/kontena/machine/common.rb +17 -0
  270. data/lib/kontena/machine/random_name.rb +42 -0
  271. data/lib/kontena/main_command.rb +66 -0
  272. data/lib/kontena/plugin_manager/cleaner.rb +33 -0
  273. data/lib/kontena/plugin_manager/common.rb +89 -0
  274. data/lib/kontena/plugin_manager/installer.rb +78 -0
  275. data/lib/kontena/plugin_manager/loader.rb +93 -0
  276. data/lib/kontena/plugin_manager/rubygems_client.rb +59 -0
  277. data/lib/kontena/plugin_manager/uninstaller.rb +34 -0
  278. data/lib/kontena/plugin_manager.rb +26 -0
  279. data/lib/kontena/presets/github_auth_provider.yml +11 -0
  280. data/lib/kontena/presets/kontena_auth_provider.yml +11 -0
  281. data/lib/kontena/scripts/completer +9 -0
  282. data/lib/kontena/scripts/completer.rb +334 -0
  283. data/lib/kontena/scripts/init +18 -0
  284. data/lib/kontena/scripts/kontena.zsh +11 -0
  285. data/lib/kontena/scripts/krates.bash +8 -0
  286. data/lib/kontena/stacks/change_resolver.rb +118 -0
  287. data/lib/kontena/stacks/stack_data.rb +58 -0
  288. data/lib/kontena/stacks/stack_data_set.rb +51 -0
  289. data/lib/kontena/stacks_cache.rb +110 -0
  290. data/lib/kontena/stacks_client.rb +177 -0
  291. data/lib/kontena/util.rb +116 -0
  292. data/lib/kontena_cli.rb +190 -0
  293. metadata +518 -0
@@ -0,0 +1,87 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class StatsCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include ServicesHelper
8
+
9
+ MEM_MAX_LIMITS = [
10
+ 2**64,
11
+ 2**63 - 4096
12
+ ]
13
+
14
+ parameter "NAME", "Service name"
15
+ option ["-t", "--tail"], :flag, "Tail (follow) stats in real time", default: false
16
+
17
+ def execute
18
+ require_api_url
19
+ token = require_token
20
+ if tail?
21
+ system('clear')
22
+ render_header
23
+ end
24
+ loop do
25
+ fetch_stats(token, name, tail?)
26
+ break unless tail?
27
+ sleep(2)
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def fetch_stats(token, service_id, follow)
34
+ result = client(token).get("services/#{parse_service_id(service_id)}/stats")
35
+ system('clear') if follow
36
+ render_header
37
+ result['stats'].each do |stat|
38
+ render_stat_row(stat)
39
+ end
40
+ end
41
+
42
+ def render_header
43
+ puts '%-30.30s %-15s %-20s %-15s %-15s' % ['INSTANCE', 'CPU %', 'MEM USAGE/LIMIT', 'MEM %', 'NET I/O']
44
+ end
45
+
46
+ def render_stat_row(stat)
47
+ memory = stat['memory'].nil? ? 'N/A' : filesize_to_human(stat['memory']['usage'])
48
+ if !stat['memory'].nil? && (stat['memory']['limit'] && !MEM_MAX_LIMITS.include?(stat['memory']['limit']))
49
+ memory_limit = filesize_to_human(stat['memory']['limit'])
50
+ memory_pct = "#{(stat['memory']['usage'].to_f / stat['memory']['limit'].to_f * 100).round(2)}%"
51
+ else
52
+ memory_limit = 'N/A'
53
+ memory_pct = 'N/A'
54
+ end
55
+
56
+ cpu = stat['cpu'].nil? ? 'N/A' : stat['cpu']['usage']
57
+
58
+ network_in = stat['network'].nil? ? 'N/A' : filesize_to_human(network_bytes(stat['network'], 'rx_bytes'))
59
+ network_out = stat['network'].nil? ? 'N/A' : filesize_to_human(network_bytes(stat['network'], 'tx_bytes'))
60
+
61
+ prefix = self.name.split('/')[0]
62
+ instance_name = stat['container_id'].gsub("#{prefix}-", "")
63
+ puts '%-30.30s %-15s %-20s %-15s %-15s' % [ instance_name, "#{cpu}%", "#{memory} / #{memory_limit}", "#{memory_pct}", "#{network_in}/#{network_out}"]
64
+ end
65
+
66
+ ##
67
+ # @param [Integer] size
68
+ # @return [String]
69
+ def filesize_to_human(size)
70
+ return '0B' if size.to_f == 0.0
71
+ units = %w{B K M G T}
72
+ e = (Math.log(size) / Math.log(1000)).floor
73
+ s = '%.2f' % (size.to_f / 1000**e)
74
+ s.sub(/\.?0*$/, units[e])
75
+ rescue FloatDomainError
76
+ 'N/A'
77
+ end
78
+
79
+ ##
80
+ # @param [Hash] network
81
+ # @param [String] key
82
+ # @return [Integer]
83
+ def network_bytes(network, key)
84
+ (network.dig('internal', key) || 0) + (network.dig('external', key) || 0)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class StopCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include ServicesHelper
8
+
9
+ parameter "NAME ...", "Service name", attribute_name: :names
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ names.each do |name|
15
+ spinner "Sending stop signal to #{pastel.cyan(name)} service " do
16
+ stop_service(token, name)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class UnlinkCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include ServicesHelper
8
+
9
+ parameter "NAME", "Service name"
10
+ parameter "TARGET", "Link target service name"
11
+
12
+ def execute
13
+ require_api_url
14
+ token = require_token
15
+ target_service = target
16
+ target_service = "null/#{target_service}" unless target_service.include?('/')
17
+ target_id = "#{current_grid}/#{target_service}"
18
+ service = client(token).get("services/#{parse_service_id(name)}")
19
+ links = service['links']
20
+ unless links.find { |l| l['id'] == target_id }
21
+ exit_with_error("Service is not linked to #{target.to_s}")
22
+ end
23
+ links.delete_if { |l| l['id'] == target_id }
24
+ data = {links: links}
25
+ spinner "Unlinking #{pastel.cyan(name)} from #{pastel.cyan(target)} " do
26
+ update_service(token, name, data)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,94 @@
1
+ require_relative 'services_helper'
2
+ require 'shellwords'
3
+
4
+ module Kontena::Cli::Services
5
+ class UpdateCommand < Kontena::Command
6
+ include Kontena::Cli::Common
7
+ include Kontena::Cli::GridOptions
8
+ include ServicesHelper
9
+
10
+ parameter "NAME", "Service name"
11
+
12
+ option "--image", "IMAGE", "Docker image to use"
13
+ option ["-p", "--ports"], "PORT", "Publish a service's port to the host", multivalued: true
14
+ option ["-e", "--env"], "ENV", "Set environment variables", multivalued: true
15
+ option ["-l", "--link"], "LINK", "Add link to another service in the form of name:alias", multivalued: true
16
+ option ["-a", "--affinity"], "AFFINITY", "Set service affinity", multivalued: true
17
+ option "--cpus", "CPUS", "Number of CPUs" do |cpus|
18
+ Float(cpus)
19
+ end
20
+ option ["-c", "--cpu-shares"], "CPU_SHARES", "CPU shares (relative weight)"
21
+ option ["-m", "--memory"], "MEMORY", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)"
22
+ option ["--memory-swap"], "MEMORY_SWAP", "Total memory usage (memory + swap), set \'-1\' to disable swap (format: <number><optional unit>, where unit = b, k, m or g)"
23
+ option ["--shm-size"], "SHM_SIZE", "Size of /dev/shm (format: <number><optional unit>, where unit = b, k, m or g)"
24
+ option "--cmd", "CMD", "Command to execute"
25
+ option "--instances", "INSTANCES", "How many instances should be deployed"
26
+ option ["-u", "--user"], "USER", "Username who executes first process inside container"
27
+ option "--privileged", :flag, "Give extended privileges to this service", default: false
28
+ option "--cap-add", "CAP_ADD", "Add capabitilies", multivalued: true, default: nil
29
+ option "--cap-drop", "CAP_DROP", "Drop capabitilies", multivalued: true, default: nil
30
+ option "--net", "NET", "Network mode"
31
+ option "--log-driver", "LOG_DRIVER", "Set logging driver"
32
+ option "--log-opt", "LOG_OPT", "Add logging options", multivalued: true, default: nil
33
+ option "--deploy-strategy", "STRATEGY", "Deploy strategy to use (ha, daemon, random)"
34
+ option "--deploy-wait-for-port", "PORT", "Wait for port to respond when deploying"
35
+ option "--deploy-min-health", "FLOAT", "The minimum percentage (0.0 - 1.0) of healthy instances that do not sacrifice overall service availability while deploying"
36
+ option "--deploy-interval", "TIME", "Auto-deploy with given interval (format: <number><unit>, where unit = min, h, d)"
37
+ option "--pid", "PID", "Pid namespace to use"
38
+ option "--secret", "SECRET", "Import secret from Vault (format: <secret>:<name>:<type>)", multivalued: true
39
+ option "--health-check-uri", "URI", "URI path for HTTP health check"
40
+ option "--health-check-timeout", "TIMEOUT", "Timeout for HTTP health check"
41
+ option "--health-check-interval", "INTERVAL", "Interval for HTTP health check"
42
+ option "--health-check-initial-delay", "DELAY", "Initial for HTTP health check"
43
+ option "--health-check-port", "PORT", "Port for HTTP health check"
44
+ option "--health-check-protocol", "PROTOCOL", "Protocol of health check"
45
+ option "--stop-signal", "STOP_SIGNAL", "Alternative signal to stop container"
46
+ option "--stop-timeout", "STOP_TIMEOUT", "Timeout (duration) to stop a container"
47
+
48
+ def execute
49
+ require_api_url
50
+ token = require_token
51
+
52
+ data = parse_service_data_from_options
53
+ spinner "Updating #{pastel.cyan(name)} service " do
54
+ update_service(token, name, data)
55
+ end
56
+ end
57
+
58
+ ##
59
+ # parse given options to hash
60
+ # @return [Hash]
61
+ def parse_service_data_from_options
62
+ data = {}
63
+ data[:strategy] = deploy_strategy if deploy_strategy
64
+ data[:ports] = parse_ports(ports_list) unless ports_list.empty?
65
+ data[:links] = parse_links(link_list) unless link_list.empty?
66
+ data[:memory] = parse_memory(memory) if memory
67
+ data[:memory_swap] = parse_memory(memory_swap) if memory_swap
68
+ data[:shm_size] = parse_memory(shm_size) if shm_size
69
+ data[:cpus] = cpus if cpus
70
+ data[:cpu_shares] = cpu_shares if cpu_shares
71
+ data[:affinity] = affinity_list unless affinity_list.empty?
72
+ data[:env] = env_list unless env_list.empty?
73
+ data[:secrets] = parse_secrets(secret_list) unless secret_list.empty?
74
+ data[:container_count] = instances if instances
75
+ data[:cmd] = Shellwords.split(cmd) if cmd
76
+ data[:user] = user if user
77
+ data[:image] = parse_image(image) if image
78
+ data[:privileged] = privileged?
79
+ data[:cap_add] = cap_add_list if cap_add_list
80
+ data[:cap_drop] = cap_drop_list if cap_drop_list
81
+ data[:net] = net if net
82
+ data[:log_driver] = log_driver if log_driver
83
+ data[:log_opts] = parse_log_opts(log_opt_list) if log_opt_list
84
+ deploy_opts = parse_deploy_opts
85
+ data[:deploy_opts] = deploy_opts unless deploy_opts.empty?
86
+ health_check = parse_health_check
87
+ data[:health_check] = health_check unless health_check.empty?
88
+ data[:pid] = pid if pid
89
+ data[:stop_signal] = stop_signal if stop_signal
90
+ data[:stop_grace_period] = stop_timeout if stop_timeout
91
+ data
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,205 @@
1
+ module Kontena
2
+ module Cli
3
+ SpinAbort = Class.new(StandardError)
4
+
5
+ class SpinnerStatus
6
+ attr_reader :thread, :result
7
+
8
+ def initialize(thread)
9
+ @thread = thread
10
+ @result = :done
11
+ end
12
+
13
+ def set_title(message)
14
+ if $stdout.tty?
15
+ thread['update_msg'] = message
16
+ else
17
+ Kernel.puts "- #{message}"
18
+ end
19
+ end
20
+
21
+ def warn?
22
+ @result == :warn
23
+ end
24
+
25
+ def failed?
26
+ @result == :fail
27
+ end
28
+
29
+ def fail
30
+ @result = :fail
31
+ end
32
+
33
+ def fail!
34
+ @result = :fail
35
+ thread['abort'] = true
36
+ raise SpinAbort
37
+ end
38
+
39
+ def warn
40
+ @result = :warn
41
+ end
42
+ end
43
+
44
+ class Spinner
45
+ CHARS = ['\\', '|', '/', '-']
46
+ CHARS_LENGTH = CHARS.length
47
+
48
+ def self.spin_no_tty(msg, &block)
49
+ unless block_given?
50
+ Kernel.puts "\r [" + Kontena.pastel.green("done") + "] #{msg}"
51
+ return
52
+ end
53
+
54
+ Kernel.puts "* #{msg}.. "
55
+ result = nil
56
+ status = nil
57
+ begin
58
+ spin_status = SpinnerStatus.new(Thread.current)
59
+ result = yield spin_status
60
+ Kernel.puts "* #{msg}.. #{spin_status.result}"
61
+ rescue SpinAbort
62
+ Kernel.puts "* #{msg}.. fail"
63
+ rescue SystemExit => ex
64
+ status = ex.status
65
+ if status == 0
66
+ Kernel.puts "* #{msg}.. done"
67
+ else
68
+ Kernel.puts "* #{msg}.. fail"
69
+ end
70
+ rescue Exception => ex
71
+ Kernel.puts "* #{msg}.. fail"
72
+ Kontena.logger.error(ex)
73
+ raise ex
74
+ end
75
+ exit(status) if status
76
+ result
77
+ end
78
+
79
+ def self.spin(msg, &block)
80
+ return spin_no_tty(msg, &block) unless $stdout.tty?
81
+
82
+ unless block_given?
83
+ Kernel.puts "\r [" + Kontena.pastel.green("done") + "] #{msg}"
84
+ return
85
+ end
86
+
87
+ Thread.main['spinners'] ||= []
88
+ unless Thread.main['spinners'].empty?
89
+ Thread.main['spinners'].each do |thread|
90
+ thread['pause'] = true
91
+ end
92
+ Kernel.puts "\r [#{Kontena.pastel.yellow('....')}] #{Thread.main['spinners'].last['msg']}"
93
+ end
94
+
95
+ Thread.main['spinner_msgs'] = []
96
+ spin_thread = Thread.new do
97
+ Thread.current['msg'] = msg
98
+ message = " * #{msg} .. "
99
+ Kernel.print(message + CHARS.first)
100
+ curr_index = 0
101
+ loop do
102
+ if Thread.current['pause']
103
+ until !Thread.current['pause'] || Thread.current['abort']
104
+ sleep 0.1
105
+ end
106
+ Kernel.print "\r#{message}#{CHARS[curr_index]}"
107
+ end
108
+
109
+ if Thread.current['update_msg']
110
+ msg = Thread.current['update_msg']
111
+ Thread.current['update_msg'] = nil
112
+ Thread.current['msg'] = msg
113
+ message = " * #{msg} .. "
114
+ Kernel.print "\r#{message}#{CHARS[curr_index]}"
115
+ end
116
+
117
+ break if Thread.current['abort']
118
+
119
+ if Thread.main['spinner_msgs']
120
+ Kernel.print "\r#{' ' * (message.gsub(/\e.+?m/, '').length + 1)}\r"
121
+ while Thread.main['spinner_msgs'].size > 0
122
+ Kernel.puts "\r#{Thread.main['spinner_msgs'].shift}"
123
+ end
124
+ Kernel.print "\r#{message + CHARS[curr_index]}"
125
+ end
126
+ sleep 0.1
127
+ Kernel.print "\b#{CHARS[curr_index]}"
128
+ curr_index = curr_index == CHARS_LENGTH - 1 ? 0 : curr_index + 1
129
+ end
130
+ end
131
+
132
+ Thread.main['spinners'] << spin_thread
133
+
134
+ status = nil
135
+ result = nil
136
+ begin
137
+ spin_status = SpinnerStatus.new(spin_thread)
138
+ result = yield spin_status
139
+ spin_thread.kill
140
+ case spin_status.result
141
+ when :warn
142
+ Kernel.puts "\r [" + Kontena.pastel.yellow("warn") + "] #{msg} "
143
+ when :fail
144
+ Kernel.puts "\r [" + Kontena.pastel.red("fail") + "] #{msg} "
145
+ else
146
+ Kernel.puts "\r [" + Kontena.pastel.green("done") + "] #{msg} "
147
+ end
148
+ rescue SystemExit => ex
149
+ spin_thread.kill
150
+ if ex.status == 0
151
+ Kernel.puts "\r [" + Kontena.pastel.green("done") + "] #{msg} "
152
+ else
153
+ Kernel.puts "\r [" + Kontena.pastel.red("fail") + "] #{msg} "
154
+ end
155
+ status = ex.status
156
+ rescue SpinAbort
157
+ spin_thread.kill
158
+ Kernel.puts "\r [" + Kontena.pastel.red("fail") + "] #{msg} "
159
+ Kontena.logger.debug { "Spin aborted through fail!" }
160
+ rescue Exception => ex
161
+ spin_thread.kill
162
+ Kernel.puts "\r [" + Kontena.pastel.red("fail") + "] #{msg} "
163
+ Kontena.logger.error(ex)
164
+ raise ex
165
+ ensure
166
+ unless Thread.main['spinner_msgs'].empty?
167
+ while msg = Thread.main['spinner_msgs'].shift
168
+ Kernel.puts msg
169
+ end
170
+ end
171
+ Thread.main['spinners'].delete(spin_thread)
172
+ end
173
+
174
+ exit(status) if status
175
+ Thread.main['spinners'].pop
176
+ unless Thread.main['spinners'].empty?
177
+ Thread.main['spinners'].last['pause'] = false
178
+ end
179
+ result
180
+ end
181
+ end
182
+
183
+ module ShellSpinner
184
+ def spinner(msg = "", &block)
185
+ Kontena::Cli::Spinner.spin(msg, &block)
186
+ end
187
+
188
+ def puts(*msgs)
189
+ if Thread.main['spinners'] && !Thread.main['spinners'].empty?
190
+ msgs.each { |msg| Thread.main['spinner_msgs'] << msg }
191
+ else
192
+ super(*msgs)
193
+ end
194
+ end
195
+
196
+ def print(*msgs)
197
+ if Thread.main['spinners'] && !Thread.main['spinners'].empty?
198
+ Thread.main['spinner_msgs'] << msgs.join
199
+ else
200
+ super(*msgs)
201
+ end
202
+ end
203
+ end
204
+ end
205
+ end
@@ -0,0 +1,21 @@
1
+ class Kontena::Cli::StackCommand < Kontena::Command
2
+ subcommand "install", "Install a stack to a grid", load_subcommand('stacks/install_command')
3
+ subcommand ["ls", "list"], "List installed stacks in a grid", load_subcommand('stacks/list_command')
4
+ subcommand ["remove","rm"], "Remove a deployed stack from a grid", load_subcommand('stacks/remove_command')
5
+ subcommand "show", "Show details about a stack in a grid", load_subcommand('stacks/show_command')
6
+ subcommand "inspect", "Show the Stack YAML of an installed stack", load_subcommand('stacks/inspect_command')
7
+ subcommand "upgrade", "Upgrade a stack in a grid", load_subcommand('stacks/upgrade_command')
8
+ subcommand ["start", "deploy"], "Deploy an installed stack in a grid", load_subcommand('stacks/deploy_command')
9
+ subcommand "logs", "Show logs from services in a stack", load_subcommand('stacks/logs_command')
10
+ subcommand "events", "Show events from services in a stack", load_subcommand('stacks/events_command')
11
+ subcommand "monitor", "Monitor services in a stack", load_subcommand('stacks/monitor_command')
12
+ subcommand "build", "Build images listed in a stack file and push them to an image registry", load_subcommand('stacks/build_command')
13
+ subcommand ["reg", "registry"], "Stack registry related commands", load_subcommand('stacks/registry_command')
14
+ subcommand "validate", "Process and validate a stack file", load_subcommand('stacks/validate_command')
15
+ subcommand "stop", "Stop stacks services", load_subcommand('stacks/stop_command')
16
+ subcommand "restart", "Restart stacks services", load_subcommand('stacks/restart_command')
17
+ subcommand "label", "Stack label related commands", load_subcommand('stacks/label_command')
18
+
19
+ def execute
20
+ end
21
+ end
@@ -0,0 +1,125 @@
1
+ require_relative 'common'
2
+ require 'shellwords'
3
+
4
+ module Kontena::Cli::Stacks
5
+ class BuildCommand < Kontena::Command
6
+ include Kontena::Cli::Common
7
+ include Common
8
+
9
+ banner "Build images listed in a stack file and push them to your image registry"
10
+
11
+ option ['-f', '--file'], 'FILE', 'Specify an alternate Kontena compose file', attribute_name: :source, default: 'kontena.yml'
12
+
13
+ option ['--no-cache'], :flag, 'Do not use cache when building the image', default: false
14
+ option ['--no-push'], :flag, 'Do not push images to registry', default: false
15
+ option ['--no-pull'], :flag, 'Do not attempt to pull a newer version of the image', default: false
16
+ option ['--[no-]sudo'], :flag, 'Run docker using sudo', hidden: Kontena.on_windows?, environment_variable: 'KONTENA_SUDO', default: false
17
+
18
+ option ['-n', '--name'], 'NAME', 'Define stack name (by default comes from stack file)'
19
+
20
+ include Common::StackValuesToOption
21
+ include Common::StackValuesFromOption
22
+
23
+ parameter "[SERVICE] ...", "Services to build"
24
+
25
+ requires_current_master # the stack may use a vault resolver
26
+ requires_current_master_token
27
+
28
+ def execute
29
+ set_env_variables(stack_name, current_grid)
30
+ stack # runs validations
31
+
32
+ services = stack['services']
33
+
34
+ unless service_list.empty?
35
+ services.select! { |service| service_list.include?(service['name']) }
36
+ end
37
+
38
+ if services.none?{ |service| service['build'] }
39
+ abort pastel.red("Didn't find any services to build")
40
+ end
41
+ build_docker_images(services)
42
+ push_docker_images(services) unless no_push?
43
+ end
44
+
45
+ # @param [Hash] services
46
+ def build_docker_images(services)
47
+ services.each do |service|
48
+ if service['build']
49
+ dockerfile = service['build']['dockerfile'] || 'Dockerfile'
50
+ abort("'#{service['image']}' is not valid Docker image name") unless valid_image_name?(service['image'])
51
+ abort("'#{service['build']['context']}' does not have #{dockerfile}") unless dockerfile_exist?(service['build']['context'], dockerfile)
52
+ if service['hooks'] && service['hooks']['pre_build']
53
+ puts pastel.cyan("Running pre_build hook")
54
+ run_pre_build_hook(service['hooks']['pre_build'])
55
+ end
56
+ puts "Building image #{pastel.cyan(service['image'])}"
57
+ build_docker_image(service)
58
+ end
59
+ end
60
+ end
61
+
62
+ # @param [Hash] services
63
+ def push_docker_images(services)
64
+ services.each do |service|
65
+ if service['build']
66
+ puts "Pushing image #{pastel.cyan(service['image'])}"
67
+ push_docker_image(service['image'])
68
+ end
69
+ end
70
+ end
71
+
72
+ # @param [Hash] service
73
+ # @return [Integer]
74
+ def build_docker_image(service)
75
+ dockerfile = dockerfile = service['build']['dockerfile'] || 'Dockerfile'
76
+ build_context = service['build']['context']
77
+ cmd = ['docker', 'build', '-t', service['image']]
78
+ cmd << ['-f', File.join(File.expand_path(build_context), dockerfile)] if dockerfile != "Dockerfile"
79
+ cmd << '--no-cache' if no_cache?
80
+ cmd << '--pull' unless no_pull?
81
+ cmd.unshift('sudo') if sudo?
82
+
83
+ args = service['build']['args'] || {}
84
+ args.each do |k, v|
85
+ cmd << "--build-arg=#{k}=#{v}"
86
+ end
87
+ cmd << build_context
88
+ ret = system(*cmd.flatten)
89
+ raise ("Failed to build image #{pastel.cyan(service['image'])}") unless ret
90
+ ret
91
+ end
92
+
93
+ # @param [String] image
94
+ # @return [Integer]
95
+ def push_docker_image(image)
96
+ cmd = ['docker', 'push', image]
97
+ cmd.unshift('sudo') if sudo?
98
+ ret = system(*cmd)
99
+ raise ("Failed to push image #{pastel.cyan(image)}") unless ret
100
+ ret
101
+ end
102
+
103
+ # @param [String] name
104
+ # @return [Boolean]
105
+ def valid_image_name?(name)
106
+ !(/\A[\w.\/\-:]+:?+[\w+.]+\z/ =~ name).nil?
107
+ end
108
+
109
+ # @param [String] path
110
+ # @param [String] dockerfile
111
+ # @return [Boolean]
112
+ def dockerfile_exist?(path, dockerfile)
113
+ file = File.join(File.expand_path(path), dockerfile)
114
+ File.exist?(file)
115
+ end
116
+
117
+ # @param [Hash] hook
118
+ def run_pre_build_hook(hook)
119
+ hook.each do |h|
120
+ ret = system(h['cmd'])
121
+ raise ("Failed to run pre_build hook: #{h['name']}!") unless ret
122
+ end
123
+ end
124
+ end
125
+ end