hybrid_platforms_conductor 32.16.2 → 32.18.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/README.md +3 -0
  4. data/bin/last_deploys +4 -1
  5. data/bin/nodes_to_deploy +5 -5
  6. data/docs/config_dsl.md +22 -0
  7. data/docs/gen/mermaid/README.md-0.png +0 -0
  8. data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
  9. data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
  10. data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
  11. data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
  12. data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
  13. data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
  14. data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
  15. data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
  16. data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
  17. data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
  18. data/docs/plugins.md +26 -0
  19. data/docs/plugins/connector/ssh.md +1 -1
  20. data/docs/plugins/log/remote_fs.md +26 -0
  21. data/docs/plugins/test/bitbucket_conf.md +1 -1
  22. data/docs/plugins/test/check_deploy_and_idempotence.md +1 -1
  23. data/docs/plugins/test/connection.md +1 -0
  24. data/docs/plugins/test/deploy_removes_root_access.md +1 -1
  25. data/docs/plugins/test/file_system.md +1 -0
  26. data/docs/plugins/test/github_ci.md +48 -0
  27. data/docs/plugins/test/hostname.md +1 -0
  28. data/docs/plugins/test/ip.md +1 -0
  29. data/docs/plugins/test/jenkins_ci_conf.md +1 -1
  30. data/docs/plugins/test/jenkins_ci_masters_ok.md +1 -1
  31. data/docs/plugins/test/local_users.md +1 -0
  32. data/docs/plugins/test/mounts.md +1 -0
  33. data/docs/plugins/test/orphan_files.md +1 -0
  34. data/docs/plugins/test/ports.md +1 -0
  35. data/docs/plugins/test/spectre.md +1 -0
  36. data/docs/plugins/test/vulnerabilities.md +1 -0
  37. data/lib/hybrid_platforms_conductor/actions_executor.rb +8 -1
  38. data/lib/hybrid_platforms_conductor/common_config_dsl/github.rb +62 -0
  39. data/lib/hybrid_platforms_conductor/deployer.rb +97 -105
  40. data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +3 -3
  41. data/lib/hybrid_platforms_conductor/hpc_plugins/log/my_log_plugin.rb.sample +100 -0
  42. data/lib/hybrid_platforms_conductor/hpc_plugins/log/remote_fs.rb +179 -0
  43. data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +2 -2
  44. data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +1 -1
  45. data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +3 -1
  46. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +7 -20
  47. data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +1 -1
  48. data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +2 -1
  49. data/lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb +32 -0
  50. data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +3 -1
  51. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +3 -1
  52. data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +3 -1
  53. data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +3 -1
  54. data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +3 -1
  55. data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +3 -1
  56. data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +3 -1
  57. data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +2 -1
  58. data/lib/hybrid_platforms_conductor/log.rb +31 -0
  59. data/lib/hybrid_platforms_conductor/test_only_remote_node.rb +18 -0
  60. data/lib/hybrid_platforms_conductor/version.rb +1 -1
  61. data/spec/hybrid_platforms_conductor_test.rb +22 -6
  62. data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +3 -3
  63. data/spec/hybrid_platforms_conductor_test/api/deployer/config_dsl_spec.rb +24 -4
  64. data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +187 -212
  65. data/spec/hybrid_platforms_conductor_test/api/deployer/log_plugins/remote_fs_spec.rb +223 -0
  66. data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +4 -4
  67. data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +2 -2
  68. data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +1 -1
  69. data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb +72 -0
  70. data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +146 -98
  71. data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +240 -83
  72. data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +2 -1
  73. data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +1 -1
  74. data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +40 -53
  75. data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +2 -2
  76. data/spec/hybrid_platforms_conductor_test/test_log_no_read_plugin.rb +82 -0
  77. data/spec/hybrid_platforms_conductor_test/test_log_plugin.rb +103 -0
  78. metadata +30 -2
@@ -54,6 +54,7 @@ None
54
54
  | Metadata | Type | Usage
55
55
  | --- | --- | --- |
56
56
  | `image` | `String` | The name of the OS image to be used. The [configuration](../../config_dsl.md) should define the image and point it to a directory containing a `oval.json` that will contain definition of OVAL files to be checked for this OS(see above). |
