hybrid_platforms_conductor 33.5.0 → 33.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/hybrid_platforms_conductor/actions_executor.rb +29 -1
- data/lib/hybrid_platforms_conductor/connector.rb +4 -1
- data/lib/hybrid_platforms_conductor/deployer.rb +5 -7
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/local.rb +2 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +4 -3
- data/lib/hybrid_platforms_conductor/hpc_plugins/log/remote_fs.rb +5 -6
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/provisioner/proxmox.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/file_system.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/hostname.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/ip.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/local_users.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/mounts.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/orphan_files.rb +1 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/spectre.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/vulnerabilities.rb +1 -2
- data/lib/hybrid_platforms_conductor/test.rb +21 -7
- data/lib/hybrid_platforms_conductor/tests_runner.rb +7 -6
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/local/remote_actions_spec.rb +78 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/helpers_spec.rb +195 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/log_plugins/remote_fs_spec.rb +215 -0
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +38 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/chef_versions.yml +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/nodes/node.json +15 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/policyfiles/test_policy.rb +3 -0
- data/spec/hybrid_platforms_conductor_test/shared_examples/deployer.rb +134 -0
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a1e882e48d05f919ad5818c9251e045f941d78a9eacc16824f3fd49e787d91b5
|
|
4
|
+
data.tar.gz: b685a6a1ca1f6f40714da2443ad7de95d78e90489f15a4b8499e153f4d84945a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f9386d953b2e652fd453656a21a935470099ba3f935a82229829d5777408e93149833883d7acd277da6cf2f08ba5ca49c8c62d43d3207b34113c347299335e5f
|
|
7
|
+
data.tar.gz: 9066d78f77fed46560b1884bade1074055da61547bd196c2a6479cf9412ba30f9d7518f91e05244307b703ebd241a620985e59f93a7911cd353543af26ae3699
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
# [v33.5.1](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.5.0...v33.5.1) (2021-07-07 12:01:32)
|
|
2
|
+
|
|
3
|
+
### Patches
|
|
4
|
+
|
|
5
|
+
* [[Bugfix] [#87] Make sure local nodes and root accounts are taken into account when getting sudo prefixes](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/cb626f1c99a6f1a95c9c884c03bf3fd71045259c)
|
|
6
|
+
|
|
1
7
|
# [v33.5.0](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.4.0...v33.5.0) (2021-07-07 11:03:01)
|
|
2
8
|
|
|
3
9
|
### Features
|
|
@@ -53,7 +53,8 @@ module HybridPlatformsConductor
|
|
|
53
53
|
logger_stderr: @logger_stderr,
|
|
54
54
|
config: @config,
|
|
55
55
|
cmd_runner: @cmd_runner,
|
|
56
|
-
nodes_handler: @nodes_handler
|
|
56
|
+
nodes_handler: @nodes_handler,
|
|
57
|
+
actions_executor: self
|
|
57
58
|
)
|
|
58
59
|
end
|
|
59
60
|
)
|
|
@@ -246,6 +247,33 @@ module HybridPlatformsConductor
|
|
|
246
247
|
@connector_plugins[connector_name]
|
|
247
248
|
end
|
|
248
249
|
|
|
250
|
+
# Is the access to a given node privileged?
|
|
251
|
+
# Take into account if remote actions are executed on a local node, and configurable sudos.
|
|
252
|
+
#
|
|
253
|
+
# Parameters::
|
|
254
|
+
# * *node* (String): Node on which we want privileged access
|
|
255
|
+
# Result::
|
|
256
|
+
# * Boolean: Is the access privileged?
|
|
257
|
+
def privileged_access?(node)
|
|
258
|
+
(@nodes_handler.get_local_node_of(node) ? @cmd_runner.whoami : connector(:ssh).ssh_user) == 'root'
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# Get the sudo prefix to get privileged access.
|
|
262
|
+
# Take into account if remote actions are executed on a local node, and configurable sudos.
|
|
263
|
+
#
|
|
264
|
+
# Parameters::
|
|
265
|
+
# * *node* (String): Node on which we want privileged access
|
|
266
|
+
# * *forward_env* (Boolean): Do we need to forward environment in case of sudo? [default: false]
|
|
267
|
+
# Result::
|
|
268
|
+
# * String: Sudo prefix to be used (can be empty if root is being used)
|
|
269
|
+
def sudo_prefix(node, forward_env: false)
|
|
270
|
+
if privileged_access?(node)
|
|
271
|
+
''
|
|
272
|
+
else
|
|
273
|
+
"#{@nodes_handler.sudo_on(node)} #{forward_env ? '-E ' : ''}"
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
249
277
|
private
|
|
250
278
|
|
|
251
279
|
# Execute a list of actions for a node, and return exit codes, stdout and stderr of those actions.
|
|
@@ -14,16 +14,19 @@ module HybridPlatformsConductor
|
|
|
14
14
|
# * *config* (Config): Config to be used. [default: Config.new]
|
|
15
15
|
# * *cmd_runner* (CmdRunner): Command executor to be used. [default: CmdRunner.new]
|
|
16
16
|
# * *nodes_handler* (NodesHandler): NodesHandler to be used. [default: NodesHandler.new]
|
|
17
|
+
# * *actions_executor* (ActionsExecutor): ActionsExecutor to be used. [default: ActionsExecutor.new]
|
|
17
18
|
def initialize(
|
|
18
19
|
logger: Logger.new($stdout),
|
|
19
20
|
logger_stderr: Logger.new($stderr),
|
|
20
21
|
config: Config.new,
|
|
21
22
|
cmd_runner: CmdRunner.new,
|
|
22
|
-
nodes_handler: NodesHandler.new
|
|
23
|
+
nodes_handler: NodesHandler.new,
|
|
24
|
+
actions_executor: ActionsExecutor.new
|
|
23
25
|
)
|
|
24
26
|
super(logger: logger, logger_stderr: logger_stderr, config: config)
|
|
25
27
|
@cmd_runner = cmd_runner
|
|
26
28
|
@nodes_handler = nodes_handler
|
|
29
|
+
@actions_executor = actions_executor
|
|
27
30
|
# If the connector has an initializer, use it
|
|
28
31
|
init if respond_to?(:init)
|
|
29
32
|
end
|
|
@@ -544,15 +544,13 @@ module HybridPlatformsConductor
|
|
|
544
544
|
# Result::
|
|
545
545
|
# * 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.
|
|
546
546
|
def deploy(services)
|
|
547
|
-
# Get the ssh user directly from the connector
|
|
548
|
-
ssh_user = @actions_executor.connector(:ssh).ssh_user
|
|
549
|
-
|
|
550
547
|
# Deploy for real
|
|
551
548
|
@nodes_handler.prefetch_metadata_of services.keys, :image
|
|
552
549
|
outputs = @actions_executor.execute_actions(
|
|
553
550
|
services.map do |node, node_services|
|
|
554
551
|
image_id = @nodes_handler.get_image_of(node)
|
|
555
|
-
|
|
552
|
+
need_sudo = !@actions_executor.privileged_access?(node)
|
|
553
|
+
sudo = @actions_executor.sudo_prefix(node)
|
|
556
554
|
# Install corporate certificates if present
|
|
557
555
|
certificate_actions =
|
|
558
556
|
if @local_environment && ENV['hpc_certificates']
|
|
@@ -568,7 +566,7 @@ module HybridPlatformsConductor
|
|
|
568
566
|
{
|
|
569
567
|
scp: {
|
|
570
568
|
ENV['hpc_certificates'] => '/usr/local/share/ca-certificates',
|
|
571
|
-
:sudo =>
|
|
569
|
+
:sudo => need_sudo
|
|
572
570
|
},
|
|
573
571
|
remote_bash: "#{sudo}update-ca-certificates"
|
|
574
572
|
}
|
|
@@ -584,7 +582,7 @@ module HybridPlatformsConductor
|
|
|
584
582
|
cert_file,
|
|
585
583
|
'/etc/pki/ca-trust/source/anchors'
|
|
586
584
|
]
|
|
587
|
-
end.to_h.merge(sudo:
|
|
585
|
+
end.to_h.merge(sudo: need_sudo),
|
|
588
586
|
remote_bash: [
|
|
589
587
|
"#{sudo}update-ca-trust enable",
|
|
590
588
|
"#{sudo}update-ca-trust extract"
|
|
@@ -619,7 +617,7 @@ module HybridPlatformsConductor
|
|
|
619
617
|
services.keys.map do |node|
|
|
620
618
|
[
|
|
621
619
|
node,
|
|
622
|
-
{ remote_bash: "#{
|
|
620
|
+
{ remote_bash: "#{@actions_executor.sudo_prefix(node)}./mutex_dir unlock /tmp/hybrid_platforms_conductor_deploy_lock" }
|
|
623
621
|
]
|
|
624
622
|
end.to_h,
|
|
625
623
|
timeout: 10,
|
|
@@ -77,8 +77,8 @@ module HybridPlatformsConductor
|
|
|
77
77
|
def remote_copy(from, to, sudo: false, owner: nil, group: nil)
|
|
78
78
|
# If the destination is a relative path, prepend the workspace dir to it.
|
|
79
79
|
to = "#{workspace_for(@node)}/#{to}" unless to.start_with?('/')
|
|
80
|
-
if sudo
|
|
81
|
-
run_cmd "#{@
|
|
80
|
+
if sudo && !@actions_executor.privileged_access?(@node)
|
|
81
|
+
run_cmd "#{@actions_executor.sudo_prefix(@node)}cp -r \"#{from}\" \"#{to}\""
|
|
82
82
|
else
|
|
83
83
|
FileUtils.cp_r from, to unless @cmd_runner.dry_run
|
|
84
84
|
end
|
|
@@ -310,13 +310,14 @@ module HybridPlatformsConductor
|
|
|
310
310
|
# * *owner* (String or nil): Owner to be used when copying the files, or nil for current one [default: nil]
|
|
311
311
|
# * *group* (String or nil): Group to be used when copying the files, or nil for current one [default: nil]
|
|
312
312
|
def remote_copy(from, to, sudo: false, owner: nil, group: nil)
|
|
313
|
+
need_sudo = sudo && !@actions_executor.privileged_access?(@node)
|
|
313
314
|
if @nodes_handler.get_ssh_session_exec_of(@node) == false
|
|
314
315
|
# We don't have ExecSession, so don't use ssh, but scp instead.
|
|
315
|
-
if
|
|
316
|
+
if need_sudo
|
|
316
317
|
# We need to first copy the file in an accessible directory, and then sudo mv
|
|
317
318
|
remote_bash('mkdir -p hpc_tmp_scp')
|
|
318
319
|
run_cmd "scp -S #{ssh_exec} #{from} #{ssh_url}:./hpc_tmp_scp"
|
|
319
|
-
remote_bash("#{@
|
|
320
|
+
remote_bash("#{@actions_executor.sudo_prefix(@node)}mv ./hpc_tmp_scp/#{File.basename(from)} #{to}")
|
|
320
321
|
else
|
|
321
322
|
run_cmd "scp -S #{ssh_exec} #{from} #{ssh_url}:#{to}"
|
|
322
323
|
end
|
|
@@ -332,7 +333,7 @@ module HybridPlatformsConductor
|
|
|
332
333
|
#{File.basename(from)} | \
|
|
333
334
|
#{ssh_exec} \
|
|
334
335
|
#{ssh_url} \
|
|
335
|
-
\"#{
|
|
336
|
+
\"#{need_sudo ? @actions_executor.sudo_prefix(@node) : ''}tar \
|
|
336
337
|
--extract \
|
|
337
338
|
--gunzip \
|
|
338
339
|
--file - \
|
|
@@ -29,10 +29,9 @@ module HybridPlatformsConductor
|
|
|
29
29
|
# Result::
|
|
30
30
|
# * Array< Hash<Symbol,Object> >: List of actions to be done
|
|
31
31
|
def actions_to_save_logs(node, services, deployment_info, exit_status, stdout, stderr)
|
|
32
|
-
# Create a log file to be scp with all relevant info
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
log_file = "#{Dir.tmpdir}/hpc_deploy_logs/#{node}_#{Time.now.utc.strftime('%F_%H%M%S')}_#{ssh_user}"
|
|
32
|
+
# Create a log file to be scp-ed with all relevant info
|
|
33
|
+
sudo_prefix = @actions_executor.sudo_prefix(node)
|
|
34
|
+
log_file = "#{Dir.tmpdir}/hpc_deploy_logs/#{node}_#{Time.now.utc.strftime('%F_%H%M%S')}_#{@actions_executor.connector(:ssh).ssh_user}"
|
|
36
35
|
[
|
|
37
36
|
{
|
|
38
37
|
ruby: proc do
|
|
@@ -56,7 +55,7 @@ module HybridPlatformsConductor
|
|
|
56
55
|
{
|
|
57
56
|
scp: {
|
|
58
57
|
log_file => '/var/log/deployments',
|
|
59
|
-
:sudo =>
|
|
58
|
+
:sudo => !@actions_executor.privileged_access?(node),
|
|
60
59
|
:owner => 'root',
|
|
61
60
|
:group => 'root'
|
|
62
61
|
}
|
|
@@ -85,7 +84,7 @@ module HybridPlatformsConductor
|
|
|
85
84
|
# Result::
|
|
86
85
|
# * Array< Hash<Symbol,Object> >: List of actions to be done
|
|
87
86
|
def actions_to_read_logs(node)
|
|
88
|
-
sudo_prefix = @actions_executor.
|
|
87
|
+
sudo_prefix = @actions_executor.sudo_prefix(node)
|
|
89
88
|
[
|
|
90
89
|
{ remote_bash: "#{sudo_prefix}cat /var/log/deployments/`#{sudo_prefix}ls -t /var/log/deployments/ | head -1`" }
|
|
91
90
|
]
|
|
@@ -263,7 +263,7 @@ module HybridPlatformsConductor
|
|
|
263
263
|
raise "Missing file #{chef_versions_file} specifying the Chef Infra Client version to be deployed" unless File.exist?(chef_versions_file)
|
|
264
264
|
|
|
265
265
|
required_chef_client_version = YAML.load_file(chef_versions_file)['client']
|
|
266
|
-
sudo =
|
|
266
|
+
sudo = @actions_executor.sudo_prefix(node, forward_env: true)
|
|
267
267
|
[
|
|
268
268
|
{
|
|
269
269
|
# Install dependencies
|
|
@@ -436,7 +436,7 @@ module HybridPlatformsConductor
|
|
|
436
436
|
{
|
|
437
437
|
proxmox_test_info[:sync_node] => {
|
|
438
438
|
remote_bash: {
|
|
439
|
-
commands: "#{@actions_executor.
|
|
439
|
+
commands: "#{@actions_executor.sudo_prefix(proxmox_test_info[:sync_node], forward_env: true)}./proxmox/#{cmd}",
|
|
440
440
|
env: {
|
|
441
441
|
'hpc_user_for_proxmox' => user,
|
|
442
442
|
'hpc_password_for_proxmox' => password,
|
|
@@ -17,7 +17,7 @@ module HybridPlatformsConductor
|
|
|
17
17
|
# Flatten the paths rules so that we can spot inconsistencies in configuration
|
|
18
18
|
@config.aggregate_files_rules(@nodes_handler, @node).map do |path, rule_info|
|
|
19
19
|
[
|
|
20
|
-
"if #{@
|
|
20
|
+
"if #{@actions_executor.sudo_prefix(@node)}/bin/bash -c '[[ -d \"#{path}\" ]]' ; then echo 1 ; else echo 0 ; fi",
|
|
21
21
|
{
|
|
22
22
|
validator: proc do |stdout, stderr|
|
|
23
23
|
case stdout.last
|
|
@@ -12,8 +12,7 @@ module HybridPlatformsConductor
|
|
|
12
12
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
13
13
|
def test_on_node
|
|
14
14
|
{
|
|
15
|
-
#
|
|
16
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}hostname -s" => proc do |stdout|
|
|
15
|
+
"#{@actions_executor.sudo_prefix(@node)}hostname -s" => proc do |stdout|
|
|
17
16
|
assert_equal stdout.first, @node, "Expected hostname to be #{@node}, but got #{stdout.first} instead."
|
|
18
17
|
end
|
|
19
18
|
}
|
|
@@ -12,8 +12,7 @@ module HybridPlatformsConductor
|
|
|
12
12
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
13
13
|
def test_on_node
|
|
14
14
|
{
|
|
15
|
-
#
|
|
16
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}hostname -I" => proc do |stdout|
|
|
15
|
+
"#{@actions_executor.sudo_prefix(@node)}hostname -I" => proc do |stdout|
|
|
17
16
|
if stdout.first.nil?
|
|
18
17
|
error 'No IP returned by "hostname -I"'
|
|
19
18
|
else
|
|
@@ -59,8 +59,7 @@ module HybridPlatformsConductor
|
|
|
59
59
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
60
60
|
def test_on_node
|
|
61
61
|
{
|
|
62
|
-
#
|
|
63
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}cat /etc/passwd" => proc do |stdout|
|
|
62
|
+
"#{@actions_executor.sudo_prefix(@node)}cat /etc/passwd" => proc do |stdout|
|
|
64
63
|
passwd_users = stdout.map { |passwd_line| passwd_line.split(':').first }
|
|
65
64
|
missing_users = @nodes_handler.
|
|
66
65
|
select_confs_for_node(@node, @config.users_that_should_be_present).
|
|
@@ -63,8 +63,7 @@ module HybridPlatformsConductor
|
|
|
63
63
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
64
64
|
def test_on_node
|
|
65
65
|
{
|
|
66
|
-
#
|
|
67
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}mount" => proc do |stdout|
|
|
66
|
+
"#{@actions_executor.sudo_prefix(@node)}mount" => proc do |stdout|
|
|
68
67
|
mounts_info = stdout.map do |line|
|
|
69
68
|
fields = line.split
|
|
70
69
|
{
|
|
@@ -52,8 +52,7 @@ module HybridPlatformsConductor
|
|
|
52
52
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
53
53
|
def test_on_node
|
|
54
54
|
{
|
|
55
|
-
#
|
|
56
|
-
"#{@deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "}/usr/bin/find / \\( #{
|
|
55
|
+
"#{@actions_executor.sudo_prefix(@node)}/usr/bin/find / \\( #{
|
|
57
56
|
@nodes_handler.
|
|
58
57
|
select_confs_for_node(@node, @config.ignored_orphan_files_paths).
|
|
59
58
|
inject(DIRECTORIES_TO_ALWAYS_IGNORE) { |merged_paths, paths_to_ignore_info| merged_paths + paths_to_ignore_info[:ignored_paths] }.
|
|
@@ -18,7 +18,7 @@ module HybridPlatformsConductor
|
|
|
18
18
|
# Check my_test_plugin.rb.sample documentation for signature details.
|
|
19
19
|
def test_on_node
|
|
20
20
|
spectre_cmd = <<~EO_BASH
|
|
21
|
-
#{@
|
|
21
|
+
#{@actions_executor.sudo_prefix(@node)}/bin/bash <<'EOAction'
|
|
22
22
|
#{File.read("#{__dir__}/spectre-meltdown-checker.sh")}
|
|
23
23
|
EOAction
|
|
24
24
|
EO_BASH
|
|
@@ -56,8 +56,7 @@ module HybridPlatformsConductor
|
|
|
56
56
|
current_url
|
|
57
57
|
end
|
|
58
58
|
)
|
|
59
|
-
|
|
60
|
-
sudo = @deployer.instance_variable_get(:@actions_executor).connector(:ssh).ssh_user == 'root' ? '' : "#{@nodes_handler.sudo_on(@node)} "
|
|
59
|
+
sudo = @actions_executor.sudo_prefix(@node)
|
|
61
60
|
urls.map do |url|
|
|
62
61
|
# 1. Get the OVAL file on the node to be tested (uncompress it if needed)
|
|
63
62
|
# 2. Make sure oscap is installed
|
|
@@ -36,20 +36,34 @@ module HybridPlatformsConductor
|
|
|
36
36
|
# Constructor
|
|
37
37
|
#
|
|
38
38
|
# Parameters::
|
|
39
|
-
# * *logger* (Logger): Logger to be used
|
|
40
|
-
# * *logger_stderr* (Logger): Logger to be used for stderr
|
|
41
|
-
# * *config* (Config): Config to be used.
|
|
42
|
-
# * *cmd_runner* (CmdRunner):
|
|
43
|
-
# * *nodes_handler* (NodesHandler): Nodes handler
|
|
44
|
-
# * *
|
|
39
|
+
# * *logger* (Logger): Logger to be used [default: Logger.new($stdout)]
|
|
40
|
+
# * *logger_stderr* (Logger): Logger to be used for stderr [default: Logger.new($stderr)]
|
|
41
|
+
# * *config* (Config): Config to be used. [default: Config.new]
|
|
42
|
+
# * *cmd_runner* (CmdRunner): Command executor to be used. [default: CmdRunner.new]
|
|
43
|
+
# * *nodes_handler* (NodesHandler): Nodes handler to be used. [default: NodesHandler.new]
|
|
44
|
+
# * *actions_executor* (ActionsExecutor): Actions Executor to be used. [default: ActionsExecutor.new]
|
|
45
|
+
# * *deployer* (Deployer): Deployer that can be used by tests [default: Deployer.new]
|
|
45
46
|
# * *name* (String): Name of the test being instantiated [default: 'unknown_test']
|
|
46
47
|
# * *platform* (PlatformHandler): Platform handler for which the test is instantiated, or nil if global or node specific [default: nil]
|
|
47
48
|
# * *node* (String): Node name for which the test is instantiated, or nil if global or platform specific [default: nil]
|
|
48
49
|
# * *expected_failure* (String or nil): Expected failure, or nil if not expected to fail [default: nil]
|
|
49
|
-
def initialize(
|
|
50
|
+
def initialize(
|
|
51
|
+
logger: Logger.new($stdout),
|
|
52
|
+
logger_stderr: Logger.new($stderr),
|
|
53
|
+
config: Config.new,
|
|
54
|
+
cmd_runner: CmdRunner.new,
|
|
55
|
+
nodes_handler: NodesHandler.new,
|
|
56
|
+
actions_executor: ActionsExecutor.new,
|
|
57
|
+
deployer: Deployer.new,
|
|
58
|
+
name: 'unknown_test',
|
|
59
|
+
platform: nil,
|
|
60
|
+
node: nil,
|
|
61
|
+
expected_failure: nil
|
|
62
|
+
)
|
|
50
63
|
super(logger: logger, logger_stderr: logger_stderr, config: config)
|
|
51
64
|
@cmd_runner = cmd_runner
|
|
52
65
|
@nodes_handler = nodes_handler
|
|
66
|
+
@actions_executor = actions_executor
|
|
53
67
|
@deployer = deployer
|
|
54
68
|
@name = name
|
|
55
69
|
@platform = platform
|
|
@@ -274,12 +274,13 @@ module HybridPlatformsConductor
|
|
|
274
274
|
# * Test: Corresponding test
|
|
275
275
|
def new_test(test_name, platform: nil, node: nil, ignore_expected_failure: false)
|
|
276
276
|
(test_name.nil? ? Test : @tests_plugins[test_name]).new(
|
|
277
|
-
@logger,
|
|
278
|
-
@logger_stderr,
|
|
279
|
-
@config,
|
|
280
|
-
@cmd_runner,
|
|
281
|
-
@nodes_handler,
|
|
282
|
-
@
|
|
277
|
+
logger: @logger,
|
|
278
|
+
logger_stderr: @logger_stderr,
|
|
279
|
+
config: @config,
|
|
280
|
+
cmd_runner: @cmd_runner,
|
|
281
|
+
nodes_handler: @nodes_handler,
|
|
282
|
+
actions_executor: @actions_executor,
|
|
283
|
+
deployer: @deployer,
|
|
283
284
|
name: test_name.nil? ? :global : test_name,
|
|
284
285
|
platform: platform,
|
|
285
286
|
node: node,
|
|
@@ -107,6 +107,10 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
|
107
107
|
it 'copies files remotely with sudo' do
|
|
108
108
|
with_test_platform_for_remote_testing(
|
|
109
109
|
expected_cmds: [
|
|
110
|
+
[
|
|
111
|
+
'whoami',
|
|
112
|
+
proc { [0, 'test_user', ''] }
|
|
113
|
+
],
|
|
110
114
|
[
|
|
111
115
|
'sudo -u root cp -r "/path/to/src.file" "/remote_path/to/dst.dir"',
|
|
112
116
|
proc { [0, '', ''] }
|
|
@@ -117,9 +121,27 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
|
117
121
|
end
|
|
118
122
|
end
|
|
119
123
|
|
|
124
|
+
it 'copies files remotely with sudo when being root' do
|
|
125
|
+
with_test_platform_for_remote_testing(
|
|
126
|
+
expected_cmds: [
|
|
127
|
+
[
|
|
128
|
+
'whoami',
|
|
129
|
+
proc { [0, 'root', ''] }
|
|
130
|
+
]
|
|
131
|
+
]
|
|
132
|
+
) do
|
|
133
|
+
expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/remote_path/to/dst.dir')
|
|
134
|
+
test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir', sudo: true)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
120
138
|
it 'copies files remotely with a different sudo' do
|
|
121
139
|
with_test_platform_for_remote_testing(
|
|
122
140
|
expected_cmds: [
|
|
141
|
+
[
|
|
142
|
+
'whoami',
|
|
143
|
+
proc { [0, 'test_user', ''] }
|
|
144
|
+
],
|
|
123
145
|
[
|
|
124
146
|
'other_sudo --user root cp -r "/path/to/src.file" "/remote_path/to/dst.dir"',
|
|
125
147
|
proc { [0, '', ''] }
|
|
@@ -133,6 +155,23 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
|
133
155
|
end
|
|
134
156
|
end
|
|
135
157
|
|
|
158
|
+
it 'copies files remotely with a different sudo when being root' do
|
|
159
|
+
with_test_platform_for_remote_testing(
|
|
160
|
+
expected_cmds: [
|
|
161
|
+
[
|
|
162
|
+
'whoami',
|
|
163
|
+
proc { [0, 'root', ''] }
|
|
164
|
+
]
|
|
165
|
+
],
|
|
166
|
+
additional_config: <<~'EO_CONFIG'
|
|
167
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
|
168
|
+
EO_CONFIG
|
|
169
|
+
) do
|
|
170
|
+
expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/remote_path/to/dst.dir')
|
|
171
|
+
test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir', sudo: true)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
136
175
|
it 'copies files remotely with timeout' do
|
|
137
176
|
with_test_platform_for_remote_testing(
|
|
138
177
|
timeout: 5
|
|
@@ -152,6 +191,10 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
|
152
191
|
it 'copies relative files remotely with sudo' do
|
|
153
192
|
with_test_platform_for_remote_testing(
|
|
154
193
|
expected_cmds: [
|
|
194
|
+
[
|
|
195
|
+
'whoami',
|
|
196
|
+
proc { [0, 'test_user', ''] }
|
|
197
|
+
],
|
|
155
198
|
[
|
|
156
199
|
'sudo -u root cp -r "/path/to/src.file" "/tmp/hpc_local_workspaces/node/to/dst.dir"',
|
|
157
200
|
proc { [0, '', ''] }
|
|
@@ -162,9 +205,27 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
|
162
205
|
end
|
|
163
206
|
end
|
|
164
207
|
|
|
208
|
+
it 'copies relative files remotely with sudo when being root' do
|
|
209
|
+
with_test_platform_for_remote_testing(
|
|
210
|
+
expected_cmds: [
|
|
211
|
+
[
|
|
212
|
+
'whoami',
|
|
213
|
+
proc { [0, 'root', ''] }
|
|
214
|
+
]
|
|
215
|
+
]
|
|
216
|
+
) do
|
|
217
|
+
expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/tmp/hpc_local_workspaces/node/to/dst.dir')
|
|
218
|
+
test_connector.remote_copy('/path/to/src.file', 'to/dst.dir', sudo: true)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
165
222
|
it 'copies relative files remotely with a different sudo' do
|
|
166
223
|
with_test_platform_for_remote_testing(
|
|
167
224
|
expected_cmds: [
|
|
225
|
+
[
|
|
226
|
+
'whoami',
|
|
227
|
+
proc { [0, 'test_user', ''] }
|
|
228
|
+
],
|
|
168
229
|
[
|
|
169
230
|
'other_sudo --user root cp -r "/path/to/src.file" "/tmp/hpc_local_workspaces/node/to/dst.dir"',
|
|
170
231
|
proc { [0, '', ''] }
|
|
@@ -178,6 +239,23 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
|
178
239
|
end
|
|
179
240
|
end
|
|
180
241
|
|
|
242
|
+
it 'copies relative files remotely with a different sudo when being root' do
|
|
243
|
+
with_test_platform_for_remote_testing(
|
|
244
|
+
expected_cmds: [
|
|
245
|
+
[
|
|
246
|
+
'whoami',
|
|
247
|
+
proc { [0, 'root', ''] }
|
|
248
|
+
]
|
|
249
|
+
],
|
|
250
|
+
additional_config: <<~'EO_CONFIG'
|
|
251
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
|
252
|
+
EO_CONFIG
|
|
253
|
+
) do
|
|
254
|
+
expect(FileUtils).to receive(:cp_r).with('/path/to/src.file', '/tmp/hpc_local_workspaces/node/to/dst.dir')
|
|
255
|
+
test_connector.remote_copy('/path/to/src.file', 'to/dst.dir', sudo: true)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
181
259
|
end
|
|
182
260
|
|
|
183
261
|
end
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
describe HybridPlatformsConductor::ActionsExecutor do
|
|
2
|
+
|
|
3
|
+
context 'when checking helpers' do
|
|
4
|
+
|
|
5
|
+
it 'gives access to connectors' do
|
|
6
|
+
with_test_platform({}) do
|
|
7
|
+
expect(test_actions_executor.connector(:ssh)).not_to be_nil
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'returns if a user has privileged access on a node' do
|
|
12
|
+
with_test_platform({ nodes: { 'node' => {} } }) do
|
|
13
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
14
|
+
expect(test_actions_executor.privileged_access?('node')).to eq false
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'returns if a user has privileged access on a node when connecting with root' do
|
|
19
|
+
with_test_platform({ nodes: { 'node' => {} } }) do
|
|
20
|
+
test_actions_executor.connector(:ssh).ssh_user = 'root'
|
|
21
|
+
expect(test_actions_executor.privileged_access?('node')).to eq true
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'returns if a user has privileged access on a local node' do
|
|
26
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true } } } }) do
|
|
27
|
+
with_cmd_runner_mocked [
|
|
28
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
29
|
+
] do
|
|
30
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
31
|
+
expect(test_actions_executor.privileged_access?('node')).to eq false
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'returns if a user has privileged access on a local node when local user is root' do
|
|
37
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true } } } }) do
|
|
38
|
+
with_cmd_runner_mocked [
|
|
39
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
40
|
+
] do
|
|
41
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
42
|
+
expect(test_actions_executor.privileged_access?('node')).to eq true
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context 'with connection on a remote node' do
|
|
48
|
+
|
|
49
|
+
it 'returns the correct sudo prefix' do
|
|
50
|
+
with_test_platform({ nodes: { 'node' => {} } }) do
|
|
51
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
52
|
+
expect(test_actions_executor.sudo_prefix('node')).to eq 'sudo -u root '
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'returns the correct sudo prefix with env forwarding' do
|
|
57
|
+
with_test_platform({ nodes: { 'node' => {} } }) do
|
|
58
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
59
|
+
expect(test_actions_executor.sudo_prefix('node', forward_env: true)).to eq 'sudo -u root -E '
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'returns the correct sudo prefix when connecting as root' do
|
|
64
|
+
with_test_platform({ nodes: { 'node' => {} } }) do
|
|
65
|
+
test_actions_executor.connector(:ssh).ssh_user = 'root'
|
|
66
|
+
expect(test_actions_executor.sudo_prefix('node')).to eq ''
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'returns the correct sudo prefix with a different sudo' do
|
|
71
|
+
with_test_platform(
|
|
72
|
+
{ nodes: { 'node' => {} } },
|
|
73
|
+
additional_config: <<~'EO_CONFIG'
|
|
74
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
|
75
|
+
EO_CONFIG
|
|
76
|
+
) do
|
|
77
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
78
|
+
expect(test_actions_executor.sudo_prefix('node')).to eq 'other_sudo --user root '
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'returns the correct sudo prefix with a different sudo and env forwarding' do
|
|
83
|
+
with_test_platform(
|
|
84
|
+
{ nodes: { 'node' => {} } },
|
|
85
|
+
additional_config: <<~'EO_CONFIG'
|
|
86
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
|
87
|
+
EO_CONFIG
|
|
88
|
+
) do
|
|
89
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
90
|
+
expect(test_actions_executor.sudo_prefix('node', forward_env: true)).to eq 'other_sudo --user root -E '
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it 'returns the correct sudo prefix with a different sudo when connecting as root' do
|
|
95
|
+
with_test_platform(
|
|
96
|
+
{ nodes: { 'node' => {} } },
|
|
97
|
+
additional_config: <<~'EO_CONFIG'
|
|
98
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
|
99
|
+
EO_CONFIG
|
|
100
|
+
) do
|
|
101
|
+
test_actions_executor.connector(:ssh).ssh_user = 'root'
|
|
102
|
+
expect(test_actions_executor.sudo_prefix('node')).to eq ''
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
context 'with connection on a local node' do
|
|
109
|
+
|
|
110
|
+
it 'returns the correct sudo prefix' do
|
|
111
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true } } } }) do
|
|
112
|
+
with_cmd_runner_mocked [
|
|
113
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
114
|
+
] do
|
|
115
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
116
|
+
expect(test_actions_executor.sudo_prefix('node')).to eq 'sudo -u root '
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'returns the correct sudo prefix with env forwarding' do
|
|
122
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true } } } }) do
|
|
123
|
+
with_cmd_runner_mocked [
|
|
124
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
125
|
+
] do
|
|
126
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
127
|
+
expect(test_actions_executor.sudo_prefix('node', forward_env: true)).to eq 'sudo -u root -E '
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it 'returns the correct sudo prefix when connecting as root' do
|
|
133
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true } } } }) do
|
|
134
|
+
with_cmd_runner_mocked [
|
|
135
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
136
|
+
] do
|
|
137
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
138
|
+
expect(test_actions_executor.sudo_prefix('node')).to eq ''
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it 'returns the correct sudo prefix with a different sudo' do
|
|
144
|
+
with_test_platform(
|
|
145
|
+
{ nodes: { 'node' => { meta: { local_node: true } } } },
|
|
146
|
+
additional_config: <<~'EO_CONFIG'
|
|
147
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
|
148
|
+
EO_CONFIG
|
|
149
|
+
) do
|
|
150
|
+
with_cmd_runner_mocked [
|
|
151
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
152
|
+
] do
|
|
153
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
154
|
+
expect(test_actions_executor.sudo_prefix('node')).to eq 'other_sudo --user root '
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it 'returns the correct sudo prefix with a different sudo and env forwarding' do
|
|
160
|
+
with_test_platform(
|
|
161
|
+
{ nodes: { 'node' => { meta: { local_node: true } } } },
|
|
162
|
+
additional_config: <<~'EO_CONFIG'
|
|
163
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
|
164
|
+
EO_CONFIG
|
|
165
|
+
) do
|
|
166
|
+
with_cmd_runner_mocked [
|
|
167
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
168
|
+
] do
|
|
169
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
170
|
+
expect(test_actions_executor.sudo_prefix('node', forward_env: true)).to eq 'other_sudo --user root -E '
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it 'returns the correct sudo prefix with a different sudo when connecting as root' do
|
|
176
|
+
with_test_platform(
|
|
177
|
+
{ nodes: { 'node' => { meta: { local_node: true } } } },
|
|
178
|
+
additional_config: <<~'EO_CONFIG'
|
|
179
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
|
180
|
+
EO_CONFIG
|
|
181
|
+
) do
|
|
182
|
+
with_cmd_runner_mocked [
|
|
183
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
184
|
+
] do
|
|
185
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
186
|
+
expect(test_actions_executor.sudo_prefix('node')).to eq ''
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
end
|
|
@@ -129,6 +129,127 @@ describe HybridPlatformsConductor::Deployer do
|
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
131
|
|
|
132
|
+
it 'returns actions to save logs on a local node' do
|
|
133
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true }, services: %w[service1 service2] } } }, additional_config: 'send_logs_to :remote_fs') do
|
|
134
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
135
|
+
expect_services_handler_to_deploy('node' => %w[service1 service2])
|
|
136
|
+
expect_actions_executor_runs [
|
|
137
|
+
# First run, we expect the mutex to be setup, and the deployment actions to be run
|
|
138
|
+
proc do |actions_per_nodes|
|
|
139
|
+
expect_actions_to_deploy_on(
|
|
140
|
+
actions_per_nodes,
|
|
141
|
+
'node',
|
|
142
|
+
mocked_result: { 'node' => [0, 'Deploy successful stdout', 'Deploy successful stderr'] }
|
|
143
|
+
)
|
|
144
|
+
end,
|
|
145
|
+
# Second run, we expect the mutex to be released
|
|
146
|
+
proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, 'node') },
|
|
147
|
+
# Third run, we expect logs to be uploaded on the node
|
|
148
|
+
proc do |actions_per_nodes|
|
|
149
|
+
expect(actions_per_nodes['node'].size).to eq 3
|
|
150
|
+
expect(actions_per_nodes['node'][0].keys.sort).to eq %i[ruby remote_bash].sort
|
|
151
|
+
expect(actions_per_nodes['node'][0][:remote_bash]).to eq 'sudo -u root mkdir -p /var/log/deployments && sudo -u root chmod 600 /var/log/deployments'
|
|
152
|
+
expect(actions_per_nodes['node'][1].keys.sort).to eq %i[scp].sort
|
|
153
|
+
expect(actions_per_nodes['node'][1][:scp].delete(:sudo)).to eq true
|
|
154
|
+
expect(actions_per_nodes['node'][1][:scp].delete(:owner)).to eq 'root'
|
|
155
|
+
expect(actions_per_nodes['node'][1][:scp].delete(:group)).to eq 'root'
|
|
156
|
+
expect(actions_per_nodes['node'][1][:scp].size).to eq 1
|
|
157
|
+
tmp_log_file = actions_per_nodes['node'][1][:scp].first[0]
|
|
158
|
+
expect(actions_per_nodes['node'][1][:scp].first[1]).to eq '/var/log/deployments'
|
|
159
|
+
expect(actions_per_nodes['node'][2].keys.sort).to eq %i[ruby remote_bash].sort
|
|
160
|
+
expect(actions_per_nodes['node'][2][:remote_bash]).to eq "sudo -u root chmod 600 /var/log/deployments/#{File.basename(tmp_log_file)}"
|
|
161
|
+
# Call the Ruby codes to be tested
|
|
162
|
+
actions_per_nodes['node'][0][:ruby].call
|
|
163
|
+
expect(File.exist?(tmp_log_file)).to eq true
|
|
164
|
+
file_content_regexp = Regexp.new <<~EOREGEXP
|
|
165
|
+
repo_name_0: platform
|
|
166
|
+
commit_id_0: 123456
|
|
167
|
+
commit_message_0: Test commit for node: service1, service2
|
|
168
|
+
date: \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}
|
|
169
|
+
user: test_user
|
|
170
|
+
debug: No
|
|
171
|
+
services: service1, service2
|
|
172
|
+
exit_status: 0
|
|
173
|
+
===== STDOUT =====
|
|
174
|
+
Deploy successful stdout
|
|
175
|
+
===== STDERR =====
|
|
176
|
+
Deploy successful stderr
|
|
177
|
+
EOREGEXP
|
|
178
|
+
expect(File.read(tmp_log_file)).to match file_content_regexp
|
|
179
|
+
actions_per_nodes['node'][2][:ruby].call
|
|
180
|
+
# Check temporary log file gets deleted for security reasons
|
|
181
|
+
expect(File.exist?(tmp_log_file)).to eq false
|
|
182
|
+
end
|
|
183
|
+
]
|
|
184
|
+
with_cmd_runner_mocked [
|
|
185
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
186
|
+
] do
|
|
187
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => [0, 'Deploy successful stdout', 'Deploy successful stderr'])
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it 'returns actions to save logs on a local node as root' do
|
|
193
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true }, services: %w[service1 service2] } } }, additional_config: 'send_logs_to :remote_fs') do
|
|
194
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
195
|
+
expect_services_handler_to_deploy('node' => %w[service1 service2])
|
|
196
|
+
expect_actions_executor_runs [
|
|
197
|
+
# First run, we expect the mutex to be setup, and the deployment actions to be run
|
|
198
|
+
proc do |actions_per_nodes|
|
|
199
|
+
expect_actions_to_deploy_on(
|
|
200
|
+
actions_per_nodes,
|
|
201
|
+
'node',
|
|
202
|
+
sudo: nil,
|
|
203
|
+
mocked_result: { 'node' => [0, 'Deploy successful stdout', 'Deploy successful stderr'] }
|
|
204
|
+
)
|
|
205
|
+
end,
|
|
206
|
+
# Second run, we expect the mutex to be released
|
|
207
|
+
proc { |actions_per_nodes| expect_actions_to_unlock(actions_per_nodes, 'node', sudo: nil) },
|
|
208
|
+
# Third run, we expect logs to be uploaded on the node
|
|
209
|
+
proc do |actions_per_nodes|
|
|
210
|
+
expect(actions_per_nodes['node'].size).to eq 3
|
|
211
|
+
expect(actions_per_nodes['node'][0].keys.sort).to eq %i[ruby remote_bash].sort
|
|
212
|
+
expect(actions_per_nodes['node'][0][:remote_bash]).to eq 'mkdir -p /var/log/deployments && chmod 600 /var/log/deployments'
|
|
213
|
+
expect(actions_per_nodes['node'][1].keys.sort).to eq %i[scp].sort
|
|
214
|
+
expect(actions_per_nodes['node'][1][:scp].delete(:sudo)).to eq false
|
|
215
|
+
expect(actions_per_nodes['node'][1][:scp].delete(:owner)).to eq 'root'
|
|
216
|
+
expect(actions_per_nodes['node'][1][:scp].delete(:group)).to eq 'root'
|
|
217
|
+
expect(actions_per_nodes['node'][1][:scp].size).to eq 1
|
|
218
|
+
tmp_log_file = actions_per_nodes['node'][1][:scp].first[0]
|
|
219
|
+
expect(actions_per_nodes['node'][1][:scp].first[1]).to eq '/var/log/deployments'
|
|
220
|
+
expect(actions_per_nodes['node'][2].keys.sort).to eq %i[ruby remote_bash].sort
|
|
221
|
+
expect(actions_per_nodes['node'][2][:remote_bash]).to eq "chmod 600 /var/log/deployments/#{File.basename(tmp_log_file)}"
|
|
222
|
+
# Call the Ruby codes to be tested
|
|
223
|
+
actions_per_nodes['node'][0][:ruby].call
|
|
224
|
+
expect(File.exist?(tmp_log_file)).to eq true
|
|
225
|
+
file_content_regexp = Regexp.new <<~EOREGEXP
|
|
226
|
+
repo_name_0: platform
|
|
227
|
+
commit_id_0: 123456
|
|
228
|
+
commit_message_0: Test commit for node: service1, service2
|
|
229
|
+
date: \\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}
|
|
230
|
+
user: test_user
|
|
231
|
+
debug: No
|
|
232
|
+
services: service1, service2
|
|
233
|
+
exit_status: 0
|
|
234
|
+
===== STDOUT =====
|
|
235
|
+
Deploy successful stdout
|
|
236
|
+
===== STDERR =====
|
|
237
|
+
Deploy successful stderr
|
|
238
|
+
EOREGEXP
|
|
239
|
+
expect(File.read(tmp_log_file)).to match file_content_regexp
|
|
240
|
+
actions_per_nodes['node'][2][:ruby].call
|
|
241
|
+
# Check temporary log file gets deleted for security reasons
|
|
242
|
+
expect(File.exist?(tmp_log_file)).to eq false
|
|
243
|
+
end
|
|
244
|
+
]
|
|
245
|
+
with_cmd_runner_mocked [
|
|
246
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
247
|
+
] do
|
|
248
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => [0, 'Deploy successful stdout', 'Deploy successful stderr'])
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
132
253
|
it 'reads logs' do
|
|
133
254
|
with_test_platform_for_remote_fs do
|
|
134
255
|
expect_actions_executor_runs [
|
|
@@ -216,6 +337,100 @@ describe HybridPlatformsConductor::Deployer do
|
|
|
216
337
|
end
|
|
217
338
|
end
|
|
218
339
|
|
|
340
|
+
it 'reads logs on a local node' do
|
|
341
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true }, services: %w[service1 service2] } } }, additional_config: 'send_logs_to :remote_fs') do
|
|
342
|
+
expect_actions_executor_runs [
|
|
343
|
+
# Expect the actions to get log files
|
|
344
|
+
proc do |actions_per_nodes|
|
|
345
|
+
expect(actions_per_nodes).to eq('node' => [{ remote_bash: 'sudo -u root cat /var/log/deployments/`sudo -u root ls -t /var/log/deployments/ | head -1`' }])
|
|
346
|
+
{ 'node' => [0, <<~EO_STDOUT, ''] }
|
|
347
|
+
repo_name_0: platform
|
|
348
|
+
commit_id_0: 123456
|
|
349
|
+
commit_message_0: Test commit for node: service1, service2
|
|
350
|
+
diff_files_0: file1, file2, file3
|
|
351
|
+
date: 2017-11-23 18:43:01
|
|
352
|
+
user: test_user
|
|
353
|
+
debug: Yes
|
|
354
|
+
services: service1, service2, service3
|
|
355
|
+
exit_status: 0
|
|
356
|
+
===== STDOUT =====
|
|
357
|
+
Deploy successful stdout
|
|
358
|
+
===== STDERR =====
|
|
359
|
+
Deploy successful stderr
|
|
360
|
+
EO_STDOUT
|
|
361
|
+
end
|
|
362
|
+
]
|
|
363
|
+
with_cmd_runner_mocked [
|
|
364
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
365
|
+
] do
|
|
366
|
+
expect(test_deployer.deployment_info_from('node')).to eq(
|
|
367
|
+
'node' => {
|
|
368
|
+
deployment_info: {
|
|
369
|
+
repo_name_0: 'platform',
|
|
370
|
+
commit_id_0: '123456',
|
|
371
|
+
commit_message_0: 'Test commit for node: service1, service2',
|
|
372
|
+
diff_files_0: %w[file1 file2 file3],
|
|
373
|
+
date: Time.parse('2017-11-23 18:43:01 UTC'),
|
|
374
|
+
debug: true,
|
|
375
|
+
user: 'test_user'
|
|
376
|
+
},
|
|
377
|
+
exit_status: 0,
|
|
378
|
+
services: %w[service1 service2 service3],
|
|
379
|
+
stderr: 'Deploy successful stderr',
|
|
380
|
+
stdout: 'Deploy successful stdout'
|
|
381
|
+
}
|
|
382
|
+
)
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
it 'reads logs on a local node as root' do
|
|
388
|
+
with_test_platform({ nodes: { 'node' => { meta: { local_node: true }, services: %w[service1 service2] } } }, additional_config: 'send_logs_to :remote_fs') do
|
|
389
|
+
expect_actions_executor_runs [
|
|
390
|
+
# Expect the actions to get log files
|
|
391
|
+
proc do |actions_per_nodes|
|
|
392
|
+
expect(actions_per_nodes).to eq('node' => [{ remote_bash: 'cat /var/log/deployments/`ls -t /var/log/deployments/ | head -1`' }])
|
|
393
|
+
{ 'node' => [0, <<~EO_STDOUT, ''] }
|
|
394
|
+
repo_name_0: platform
|
|
395
|
+
commit_id_0: 123456
|
|
396
|
+
commit_message_0: Test commit for node: service1, service2
|
|
397
|
+
diff_files_0: file1, file2, file3
|
|
398
|
+
date: 2017-11-23 18:43:01
|
|
399
|
+
user: test_user
|
|
400
|
+
debug: Yes
|
|
401
|
+
services: service1, service2, service3
|
|
402
|
+
exit_status: 0
|
|
403
|
+
===== STDOUT =====
|
|
404
|
+
Deploy successful stdout
|
|
405
|
+
===== STDERR =====
|
|
406
|
+
Deploy successful stderr
|
|
407
|
+
EO_STDOUT
|
|
408
|
+
end
|
|
409
|
+
]
|
|
410
|
+
with_cmd_runner_mocked [
|
|
411
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
412
|
+
] do
|
|
413
|
+
expect(test_deployer.deployment_info_from('node')).to eq(
|
|
414
|
+
'node' => {
|
|
415
|
+
deployment_info: {
|
|
416
|
+
repo_name_0: 'platform',
|
|
417
|
+
commit_id_0: '123456',
|
|
418
|
+
commit_message_0: 'Test commit for node: service1, service2',
|
|
419
|
+
diff_files_0: %w[file1 file2 file3],
|
|
420
|
+
date: Time.parse('2017-11-23 18:43:01 UTC'),
|
|
421
|
+
debug: true,
|
|
422
|
+
user: 'test_user'
|
|
423
|
+
},
|
|
424
|
+
exit_status: 0,
|
|
425
|
+
services: %w[service1 service2 service3],
|
|
426
|
+
stderr: 'Deploy successful stderr',
|
|
427
|
+
stdout: 'Deploy successful stdout'
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
end
|
|
431
|
+
end
|
|
432
|
+
end
|
|
433
|
+
|
|
219
434
|
end
|
|
220
435
|
|
|
221
436
|
end
|
|
@@ -256,6 +256,44 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
|
256
256
|
|
|
257
257
|
end
|
|
258
258
|
|
|
259
|
+
context 'with a platform having 1 local node' do
|
|
260
|
+
|
|
261
|
+
it 'returns actions to deploy on this node' do
|
|
262
|
+
with_serverless_chef_platforms('1_local_node') do |platform, repository|
|
|
263
|
+
mock_package(repository)
|
|
264
|
+
platform.prepare_for_deploy(
|
|
265
|
+
services: { 'node' => %w[test_policy] },
|
|
266
|
+
secrets: {},
|
|
267
|
+
local_environment: false,
|
|
268
|
+
why_run: false
|
|
269
|
+
)
|
|
270
|
+
with_cmd_runner_mocked [
|
|
271
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
272
|
+
] do
|
|
273
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository)
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it 'returns actions to deploy on this node as root' do
|
|
279
|
+
with_serverless_chef_platforms('1_local_node') do |platform, repository|
|
|
280
|
+
mock_package(repository)
|
|
281
|
+
platform.prepare_for_deploy(
|
|
282
|
+
services: { 'node' => %w[test_policy] },
|
|
283
|
+
secrets: {},
|
|
284
|
+
local_environment: false,
|
|
285
|
+
why_run: false
|
|
286
|
+
)
|
|
287
|
+
with_cmd_runner_mocked [
|
|
288
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
289
|
+
] do
|
|
290
|
+
expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false)).to eq expected_actions_to_deploy_chef(repository, sudo: '')
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
end
|
|
296
|
+
|
|
259
297
|
context 'with a platform having several nodes' do
|
|
260
298
|
|
|
261
299
|
it 'deploys services declared on 1 node on another node if asked' do
|
data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/nodes/node.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "node",
|
|
3
|
+
"normal": {
|
|
4
|
+
"description": "Single test node",
|
|
5
|
+
"image": "debian_9",
|
|
6
|
+
"private_ips": ["172.16.0.1"],
|
|
7
|
+
"local_node": true,
|
|
8
|
+
"property_1": {
|
|
9
|
+
"property_11": "value11"
|
|
10
|
+
},
|
|
11
|
+
"property_2": "value2"
|
|
12
|
+
},
|
|
13
|
+
"policy_name": "test_policy",
|
|
14
|
+
"policy_group": "test_group"
|
|
15
|
+
}
|
|
@@ -46,6 +46,30 @@ shared_examples 'a deployer' do
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
it 'deploys on 1 local node' do
|
|
50
|
+
with_platform_to_deploy(nodes_info: { nodes: { 'node' => { meta: { local_node: true }, services: %w[service] } } }) do
|
|
51
|
+
# Make sure the ssh_user is ignored in this case
|
|
52
|
+
test_actions_executor.connector(:ssh).ssh_user = 'root'
|
|
53
|
+
with_cmd_runner_mocked [
|
|
54
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
55
|
+
] do
|
|
56
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'deploys on 1 local node as root' do
|
|
62
|
+
with_platform_to_deploy(nodes_info: { nodes: { 'node' => { meta: { local_node: true }, services: %w[service] } } }, expect_sudo: nil) do
|
|
63
|
+
# Make sure the ssh_user is ignored in this case
|
|
64
|
+
test_actions_executor.connector(:ssh).ssh_user = 'test_user'
|
|
65
|
+
with_cmd_runner_mocked [
|
|
66
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
67
|
+
] do
|
|
68
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
49
73
|
it 'deploys on 1 node using 1 secret' do
|
|
50
74
|
with_platform_to_deploy(expect_secrets: { 'secret1' => 'password1' }) do
|
|
51
75
|
test_deployer.override_secrets('secret1' => 'password1')
|
|
@@ -137,6 +161,61 @@ shared_examples 'a deployer' do
|
|
|
137
161
|
end
|
|
138
162
|
end
|
|
139
163
|
|
|
164
|
+
it 'deploys on 1 local node in local environment with certificates to install using hpc_certificates on Debian' do
|
|
165
|
+
with_certs_dir do |certs_dir|
|
|
166
|
+
with_platform_to_deploy(
|
|
167
|
+
nodes_info: { nodes: { 'node' => { meta: { local_node: true, image: 'debian_9' }, services: %w[service] } } },
|
|
168
|
+
expect_local_environment: true,
|
|
169
|
+
expect_additional_actions: [
|
|
170
|
+
{ remote_bash: 'sudo -u root apt update && sudo -u root apt install -y ca-certificates' },
|
|
171
|
+
{
|
|
172
|
+
remote_bash: 'sudo -u root update-ca-certificates',
|
|
173
|
+
scp: {
|
|
174
|
+
certs_dir => '/usr/local/share/ca-certificates',
|
|
175
|
+
:sudo => true
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
]
|
|
179
|
+
) do
|
|
180
|
+
ENV['hpc_certificates'] = certs_dir
|
|
181
|
+
test_deployer.local_environment = true
|
|
182
|
+
with_cmd_runner_mocked [
|
|
183
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
184
|
+
] do
|
|
185
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it 'deploys on 1 local node in local environment with certificates to install using hpc_certificates on Debian as root' do
|
|
192
|
+
with_certs_dir do |certs_dir|
|
|
193
|
+
with_platform_to_deploy(
|
|
194
|
+
nodes_info: { nodes: { 'node' => { meta: { local_node: true, image: 'debian_9' }, services: %w[service] } } },
|
|
195
|
+
expect_sudo: nil,
|
|
196
|
+
expect_local_environment: true,
|
|
197
|
+
expect_additional_actions: [
|
|
198
|
+
{ remote_bash: 'apt update && apt install -y ca-certificates' },
|
|
199
|
+
{
|
|
200
|
+
remote_bash: 'update-ca-certificates',
|
|
201
|
+
scp: {
|
|
202
|
+
certs_dir => '/usr/local/share/ca-certificates',
|
|
203
|
+
:sudo => false
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
) do
|
|
208
|
+
ENV['hpc_certificates'] = certs_dir
|
|
209
|
+
test_deployer.local_environment = true
|
|
210
|
+
with_cmd_runner_mocked [
|
|
211
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
212
|
+
] do
|
|
213
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
140
219
|
it 'deploys on 1 node with certificates to install using hpc_certificates on CentOS' do
|
|
141
220
|
with_certs_dir do |certs_dir|
|
|
142
221
|
with_platform_to_deploy(
|
|
@@ -212,6 +291,61 @@ shared_examples 'a deployer' do
|
|
|
212
291
|
end
|
|
213
292
|
end
|
|
214
293
|
|
|
294
|
+
it 'deploys on 1 local node with certificates to install using hpc_certificates on CentOS' do
|
|
295
|
+
with_certs_dir do |certs_dir|
|
|
296
|
+
with_platform_to_deploy(
|
|
297
|
+
nodes_info: { nodes: { 'node' => { meta: { local_node: true, image: 'centos_7' }, services: %w[service] } } },
|
|
298
|
+
expect_local_environment: true,
|
|
299
|
+
expect_additional_actions: [
|
|
300
|
+
{ remote_bash: 'sudo -u root yum install -y ca-certificates' },
|
|
301
|
+
{
|
|
302
|
+
remote_bash: ['sudo -u root update-ca-trust enable', 'sudo -u root update-ca-trust extract'],
|
|
303
|
+
scp: {
|
|
304
|
+
"#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
|
|
305
|
+
:sudo => true
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
]
|
|
309
|
+
) do
|
|
310
|
+
ENV['hpc_certificates'] = certs_dir
|
|
311
|
+
test_deployer.local_environment = true
|
|
312
|
+
with_cmd_runner_mocked [
|
|
313
|
+
['whoami', proc { [0, 'test_user', ''] }]
|
|
314
|
+
] do
|
|
315
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it 'deploys on 1 local node with certificates to install using hpc_certificates on CentOS as root' do
|
|
322
|
+
with_certs_dir do |certs_dir|
|
|
323
|
+
with_platform_to_deploy(
|
|
324
|
+
nodes_info: { nodes: { 'node' => { meta: { local_node: true, image: 'centos_7' }, services: %w[service] } } },
|
|
325
|
+
expect_sudo: nil,
|
|
326
|
+
expect_local_environment: true,
|
|
327
|
+
expect_additional_actions: [
|
|
328
|
+
{ remote_bash: 'yum install -y ca-certificates' },
|
|
329
|
+
{
|
|
330
|
+
remote_bash: ['update-ca-trust enable', 'update-ca-trust extract'],
|
|
331
|
+
scp: {
|
|
332
|
+
"#{certs_dir}/test_cert.crt" => '/etc/pki/ca-trust/source/anchors',
|
|
333
|
+
:sudo => false
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
]
|
|
337
|
+
) do
|
|
338
|
+
ENV['hpc_certificates'] = certs_dir
|
|
339
|
+
test_deployer.local_environment = true
|
|
340
|
+
with_cmd_runner_mocked [
|
|
341
|
+
['whoami', proc { [0, 'root', ''] }]
|
|
342
|
+
] do
|
|
343
|
+
expect(test_deployer.deploy_on('node')).to eq('node' => expected_deploy_result)
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
215
349
|
it 'deploys on several nodes' do
|
|
216
350
|
with_platform_to_deploy(
|
|
217
351
|
nodes_info: {
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hybrid_platforms_conductor
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 33.5.
|
|
4
|
+
version: 33.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Muriel Salvan
|
|
@@ -866,6 +866,7 @@ files:
|
|
|
866
866
|
- spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb
|
|
867
867
|
- spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb
|
|
868
868
|
- spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb
|
|
869
|
+
- spec/hybrid_platforms_conductor_test/api/actions_executor/helpers_spec.rb
|
|
869
870
|
- spec/hybrid_platforms_conductor_test/api/actions_executor/logging_spec.rb
|
|
870
871
|
- spec/hybrid_platforms_conductor_test/api/actions_executor/parallel_spec.rb
|
|
871
872
|
- spec/hybrid_platforms_conductor_test/api/actions_executor/timeout_spec.rb
|
|
@@ -982,6 +983,9 @@ files:
|
|
|
982
983
|
- spec/hybrid_platforms_conductor_test/platform_handler_plugins/test_2.rb
|
|
983
984
|
- spec/hybrid_platforms_conductor_test/report_plugin.rb
|
|
984
985
|
- spec/hybrid_platforms_conductor_test/rubocop_spec.rb
|
|
986
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/chef_versions.yml
|
|
987
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/nodes/node.json
|
|
988
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_local_node/policyfiles/test_policy.rb
|
|
985
989
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/chef_versions.yml
|
|
986
990
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/nodes/node.json
|
|
987
991
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/1_node/policyfiles/test_policy.rb
|