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.
- 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
|