57
+ | `local_node` | `Boolean` | Skip this test for nodes having this metadata set to `true` |
57
58
 
58
59
  ## Used environment variables
59
60
 
@@ -102,7 +102,14 @@ module HybridPlatformsConductor
102
102
  # * *progress_name* (String): Name to display on the progress bar [default: 'Executing actions']
103
103
  # Result::
104
104
  # * Hash<String, [Integer or Symbol, String, String]>: Exit status code (or Symbol in case of error or dry run), standard output and error for each node.
105
- def execute_actions(actions_per_nodes, timeout: nil, concurrent: false, log_to_dir: "#{@config.hybrid_platforms_dir}/run_logs", log_to_stdout: true, progress_name: 'Executing actions')
105
+ def execute_actions(
106
+ actions_per_nodes,
107
+ timeout: nil,
108
+ concurrent: false,
109
+ log_to_dir: "#{@config.hybrid_platforms_dir}/run_logs",
110
+ log_to_stdout: true,
111
+ progress_name: 'Executing actions'
112
+ )
106
113
  # Keep a list of nodes that will need remote access
107
114
  nodes_needing_connectors = []
108
115
  # Compute the ordered list of actions per selected node
@@ -0,0 +1,62 @@
1
+ require 'octokit'
2
+ require 'hybrid_platforms_conductor/credentials'
3
+
4
+ module HybridPlatformsConductor
5
+
6
+ module CommonConfigDsl
7
+
8
+ module Github
9
+
10
+ # Initialize the DSL
11
+ def init_github
12
+ # List of Github repositories definitions
13
+ # Array< Hash<Symbol, Object> >
14
+ # Each definition is just mapping the signature of #github_repos
15
+ @github_repos = []
16
+ end
17
+
18
+ # Register new Github repositories
19
+ #
20
+ # Parameters::
21
+ # * *url* (String): URL to the Github API [default: 'https://api.github.com']
22
+ # * *user* (String): User or organization name, storing repositories
23
+ # * *repos* (Array<String> or Symbol): List of repository names from this project, or :all for all [default: :all]
24
+ def github_repos(url: 'https://api.github.com', user:, repos: :all)
25
+ @github_repos << {
26
+ url: url,
27
+ user: user,
28
+ repos: repos
29
+ }
30
+ end
31
+
32
+ # Iterate over each Github repository
33
+ #
34
+ # Parameters::
35
+ # * Proc: Code called for each Github repository:
36
+ # * Parameters::
37
+ # * *github* (Octokit::Client): The client instance accessing the Github API
38
+ # * *repo_info* (Hash<Symbol, Object>): The repository info:
39
+ # * *name* (String): Repository name.
40
+ # * *slug* (String): Repository slug.
41
+ def for_each_github_repo
42
+ @github_repos.each do |repo_info|
43
+ Octokit.configure do |c|
44
+ c.api_endpoint = repo_info[:url]
45
+ end
46
+ Credentials.with_credentials_for(:github, @logger, @logger_stderr, url: repo_info[:url]) do |_github_user, github_token|
47
+ client = Octokit::Client.new(access_token: github_token)
48
+ (repo_info[:repos] == :all ? client.repositories(repo_info[:user]).map { |repo| repo[:name] } : repo_info[:repos]).each do |name|
49
+ yield client, {
50
+ name: name,
51
+ slug: "#{repo_info[:user]}/#{name}"
52
+ }
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ end
@@ -21,12 +21,19 @@ module HybridPlatformsConductor
21
21
  # Extend the Config DSL
22
22
  module ConfigDSLExtension
23
23
 
24
+ # List of log plugins. Each info has the following properties:
25
+ # * *nodes_selectors_stack* (Array<Object>): Stack of nodes selectors impacted by this rule.
26
+ # * *log_plugins* (Array<Symbol>): List of log plugins to be used to store deployment logs.
27
+ # Array< Hash<Symbol, Object> >
28
+ attr_reader :deployment_logs
29
+
24
30
  # Integer: Timeout (in seconds) for packaging repositories
25
31
  attr_reader :packaging_timeout_secs
26
32
 
27
33
  # Mixin initializer
