hybrid_platforms_conductor 32.11.0 → 32.13.1

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 (202) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1109 -0
  3. data/LICENSE.md +31 -0
  4. data/README.md +395 -0
  5. data/bin/setup +1 -1
  6. data/docs/api.md +349 -0
  7. data/docs/config_dsl.md +315 -0
  8. data/docs/executables.md +226 -0
  9. data/docs/executables/check-node.md +155 -0
  10. data/docs/executables/deploy.md +198 -0
  11. data/docs/executables/dump_nodes_json.md +110 -0
  12. data/docs/executables/free_ips.md +93 -0
  13. data/docs/executables/free_veids.md +73 -0
  14. data/docs/executables/get_impacted_nodes.md +94 -0
  15. data/docs/executables/last_deploys.md +114 -0
  16. data/docs/executables/nodes_to_deploy.md +139 -0
  17. data/docs/executables/report.md +159 -0
  18. data/docs/executables/run.md +126 -0
  19. data/docs/executables/setup.md +92 -0
  20. data/docs/executables/ssh_config.md +151 -0
  21. data/docs/executables/test.md +213 -0
  22. data/docs/executables/topograph.md +139 -0
  23. data/docs/gen/mermaid/README.md-0.png +0 -0
  24. data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
  25. data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
  26. data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
  27. data/docs/gen/mermaid/docs/executables/free_veids.md-0.png +0 -0
  28. data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
  29. data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
  30. data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
  31. data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
  32. data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
  33. data/docs/gen/mermaid/docs/executables/setup.md-0.png +0 -0
  34. data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
  35. data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
  36. data/docs/install.md +161 -0
  37. data/docs/plugins.md +215 -0
  38. data/docs/plugins/action/bash.md +37 -0
  39. data/docs/plugins/action/interactive.md +37 -0
  40. data/docs/plugins/action/remote_bash.md +67 -0
  41. data/docs/plugins/action/ruby.md +69 -0
  42. data/docs/plugins/action/scp.md +61 -0
  43. data/docs/plugins/cmdb/config.md +46 -0
  44. data/docs/plugins/cmdb/host_ip.md +33 -0
  45. data/docs/plugins/cmdb/host_keys.md +33 -0
  46. data/docs/plugins/cmdb/platform_handlers.md +33 -0
  47. data/docs/plugins/connector/local.md +28 -0
  48. data/docs/plugins/connector/ssh.md +95 -0
  49. data/docs/plugins/platform_handler/yaml_inventory.md +105 -0
  50. data/docs/plugins/provisioner/docker.md +27 -0
  51. data/docs/plugins/provisioner/podman.md +27 -0
  52. data/docs/plugins/provisioner/proxmox.md +115 -0
  53. data/docs/plugins/report/confluence.md +49 -0
  54. data/docs/plugins/report/mediawiki.md +28 -0
  55. data/docs/plugins/report/stdout.md +32 -0
  56. data/docs/plugins/test/bitbucket_conf.md +97 -0
  57. data/docs/plugins/test/can_be_checked.md +27 -0
  58. data/docs/plugins/test/check_deploy_and_idempotence.md +61 -0
  59. data/docs/plugins/test/check_from_scratch.md +28 -0
  60. data/docs/plugins/test/connection.md +27 -0
  61. data/docs/plugins/test/deploy_freshness.md +27 -0
  62. data/docs/plugins/test/deploy_from_scratch.md +28 -0
  63. data/docs/plugins/test/deploy_removes_root_access.md +29 -0
  64. data/docs/plugins/test/divergence.md +41 -0
  65. data/docs/plugins/test/executables.md +26 -0
  66. data/docs/plugins/test/file_system.md +49 -0
  67. data/docs/plugins/test/file_system_hdfs.md +65 -0
  68. data/docs/plugins/test/hostname.md +27 -0
  69. data/docs/plugins/test/idempotence.md +56 -0
  70. data/docs/plugins/test/ip.md +28 -0
  71. data/docs/plugins/test/jenkins_ci_conf.md +54 -0
  72. data/docs/plugins/test/jenkins_ci_masters_ok.md +54 -0
  73. data/docs/plugins/test/linear_strategy.md +26 -0
  74. data/docs/plugins/test/local_users.md +48 -0
  75. data/docs/plugins/test/mounts.md +55 -0
  76. data/docs/plugins/test/orphan_files.md +38 -0
  77. data/docs/plugins/test/ports.md +50 -0
  78. data/docs/plugins/test/private_ips.md +27 -0
  79. data/docs/plugins/test/public_ips.md +27 -0
  80. data/docs/plugins/test/spectre.md +26 -0
  81. data/docs/plugins/test/veids.md +27 -0
  82. data/docs/plugins/test/vulnerabilities.md +65 -0
  83. data/docs/plugins/test_report/confluence.md +43 -0
  84. data/docs/plugins/test_report/stdout.md +26 -0
  85. data/docs/plugins_create.md +135 -0
  86. data/docs/tutorial.md +61 -0
  87. data/docs/tutorial/01_installation.md +129 -0
  88. data/docs/tutorial/02_first_node.md +466 -0
  89. data/docs/tutorial/03_scale.md +876 -0
  90. data/docs/tutorial/04_test.md +975 -0
  91. data/docs/tutorial/05_extend_with_plugins.md +1130 -0
  92. data/examples/bare/Gemfile +4 -0
  93. data/examples/bare/hpc_config.rb +2 -0
  94. data/examples/localhost/Gemfile +4 -0
  95. data/examples/localhost/hpc_config.rb +2 -0
  96. data/examples/localhost/inventory.yaml +4 -0
  97. data/examples/tutorial/01_installation/my-platforms/Gemfile +3 -0
  98. data/examples/tutorial/01_installation/my-platforms/hpc_config.rb +0 -0
  99. data/examples/tutorial/02_first_node/my-platforms/Gemfile +3 -0
  100. data/examples/tutorial/02_first_node/my-platforms/hpc_config.rb +1 -0
  101. data/examples/tutorial/02_first_node/my-service-conf-repo/inventory.yaml +13 -0
  102. data/examples/tutorial/02_first_node/my-service-conf-repo/my-service.conf.erb +3 -0
  103. data/examples/tutorial/02_first_node/my-service-conf-repo/service_my-service.rb +58 -0
  104. data/examples/tutorial/02_first_node/node/my-service.conf +4 -0
  105. data/examples/tutorial/03_scale/my-platforms/Gemfile +3 -0
  106. data/examples/tutorial/03_scale/my-platforms/hpc_config.rb +1 -0
  107. data/examples/tutorial/03_scale/my-platforms/my_commands.bash +2 -0
  108. data/examples/tutorial/03_scale/my-service-conf-repo/inventory.yaml +90 -0
  109. data/examples/tutorial/03_scale/my-service-conf-repo/my-service.conf.erb +3 -0
  110. data/examples/tutorial/03_scale/my-service-conf-repo/service_my-service.rb +58 -0
  111. data/examples/tutorial/03_scale/my-service-conf-repo/service_web-hello.rb +43 -0
  112. data/examples/tutorial/03_scale/node/my-service.conf +4 -0
  113. data/examples/tutorial/03_scale/web_docker_image/Dockerfile +33 -0
  114. data/examples/tutorial/03_scale/web_docker_image/hello_world.txt +1 -0
  115. data/examples/tutorial/03_scale/web_docker_image/hpc_root.key +27 -0
  116. data/examples/tutorial/03_scale/web_docker_image/hpc_root.key.pub +1 -0
  117. data/examples/tutorial/03_scale/web_docker_image/main.go +43 -0
  118. data/examples/tutorial/03_scale/web_docker_image/start.sh +7 -0
  119. data/examples/tutorial/03_scale/web_docker_image/test.bash +6 -0
  120. data/examples/tutorial/04_test/my-platforms/Gemfile +3 -0
  121. data/examples/tutorial/04_test/my-platforms/hpc_config.rb +12 -0
  122. data/examples/tutorial/04_test/my-platforms/images/debian_10/Dockerfile +13 -0
  123. data/examples/tutorial/04_test/my-platforms/my_commands.bash +2 -0
  124. data/examples/tutorial/04_test/my-service-conf-repo/inventory.yaml +100 -0
  125. data/examples/tutorial/04_test/my-service-conf-repo/my-service.conf.erb +3 -0
  126. data/examples/tutorial/04_test/my-service-conf-repo/service_my-service.rb +58 -0
  127. data/examples/tutorial/04_test/my-service-conf-repo/service_web-hello.rb +43 -0
  128. data/examples/tutorial/04_test/node/my-service.conf +4 -0
  129. data/examples/tutorial/04_test/web_docker_image/Dockerfile +33 -0
  130. data/examples/tutorial/04_test/web_docker_image/hello_world.txt +1 -0
  131. data/examples/tutorial/04_test/web_docker_image/hpc_root.key +27 -0
  132. data/examples/tutorial/04_test/web_docker_image/hpc_root.key.pub +1 -0
  133. data/examples/tutorial/04_test/web_docker_image/main.go +43 -0
  134. data/examples/tutorial/04_test/web_docker_image/start.sh +7 -0
  135. data/examples/tutorial/04_test/web_docker_image/test.bash +6 -0
  136. data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/hosts.json +12 -0
  137. data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-gcc.bash +14 -0
  138. data/examples/tutorial/05_extend_with_plugins/dev-servers-conf-repo/install-python.bash +14 -0
  139. data/examples/tutorial/05_extend_with_plugins/dev_docker_image/Dockerfile +20 -0
  140. data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key +27 -0
  141. data/examples/tutorial/05_extend_with_plugins/dev_docker_image/hpc_root.key.pub +1 -0
  142. data/examples/tutorial/05_extend_with_plugins/my-platforms/Gemfile +4 -0
  143. data/examples/tutorial/05_extend_with_plugins/my-platforms/hpc_config.rb +13 -0
  144. data/examples/tutorial/05_extend_with_plugins/my-platforms/images/debian_10/Dockerfile +13 -0
  145. data/examples/tutorial/05_extend_with_plugins/my-platforms/my_commands.bash +2 -0
  146. data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/inventory.yaml +100 -0
  147. data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/my-service.conf.erb +3 -0
  148. data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_my-service.rb +58 -0
  149. data/examples/tutorial/05_extend_with_plugins/my-service-conf-repo/service_web-hello.rb +43 -0
  150. data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/platform_handler/json_bash.rb +115 -0
  151. data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/report/web_report.rb +52 -0
  152. data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/lib/my_hpc_plugins/hpc_plugins/test/root_space.rb +44 -0
  153. data/examples/tutorial/05_extend_with_plugins/my_hpc_plugins/my_hpc_plugins.gemspec +15 -0
  154. data/examples/tutorial/05_extend_with_plugins/node/my-service.conf +4 -0
  155. data/examples/tutorial/05_extend_with_plugins/web_docker_image/Dockerfile +33 -0
  156. data/examples/tutorial/05_extend_with_plugins/web_docker_image/hello_world.txt +1 -0
  157. data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key +27 -0
  158. data/examples/tutorial/05_extend_with_plugins/web_docker_image/hpc_root.key.pub +1 -0
  159. data/examples/tutorial/05_extend_with_plugins/web_docker_image/main.go +43 -0
  160. data/examples/tutorial/05_extend_with_plugins/web_docker_image/start.sh +7 -0
  161. data/examples/tutorial/05_extend_with_plugins/web_docker_image/test.bash +6 -0
  162. data/lib/hybrid_platforms_conductor/actions_executor.rb +1 -0
  163. data/lib/hybrid_platforms_conductor/deployer.rb +3 -2
  164. data/lib/hybrid_platforms_conductor/hpc_plugins/action/remote_bash.rb +29 -13
  165. data/lib/hybrid_platforms_conductor/hpc_plugins/action/scp.rb +1 -1
  166. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +98 -0
  167. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/my_connector.rb.sample +2 -2
  168. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +15 -4
  169. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/platform_handler_plugin.rb.sample +5 -5
  170. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/yaml_inventory.rb +140 -0
  171. data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +6 -3
  172. data/lib/hybrid_platforms_conductor/hpc_plugins/report/templates/confluence_inventory.html.erb +1 -1
  173. data/lib/hybrid_platforms_conductor/hpc_plugins/test/bitbucket_conf.rb +4 -4
  174. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +1 -1
  175. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +19 -17
  176. data/lib/hybrid_platforms_conductor/hpc_plugins/test/divergence.rb +3 -0
  177. data/lib/hybrid_platforms_conductor/hpc_plugins/test/executables.rb +27 -13
  178. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +2 -1
  179. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +2 -1
  180. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +2 -1
  181. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +4 -3
  182. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +2 -1
  183. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +1 -1
  184. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +8 -7
  185. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/confluence.rb +1 -1
  186. data/lib/hybrid_platforms_conductor/hpc_plugins/test_report/templates/confluence.html.erb +1 -1
  187. data/lib/hybrid_platforms_conductor/json_dumper.rb +1 -1
  188. data/lib/hybrid_platforms_conductor/platform_handler.rb +1 -1
  189. data/lib/hybrid_platforms_conductor/services_handler.rb +18 -16
  190. data/lib/hybrid_platforms_conductor/tests_runner.rb +0 -1
  191. data/lib/hybrid_platforms_conductor/topographer.rb +0 -1
  192. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  193. data/spec/hybrid_platforms_conductor_test/api/actions_executor/actions/remote_bash_spec.rb +16 -0
  194. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/connectable_nodes_spec.rb +30 -0
  195. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +113 -0
  196. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/cli_options_spec.rb +6 -2
  197. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +38 -1
  198. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +37 -4
  199. data/spec/hybrid_platforms_conductor_test/docs_spec.rb +10 -0
  200. data/tools/check_md +89 -0
  201. data/tools/generate_mermaid +75 -0
  202. metadata +337 -12
