hybrid_platforms_conductor 32.5.0 → 32.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hybrid_platforms_conductor/deployer.rb +12 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/connector/ssh.rb +157 -81
- data/lib/hybrid_platforms_conductor/hpc_plugins/test/check_deploy_and_idempotence.rb +11 -9
- data/lib/hybrid_platforms_conductor/provisioner.rb +9 -0
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/config_dsl_spec.rb +35 -0
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb +67 -5
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb +50 -6
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb +34 -10
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +74 -10
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/{config_spec.rb → config_dsl_spec.rb} +4 -4
- data/spec/hybrid_platforms_conductor_test/executables/options/common_spec.rb +2 -1
- data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +33 -11
- data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +46 -12
- metadata +3 -3
data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/config_dsl_spec.rb
CHANGED
@@ -43,6 +43,41 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
it 'returns ssh transformation procs' do
|
47
|
+
with_test_platform(
|
48
|
+
{
|
49
|
+
nodes: {
|
50
|
+
'node1' => {},
|
51
|
+
'node2' => {},
|
52
|
+
'node3' => {}
|
53
|
+
},
|
54
|
+
},
|
55
|
+
false,
|
56
|
+
'
|
57
|
+
for_nodes(%w[node1 node3]) do
|
58
|
+
transform_ssh_connection do |node, connection, connection_user, gateway, gateway_user|
|
59
|
+
["#{connection}_#{node}_13", "#{connection_user}_#{node}_13", "#{gateway}_#{node}_13", "#{gateway_user}_#{node}_13"]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
for_nodes(\'node1\') do
|
63
|
+
transform_ssh_connection do |node, connection, connection_user, gateway, gateway_user|
|
64
|
+
["#{connection}_#{node}_1", "#{connection_user}_#{node}_1", "#{gateway}_#{node}_1", "#{gateway_user}_#{node}_1"]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
'
|
68
|
+
) do
|
69
|
+
expect(test_config.ssh_connection_transforms.size).to eq 2
|
70
|
+
expect(test_config.ssh_connection_transforms[0][:nodes_selectors_stack]).to eq [%w[node1 node3]]
|
71
|
+
expect(test_config.ssh_connection_transforms[0][:transform].call('node1', 'test_host', 'test_user', 'test_gateway', 'test_gateway_user')).to eq [
|
72
|
+
'test_host_node1_13', 'test_user_node1_13', 'test_gateway_node1_13', 'test_gateway_user_node1_13'
|
73
|
+
]
|
74
|
+
expect(test_config.ssh_connection_transforms[1][:nodes_selectors_stack]).to eq ['node1']
|
75
|
+
expect(test_config.ssh_connection_transforms[1][:transform].call('node1', 'test_host', 'test_user', 'test_gateway', 'test_gateway_user')).to eq [
|
76
|
+
'test_host_node1_1', 'test_user_node1_1', 'test_gateway_node1_1', 'test_gateway_user_node1_1'
|
77
|
+
]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
46
81
|
end
|
47
82
|
|
48
83
|
end
|
data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb
CHANGED
@@ -28,6 +28,22 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
+
it 'creates an SSH master to 1 node not having Session Exec capabilities' do
|
32
|
+
with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42', ssh_session_exec: 'false' } } }) do
|
33
|
+
with_cmd_runner_mocked(
|
34
|
+
[
|
35
|
+
['which env', proc { [0, "/usr/bin/env\n", ''] }],
|
36
|
+
['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
|
37
|
+
] + ssh_expected_commands_for({ 'node' => { connection: '192.168.42.42', user: 'test_user' } }, with_session_exec: false)
|
38
|
+
) do
|
39
|
+
test_connector.ssh_user = 'test_user'
|
40
|
+
test_connector.with_connection_to(['node']) do |connected_nodes|
|
41
|
+
expect(connected_nodes).to eq ['node']
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
31
47
|
it 'creates SSH master to several nodes' do
|
32
48
|
with_test_platform(nodes: {
|
33
49
|
'node1' => { meta: { host_ip: '192.168.42.1' } },
|
@@ -52,6 +68,45 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
52
68
|
end
|
53
69
|
end
|
54
70
|
|
71
|
+
it 'creates SSH master to several nodes with ssh connections transformed' do
|
72
|
+
with_test_platform(
|
73
|
+
{ nodes: {
|
74
|
+
'node1' => { meta: { host_ip: '192.168.42.1' } },
|
75
|
+
'node2' => { meta: { host_ip: '192.168.42.2' } },
|
76
|
+
'node3' => { meta: { host_ip: '192.168.42.3' } }
|
77
|
+
} },
|
78
|
+
false,
|
79
|
+
'
|
80
|
+
for_nodes(%w[node1 node3]) do
|
81
|
+
transform_ssh_connection do |node, connection, connection_user, gateway, gateway_user|
|
82
|
+
["#{connection}_#{node}_13", "#{connection_user}_#{node}_13", "#{gateway}_#{node}_13", "#{gateway_user}_#{node}_13"]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
for_nodes(\'node1\') do
|
86
|
+
transform_ssh_connection do |node, connection, connection_user, gateway, gateway_user|
|
87
|
+
["#{connection}_#{node}_1", "#{connection_user}_#{node}_1", "#{gateway}_#{node}_1", "#{gateway_user}_#{node}_1"]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
'
|
91
|
+
) do
|
92
|
+
with_cmd_runner_mocked(
|
93
|
+
[
|
94
|
+
['which env', proc { [0, "/usr/bin/env\n", ''] }],
|
95
|
+
['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
|
96
|
+
] + ssh_expected_commands_for(
|
97
|
+
'node1' => { ip: '192.168.42.1', connection: '192.168.42.1_node1_13_node1_1', user: 'test_user_node1_13_node1_1' },
|
98
|
+
'node2' => { ip: '192.168.42.2', connection: '192.168.42.2', user: 'test_user' },
|
99
|
+
'node3' => { ip: '192.168.42.3', connection: '192.168.42.3_node3_13', user: 'test_user_node3_13' }
|
100
|
+
)
|
101
|
+
) do
|
102
|
+
test_connector.ssh_user = 'test_user'
|
103
|
+
test_connector.with_connection_to(%w[node1 node2 node3]) do |connected_nodes|
|
104
|
+
expect(connected_nodes.sort).to eq %w[node1 node2 node3].sort
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
55
110
|
it 'fails when an SSH master can\'t be created' do
|
56
111
|
with_test_platform(nodes: {
|
57
112
|
'node1' => { meta: { host_ip: '192.168.42.1' } },
|
@@ -63,8 +118,14 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
63
118
|
['which env', proc { [0, "/usr/bin/env\n", ''] }],
|
64
119
|
['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }]
|
65
120
|
] + ssh_expected_commands_for(
|
66
|
-
|
67
|
-
|
121
|
+
{
|
122
|
+
'node1' => { connection: '192.168.42.1', user: 'test_user' },
|
123
|
+
'node3' => { connection: '192.168.42.3', user: 'test_user' }
|
124
|
+
},
|
125
|
+
# Here the threads for node1's and node3's ControlMasters might not trigger before the one for node2, so they will not destroy it.
|
126
|
+
# Sometimes they don't even have time to create the Control Masters that node2 has already failed.
|
127
|
+
with_control_master_create_optional: true,
|
128
|
+
with_control_master_destroy_optional: true
|
68
129
|
) + ssh_expected_commands_for(
|
69
130
|
{
|
70
131
|
'node2' => { connection: '192.168.42.2', user: 'test_user', control_master_create_error: 'Can\'t connect to 192.168.42.2' }
|
@@ -73,7 +134,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
73
134
|
)
|
74
135
|
) do
|
75
136
|
test_connector.ssh_user = 'test_user'
|
76
|
-
expect { test_connector.with_connection_to(%w[node1 node2 node3]) }.to raise_error(/^Error while starting SSH Control Master with .+\/ssh -o BatchMode=yes -o ControlMaster=yes -o ControlPersist=yes
|
137
|
+
expect { test_connector.with_connection_to(%w[node1 node2 node3]) }.to raise_error(/^Error while starting SSH Control Master with .+\/ssh -o BatchMode=yes -o ControlMaster=yes -o ControlPersist=yes hpc.node2 true: Can't connect to 192.168.42.2$/)
|
77
138
|
end
|
78
139
|
end
|
79
140
|
end
|
@@ -239,7 +300,8 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
239
300
|
) do
|
240
301
|
test_connector.ssh_use_control_master = false
|
241
302
|
test_connector.ssh_user = 'test_user'
|
242
|
-
test_connector.with_connection_to(['node']) do
|
303
|
+
test_connector.with_connection_to(['node']) do |connected_nodes|
|
304
|
+
expect(connected_nodes).to eq %w[node]
|
243
305
|
end
|
244
306
|
end
|
245
307
|
end
|
@@ -416,7 +478,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
416
478
|
['ssh -V 2>&1', proc { [0, "OpenSSH_7.4p1 Debian-10+deb9u7, OpenSSL 1.0.2u 20 Dec 2019\n", ''] }],
|
417
479
|
] +
|
418
480
|
[[
|
419
|
-
/^.+\/ssh -o BatchMode=yes -o ControlMaster=yes -o ControlPersist=yes
|
481
|
+
/^.+\/ssh -o BatchMode=yes -o ControlMaster=yes -o ControlPersist=yes hpc\.node true$/,
|
420
482
|
proc do
|
421
483
|
nbr_boot_messages += 1
|
422
484
|
[255, '', "System is booting up. See pam_nologin(8)\nAuthentication failed.\n"]
|
data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/global_helpers_spec.rb
CHANGED
@@ -35,8 +35,11 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
35
35
|
begin_marker = node.nil? ? /^Host \*$/ : /^# #{Regexp.escape(node)} - .+$/
|
36
36
|
start_idx = ssh_config_lines.index { |line| line =~ begin_marker }
|
37
37
|
return nil if start_idx.nil?
|
38
|
-
|
39
|
-
|
38
|
+
end_markers = [
|
39
|
+
/^\# \w+ - .+$/,
|
40
|
+
/^\#+$/
|
41
|
+
]
|
42
|
+
end_idx = ssh_config_lines[start_idx + 1..-1].index { |line| end_markers.any? { |end_marker| line =~ end_marker } }
|
40
43
|
end_idx = end_idx.nil? ? -1 : start_idx + end_idx
|
41
44
|
ssh_config_lines[start_idx..end_idx].select do |line|
|
42
45
|
stripped_line = line.strip
|
@@ -50,7 +53,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
50
53
|
expect(ssh_config_for(nil)).to eq <<~EOS
|
51
54
|
Host *
|
52
55
|
User test_user
|
53
|
-
ControlPath #{Dir.tmpdir}/hpc_ssh/
|
56
|
+
ControlPath #{Dir.tmpdir}/hpc_ssh/hpc_ssh_mux_%h_%p_%r
|
54
57
|
PubkeyAcceptedKeyTypes +ssh-dss
|
55
58
|
EOS
|
56
59
|
end
|
@@ -62,7 +65,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
62
65
|
expect(ssh_config_for(nil)).to eq <<~EOS
|
63
66
|
Host *
|
64
67
|
User test_user
|
65
|
-
ControlPath #{Dir.tmpdir}/hpc_ssh/
|
68
|
+
ControlPath #{Dir.tmpdir}/hpc_ssh/hpc_ssh_mux_%h_%p_%r
|
66
69
|
PubkeyAcceptedKeyTypes +ssh-dss
|
67
70
|
EOS
|
68
71
|
end
|
@@ -74,7 +77,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
74
77
|
expect(ssh_config_for(nil, known_hosts_file: '/path/to/known_hosts')).to eq <<~EOS
|
75
78
|
Host *
|
76
79
|
User test_user
|
77
|
-
ControlPath #{Dir.tmpdir}/hpc_ssh/
|
80
|
+
ControlPath #{Dir.tmpdir}/hpc_ssh/hpc_ssh_mux_%h_%p_%r
|
78
81
|
PubkeyAcceptedKeyTypes +ssh-dss
|
79
82
|
UserKnownHostsFile /path/to/known_hosts
|
80
83
|
EOS
|
@@ -88,7 +91,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
88
91
|
expect(ssh_config_for(nil)).to eq <<~EOS
|
89
92
|
Host *
|
90
93
|
User test_user
|
91
|
-
ControlPath #{Dir.tmpdir}/hpc_ssh/
|
94
|
+
ControlPath #{Dir.tmpdir}/hpc_ssh/hpc_ssh_mux_%h_%p_%r
|
92
95
|
PubkeyAcceptedKeyTypes +ssh-dss
|
93
96
|
StrictHostKeyChecking no
|
94
97
|
EOS
|
@@ -274,6 +277,47 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
274
277
|
end
|
275
278
|
end
|
276
279
|
|
280
|
+
it 'uses node transformed SSH connection' do
|
281
|
+
with_test_platform(
|
282
|
+
{ nodes: {
|
283
|
+
'node1' => { meta: { host_ip: '192.168.42.1', gateway: 'test_gateway1', gateway_user: 'test_gateway1_user' } },
|
284
|
+
'node2' => { meta: { host_ip: '192.168.42.2', gateway: 'test_gateway2', gateway_user: 'test_gateway2_user' } },
|
285
|
+
'node3' => { meta: { host_ip: '192.168.42.3', gateway: 'test_gateway3', gateway_user: 'test_gateway3_user' } }
|
286
|
+
} },
|
287
|
+
false,
|
288
|
+
'
|
289
|
+
for_nodes(%w[node1 node3]) do
|
290
|
+
transform_ssh_connection do |node, connection, connection_user, gateway, gateway_user|
|
291
|
+
["#{connection}_#{node}_13", "#{connection_user}_#{node}_13", "#{gateway}_#{node}_13", "#{gateway_user}_#{node}_13"]
|
292
|
+
end
|
293
|
+
end
|
294
|
+
for_nodes(\'node1\') do
|
295
|
+
transform_ssh_connection do |node, connection, connection_user, gateway, gateway_user|
|
296
|
+
["#{connection}_#{node}_1", "#{connection_user}_#{node}_1", "#{gateway}_#{node}_1", "#{gateway_user}_#{node}_1"]
|
297
|
+
end
|
298
|
+
end
|
299
|
+
') do
|
300
|
+
test_connector.ssh_user = 'test_user'
|
301
|
+
expect(ssh_config_for('node1')).to eq <<~EOS
|
302
|
+
Host hpc.node1
|
303
|
+
Hostname 192.168.42.1_node1_13_node1_1
|
304
|
+
User "test_user_node1_13_node1_1"
|
305
|
+
ProxyCommand ssh -q -W %h:%p test_gateway1_user_node1_13_node1_1@test_gateway1_node1_13_node1_1
|
306
|
+
EOS
|
307
|
+
expect(ssh_config_for('node2')).to eq <<~EOS
|
308
|
+
Host hpc.node2
|
309
|
+
Hostname 192.168.42.2
|
310
|
+
ProxyCommand ssh -q -W %h:%p test_gateway2_user@test_gateway2
|
311
|
+
EOS
|
312
|
+
expect(ssh_config_for('node3')).to eq <<~EOS
|
313
|
+
Host hpc.node3
|
314
|
+
Hostname 192.168.42.3_node3_13
|
315
|
+
User "test_user_node3_13"
|
316
|
+
ProxyCommand ssh -q -W %h:%p test_gateway3_user_node3_13@test_gateway3_node3_13
|
317
|
+
EOS
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
277
321
|
it 'generates a config compatible for passwords authentication' do
|
278
322
|
with_test_platform(nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }) do
|
279
323
|
test_connector.passwords['node'] = 'PaSsWoRd'
|
data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/node_helpers_spec.rb
CHANGED
@@ -13,7 +13,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
13
13
|
|
14
14
|
it 'provides an SSH URL that can be used by other processes to connect to this node' do
|
15
15
|
with_test_platform_for_remote_testing do
|
16
|
-
expect(test_connector.ssh_url).to eq '
|
16
|
+
expect(test_connector.ssh_url).to eq 'hpc.node'
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/remote_actions_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
6
6
|
|
7
7
|
it 'executes bash commands remotely' do
|
8
8
|
with_test_platform_for_remote_testing(
|
9
|
-
expected_cmds: [[/.+\/ssh
|
9
|
+
expected_cmds: [[/.+\/ssh hpc\.node \/bin\/bash <<'EOF'\nbash_cmd.bash\nEOF/, proc { [0, 'Bash commands executed on node', ''] }]],
|
10
10
|
expected_stdout: 'Bash commands executed on node'
|
11
11
|
) do
|
12
12
|
test_connector.remote_bash('bash_cmd.bash')
|
@@ -17,7 +17,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
17
17
|
with_test_platform_for_remote_testing(
|
18
18
|
expected_cmds: [
|
19
19
|
[
|
20
|
-
/.+\/ssh
|
20
|
+
/.+\/ssh hpc\.node \/bin\/bash <<'EOF'\nbash_cmd.bash\nEOF/,
|
21
21
|
proc do |cmd, log_to_file: nil, log_to_stdout: true, log_stdout_to_io: nil, log_stderr_to_io: nil, expected_code: 0, timeout: nil, no_exception: false|
|
22
22
|
expect(timeout).to eq 5
|
23
23
|
[0, '', '']
|
@@ -33,7 +33,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
33
33
|
it 'executes interactive commands remotely' do
|
34
34
|
with_test_platform_for_remote_testing do
|
35
35
|
expect(test_connector).to receive(:system) do |cmd|
|
36
|
-
expect(cmd).to match /^.+\/ssh
|
36
|
+
expect(cmd).to match /^.+\/ssh hpc\.node$/
|
37
37
|
end
|
38
38
|
test_connector.remote_interactive
|
39
39
|
end
|
@@ -43,7 +43,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
43
43
|
with_test_platform_for_remote_testing(
|
44
44
|
expected_cmds: [
|
45
45
|
[
|
46
|
-
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+
|
46
|
+
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+hpc\.node\s+"tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
47
47
|
proc { [0, '', ''] }
|
48
48
|
]
|
49
49
|
]
|
@@ -56,7 +56,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
56
56
|
with_test_platform_for_remote_testing(
|
57
57
|
expected_cmds: [
|
58
58
|
[
|
59
|
-
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+
|
59
|
+
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+hpc\.node\s+"tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
60
60
|
proc do |cmd, log_to_file: nil, log_to_stdout: true, log_stdout_to_io: nil, log_stderr_to_io: nil, expected_code: 0, timeout: nil, no_exception: false|
|
61
61
|
expect(timeout).to eq 5
|
62
62
|
[0, '', '']
|
@@ -76,7 +76,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
76
76
|
[
|
77
77
|
/.+\/hpc_temp_cmds_.+\.sh$/,
|
78
78
|
proc do |received_cmd|
|
79
|
-
expect(File.read(received_cmd)).to match /.+\/ssh
|
79
|
+
expect(File.read(received_cmd)).to match /.+\/ssh hpc\.node \/bin\/bash <<'EOF'\n#{Regexp.escape(cmd)}\nEOF/
|
80
80
|
[0, 'Bash commands executed on node', '']
|
81
81
|
end
|
82
82
|
]
|
@@ -92,7 +92,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
92
92
|
with_test_platform_for_remote_testing(
|
93
93
|
expected_cmds: [
|
94
94
|
[
|
95
|
-
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+
|
95
|
+
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+hpc\.node\s+"sudo -u root tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
96
96
|
proc { [0, '', ''] }
|
97
97
|
]
|
98
98
|
]
|
@@ -105,7 +105,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
105
105
|
with_test_platform_for_remote_testing(
|
106
106
|
expected_cmds: [
|
107
107
|
[
|
108
|
-
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+
|
108
|
+
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+src.file \| \/.+\/ssh\s+hpc\.node\s+"other_sudo --user root tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
109
109
|
proc { [0, '', ''] }
|
110
110
|
]
|
111
111
|
],
|
@@ -119,7 +119,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
119
119
|
with_test_platform_for_remote_testing(
|
120
120
|
expected_cmds: [
|
121
121
|
[
|
122
|
-
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+--owner remote_user\s+src.file \| \/.+\/ssh\s+
|
122
|
+
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+--owner remote_user\s+src.file \| \/.+\/ssh\s+hpc\.node\s+"tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
123
123
|
proc { [0, '', ''] }
|
124
124
|
]
|
125
125
|
]
|
@@ -132,7 +132,7 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
132
132
|
with_test_platform_for_remote_testing(
|
133
133
|
expected_cmds: [
|
134
134
|
[
|
135
|
-
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+--group remote_group\s+src.file \| \/.+\/ssh\s+
|
135
|
+
/cd \/path\/to && tar\s+--create\s+--gzip\s+--file -\s+--group remote_group\s+src.file \| \/.+\/ssh\s+hpc\.node\s+"tar\s+--extract\s+--gunzip\s+--file -\s+--directory \/remote_path\/to\/dst.dir\s+--owner root\s+"/,
|
136
136
|
proc { [0, '', ''] }
|
137
137
|
]
|
138
138
|
]
|
@@ -141,6 +141,30 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
+
it 'executes bash commands remotely without Session Exec capabilities' do
|
145
|
+
with_test_platform_for_remote_testing(
|
146
|
+
expected_cmds: [[/^\{ cat \| .+\/ssh hpc\.node -T; } <<'EOF'\nbash_cmd.bash\nEOF$/, proc { [0, 'Bash commands executed on node', ''] }]],
|
147
|
+
expected_stdout: 'Bash commands executed on node',
|
148
|
+
session_exec: false
|
149
|
+
) do
|
150
|
+
test_connector.remote_bash('bash_cmd.bash')
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'copies files remotely without Session Exec capabilities' do
|
155
|
+
with_test_platform_for_remote_testing(
|
156
|
+
expected_cmds: [
|
157
|
+
[
|
158
|
+
/^scp -S .+\/ssh \/path\/to\/src.file hpc\.node:\/remote_path\/to\/dst.dir$/,
|
159
|
+
proc { [0, '', ''] }
|
160
|
+
]
|
161
|
+
],
|
162
|
+
session_exec: false
|
163
|
+
) do
|
164
|
+
test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir')
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
144
168
|
end
|
145
169
|
|
146
170
|
end
|
@@ -17,8 +17,8 @@ describe HybridPlatformsConductor::Deployer do
|
|
17
17
|
block.call
|
18
18
|
end
|
19
19
|
provisioner = nil
|
20
|
-
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner') do |
|
21
|
-
expect(
|
20
|
+
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner') do |sub_test_deployer, test_instance|
|
21
|
+
expect(sub_test_deployer.local_environment).to eq true
|
22
22
|
provisioner = test_instance
|
23
23
|
expect(test_instance.node).to eq 'node'
|
24
24
|
expect(test_instance.environment).to match /^#{Regexp.escape(`whoami`.strip)}_hpc_testing_provisioner_\d+_\d+_\w+$/
|
@@ -40,8 +40,8 @@ describe HybridPlatformsConductor::Deployer do
|
|
40
40
|
block.call
|
41
41
|
end
|
42
42
|
provisioner = nil
|
43
|
-
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner') do |
|
44
|
-
expect(
|
43
|
+
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner') do |sub_test_deployer, test_instance|
|
44
|
+
expect(sub_test_deployer.local_environment).to eq true
|
45
45
|
provisioner = test_instance
|
46
46
|
expect(test_instance.node).to eq 'node'
|
47
47
|
expect(test_instance.environment).to match /^#{Regexp.escape(`whoami`.strip)}_hpc_testing_provisioner_\d+_\d+_\w+$/
|
@@ -50,6 +50,70 @@ describe HybridPlatformsConductor::Deployer do
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
it 'gives a new test instance ready to be used in place of the node without SSH transformations' do
|
54
|
+
with_test_platform(
|
55
|
+
{
|
56
|
+
nodes: {
|
57
|
+
'node1' => { meta: { host_ip: '192.168.42.1', ssh_session_exec: 'false' } },
|
58
|
+
'node2' => { meta: { host_ip: '192.168.42.2', ssh_session_exec: 'false' } }
|
59
|
+
}
|
60
|
+
},
|
61
|
+
false,
|
62
|
+
'
|
63
|
+
for_nodes(%w[node1 node2]) do
|
64
|
+
transform_ssh_connection do |node, connection, connection_user, gateway, gateway_user|
|
65
|
+
["#{connection}_#{node}", "#{connection_user}_#{node}", "#{gateway}_#{node}", "#{gateway_user}_#{node}"]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
'
|
69
|
+
) do |repository|
|
70
|
+
register_plugins(:provisioner, { test_provisioner: HybridPlatformsConductorTest::TestProvisioner })
|
71
|
+
File.write("#{test_config.hybrid_platforms_dir}/dummy_secrets.json", '{}')
|
72
|
+
HybridPlatformsConductorTest::TestProvisioner.mocked_states = %i[created created running exited]
|
73
|
+
HybridPlatformsConductorTest::TestProvisioner.mocked_ip = '172.17.0.1'
|
74
|
+
expect(Socket).to receive(:tcp).with('172.17.0.1', 22, { connect_timeout: 1 }) do |&block|
|
75
|
+
block.call
|
76
|
+
end
|
77
|
+
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node1', environment: 'hpc_testing_provisioner') do |sub_test_deployer, test_instance|
|
78
|
+
expect(sub_test_deployer.instance_eval { @nodes_handler.get_ssh_session_exec_of('node1') }).to eq 'true'
|
79
|
+
expect(sub_test_deployer.instance_eval { @nodes_handler.get_ssh_session_exec_of('node2') }).to eq 'false'
|
80
|
+
ssh_transforms = test_instance.instance_eval { @config.ssh_connection_transforms }
|
81
|
+
expect(ssh_transforms.size).to eq 1
|
82
|
+
expect(ssh_transforms[0][:nodes_selectors_stack]).to eq [%w[node2]]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'gives a new test instance ready to be used in place of the node without sudo specificities' do
|
88
|
+
with_test_platform(
|
89
|
+
{
|
90
|
+
nodes: {
|
91
|
+
'node1' => { meta: { host_ip: '192.168.42.1' } },
|
92
|
+
'node2' => { meta: { host_ip: '192.168.42.2' } }
|
93
|
+
}
|
94
|
+
},
|
95
|
+
false,
|
96
|
+
'
|
97
|
+
for_nodes(%w[node1 node2]) do
|
98
|
+
sudo_for { |user| "other_sudo --user #{user}" }
|
99
|
+
end
|
100
|
+
'
|
101
|
+
) do |repository|
|
102
|
+
register_plugins(:provisioner, { test_provisioner: HybridPlatformsConductorTest::TestProvisioner })
|
103
|
+
File.write("#{test_config.hybrid_platforms_dir}/dummy_secrets.json", '{}')
|
104
|
+
HybridPlatformsConductorTest::TestProvisioner.mocked_states = %i[created created running exited]
|
105
|
+
HybridPlatformsConductorTest::TestProvisioner.mocked_ip = '172.17.0.1'
|
106
|
+
expect(Socket).to receive(:tcp).with('172.17.0.1', 22, { connect_timeout: 1 }) do |&block|
|
107
|
+
block.call
|
108
|
+
end
|
109
|
+
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node1', environment: 'hpc_testing_provisioner') do |sub_test_deployer, test_instance|
|
110
|
+
sudo_procs = test_instance.instance_eval { @config.sudo_procs }
|
111
|
+
expect(sudo_procs.size).to eq 1
|
112
|
+
expect(sudo_procs[0][:nodes_selectors_stack]).to eq [%w[node2]]
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
53
117
|
it 'does not destroy instances when asked to reuse' do
|
54
118
|
with_test_platform(
|
55
119
|
nodes: { 'node' => { meta: { host_ip: '192.168.42.42' } } }
|
@@ -62,8 +126,8 @@ describe HybridPlatformsConductor::Deployer do
|
|
62
126
|
block.call
|
63
127
|
end
|
64
128
|
provisioner = nil
|
65
|
-
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner', reuse_instance: true) do |
|
66
|
-
expect(
|
129
|
+
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner', reuse_instance: true) do |sub_test_deployer, test_instance|
|
130
|
+
expect(sub_test_deployer.local_environment).to eq true
|
67
131
|
provisioner = test_instance
|
68
132
|
expect(test_instance.node).to eq 'node'
|
69
133
|
expect(test_instance.environment).to eq "#{`whoami`.strip}_hpc_testing_provisioner"
|
@@ -84,8 +148,8 @@ describe HybridPlatformsConductor::Deployer do
|
|
84
148
|
block.call
|
85
149
|
end
|
86
150
|
provisioner = nil
|
87
|
-
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner', reuse_instance: true) do |
|
88
|
-
expect(
|
151
|
+
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner', reuse_instance: true) do |sub_test_deployer, test_instance|
|
152
|
+
expect(sub_test_deployer.local_environment).to eq true
|
89
153
|
provisioner = test_instance
|
90
154
|
expect(test_instance.node).to eq 'node'
|
91
155
|
expect(test_instance.environment).to eq "#{`whoami`.strip}_hpc_testing_provisioner"
|
@@ -102,7 +166,7 @@ describe HybridPlatformsConductor::Deployer do
|
|
102
166
|
File.write("#{test_config.hybrid_platforms_dir}/dummy_secrets.json", '{}')
|
103
167
|
HybridPlatformsConductorTest::TestProvisioner.mocked_states = %i[created created created exited exited]
|
104
168
|
expect do
|
105
|
-
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner') do |
|
169
|
+
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner') do |sub_test_deployer, test_instance|
|
106
170
|
end
|
107
171
|
end.to raise_error /\[ node\/#{Regexp.escape(`whoami`.strip)}_hpc_testing_provisioner_\d+_\d+_\w+ \] - Instance fails to be in a state among \(running\) with timeout 1\. Currently in state exited/
|
108
172
|
end
|
@@ -120,7 +184,7 @@ describe HybridPlatformsConductor::Deployer do
|
|
120
184
|
raise Errno::ETIMEDOUT, 'Timeout while reading from port 22'
|
121
185
|
end
|
122
186
|
expect do
|
123
|
-
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner') do |
|
187
|
+
test_deployer.with_test_provisioned_instance(:test_provisioner, 'node', environment: 'hpc_testing_provisioner') do |sub_test_deployer, test_instance|
|
124
188
|
end
|
125
189
|
end.to raise_error /\[ node\/#{Regexp.escape(`whoami`.strip)}_hpc_testing_provisioner_\d+_\d+_\w+ \] - Instance fails to have port 22 opened with timeout 1\./
|
126
190
|
end
|