28
34
  def init_deployer_config
29
35
  @packaging_timeout_secs = 60
36
+ @deployment_logs = []
30
37
  end
31
38
 
32
39
  # Set the packaging timeout
@@ -37,6 +44,17 @@ module HybridPlatformsConductor
37
44
  @packaging_timeout_secs = packaging_timeout_secs
38
45
  end
39
46
 
47
+ # Set the deployment log plugins to be used
48
+ #
49
+ # Parameters::
50
+ # * *log_plugins* (Symbol or Array<Symbol>): The list of (or single) log plugins to be used
51
+ def send_logs_to(*log_plugins)
52
+ @deployment_logs << {
53
+ nodes_selectors_stack: current_nodes_selectors_stack,
54
+ log_plugins: log_plugins.flatten
55
+ }
56
+ end
57
+
40
58
  end
41
59
 
42
60
  include LoggerHelpers
@@ -94,6 +112,20 @@ module HybridPlatformsConductor
94
112
  @services_handler = services_handler
95
113
  @secrets = []
96
114
  @provisioners = Plugins.new(:provisioner, logger: @logger, logger_stderr: @logger_stderr)
115
+ @log_plugins = Plugins.new(
116
+ :log,
117
+ logger: @logger,
118
+ logger_stderr: @logger_stderr,
119
+ init_plugin: proc do |plugin_class|
120
+ plugin_class.new(
121
+ logger: @logger,
122
+ logger_stderr: @logger_stderr,
123
+ config: @config,
124
+ nodes_handler: @nodes_handler,
125
+ actions_executor: @actions_executor
126
+ )
127
+ end
128
+ )
97
129
  # Default values
98
130
  @use_why_run = false
99
131
  @timeout = nil
@@ -319,7 +351,7 @@ module HybridPlatformsConductor
319
351
  )
320
352
  instance.with_running_instance(stop_on_exit: true, destroy_on_exit: !reuse_instance, port: 22) do
321
353
  # Test-provisioned nodes have SSH Session Exec capabilities and are not local
322
- sub_executable.nodes_handler.override_metadata_of node, :ssh_session_exec, 'true'
354
+ sub_executable.nodes_handler.override_metadata_of node, :ssh_session_exec, true
323
355
  sub_executable.nodes_handler.override_metadata_of node, :local_node, false
324
356
  # Test-provisioned nodes use default sudo