@@ -50,7 +50,8 @@ module HybridPlatformsConductor
50
50
  # Check my_test_plugin.rb.sample documentation for signature details.
51
51
  def test_on_node
52
52
  {
53
- "#{@nodes_handler.sudo_on(@node)} /usr/bin/find / \\( #{@nodes_handler.
53
+ # TODO: Access the user correctly when the user notion will be moved out of the ssh connector
54
+ "#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}/usr/bin/find / \\( #{@nodes_handler.
54
55
  select_confs_for_node(@node, @config.ignored_orphan_files_paths).
55
56
  inject(DIRECTORIES_TO_ALWAYS_IGNORE) { |merged_paths, paths_to_ignore_info| merged_paths + paths_to_ignore_info[:ignored_paths] }.
56
57
  uniq.
@@ -16,7 +16,7 @@ module HybridPlatformsConductor
16
16
  # Check my_test_plugin.rb.sample documentation for signature details.
17
17
  def test_on_node
18
18
  spectre_cmd = <<~EOS
19
- #{@nodes_handler.sudo_on(@node)} /bin/bash <<'EOAction'
19
+ #{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}/bin/bash <<'EOAction'
20
20
  #{File.read("#{__dir__}/spectre-meltdown-checker.sh")}
21
21
  EOAction
22
22
  EOS
@@ -54,7 +54,8 @@ module HybridPlatformsConductor
54
54
  current_url
55
55
  end
56
56
  )
