hybrid_platforms_conductor 32.16.2 → 32.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -0
- data/README.md +3 -0
- data/bin/last_deploys +4 -1
- data/bin/nodes_to_deploy +5 -5
- data/docs/config_dsl.md +22 -0
- data/docs/gen/mermaid/README.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/check-node.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/deploy.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/free_ips.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/get_impacted_nodes.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/last_deploys.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/nodes_to_deploy.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/report.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/run.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/ssh_config.md-0.png +0 -0
- data/docs/gen/mermaid/docs/executables/test.md-0.png +0 -0
- data/docs/plugins.md +26 -0
- data/docs/plugins/connector/ssh.md +1 -1
- data/docs/plugins/log/remote_fs.md +26 -0
- data/docs/plugins/test/bitbucket_conf.md +1 -1
- data/docs/plugins/test/check_deploy_and_idempotence.md +1 -1
- data/docs/plugins/test/connection.md +1 -0
- data/docs/plugins/test/deploy_removes_root_access.md +1 -1
- data/docs/plugins/test/file_system.md +1 -0
- data/docs/plugins/test/github_ci.md +48 -0
- data/docs/plugins/test/hostname.md +1 -0
- data/docs/plugins/test/ip.md +1 -0
- data/docs/plugins/test/jenkins_ci_conf.md +1 -1
- data/docs/plugins/test/jenkins_ci_masters_ok.md +1 -1
- data/docs/plugins/test/local_users.md +1 -0
- data/docs/plugins/test/mounts.md +1 -0
- data/docs/plugins/test/orphan_files.md +1 -0
- data/docs/plugins/test/ports.md +1 -0
- data/docs/plugins/test/spectre.md +1 -0
- data/docs/plugins/test/vulnerabilities.md +1 -0
- data/lib/hybrid_platforms_conductor/actions_executor.rb +8 -1
- data/lib/hybrid_platforms_conductor/common_config_dsl/github.rb +62 -0
- data/lib/hybrid_platforms_conductor/deployer.rb +97 -105
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +3 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/log/my_log_plugin.rb.sample +100 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/log/remote_fs.rb +179 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/connection.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_freshness.rb +7 -20
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/deploy_removes_root_access.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +2 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/github_ci.rb +32 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ports.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +3 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +2 -1
- data/lib/hybrid_platforms_conductor/log.rb +31 -0
- data/lib/hybrid_platforms_conductor/test_only_remote_node.rb +18 -0
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test.rb +22 -6
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +3 -3
- data/spec/hybrid_platforms_conductor_test/api/deployer/config_dsl_spec.rb +24 -4
- data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +187 -212
- data/spec/hybrid_platforms_conductor_test/api/deployer/log_plugins/remote_fs_spec.rb +223 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +4 -4
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +2 -2
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/global_spec.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/tests_runner/test_plugins/github_ci_spec.rb +72 -0
- data/spec/hybrid_platforms_conductor_test/executables/last_deploys_spec.rb +146 -98
- data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +240 -83
- data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +2 -1
- data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/helpers/deployer_helpers.rb +40 -53
- data/spec/hybrid_platforms_conductor_test/helpers/deployer_test_helpers.rb +2 -2
- data/spec/hybrid_platforms_conductor_test/test_log_no_read_plugin.rb +82 -0
- data/spec/hybrid_platforms_conductor_test/test_log_plugin.rb +103 -0
- 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(
|
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,
|
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
|
-
#
|
359
|
-
# * *
|
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
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
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
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
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) ==
|
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) ==
|
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) ==
|
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
|