325
357
  sub_executable.config.sudo_procs.replace(sub_executable.config.sudo_procs.map do |sudo_proc_info|
@@ -355,72 +387,31 @@ module HybridPlatformsConductor
355
387
  # * *nodes* (Array<String>): Nodes to get info from
356
388
  # Result::
357
389
  # * Hash<String, Hash<Symbol,Object>: The deployed info, per node name.
358
- # Properties are defined by the Deployer#save_logs method, and additionally to them the following properties can be set:
359
- # * *error* (String): Optional property set in case of error
390
+ # * *error* (String): Error string in case deployment logs could not be retrieved. If set then further properties will be ignored. [optional]
391
+ # * *services* (Array<String>): List of services deployed on the node
392
+ # * *deployment_info* (Hash<Symbol,Object>): Deployment metadata
393
+ # * *exit_status* (Integer or Symbol): Deployment exit status
394
+ # * *stdout* (String): Deployment stdout
395
+ # * *stderr* (String): Deployment stderr
360
396
  def deployment_info_from(*nodes)
397
+ nodes = nodes.flatten
361
398
  @actions_executor.max_threads = 64
362
- Hash[@actions_executor.
363
- execute_actions(
364
- Hash[nodes.flatten.map do |node|
365
- [
366
- node,
367
- { remote_bash: "cd /var/log/deployments && ls -t | head -1 | xargs sed '/===== STDOUT =====/q'" }
368
- ]
369
- end],
370
- log_to_stdout: false,
371
- concurrent: true,
372
- timeout: 10,
373
- progress_name: 'Getting deployment info'
374
- ).
375
- map do |node, (exit_status, stdout, stderr)|
376
- # Expected format for stdout:
377
- # Property1: Value1
378
- # ...
379
- # PropertyN: ValueN
380
- # ===== STDOUT =====
381
- # ...
382
- deploy_info = {}
383
- if exit_status.is_a?(Symbol)
384
- deploy_info[:error] = "Error: #{exit_status}\n#{stderr}"
385
- else
386
- stdout_lines = stdout.split("\n")
387
- if stdout_lines.first =~ /No such file or directory/
388
- deploy_info[:error] = '/var/log/deployments missing'
389
- else
390
- stdout_lines.each do |line|
391
- if line =~ /^([^:]+): (.+)$/
392
- key_str, value = $1, $2
393
- key = key_str.to_sym
394
- # Type-cast some values
395
- case key_str
396
- when 'date'
397
- # Date and time values
398
- # Thu Nov 23 18:43:01 UTC 2017
399
- deploy_info[key] = Time.parse(value)
400
- when 'debug'
401
- # Boolean values
402
- # Yes
403
- deploy_info[key] = (value == 'Yes')
404
- when /^diff_files_.+$/, 'services'
405
- # Array of strings
406
- # my_file.txt, other_file.txt
407
- deploy_info[key] = value.split(', ')
408
- else
409
- deploy_info[key] = value
410
- end
411
- else
412
- deploy_info[:unknown_lines] = [] unless deploy_info.key?(:unknown_lines)
413
- deploy_info[:unknown_lines] << line
414
- end
415
- end
416
- end
417
- end
418
- [
419
- node,
420
- deploy_info
421
- ]
422
- end
423
- ]
399
+ read_actions_results = @actions_executor.execute_actions(
400
+ Hash[nodes.map do |node|
401
+ master_log_plugin = @log_plugins[log_plugins_for(node).first]
402
+ master_log_plugin.respond_to?(:actions_to_read_logs) ? [node, master_log_plugin.actions_to_read_logs(node)] : nil
403
+ end.compact],
404
+ log_to_stdout: false,
405
+ concurrent: true,
406
+ timeout: 10,
407
+ progress_name: 'Read deployment logs'
408
+ )
409
+ Hash[nodes.map do |node|
410
+ [
411
+ node,
412
+ @log_plugins[log_plugins_for(node).first].logs_for(node, *(read_actions_results[node] || [nil, nil, nil]))
413
+ ]
414
+ end]
424
415
  end
425
416
 
426
417
  # Parse stdout and stderr of a given deploy run and get the list of tasks with their status
@@ -584,47 +575,48 @@ module HybridPlatformsConductor
584
575
  # * *services* (Hash<String, Array<String>>): List of services that have been deployed, per node
585
576
  def save_logs(logs, services)
586
577
  section "Saving deployment logs for #{logs.size} nodes" do
587
- Dir.mktmpdir('hybrid_platforms_conductor-logs') do |tmp_dir|
588
- ssh_user = @actions_executor.connector(:ssh).ssh_user
589
- @actions_executor.execute_actions(
590
- Hash[logs.map do |node, (exit_status, stdout, stderr)|
591
- # Create a log file to be scp with all relevant info
592
- now = Time.now.utc
593
- log_file = "#{tmp_dir}/#{node}_#{now.strftime('%F_%H%M%S')}_#{ssh_user}"
594
- services_info = @services_handler.log_info_for(node, services[node])
595
- File.write(
596
- log_file,
597
- services_info.merge(
598
- date: now.strftime('%F %T'),
599
- user: ssh_user,
600
- debug: log_debug? ? 'Yes' : 'No',
601
- services: services[node].join(', '),
602
- exit_status: exit_status
603
- ).map { |property, value| "#{property}: #{value}" }.join("\n") +
604
- "\n===== STDOUT =====\n" +
605
- (stdout || '') +
606
- "\n===== STDERR =====\n" +
607
- (stderr || '')
608
- )
609
- [
610
- node,
611
- {
612
- remote_bash: "#{ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(node)} "}mkdir -p /var/log/deployments",
613
- scp: {
614
- log_file => '/var/log/deployments',
615
- :sudo => ssh_user != 'root',
616
- :owner => 'root',
617
- :group => 'root'
618
- }
619
- }
620
- ]
621
- end],
622
- timeout: 10,
623
- concurrent: true,
624
- log_to_dir: nil
625
- )
626
- end
578
+ ssh_user = @actions_executor.connector(:ssh).ssh_user
579
+ @actions_executor.execute_actions(
580
+ Hash[logs.map do |node, (exit_status, stdout, stderr)|
581
+ [
582
+ node,
583
+ log_plugins_for(node).
584
+ map do |log_plugin|
585
+ @log_plugins[log_plugin].actions_to_save_logs(
586
+ node,
587
+ services[node],
588
+ @services_handler.log_info_for(node, services[node]).merge(
589
+ date: Time.now.utc.strftime('%F %T'),
590
+ user: ssh_user
591
+ ),
592
+ exit_status,
593
+ stdout,
594
+ stderr
595
+ )
596
+ end.
597
+ flatten(1)
598
+ ]
599
+ end],
600
+ timeout: 10,
601
+ concurrent: true,
602
+ log_to_dir: nil,
603
+ progress_name: 'Saving logs'
604
+ )
605
+ end
606
+ end
607
+
608
+ # Get the list of log plugins to be used for a given node
609
+ #
610
+ # Parameters::
611
+ # * *node* (String): The node for which log plugins are queried
612
+ # Result::
613
+ # * Array<Symbol>: The list of log plugins
614
+ def log_plugins_for(node)
615
+ node_log_plugins = @nodes_handler.select_confs_for_node(node, @config.deployment_logs).inject([]) do |log_plugins, deployment_logs_info|
616
+ log_plugins + deployment_logs_info[:log_plugins]
627
617
  end
