hybrid_platforms_conductor 32.7.2 → 32.7.3
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/lib/hybrid_platforms_conductor/deployer.rb +12 -1
- 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/connections_spec.rb +2 -0
- data/spec/hybrid_platforms_conductor_test/api/deployer/provisioner_spec.rb +74 -10
- data/spec/hybrid_platforms_conductor_test/helpers/cmd_runner_helpers.rb +5 -1
- data/spec/hybrid_platforms_conductor_test/helpers/connector_ssh_helpers.rb +4 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 83352b7821e41bc5b0282c693c47f0cac0f5a9915a45dfa37affd3d1fcaadd8c
|
|
4
|
+
data.tar.gz: fba8bf35c2569716b2b8f934a46684c8b29843e50fe49b8133d3eeae580938d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 69c667f1f6c626372ecef7c21c9afdb2865a38e418ad6add2ec4d04d9a0eeda6892fed168d546d89d8805d843c31945eb885d53b0cf5208a65a7eb89ba75ea74
|
|
7
|
+
data.tar.gz: b9478d38660f80b7c9f62411d72d0e890e74ec509973ceb3d417721d21f5f9923ffc5dfbc96b857af6301d7bd708630638d393dc3bbf2abcd4cf7d12e22a7af6
|
|
@@ -311,13 +311,24 @@ module HybridPlatformsConductor
|
|
|
311
311
|
environment: environment,
|
|
312
312
|
logger: @logger,
|
|
313
313
|
logger_stderr: @logger_stderr,
|
|
314
|
-
config:
|
|
314
|
+
config: sub_executable.config,
|
|
315
315
|
cmd_runner: @cmd_runner,
|
|
316
316
|
# Here we use the NodesHandler that will be bound to the sub-Deployer only, as the node's metadata might be modified by the Provisioner.
|
|
317
317
|
nodes_handler: sub_executable.nodes_handler,
|
|
318
318
|
actions_executor: @actions_executor
|
|
319
319
|
)
|
|
320
320
|
instance.with_running_instance(stop_on_exit: true, destroy_on_exit: !reuse_instance, port: 22) do
|
|
321
|
+
# Test-provisioned nodes have SSH Session Exec capabilities
|
|
322
|
+
sub_executable.nodes_handler.override_metadata_of node, :ssh_session_exec, 'true'
|
|
323
|
+
# Test-provisioned nodes use default sudo
|
|
324
|
+
sub_executable.config.sudo_procs.replace(sub_executable.config.sudo_procs.map do |sudo_proc_info|
|
|
325
|
+
{
|
|
326
|
+
nodes_selectors_stack: sudo_proc_info[:nodes_selectors_stack].map do |nodes_selector|
|
|
327
|
+
@nodes_handler.select_nodes(nodes_selector).select { |selected_node| selected_node != node }
|
|
328
|
+
end,
|
|
329
|
+
sudo_proc: sudo_proc_info[:sudo_proc]
|
|
330
|
+
}
|
|
331
|
+
end)
|
|
321
332
|
actions_executor = sub_executable.actions_executor
|
|
322
333
|
deployer = sub_executable.deployer
|
|
323
334
|
# Setup test environment for this container
|
|
@@ -54,17 +54,19 @@ module HybridPlatformsConductor
|
|
|
54
54
|
instance.stop
|
|
55
55
|
instance.with_running_instance(port: 22) do
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
unless @nodes_handler.get_root_access_allowed_of(@node) == 'true'
|
|
58
|
+
# ===== Deploy removes root access
|
|
59
|
+
# Check that we can't connect with root
|
|
60
|
+
ssh_ok = false
|
|
61
|
+
begin
|
|
62
|
+
Net::SSH.start(instance.ip, 'root', password: 'root_pwd', auth_methods: ['password'], verify_host_key: :never) do |ssh|
|
|
63
|
+
ssh_ok = ssh.exec!('echo Works').strip == 'Works'
|
|
64
|
+
end
|
|
65
|
+
rescue
|
|
63
66
|
end
|
|
64
|
-
|
|
67
|
+
assert_equal ssh_ok, false, 'Root can still connect on the image after deployment'
|
|
68
|
+
# Even if we can connect using root, run the idempotence test
|
|
65
69
|
end
|
|
66
|
-
assert_equal ssh_ok, false, 'Root can still connect on the image after deployment'
|
|
67
|
-
# Even if we can connect using root, run the idempotence test
|
|
68
70
|
|
|
69
71
|
# ===== Idempotence
|
|
70
72
|
unless ssh_ok
|
|
@@ -76,6 +76,15 @@ module HybridPlatformsConductor
|
|
|
76
76
|
# Make sure we update it.
|
|
77
77
|
@nodes_handler.override_metadata_of @node, :host_ip, instance_ip
|
|
78
78
|
@nodes_handler.invalidate_metadata_of @node, :host_keys
|
|
79
|
+
# Make sure the SSH transformations don't apply to this node
|
|
80
|
+
@config.ssh_connection_transforms.replace(@config.ssh_connection_transforms.map do |ssh_transform_info|
|
|
81
|
+
{
|
|
82
|
+
nodes_selectors_stack: ssh_transform_info[:nodes_selectors_stack].map do |nodes_selector|
|
|
83
|
+
@nodes_handler.select_nodes(nodes_selector).select { |selected_node| selected_node != @node }
|
|
84
|
+
end,
|
|
85
|
+
transform: ssh_transform_info[:transform]
|
|
86
|
+
}
|
|
87
|
+
end)
|
|
79
88
|
end
|
|
80
89
|
wait_for_port!(port) if port
|
|
81
90
|
yield
|
data/spec/hybrid_platforms_conductor_test/api/actions_executor/connectors/ssh/connections_spec.rb
CHANGED
|
@@ -123,6 +123,8 @@ describe HybridPlatformsConductor::ActionsExecutor do
|
|
|
123
123
|
'node3' => { connection: '192.168.42.3', user: 'test_user' }
|
|
124
124
|
},
|
|
125
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,
|
|
126
128
|
with_control_master_destroy_optional: true
|
|
127
129
|
) + ssh_expected_commands_for(
|
|
128
130
|
{
|
|
@@ -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
|
|
@@ -89,7 +89,11 @@ module HybridPlatformsConductorTest
|
|
|
89
89
|
remaining_expected_commands.select do |(_expected_command, _command_code, options)|
|
|
90
90
|
!options[:optional]
|
|
91
91
|
end
|
|
92
|
-
).to eq([]), "Expected CmdRunner commands were not run:\n#{
|
|
92
|
+
).to eq([]), "Expected CmdRunner commands were not run:\n#{
|
|
93
|
+
remaining_expected_commands.map do |(expected_command, _command_code, options)|
|
|
94
|
+
"#{options[:optional] ? '[Optional] ' : ''}#{expected_command}"
|
|
95
|
+
end.join("\n")
|
|
96
|
+
}"
|
|
93
97
|
# Un-mock the command runner
|
|
94
98
|
allow(cmd_runner).to receive(:run_cmd).and_call_original
|
|
95
99
|
end
|
|
@@ -15,6 +15,7 @@ module HybridPlatformsConductorTest
|
|
|
15
15
|
# * *times* (Integer): Number of times this connection should be used [default: 1]
|
|
16
16
|
# * *control_master_create_error* (String or nil): Error to simulate during the SSH ControlMaster creation, or nil for none [default: nil]
|
|
17
17
|
# * *with_control_master_create* (Boolean): Do we create the control master? [default: true]
|
|
18
|
+
# * *with_control_master_create_optional* (Boolean): If true, then consider the ControlMaster creation to be optional [default: false]
|
|
18
19
|
# * *with_control_master_check* (Boolean): Do we check the control master? [default: false]
|
|
19
20
|
# * *with_control_master_destroy* (Boolean): Do we destroy the control master? [default: true]
|
|
20
21
|
# * *with_control_master_destroy_optional* (Boolean): If true, then consider the ControlMaster destruction to be optional [default: false]
|
|
@@ -26,6 +27,7 @@ module HybridPlatformsConductorTest
|
|
|
26
27
|
def ssh_expected_commands_for(
|
|
27
28
|
nodes_connections,
|
|
28
29
|
with_control_master_create: true,
|
|
30
|
+
with_control_master_create_optional: false,
|
|
29
31
|
with_control_master_check: false,
|
|
30
32
|
with_control_master_destroy: true,
|
|
31
33
|
with_control_master_destroy_optional: false,
|
|
@@ -78,7 +80,8 @@ module HybridPlatformsConductorTest
|
|
|
78
80
|
else
|
|
79
81
|
[255, '', node_connection_info[:control_master_create_error]]
|
|
80
82
|
end
|
|
81
|
-
end
|
|
83
|
+
end,
|
|
84
|
+
{ optional: with_control_master_create_optional }
|
|
82
85
|
]
|
|
83
86
|
end
|
|
84
87
|
if with_control_master_check
|