57
- sudo = @nodes_handler.sudo_on(@node)
57
+ # TODO: Access the user correctly when the user notion will be moved out of the ssh connector
58
+ sudo = @deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "
58
59
  Hash[urls.map do |url|
59
60
  # 1. Get the OVAL file on the node to be tested (uncompress it if needed)
60
61
  # 2. Make sure oscap is installed
@@ -75,9 +76,9 @@ module HybridPlatformsConductor
75
76
  #{
76
77
  case image
77
78
  when :centos_7
78
- "#{sudo} yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
79
+ "#{sudo}yum install -y wget openscap-scanner #{packages_to_install.join(' ')}"
79
80
  when :debian_9
80
- "#{sudo} apt install -y wget libopenscap8 #{packages_to_install.join(' ')}"
81
+ "#{sudo}apt install -y wget libopenscap8 #{packages_to_install.join(' ')}"
81
82
  when :debian_10
82
83
  # On Debian 10 we have to compile it from sources, as the packaged official version has core dumps.
83
84
  # cf https://www.mail-archive.com/debian-bugs-dist@lists.debian.org/msg1688223.html
@@ -87,13 +88,13 @@ module HybridPlatformsConductor
87
88
  rm -rf openscap
88
89
  git clone --recurse-submodules https://github.com/OpenSCAP/openscap.git
89
90
  cd openscap
90
- #{sudo} apt install -y cmake libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt20-dev libselinux1-dev libxslt1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libldap2-dev libpcre3-dev python-dev swig libxml-parser-perl libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libapt-pkg-dev libyaml-dev
91
+ #{sudo}apt install -y cmake libdbus-1-dev libdbus-glib-1-dev libcurl4-openssl-dev libgcrypt20-dev libselinux1-dev libxslt1-dev libgconf2-dev libacl1-dev libblkid-dev libcap-dev libxml2-dev libldap2-dev libpcre3-dev python-dev swig libxml-parser-perl libxml-xpath-perl libperl-dev libbz2-dev librpm-dev g++ libapt-pkg-dev libyaml-dev
91
92
  cd build
92
93
  cmake ../
93
94
  make
94
- #{sudo} make install
95
+ #{sudo}make install
95
96
  fi
96
- #{sudo} apt install -y wget #{packages_to_install.join(' ')}
97
+ #{sudo}apt install -y wget #{packages_to_install.join(' ')}
97
98
  EOS2
98
99
  else
99
100
  raise "Non supported image: #{image}. Please adapt this test's code."
@@ -104,7 +105,7 @@ module HybridPlatformsConductor
104
105
  cd hpc_vulnerabilities_test
105
106
  wget -N #{url}
106
107
  #{uncompress_cmds.join("\n")}
107
- #{sudo} oscap oval eval --skip-valid --results "#{local_oval_file}.results.xml" "#{local_oval_file}"
108
+ #{sudo}oscap oval eval --skip-valid --results "#{local_oval_file}.results.xml" "#{local_oval_file}"
108
109
  echo "===== RESULTS ====="
109
110
  cat "#{local_oval_file}.results.xml"
110
111
  cd ..
@@ -53,7 +53,7 @@ module HybridPlatformsConductor
53
53
 
54
54
  private
55
55
 
56
- TEMPLATES_PATH = File.expand_path("#{File.dirname(__FILE__)}/templates")
56
+ TEMPLATES_PATH = File.expand_path("#{__dir__}/templates")
57
57
 
58
58
  # Render a given ERB template into a String
59
59
  #
@@ -237,6 +237,6 @@
237
237
  </table>
238
238
  <p>
239
239
  <br/>
240
- Generated at <%= Time.now.utc.strftime('%F %T') %> UTC by <a href="https://www.site.my_company.net/git/projects/PROJECTrepos/hybrid_platforms_conductor/browse">Hybrid Platforms Conductor</a>.
240
+ Generated at <%= Time.now.utc.strftime('%F %T') %> UTC by <a href="https://github.com/sweet-delights/hybrid-platforms-conductor">Hybrid Platforms Conductor</a>.
241
241
  <br/>
242
242
  </p>
@@ -56,7 +56,7 @@ module HybridPlatformsConductor
56
56
  nodes = @nodes_handler.select_nodes(nodes_selectors)
57
57
  unless @skip_run
58
58
  nodes.map { |node| @nodes_handler.platform_for(node) }.uniq.each.each do |platform_handler|
59
- platform_handler.prepare_why_run_deploy_for_json_dump
59
+ platform_handler.prepare_why_run_deploy_for_json_dump if platform_handler.respond_to?(:prepare_why_run_deploy_for_json_dump)
60
60
  end
61
61
  @deployer.concurrent_execution = true
62
62
  @deployer.use_why_run = true
@@ -142,7 +142,7 @@ module HybridPlatformsConductor
142
142
  git_status = git.status
143
143
  git_commit = git.log.first
144
144
  {
145
- repo_name: File.basename(git.remotes.first.url).gsub(/\.git$/, ''),
145
+ repo_name: git.remotes.empty? ? File.basename(@repository_path) : File.basename(git.remotes.first.url).gsub(/\.git$/, ''),
146
146
  commit: {
147
147
  id: git_commit.sha,
148
148
  ref: git_commit.name,
@@ -108,23 +108,25 @@ module HybridPlatformsConductor
108
108
  local_environment:
109
109
  )
110
110
  platforms_for(services).each do |platform, platform_services|
111
- platform_name = platform.name
112
- # Compute the package ID that is unique to this packaging, so that we don't mix it with others if needed.
113
- package_id = {
114
- platform_name: platform_name,
115
- services: Hash[platform_services.map { |node, node_services| [node, node_services.sort] }].sort,
116
- secrets: secrets.sort,
117
- local_environment: local_environment
118
- }
119
- if ServicesHandler.packaged_deployments.include?(package_id)
120
- log_debug "Platform #{platform_name} has already been packaged for this deployment (package ID #{package_id}). Won't package it another time."
121
- else
122
- platform.package(
123
- services: platform_services,
124
- secrets: secrets,
111
+ if platform.respond_to?(:package)
112
+ platform_name = platform.name
113
+ # Compute the package ID that is unique to this packaging, so that we don't mix it with others if needed.
114
+ package_id = {
115
+ platform_name: platform_name,
116
+ services: Hash[platform_services.map { |node, node_services| [node, node_services.sort] }].sort,
117
+ secrets: secrets.sort,
125
118
  local_environment: local_environment
126
- )
127
- ServicesHandler.packaged_deployments << package_id
119
+ }
120
+ if ServicesHandler.packaged_deployments.include?(package_id)
121
+ log_debug "Platform #{platform_name} has already been packaged for this deployment (package ID #{package_id}). Won't package it another time."
122
+ else
123
+ platform.package(
124
+ services: platform_services,
125
+ secrets: secrets,
126
+ local_environment: local_environment
127
+ )
128
+ ServicesHandler.packaged_deployments << package_id
129
+ end
128
130
  end
129
131
  end
130
132
  end
@@ -452,7 +452,6 @@ module HybridPlatformsConductor
452
452
  end]
453
453
  section "Run test commands on #{@test_cmds.keys.size} connected nodes (timeout to #{timeout} secs)" do
454
454
  start_time = Time.now
455
- nbr_secs = nil
456
455
  @actions_executor.max_threads = @max_threads_connection_on_nodes
457
456
  @actions_result = @actions_executor.execute_actions(
458
457
  @test_cmds,
@@ -110,7 +110,6 @@ module HybridPlatformsConductor
110
110
  @skip_run = false
111
111
 
112
112
  # Parse plugins
113
- root_path = File.expand_path("#{File.dirname(__FILE__)}/..")
114
113
  @plugins = Hash[Dir.
115
114
  glob("#{File.dirname(__FILE__)}/topographer/plugins/*.rb").
116
115
  map do |file_name|
@@ -1,5 +1,5 @@
1
1
  module HybridPlatformsConductor
2
2
 
3
- VERSION = '32.11.0'
3
+ VERSION = '32.13.1'
4
4
 
5
5
  end
@@ -79,6 +79,22 @@ describe HybridPlatformsConductor::ActionsExecutor do
79
79
  end
80
80
  end
81
81
 
82
+ it 'executes remote Bash code both from commands and a file in sequence' do
83
+ with_test_platform_for_action_plugins do |repository|
84
+ File.write("#{repository}/commands.txt", "bash_cmd3.bash\nbash_cmd4.bash")
85
+ test_actions_executor.execute_actions('node' => { remote_bash: [
86
+ 'bash_cmd1.bash',
87
+ 'bash_cmd2.bash',
88
+ { file: "#{repository}/commands.txt" }
89
+ ] })
90
+ expect(test_actions_executor.connector(:test_connector).calls).to eq [
91
+ [:connectable_nodes_from, ['node']],
92
+ [:with_connection_to, ['node'], { no_exception: true }],
93
+ [:remote_bash, "bash_cmd1.bash\nbash_cmd2.bash\nbash_cmd3.bash\nbash_cmd4.bash"]
94
+ ]
95
+ end
96
+ end
97
+
82
98
  it 'executes remote Bash code with environment variables set' do
83
99
  with_test_platform_for_action_plugins do
84
100
  test_actions_executor.execute_actions('node' => { remote_bash: {
@@ -0,0 +1,30 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connector plugin local' do
4
+
5
+ context 'checking connectable nodes selection' do
6
+
7
+ # Return the connector to be tested
8
+ #
9
+ # Result::
10
+ # * Connector: Connector to be tested
11
+ def test_connector
12
+ test_actions_executor.connector(:local)
13
+ end
14
+
15
+ it 'selects connectable nodes correctly' do
16
+ with_test_platform(nodes: {
17
+ 'node1' => { meta: { host_ip: '192.168.42.42' } },
18
+ 'node2' => {},
19
+ 'node3' => { meta: { host_ip: '127.0.0.1', local_node: true } },
20
+ 'node4' => { meta: { local_node: true } }
21
+ }) do
22
+ expect(test_connector.connectable_nodes_from(%w[node1 node2 node3 node4]).sort).to eq %w[node3 node4].sort
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,113 @@
1
+ describe HybridPlatformsConductor::ActionsExecutor do
2
+
3
+ context 'checking connector plugin local' do
4
+
5
+ context 'checking remote actions' do
6
+
7
+ # Return the connector to be tested
8
+ #
9
+ # Result::
10
+ # * Connector: Connector to be tested
11
+ def test_connector
12
+ test_actions_executor.connector(:local)
13
+ end
14
+
15
+ # Get a test platform and the connector prepared the same way Actions Executor does before calling remote_* methods
16
+ #
17
+ # Parameters::
18
+ # * *expected_cmds* (Array< [String or Regexp, Proc] >): The expected commands that should be used, and their corresponding mocked code [default: []]
19
+ # * *expected_stdout* (String): Expected stdout after client code execution [default: '']
20
+ # * *expected_stderr* (String): Expected stderr after client code execution [default: '']
21
+ # * *timeout* (Integer or nil): Timeout to prepare the connector for [default: nil]
22
+ # * *password* (String or nil): Password to set for the node, or nil for none [default: nil]
23
+ # * *additional_config* (String): Additional config [default: '']
24
+ # * Proc: Client code to execute testing
25
+ def with_test_platform_for_remote_testing(
26
+ expected_cmds: [],
27
+ expected_stdout: '',
28
+ expected_stderr: '',
29
+ timeout: nil,
30
+ password: nil,
31
+ additional_config: ''
32
+ )
33
+ with_test_platform(
34
+ { nodes: { 'node' => { meta: { local_node: true } } } },
35
+ false,
36
+ additional_config
37
+ ) do
38
+ with_cmd_runner_mocked(expected_cmds) do
39
+ test_connector.with_connection_to(['node']) do
40
+ stdout = ''
41
+ stderr = ''
42
+ test_connector.prepare_for('node', timeout, stdout, stderr)
43
+ yield
44
+ expect(stdout).to eq expected_stdout
45
+ expect(stderr).to eq expected_stderr
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ it 'executes bash commands remotely' do
52
+ with_test_platform_for_remote_testing(
53
+ expected_cmds: [['cd /tmp/hpc_local_workspaces/node ; bash_cmd.bash', proc { [0, 'Bash commands executed on node', ''] }]],
54
+ expected_stdout: 'Bash commands executed on node'
55
+ ) do
56
+ test_connector.remote_bash('bash_cmd.bash')
57
+ end
58
+ end
59
+
60
+ it 'executes bash commands remotely with timeout' do
61
+ with_test_platform_for_remote_testing(
62
+ expected_cmds: [
63
+ [
64
+ 'cd /tmp/hpc_local_workspaces/node ; bash_cmd.bash',
65
+ proc do |cmd, log_to_file: nil, log_to_stdout: true, log_stdout_to_io: nil, log_stderr_to_io: nil, expected_code: 0, timeout: nil, no_exception: false|
66
+ expect(timeout).to eq 5
67
+ [0, '', '']
68
+ end
69
+ ]
70
+ ],
71
+ timeout: 5
72
+ ) do
73
+ test_connector.remote_bash('bash_cmd.bash')
74
+ end
75
+ end
76
+
77
+ it 'executes interactive commands remotely' do
78
+ with_test_platform_for_remote_testing do
79
+ expect(test_connector).to receive(:system) do |cmd|
80
+ expect(cmd).to eq 'cd /tmp/hpc_local_workspaces/node ; /bin/bash'
81
+ end
82
+ test_connector.remote_interactive
83
+ end
84
+ end
85
+
86
+ it 'copies files remotely' do
87
+ with_test_platform_for_remote_testing do
88
+ expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/remote_path/to/dst.dir')
89
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir')
90
+ end
91
+ end
92
+
93
+ it 'copies files remotely with timeout' do
94
+ with_test_platform_for_remote_testing(
95
+ timeout: 5
96
+ ) do
97
+ expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/remote_path/to/dst.dir')
98
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir')
99
+ end
100
+ end
101
+
102
+ it 'copies relative files remotely' do
103
+ with_test_platform_for_remote_testing do
104
+ expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/tmp/hpc_local_workspaces/node/to/dst.dir')
105
+ test_connector.remote_copy('/path/to/src.file', 'to/dst.dir')
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
113
+ end
@@ -97,11 +97,15 @@ describe HybridPlatformsConductor::ActionsExecutor do
97
97
  end
98
98
  end
99
99
 
100
- it 'fails if no user name has been given, either through environment or command-line' do
100
+ it 'fails if no user name has been given, either through environment, command-line or using whoami' do
101
101
  ENV.delete 'hpc_ssh_user'
102
102
  ENV.delete 'USER'
103
103
  with_test_platform_for_cli do
104
- expect { run 'run', '--node', 'node', '--command', 'echo Hello' }.to raise_error(RuntimeError, 'No SSH user name specified. Please use --ssh-user option or hpc_ssh_user environment variable to set it.')
104
+ with_cmd_runner_mocked([
105
+ ['whoami', proc { [0, '', ''] }]
106
+ ]) do
107
+ expect { run 'run', '--node', 'node', '--command', 'echo Hello' }.to raise_error(RuntimeError, 'No SSH user name specified. Please use --ssh-user option or hpc_ssh_user environment variable to set it.')
108
+ end
105
109
  end
106
110
  end
107
111
 
@@ -47,7 +47,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
47
47
  end.join("\n") + "\n"
48
48
  end
49
49
 
50
- it 'generates a global configuration with user from environment' do
50
+ it 'generates a global configuration with user from hpc_ssh_user environment variable' do
51
51
  with_test_platform do
52
52
  ENV['hpc_ssh_user'] = 'test_user'
53
53
  expect(ssh_config_for(nil)).to eq <<~EOS
@@ -59,6 +59,43 @@ describe HybridPlatformsConductor::ActionsExecutor do
59
59
  end
60
60
  end
61
61
 
62
+ it 'generates a global configuration with user from USER environment variable' do
63
+ with_test_platform do
64
+ ENV['USER'] = 'test_user'
65
+ expect(ssh_config_for(nil)).to eq <<~EOS
66
+ Host *
67
+ User test_user
68
+ ControlPath #{Dir.tmpdir}/hpc_ssh/hpc_ssh_mux_%h_%p_%r
69
+ PubkeyAcceptedKeyTypes +ssh-dss
70
+ EOS
71
+ end
72
+ end
73
+
74
+ it 'generates a global configuration with user taken from whoami when no env variable is set' do
75
+ with_test_platform do
76
+ original_user = ENV['USER']
77
+ begin
78
+ ENV.delete 'USER'
79
+ ENV.delete 'hpc_ssh_user'
80
+ with_cmd_runner_mocked(
81
+ [
82
+ ['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }],
83
+ ['whoami', proc { [0, 'test_whoami_user', ''] }]
84
+ ]
85
+ ) do
86
+ expect(ssh_config_for(nil)).to eq <<~EOS
87
+ Host *
88
+ User test_whoami_user
89
+ ControlPath #{Dir.tmpdir}/hpc_ssh/hpc_ssh_mux_%h_%p_%r
90
+ PubkeyAcceptedKeyTypes +ssh-dss
91
+ EOS
92
+ end
93
+ ensure
94
+ ENV['USER'] = original_user
95
+ end
96
+ end
97
+ end
98
+
62
99
  it 'generates a global configuration with user from setting' do
63
100
  with_test_platform do
64
101
  test_connector.ssh_user = 'test_user'
@@ -6,7 +6,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
6
6
 
7
7
  it 'executes bash commands remotely' do
8
8
  with_test_platform_for_remote_testing(
9
- expected_cmds: [[/.+\/ssh hpc\.node \/bin\/bash <<'EOF'\nbash_cmd.bash\nEOF/, proc { [0, 'Bash commands executed on node', ''] }]],
9
+ expected_cmds: [[/.+\/ssh hpc\.node \/bin\/bash <<'HPC_EOF'\nbash_cmd.bash\nHPC_EOF/, proc { [0, 'Bash commands executed on node', ''] }]],
10
10
  expected_stdout: 'Bash commands executed on node'
11
11
  ) do
12
12
  test_connector.remote_bash('bash_cmd.bash')
@@ -17,7 +17,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
17
17
  with_test_platform_for_remote_testing(
18
18
  expected_cmds: [
19
19
  [
20
- /.+\/ssh hpc\.node \/bin\/bash <<'EOF'\nbash_cmd.bash\nEOF/,
20
+ /.+\/ssh hpc\.node \/bin\/bash <<'HPC_EOF'\nbash_cmd.bash\nHPC_EOF/,
21
21
  proc do |cmd, log_to_file: nil, log_to_stdout: true, log_stdout_to_io: nil, log_stderr_to_io: nil, expected_code: 0, timeout: nil, no_exception: false|
22
22
  expect(timeout).to eq 5
23
23
  [0, '', '']
@@ -76,7 +76,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
76
76
  [
77
77
  /.+\/hpc_temp_cmds_.+\.sh$/,
78
78
  proc do |received_cmd|
79
- expect(File.read(received_cmd)).to match /.+\/ssh hpc\.node \/bin\/bash <<'EOF'\n#{Regexp.escape(cmd)}\nEOF/
79
+ expect(File.read(received_cmd)).to match /.+\/ssh hpc\.node \/bin\/bash <<'HPC_EOF'\n#{Regexp.escape(cmd)}\nHPC_EOF/
80
80
  [0, 'Bash commands executed on node', '']
81
81
  end
82
82
  ]
@@ -143,7 +143,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
143
143
 
144
144
  it 'executes bash commands remotely without Session Exec capabilities' do
145
145
  with_test_platform_for_remote_testing(
146
- expected_cmds: [[/^\{ cat \| .+\/ssh hpc\.node -T; } <<'EOF'\nbash_cmd.bash\nEOF$/, proc { [0, 'Bash commands executed on node', ''] }]],
146
+ expected_cmds: [[/^\{ cat \| .+\/ssh hpc\.node -T; } <<'HPC_EOF'\nbash_cmd.bash\nHPC_EOF$/, proc { [0, 'Bash commands executed on node', ''] }]],
147
147
  expected_stdout: 'Bash commands executed on node',
148
148
  session_exec: false
149
149
  ) do
@@ -165,6 +165,39 @@ describe HybridPlatformsConductor::ActionsExecutor do
165
165
  end
166
166
  end
167
167
 
168
+ it 'copies files remotely without Session Exec capabilities and with sudo' do
169
+ with_test_platform_for_remote_testing(
170
+ expected_cmds: [
171
+ [/^\{ cat \| .+\/ssh hpc\.node -T; } <<'HPC_EOF'\nmkdir -p hpc_tmp_scp\nHPC_EOF$/, proc { [0, '', ''] }],
172
+ [
173
+ /^scp -S .+\/ssh \/path\/to\/src.file hpc\.node:\.\/hpc_tmp_scp$/,
174
+ proc { [0, '', ''] }
175
+ ],
176
+ [/^\{ cat \| .+\/ssh hpc\.node -T; } <<'HPC_EOF'\nsudo -u root mv \.\/hpc_tmp_scp\/src\.file \/remote_path\/to\/dst\.dir\nHPC_EOF$/, proc { [0, '', ''] }]
177
+ ],
178
+ session_exec: false
179
+ ) do
180
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir', sudo: true)
181
+ end
182
+ end
183
+
184
+ it 'copies files remotely without Session Exec capabilities and with a different sudo' do
185
+ with_test_platform_for_remote_testing(
186
+ expected_cmds: [
187
+ [/^\{ cat \| .+\/ssh hpc\.node -T; } <<'HPC_EOF'\nmkdir -p hpc_tmp_scp\nHPC_EOF$/, proc { [0, '', ''] }],
188
+ [
189
+ /^scp -S .+\/ssh \/path\/to\/src.file hpc\.node:\.\/hpc_tmp_scp$/,
190
+ proc { [0, '', ''] }
191
+ ],
192
+ [/^\{ cat \| .+\/ssh hpc\.node -T; } <<'HPC_EOF'\nother_sudo --user root mv \.\/hpc_tmp_scp\/src\.file \/remote_path\/to\/dst\.dir\nHPC_EOF$/, proc { [0, '', ''] }]
193
+ ],
194
+ additional_config: 'sudo_for { |user| "other_sudo --user #{user}" }',
195
+ session_exec: false
196
+ ) do
197
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir', sudo: true)
198
+ end
199
+ end
200
+
168
201
  end
169
202
 
170
203
  end