618
+ node_log_plugins << :remote_fs if node_log_plugins.empty?
619
+ node_log_plugins
628
620
  end
629
621
 
630
622
  end
@@ -238,7 +238,7 @@ module HybridPlatformsConductor
238
238
  # * *bash_cmds* (String): Bash commands to execute
239
239
  def remote_bash(bash_cmds)
240
240
  ssh_cmd =
241
- if @nodes_handler.get_ssh_session_exec_of(@node) == 'false'
241
+ if @nodes_handler.get_ssh_session_exec_of(@node) == false
242
242
  # When ExecSession is disabled we need to use stdin directly
243
243
  "{ cat | #{ssh_exec} #{ssh_url} -T; } <<'HPC_EOF'\n#{bash_cmds}\nHPC_EOF"
244
244
  else
@@ -300,7 +300,7 @@ module HybridPlatformsConductor
300
300
  # * *owner* (String or nil): Owner to be used when copying the files, or nil for current one [default: nil]
301
301
  # * *group* (String or nil): Group to be used when copying the files, or nil for current one [default: nil]
302
302
  def remote_copy(from, to, sudo: false, owner: nil, group: nil)
303
- if @nodes_handler.get_ssh_session_exec_of(@node) == 'false'
303
+ if @nodes_handler.get_ssh_session_exec_of(@node) == false
304
304
  # We don't have ExecSession, so don't use ssh, but scp instead.
305
305
  if sudo
306
306
  # We need to first copy the file in an accessible directory, and then sudo mv
@@ -513,7 +513,7 @@ module HybridPlatformsConductor
513
513
  if current_users.empty?
514
514
  log_debug "[ ControlMaster - #{ssh_url} ] - Creating SSH ControlMaster..."
515
515
  exit_status = nil
516
- if @nodes_handler.get_ssh_session_exec_of(node) == 'false'
516
+ if @nodes_handler.get_ssh_session_exec_of(node) == false
517
517
  # Here we have to create a ControlMaster using an interactive session, as the SSH server prohibits ExecSession, and so command executions.
518
518
  # We'll do that using another terminal spawned in the background.
519
519
  if ENV['hpc_interactive'] == 'false'
