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,105 @@
1
+ require_relative 'services_helper'
2
+ require 'shellwords'
3
+
4
+ module Kontena::Cli::Services
5
+ class CreateCommand < Kontena::Command
6
+ include Kontena::Cli::Common
7
+ include Kontena::Cli::GridOptions
8
+ include ServicesHelper
9
+
10
+ parameter "NAME", "Service name"
11
+ parameter "IMAGE", "Service image (example: redis:3.0)"
12
+
13
+ option ["-p", "--ports"], "PORTS", "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 ["-v", "--volume"], "VOLUME", "Add a volume or bind mount it from the host", multivalued: true
17
+ option "--volumes-from", "VOLUMES_FROM", "Mount volumes from another container", multivalued: true
18
+ option ["-a", "--affinity"], "AFFINITY", "Set service affinity", multivalued: true
19
+ option "--cpus", "CPUS", "Number of CPUs" do |cpus|
20
+ Float(cpus)
21
+ end
22
+ option ["-c", "--cpu-shares"], "CPU_SHARES", "CPU shares (relative weight)"
23
+ option ["-m", "--memory"], "MEMORY", "Memory limit (format: <number><optional unit>, where unit = b, k, m or g)"
24
+ 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)"
25
+ option ["--shm-size"], "SHM_SIZE", "Size of /dev/shm (format: <number><optional unit>, where unit = b, k, m or g)"
26
+ option "--cmd", "CMD", "Command to execute"
27
+ option "--instances", "INSTANCES", "How many instances should be deployed"
28
+ option ["-u", "--user"], "USER", "Username who executes first process inside container"
29
+ option "--stateful", :flag, "Set service as stateful", default: false
30
+ option "--privileged", :flag, "Give extended privileges to this service", default: false
31
+ option "--cap-add", "CAP_ADD", "Add capabitilies", multivalued: true
32
+ option "--cap-drop", "CAP_DROP", "Drop capabitilies", multivalued: true
33
+ option "--net", "NET", "Network mode"
34
+ option "--log-driver", "LOG_DRIVER", "Set logging driver"
35
+ option "--log-opt", "LOG_OPT", "Add logging options", multivalued: true
36
+ option "--deploy-strategy", "STRATEGY", "Deploy strategy to use (ha, daemon, random)"
37
+ option "--deploy-wait-for-port", "PORT", "Wait for port to respond when deploying"
38
+ option "--deploy-min-health", "FLOAT", "The minimum percentage (0.0 - 1.0) of healthy instances that do not sacrifice overall service availability while deploying"
39
+ option "--deploy-interval", "TIME", "Auto-deploy with given interval (format: <number><unit>, where unit = min, h, d)"
40
+ option "--pid", "PID", "Pid namespace to use"
41
+ option "--secret", "SECRET", "Import secret from Vault (format: <secret>:<name>:<env>)", multivalued: true
42
+ option "--health-check-uri", "URI", "URI path for HTTP health check"
43
+ option "--health-check-timeout", "TIMEOUT", "Timeout for health check"
44
+ option "--health-check-interval", "INTERVAL", "Interval for health check"
45
+ option "--health-check-initial-delay", "DELAY", "Initial delay for health check"
46
+ option "--health-check-port", "PORT", "Port for health check"
47
+ option "--health-check-protocol", "PROTOCOL", "Protocol of health check"
48
+ option "--stop-signal", "STOP_SIGNAL", "Alternative signal to stop container"
49
+ option "--stop-timeout", "STOP_TIMEOUT", "Timeout (duration) to stop a container"
50
+ option "--read-only", :flag, "Read-only root fs for the container", default: false
51
+
52
+ def execute
53
+ require_api_url
54
+ token = require_token
55
+ data = {
56
+ name: name,
57
+ image: image,
58
+ stateful: stateful?
59
+ }
60
+ data.merge!(parse_service_data_from_options)
61
+ spinner "Creating #{pastel.cyan(name)} service " do
62
+ create_service(token, current_grid, data)
63
+ end
64
+ end
65
+
66
+ ##
67
+ # parse given options to hash
68
+ # @return [Hash]
69
+ def parse_service_data_from_options
70
+ data = {}
71
+ data[:ports] = parse_ports(ports_list) unless ports_list.empty?
72
+ data[:links] = parse_links(link_list) unless link_list.empty?
73
+ data[:volumes] = volume_list unless volume_list.empty?
74
+ data[:volumes_from] = volumes_from_list unless volumes_from_list.empty?
75
+ data[:memory] = parse_memory(memory) if memory
76
+ data[:memory_swap] = parse_memory(memory_swap) if memory_swap
77
+ data[:shm_size] = parse_memory(shm_size) if shm_size
78
+ data[:cpus] = cpus if cpus
79
+ data[:cpu_shares] = cpu_shares if cpu_shares
80
+ data[:affinity] = affinity_list unless affinity_list.empty?
81
+ data[:env] = env_list unless env_list.empty?
82
+ data[:secrets] = parse_secrets(secret_list)
83
+ data[:container_count] = instances if instances
84
+ data[:cmd] = Shellwords.split(cmd) if cmd
85
+ data[:user] = user if user
86
+ data[:image] = parse_image(image) if image
87
+ data[:privileged] = privileged?
88
+ data[:cap_add] = cap_add_list unless cap_add_list.empty?
89
+ data[:cap_drop] = cap_drop_list unless cap_drop_list.empty?
90
+ data[:net] = net if net
91
+ data[:log_driver] = log_driver if log_driver
92
+ data[:log_opts] = parse_log_opts(log_opt_list)
93
+ data[:strategy] = deploy_strategy if deploy_strategy
94
+ deploy_opts = parse_deploy_opts
95
+ data[:deploy_opts] = deploy_opts unless deploy_opts.empty?
96
+ health_check = parse_health_check
97
+ data[:health_check] = health_check unless health_check.empty?
98
+ data[:pid] = pid if pid
99
+ data[:stop_signal] = stop_signal if stop_signal
100
+ data[:stop_grace_period] = stop_timeout if stop_timeout
101
+ data[:read_only] = read_only?
102
+ data
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,25 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class DeployCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include ServicesHelper
8
+
9
+ parameter "NAME", "Service name"
10
+ option '--[no-]wait', :flag, 'Wait for service deployment to finish', default: true
11
+ option '--force', :flag, 'Force deploy even if service does not have any changes'
12
+
13
+ def execute
14
+ require_api_url
15
+ token = require_token
16
+ service_id = name
17
+ data = {}
18
+ data[:force] = true if force?
19
+ spinner "Deploying service #{pastel.cyan(name)} " do
20
+ deployment = deploy_service(token, name, data)
21
+ wait_for_deploy_to_finish(token, deployment) if wait?
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,9 @@
1
+ module Kontena::Cli::Services
2
+
3
+
4
+ class EnvCommand < Kontena::Command
5
+ subcommand ["list", "ls"], "List service environment variables", load_subcommand('services/envs/list_command')
6
+ subcommand "add", "Add environment variable", load_subcommand('services/envs/add_command')
7
+ subcommand ["remove", "rm"], "Remove environment variable", load_subcommand('services/envs/remove_command')
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ require_relative '../services_helper'
2
+
3
+ module Kontena::Cli::Services::Envs
4
+ class AddCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Kontena::Cli::Services::ServicesHelper
8
+
9
+ parameter "NAME", "Service name"
10
+ parameter "ENV", "Environment variable"
11
+
12
+ def execute
13
+ require_api_url
14
+ token = require_token
15
+ data = {env: env}
16
+ spinner "Adding env variable to #{pastel.cyan(name)} service " do
17
+ client(token).post("services/#{parse_service_id(name)}/envs", data)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../services_helper'
2
+
3
+ module Kontena::Cli::Services::Envs
4
+ class ListCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Kontena::Cli::Services::ServicesHelper
8
+ include Kontena::Cli::TableGenerator::Helper
9
+
10
+ parameter "NAME", "Service name"
11
+
12
+ requires_current_master
13
+ requires_current_master_token
14
+
15
+ def execute
16
+ service = client.get("services/#{parse_service_id(name)}")
17
+ service["env"].sort.each do |env|
18
+ puts quiet? ? env.split('=', 2).first : env
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../services_helper'
2
+
3
+ module Kontena::Cli::Services::Envs
4
+ class RemoveCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Kontena::Cli::Services::ServicesHelper
8
+
9
+ parameter "NAME", "Service name"
10
+ parameter "ENV ...", "Environment variable name", attribute_name: :envs
11
+
12
+ def execute
13
+ require_api_url
14
+ token = require_token
15
+ envs.each do |env|
16
+ spinner "Removing env variable #{pastel.cyan(env)} from #{pastel.cyan(name)} service " do
17
+ client(token).delete("services/#{parse_service_id(name)}/envs/#{env}")
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,36 @@
1
+ require_relative 'services_helper'
2
+ require_relative '../helpers/log_helper'
3
+
4
+ module Kontena::Cli::Services
5
+ class EventsCommand < Kontena::Command
6
+ include Kontena::Cli::Common
7
+ include Kontena::Cli::GridOptions
8
+ include Kontena::Cli::Helpers::LogHelper
9
+ include ServicesHelper
10
+
11
+ parameter "NAME", "Service name"
12
+
13
+ def execute
14
+ require_api_url
15
+
16
+ query_params = {}
17
+
18
+ titles = ['TIME', 'TYPE', 'MESSAGE']
19
+ puts "%-25s %-20s %s" % titles
20
+ show_logs("services/#{parse_service_id(name)}/event_logs", query_params) do |log|
21
+ show_log(log)
22
+ end
23
+ end
24
+
25
+ def show_log(log)
26
+ msg = log['message']
27
+ node = log['relationships'].find { |r| r['type'] == 'node' }
28
+ if node
29
+ msg = "#{msg} (#{node['id'].split('/')[-1]})"
30
+ end
31
+ puts '%-25s %-20s %s' % [
32
+ log['created_at'], log['type'].sub('service:'.freeze, ''.freeze), msg
33
+ ]
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,107 @@
1
+ require 'shellwords'
2
+ require 'json'
3
+ require_relative 'services_helper'
4
+ require_relative '../helpers/exec_helper'
5
+
6
+ module Kontena::Cli::Services
7
+ class ExecCommand < Kontena::Command
8
+ include Kontena::Cli::Common
9
+ include Kontena::Cli::GridOptions
10
+ include Kontena::Cli::Helpers::ExecHelper
11
+ include ServicesHelper
12
+
13
+ class ExecExit < StandardError
14
+ attr_reader :exit_status
15
+
16
+ def initialize(exit_status, message = nil)
17
+ super(message)
18
+ @exit_status = exit_status
19
+ end
20
+ end
21
+
22
+ usage "[OPTIONS] [NAME] -- [CMD] ..."
23
+
24
+ parameter "NAME", "Service name"
25
+ parameter "CMD ...", "Command"
26
+
27
+ option ["--instance"], "INSTANCE", "Exec on given numbered instance, default first running" do |value| Integer(value) end
28
+ option ["-a", "--all"], :flag, "Exec on all running instances"
29
+ option ["--shell"], :flag, "Execute as a shell command", default: false
30
+ option ["-i", "--interactive"], :flag, "Keep stdin open", default: false
31
+ option ["-t", "--tty"], :flag, "Allocate a pseudo-TTY", default: false
32
+ option ["--skip"], :flag, "Skip failed instances when executing --all"
33
+ option ["--silent"], :flag, "Do not show exec status"
34
+ option ["--verbose"], :flag, "Show exec status"
35
+
36
+ requires_current_master
37
+ requires_current_grid
38
+
39
+ def execute
40
+ exit_with_error "the input device is not a TTY" if tty? && !STDIN.tty?
41
+ exit_with_error "--interactive cannot be used with --all" if all? && interactive?
42
+
43
+ service_containers = client.get("services/#{parse_service_id(name)}/containers")['containers']
44
+ service_containers.sort_by! { |container| container['instance_number'] }
45
+ running_containers = service_containers.select{|container| container['status'] == 'running' }
46
+
47
+ exit_with_error "Service #{name} does not have any running containers" if running_containers.empty?
48
+
49
+ if all?
50
+ ret = true
51
+ service_containers.each do |container|
52
+ if container['status'] == 'running'
53
+ if !execute_container(container)
54
+ ret = false
55
+ end
56
+ else
57
+ warning "Service #{name} container #{container['name']} is #{container['status']}, skipping"
58
+ end
59
+ end
60
+ return ret
61
+ elsif instance
62
+ if !(container = service_containers.find{|c| c['instance_number'] == instance})
63
+ exit_with_error "Service #{name} does not have container instance #{instance}"
64
+ elsif container['status'] != 'running'
65
+ exit_with_error "Service #{name} container #{container['name']} is not running, it is #{container['status']}"
66
+ else
67
+ execute_container(container)
68
+ end
69
+ else
70
+ execute_container(running_containers.first)
71
+ end
72
+ end
73
+
74
+ # Run block with spinner by default if --all, or when using --verbose.
75
+ # Do not use spinner if --silent.
76
+ def maybe_spinner(msg, &block)
77
+ if (all? || verbose?) && !silent?
78
+ spinner(msg, &block)
79
+ else
80
+ yield
81
+ end
82
+ end
83
+
84
+ # @param [Hash] container
85
+ # @raise [SystemExit] if exec exits with non-zero status, and not --skip
86
+ # @return [true] exit exit status zero
87
+ # @return [false] exit exit status non-zero and --skip
88
+ def execute_container(container)
89
+ maybe_spinner "Executing command on #{container['name']}" do
90
+ exit_status = container_exec(container['id'], self.cmd_list,
91
+ interactive: interactive?,
92
+ shell: shell?,
93
+ tty: tty?,
94
+ )
95
+ raise ExecExit.new(exit_status) unless exit_status.zero?
96
+ end
97
+ rescue ExecExit => exc
98
+ if skip?
99
+ return false
100
+ else
101
+ exit exc.exit_status
102
+ end
103
+ else
104
+ return true
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class LinkCommand < 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
+
17
+ target_service = "null/#{target_service}" unless target_service.include?('/')
18
+
19
+ service = client(token).get("services/#{parse_service_id(name)}")
20
+ existing_targets = service['links'].map{ |l| l['id'].split('/', 2)[1] }
21
+ if existing_targets.include?(target_service.to_s)
22
+ exit_with_error("Service is already linked to #{target.to_s}")
23
+ end
24
+ links = service['links'].map{ |l|
25
+ { name: l['id'].split('/', 2)[1], alias: l['alias'] }
26
+ }
27
+ links << {name: target_service.to_s, alias: target.to_s}
28
+ links.compact!
29
+ data = {links: links}
30
+ spinner "Linking #{pastel.cyan(name)} to #{pastel.cyan(target)} " do
31
+ update_service(token, name, data)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,66 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class ListCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include Kontena::Cli::TableGenerator::Helper
8
+ include ServicesHelper
9
+
10
+ option '--stack', 'STACK', 'Stack name'
11
+
12
+ requires_current_master
13
+ requires_current_master_token
14
+
15
+ def services
16
+ client.get("grids/#{current_grid}/services#{"?stack=#{stack}" if stack}")['services'].sort_by{|s| s['updated_at'] }.reverse
17
+ end
18
+
19
+ def fields
20
+ quiet? ? ['name'] : {name: 'name', instances: 'instances', stateful: 'stateful', state: 'state', "exposed ports" => 'ports' }
21
+ end
22
+
23
+ def service_port(port)
24
+ "#{port['ip']}:#{port['node_port']}->#{port['container_port']}/#{port['protocol']}"
25
+ end
26
+
27
+ def stack_id(service)
28
+ if quiet?
29
+ service.fetch('stack', {}).fetch('id', 'null')
30
+ else
31
+ service.fetch('stack', {}).fetch('name', nil)
32
+ end
33
+ end
34
+
35
+ def service_name(service)
36
+ stack_id = stack_id(service)
37
+ return service['name'] if stack_id == 'null'
38
+ [ stack_id(service), service['name'] ].compact.join('/')
39
+ end
40
+
41
+ def state_color(state)
42
+ case state
43
+ when 'running' then :green
44
+ when 'initialized' then :cyan
45
+ when 'stopped' then :red
46
+ else :blue
47
+ end
48
+ end
49
+
50
+ def execute
51
+ print_table(services) do |row|
52
+ row['name'] = quiet? ? service_name(row) : health_status_icon(health_status(row)) + " " + service_name(row)
53
+ next if quiet?
54
+ row['stateful'] = row['stateful'] ? pastel.green('yes') : 'no'
55
+ row['ports'] = row['ports'].map(&method(:service_port)).join(',')
56
+ row['state'] = pastel.send(state_color(row['state']), row['state'])
57
+
58
+ instances = [row['instance_counts']['running'], row['instances']]
59
+ if instances.first < instances.last
60
+ instances[0] = pastel.cyan(instances[0].to_s)
61
+ end
62
+ row['instances'] = instances.join(' / ')
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'services_helper'
2
+ require_relative '../helpers/log_helper'
3
+
4
+ module Kontena::Cli::Services
5
+ class LogsCommand < Kontena::Command
6
+ include Kontena::Cli::Common
7
+ include Kontena::Cli::GridOptions
8
+ include Kontena::Cli::Helpers::LogHelper
9
+ include ServicesHelper
10
+
11
+ parameter "NAME", "Service name"
12
+ option ["-i", "--instance"], "INSTANCE", "Show only given instance specific logs"
13
+
14
+ def execute
15
+ require_api_url
16
+
17
+ query_params = {}
18
+ query_params[:instance] = instance if instance
19
+
20
+ show_logs("services/#{parse_service_id(name)}/container_logs", query_params) do |log|
21
+ show_log(log)
22
+ end
23
+ end
24
+
25
+ def show_log(log)
26
+ color = color_for_container(log['name'])
27
+ instance_number = log['name'].match(/^.+-(\d+)$/)[1]
28
+ name = instance_number.nil? ? log['name'] : instance_number
29
+ prefix = pastel.send(color, "#{log['created_at']} [#{name}]:")
30
+ puts "#{prefix} #{log['data']}"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,58 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class MonitorCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include ServicesHelper
8
+
9
+ parameter "NAME", "Service name"
10
+ option "--interval", "SECONDS", "How often view is refreshed", default: 2
11
+
12
+ def execute
13
+ require_api_url
14
+ token = require_token
15
+
16
+ loop do
17
+ nodes = {}
18
+ service = client(token).get("services/#{parse_service_id(name)}")
19
+ result = client(token).get("services/#{parse_service_id(name)}/containers")
20
+ result['containers'].each do |container|
21
+ nodes[container['node']['name']] ||= []
22
+ nodes[container['node']['name']] << container
23
+ end
24
+ clear_terminal
25
+ puts "service: #{name} (#{result['containers'].size}/#{service['instances']} instances)"
26
+ puts "strategy: #{service['strategy']}"
27
+ puts "status: #{service['state']}"
28
+ puts "stateful: #{service['stateful'] == true ? 'yes' : 'no' }"
29
+ puts "nodes:"
30
+ node_names = nodes.keys.sort
31
+ node_names.each do |name|
32
+ containers = nodes[name]
33
+ puts " #{name} (#{containers.size} instances)"
34
+ print " "
35
+ containers.each do |container|
36
+ color = container['status']
37
+ if container['status'] == 'running'
38
+ color = :green
39
+ elsif container['status'] == 'killed'
40
+ color = :red
41
+ elsif container['status'] == 'stopped'
42
+ color = :bright_black
43
+ else
44
+ color = :yellow
45
+ end
46
+ print pastel.send(color, "■")
47
+ end
48
+ puts ''
49
+ end
50
+ sleep interval.to_f
51
+ end
52
+ end
53
+
54
+ def clear_terminal
55
+ print "\e[H\e[2J"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,60 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class RemoveCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include ServicesHelper
7
+
8
+ parameter "NAME ...", "Service name", attribute_name: :names
9
+ option "--instance", "INSTANCE", "Remove only given instance"
10
+ option "--force", :flag, "Force remove", default: false, attribute_name: :forced
11
+
12
+ banner "Remove a service"
13
+
14
+ requires_current_master
15
+ requires_current_master_token
16
+
17
+ def execute
18
+ names.each do |name|
19
+ if instance
20
+ remove_instance(name)
21
+ else
22
+ remove(name)
23
+ end
24
+ end
25
+ end
26
+
27
+ def remove(name)
28
+ confirm_command(name) unless forced?
29
+
30
+ spinner "Removing service #{pastel.cyan(name)} " do
31
+ client.delete("services/#{parse_service_id(name)}")
32
+ removed = false
33
+ until removed == true
34
+ sleep 1
35
+ begin
36
+ client.get("services/#{parse_service_id(name)}")
37
+ rescue Kontena::Errors::StandardError => exc
38
+ if exc.status == 404
39
+ removed = true
40
+ else
41
+ raise exc
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ def remove_instance(name)
49
+ instance_name = "#{name}/#{instance}"
50
+ confirm_command("#{name}/#{instance}") unless forced?
51
+ service_instance = client.get("services/#{parse_service_id(name)}/instances")['instances'].find{ |i|
52
+ i['instance_number'] == instance.to_i
53
+ }
54
+ exit_with_error("Instance not found") unless service_instance
55
+ spinner "Removing service instance #{pastel.cyan(instance_name)} " do
56
+ client.delete("services/#{parse_service_id(name)}/instances/#{service_instance['id']}")
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class RestartCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include ServicesHelper
8
+
9
+ parameter "NAME", "Service name"
10
+
11
+ def execute
12
+ require_api_url
13
+ token = require_token
14
+ spinner "Sending restart signal to service #{pastel.cyan(name)} " do
15
+ restart_service(token, name)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'services_helper'
2
+
3
+ module Kontena::Cli::Services
4
+ class ScaleCommand < Kontena::Command
5
+ include Kontena::Cli::Common
6
+ include Kontena::Cli::GridOptions
7
+ include ServicesHelper
8
+
9
+ parameter "NAME", "Service name"
10
+ parameter "INSTANCES", "Scales service to given number of instances"
11
+ option '--[no-]wait', :flag, 'Wait for service deployment', default: true
12
+
13
+ def execute
14
+ token = require_token
15
+ spinner "Scaling #{pastel.cyan(name)} to #{instances} instances " do
16
+ deployment = scale_service(token, name, instances)
17
+ wait_for_deploy_to_finish(token, deployment) if wait?
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ module Kontena::Cli::Services
2
+
3
+
4
+ class SecretCommand < Kontena::Command
5
+ subcommand "link", "Link secret from Vault", load_subcommand('services/secrets/link_command')
6
+ subcommand "unlink", "Unlink secret from Vault", load_subcommand('services/secrets/unlink_command')
7
+ end
8
+ end