@@ -0,0 +1,100 @@
1
+ require 'hybrid_platforms_conductor/log'
2
+
3
+ module HybridPlatformsConductor
4
+
5
+ module HpcPlugins
6
+
7
+ module Log
8
+
9
+ # Save logs on the remote node's file system
10
+ class RemoteFs < HybridPlatformsConductor::Log
11
+
12
+ # Get actions to save logs
13
+ # [API] - This method is mandatory.
14
+ # [API] - The following API components are accessible:
15
+ # * *@config* (Config): Main configuration API.
16
+ # * *@nodes_handler* (NodesHandler): Nodes handler API.
17
+ # * *@actions_executor* (ActionsExecutor): Actions executor API.
18
+ #
19
+ # Parameters::
20
+ # * *node* (String): Node for which logs are being saved
21
+ # * *services* (Array<String>): The list of services that have been deployed on this node
22
+ # * *deployment_info* (Hash<Symbol,Object>): Additional information to attach to the logs
23
+ # * *exit_status* (Integer or Symbol): Exit status of the deployment
24
+ # * *stdout* (String): Deployment's stdout
25
+ # * *stderr* (String): Deployment's stderr
26
+ # Result::
27
+ # * Array< Hash<Symbol,Object> >: List of actions to be done
28
+ def actions_to_save_logs(node, services, deployment_info, exit_status, stdout, stderr)
29
+ # Return here all actions that are to be run to save those logs.
30
+ [
31
+ {
32
+ bash: <<~EOS
33
+ cat <<'EOLOGFILE' >>all_logs.txt
34
+ Deployment log on #{node}:
35
+ #{stdout}
36
+ EOLOGFILE
37
+ EOS
38
+ }
39
+ ]
40
+ end
41
+
42
+ # Get actions to read logs.
43
+ # If provided, this method can return some actions to be executed that will fetch logs from servers or remote nodes.
44
+ # By using this method to run actions instead of the synchronous method logs_from, such actions will be run in parallel which can greatly improve time-consuming operations when querying a lot of nodes.
45
+ # [API] - This method is optional.
46
+ # [API] - The following API components are accessible:
47
+ # * *@config* (Config): Main configuration API.
48
+ # * *@nodes_handler* (NodesHandler): Nodes handler API.
49
+ # * *@actions_executor* (ActionsExecutor): Actions executor API.
50
+ #
51
+ # Parameters::
52
+ # * *node* (String): Node for which deployment logs are being read
53
+ # Result::
54
+ # * Array< Hash<Symbol,Object> >: List of actions to be done
55
+ def actions_to_read_logs(node)
56
+ [
57
+ { bash: 'cat all_logs.txt' }
58
+ ]
59
+ end
60
+
61
+ # Get deployment logs from a node.
62
+ # This method can use the result of actions previously run to read logs, as returned by the actions_to_read_logs method.
63
+ # [API] - This method is mandatory.
64
+ # [API] - The following API components are accessible:
65
+ # * *@config* (Config): Main configuration API.
66
+ # * *@nodes_handler* (NodesHandler): Nodes handler API.
67
+ # * *@actions_executor* (ActionsExecutor): Actions executor API.
68
+ #
69
+ # Parameters::
70
+ # * *node* (String): The node we want deployment logs from
71
+ # * *exit_status* (Integer, Symbol or nil): Exit status of actions to read logs, or nil if no action was returned by actions_to_read_logs
72
+ # * *stdout* (String or nil): stdout of actions to read logs, or nil if no action was returned by actions_to_read_logs
73
+ # * *stderr* (String or nil): stderr of actions to read logs, or nil if no action was returned by actions_to_read_logs
74
+ # Result::
75
+ # * Hash<Symbol,Object>: Deployment log information:
76
+ # * *error* (String): Error string in case deployment logs could not be retrieved. If set then further properties will be ignored. [optional]
77
+ # * *services* (Array<String>): List of services deployed on the node
78
+ # * *deployment_info* (Hash<Symbol,Object>): Deployment metadata
79
+ # * *exit_status* (Integer or Symbol): Deployment exit status
80
+ # * *stdout* (String): Deployment stdout
81
+ # * *stderr* (String): Deployment stderr
82
+ def logs_for(node, exit_status, stdout, stderr)
83
+ # Here we should retrieve this info from somewhere.
84
+ # Based on this example, stdout is the value of the execution of the action 'cat all_logs.txt' as returned by actions_to_read_logs.
85
+ {
86
+ services: %w[unknown],
87
+ deployment_info: {},
88
+ exit_status: 0,
89
+ stdout: stdout,
90
+ stderr: ''
91
+ }
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ end