hybrid_platforms_conductor 33.0.4 → 33.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bedd336d4e713f15ac516cd61d50cf964c2a25051fbb624e1ca75196ccd9dd39
4
- data.tar.gz: 2d75b29868194072733dd273f6d2f17ca001cc167f446105b72381e1620c57a1
3
+ metadata.gz: 90e31431abb4e4924342d8057fbb2d2f54d780975ef7079498045a7897262067
4
+ data.tar.gz: 3bfcb046a30115a681d407559f9395766439ada582a0d57070d5bae067776292
5
5
  SHA512:
6
- metadata.gz: f4333f83879592e3089ce6cf0e40609efab2435fe9bbecae699462871bab7c3df6b5e44da476b823dfde6f0f1868d1cbd5ca621a076ca147355950b1610b6e38
7
- data.tar.gz: e0f21e5ccec863d19c93fa1f36bcf51ce1be1a7b1e7bcdbcf83329914df3b3c852eb43b8af2e178b68f94305584c406007de0d47acc713f8170e7b7bba3da621
6
+ metadata.gz: c532fc150a6ac25db61a70de51b88332728cb93b27f1275fda6cf15b0fce03d2fce9b90f7ea1c65134c0475e10708d075235e9abc2ec5710bf8e4823a98dc2e7
7
+ data.tar.gz: d081b32a30c854f0445f98669ba417ee80256f65558b1d274e476b20bd6a0c35133f0f711adae65c9e118a027136caaffce91cd179a2202ae32623b2469d6b54
data/CHANGELOG.md CHANGED
@@ -1,3 +1,57 @@
1
+ # [v33.2.2](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.2.1...v33.2.2) (2021-06-21 12:41:35)
2
+
3
+ ## Global changes
4
+ ### Patches
5
+
6
+ * [[Hotfix(cmd_runner)] Retain dynamically set environment while executing commands](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/d709d5d2871e43196cc1f5f9eaf5b2155b34ed4e)
7
+
8
+ ## Changes for cmd_runner
9
+ ### Patches
10
+
11
+ * [[Hotfix(cmd_runner)] Retain dynamically set environment while executing commands](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/d709d5d2871e43196cc1f5f9eaf5b2155b34ed4e)
12
+
13
+ # [v33.2.1](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.2.0...v33.2.1) (2021-06-21 10:23:51)
14
+
15
+ ## Global changes
16
+ ### Patches
17
+
18
+ * [[Hotfix(platform_handler_serverless_chef)] Corrected dry-run mode not working](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/4800a0f4255c1999eed33651c1e66c445acd17bb)
19
+
20
+ ## Changes for platform_handler_serverless_chef
21
+ ### Patches
22
+
23
+ * [[Hotfix(platform_handler_serverless_chef)] Corrected dry-run mode not working](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/4800a0f4255c1999eed33651c1e66c445acd17bb)
24
+
25
+ # [v33.2.0](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.1.1...v33.2.0) (2021-06-18 23:22:21)
26
+
27
+ ## Global changes
28
+ ### Patches
29
+
30
+ * [[Feature(platform_handler_serverless_chef)] [#70] Install dependency gems from cookbook metadata before calling chef-client](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/6dfe7aa053db63489f3d0a236433304606051ecd)
31
+
32
+ ## Changes for platform_handler_serverless_chef
33
+ ### Features
34
+
35
+ * [[Feature(platform_handler_serverless_chef)] [#70] Install dependency gems from cookbook metadata before calling chef-client](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/6dfe7aa053db63489f3d0a236433304606051ecd)
36
+
37
+ # [v33.1.1](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.1.0...v33.1.1) (2021-06-18 13:19:39)
38
+
39
+ ### Patches
40
+
41
+ * [[Fix] Corrected bugs on log remote_fs plugin not working in dry-run and topographer](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/90dcde919b6fc99b8f79fc642fef8b4150a5a9d6)
42
+
43
+ # [v33.1.0](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.0.4...v33.1.0) (2021-06-18 11:37:28)
44
+
45
+ ## Global changes
46
+ ### Patches
47
+
48
+ * [[Feature(connector_local)] [#68] Add sudo support when copying files using the local connector](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/7725beca4429de0e81bcac0c0ac4fe149e625da2)
49
+
50
+ ## Changes for connector_local
51
+ ### Features
52
+
53
+ * [[Feature(connector_local)] [#68] Add sudo support when copying files using the local connector](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/7725beca4429de0e81bcac0c0ac4fe149e625da2)
54
+
1
55
  # [v33.0.4](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.0.3...v33.0.4) (2021-06-18 10:09:57)
2
56
 
3
57
  ## Global changes
@@ -130,7 +130,7 @@ module HybridPlatformsConductor
130
130
  (log_to_stdout ? [@logger_stderr] : []) +
131
131
  (file_output.nil? ? [] : [file_output])
132
132
  ) do
133
- Bundler.with_unbundled_env do
133
+ Bundler.without_bundled_env do
134
134
  cmd_result = TTY::Command.new(
135
135
  printer: :null,
136
136
  pty: true,
@@ -0,0 +1,37 @@
1
+ # Add a way to clean the current env from Bundler variables
2
+ module Bundler
3
+
4
+ class << self
5
+
6
+ # Run block with all bundler-related variables removed from the current environment
7
+ def without_bundled_env(&block)
8
+ with_env(current_unbundled_env, &block)
9
+ end
10
+
11
+ # @return [Hash] Environment with all bundler-related variables removed
12
+ def current_unbundled_env
13
+ env = ENV.clone.to_hash
14
+
15
+ env['MANPATH'] = env['BUNDLER_ORIG_MANPATH'] if env.key?('BUNDLER_ORIG_MANPATH')
16
+
17
+ env.delete_if { |k, _| k[0, 7] == 'BUNDLE_' }
18
+
19
+ if env.key?('RUBYOPT')
20
+ rubyopt = env['RUBYOPT'].split
21
+ rubyopt.delete("-r#{File.expand_path('bundler/setup', __dir__)}")
22
+ rubyopt.delete('-rbundler/setup')
23
+ env['RUBYOPT'] = rubyopt.join(' ')
24
+ end
25
+
26
+ if env.key?('RUBYLIB')
27
+ rubylib = env['RUBYLIB'].split(File::PATH_SEPARATOR)
28
+ rubylib.delete(File.expand_path(__dir__))
29
+ env['RUBYLIB'] = rubylib.join(File::PATH_SEPARATOR)
30
+ end
31
+
32
+ env
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -146,6 +146,7 @@ module HybridPlatformsConductor
146
146
  logger: @logger,
147
147
  logger_stderr: @logger_stderr,
148
148
  config: @config,
149
+ cmd_runner: @cmd_runner,
149
150
  nodes_handler: @nodes_handler,
150
151
  actions_executor: @actions_executor
151
152
  )
@@ -1,4 +1,6 @@
1
1
  require 'English'
2
+ require 'bundler'
3
+ require 'hybrid_platforms_conductor/core_extensions/bundler/without_bundled_env'
2
4
  require 'optparse'
3
5
  require 'logger'
4
6
  require 'hybrid_platforms_conductor/config'
@@ -75,7 +75,11 @@ module HybridPlatformsConductor
75
75
  def remote_copy(from, to, sudo: false, owner: nil, group: nil)
76
76
  # If the destination is a relative path, prepend the workspace dir to it.
77
77
  to = "#{workspace_for(@node)}/#{to}" unless to.start_with?('/')
78
- FileUtils.cp_r from, to
78
+ if sudo
79
+ run_cmd "#{@nodes_handler.sudo_on(@node)} cp -r \"#{from}\" \"#{to}\""
80
+ else
81
+ FileUtils.cp_r from, to unless @cmd_runner.dry_run
82
+ end
79
83
  end
80
84
  # rubocop:enable Lint/UnusedMethodArgument
81
85
 
@@ -121,7 +121,9 @@ module HybridPlatformsConductor
121
121
  # ...
122
122
  # ===== STDERR =====
123
123
  # ...
124
- if exit_status.is_a?(Symbol)
124
+ if @cmd_runner.dry_run
125
+ { error: 'No log to show in dry-run mode' }
126
+ elsif exit_status.is_a?(Symbol)
125
127
  { error: "Error: #{exit_status}\n#{stderr}" }
126
128
  else
127
129
  stdout_lines = stdout.split("\n")
@@ -179,6 +179,13 @@ module HybridPlatformsConductor
179
179
  /opt/chef-workstation/bin/chef export #{policy_file} #{package_dir} --chef-license accept#{extra_cp_data_bags}"
180
180
  next if @cmd_runner.dry_run
181
181
 
182
+ # Write the list of gems to be installed for this package
183
+ File.write(
184
+ "#{@repository_path}/#{package_dir}/gems.json",
185
+ Dir.glob("#{@repository_path}/#{package_dir}/cookbook_artifacts/*/metadata.json").map do |metadata|
186
+ JSON.parse(File.read(metadata))['gems']
187
+ end.flatten(1).to_json
188
+ )
182
189
  # Create secrets file
183
190
  secrets_file = "#{@repository_path}/#{package_dir}/data_bags/hpc_secrets/hpc_secrets.json"
184
191
  FileUtils.mkdir_p(File.dirname(secrets_file))
@@ -220,10 +227,13 @@ module HybridPlatformsConductor
220
227
  # * Array< Hash<Symbol,Object> >: List of actions to be done
221
228
  def actions_to_deploy_on(node, service, use_why_run: true)
222
229
  package_dir = "#{@repository_path}/dist/#{@local_env ? 'local' : 'prod'}/#{service}"
230
+ gems_to_install = []
223
231
  # Generate the nodes attributes file
224
232
  unless @cmd_runner.dry_run
225
233
  FileUtils.mkdir_p "#{package_dir}/nodes"
226
234
  File.write("#{package_dir}/nodes/#{node}.json", (known_nodes.include?(node) ? metadata_for(node) : {}).merge(@nodes_handler.metadata_of(node)).to_json)
235
+ # Get the gems to be installed
236
+ gems_to_install = JSON.parse(File.read("#{package_dir}/gems.json"))
227
237
  end
228
238
  client_options = [
229
239
  '--local-mode',
@@ -233,7 +243,19 @@ module HybridPlatformsConductor
233
243
  client_options << '--why-run' if use_why_run
234
244
  if @nodes_handler.get_use_local_chef_of(node)
235
245
  # Just run the chef-client directly from the packaged repository
236
- [{ bash: "cd #{package_dir} && #{@cmd_runner.root? ? '' : 'sudo '}SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client #{client_options.join(' ')}" }]
246
+ sudo_prefix = @cmd_runner.root? ? '' : 'sudo '
247
+ [
248
+ {
249
+ bash: [
250
+ 'set -e',
251
+ "cd #{package_dir}"
252
+ ] +
253
+ gems_to_install.map { |(gem_name, gem_version)| "#{sudo_prefix}SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef gem install #{gem_name} --version \"#{gem_version}\"" } +
254
+ [
255
+ "#{sudo_prefix}SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client #{client_options.join(' ')}"
256
+ ]
257
+ }
258
+ ]
237
259
  else
238
260
  # Upload the package and run it from the node
239
261
  package_name = File.basename(package_dir)
@@ -261,10 +283,14 @@ module HybridPlatformsConductor
261
283
  scp: { package_dir => './hpc_deploy' },
262
284
  remote_bash: [
263
285
  'set -e',
264
- "cd ./hpc_deploy/#{package_name}",
265
- "#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/bin/chef-client #{client_options.join(' ')}",
266
- 'cd ..'
267
- ] + (log_debug? ? [] : ["#{sudo}rm -rf ./hpc_deploy/#{package_name}"])
286
+ "cd ./hpc_deploy/#{package_name}"
287
+ ] +
288
+ gems_to_install.map { |(gem_name, gem_version)| "#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/embedded/bin/gem install #{gem_name} --version \"#{gem_version}\"" } +
289
+ [
290
+ "#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/bin/chef-client #{client_options.join(' ')}",
291
+ 'cd ..'
292
+ ] +
293
+ (log_debug? ? [] : ["#{sudo}rm -rf ./hpc_deploy/#{package_name}"])
268
294
  }
269
295
  ]
270
296
  end
@@ -12,16 +12,19 @@ module HybridPlatformsConductor
12
12
  # * *logger* (Logger): Logger to be used [default: Logger.new(STDOUT)]
13
13
  # * *logger_stderr* (Logger): Logger to be used for stderr [default: Logger.new(STDERR)]
14
14
  # * *config* (Config): Config to be used. [default: Config.new]
15
+ # * *cmd_runner* (CmdRunner): CmdRunner to be used [default: CmdRunner.new]
15
16
  # * *nodes_handler* (NodesHandler): Nodes handler to be used. [default: NodesHandler.new]
16
17
  # * *actions_executor* (ActionsExecutor): Actions executor 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,
22
+ cmd_runner: CmdRunner.new,
21
23
  nodes_handler: NodesHandler.new,
22
24
  actions_executor: ActionsExecutor.new
23
25
  )
24
26
  super(logger: logger, logger_stderr: logger_stderr, config: config)
27
+ @cmd_runner = cmd_runner
25
28
  @nodes_handler = nodes_handler
26
29
  @actions_executor = actions_executor
27
30
  end
@@ -304,7 +304,8 @@ module HybridPlatformsConductor
304
304
 
305
305
  # Define clusters of ips with 24 bits ranges.
306
306
  def define_clusters_ip_24
307
- @nodes_graph.each_key do |node_name|
307
+ # Clone keys as we modify the hash in the loop
308
+ @nodes_graph.keys.clone.each do |node_name|
308
309
  next unless @nodes_graph[node_name][:type] == :node && !@node_metadata[node_name][:private_ips].nil? && !@node_metadata[node_name][:private_ips].empty?
309
310
 
310
311
  ip_24 = "#{@node_metadata[node_name][:private_ips].first.split('.')[0..2].join('.')}.0/24"
@@ -1,5 +1,5 @@
1
1
  module HybridPlatformsConductor
2
2
 
3
- VERSION = '33.0.4'
3
+ VERSION = '33.2.2'
4
4
 
5
5
  end
@@ -87,6 +87,43 @@ describe HybridPlatformsConductor::ActionsExecutor do
87
87
  end
88
88
  end
89
89
 
90
+ it 'does not copy files remotely in dry-run mode' do
91
+ with_test_platform_for_remote_testing do
92
+ test_cmd_runner.dry_run = true
93
+ expect(FileUtils).not_to receive(:cp_r)
94
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir')
95
+ end
96
+ end
97
+
98
+ it 'copies files remotely with sudo' do
99
+ with_test_platform_for_remote_testing(
100
+ expected_cmds: [
101
+ [
102
+ 'sudo -u root cp -r "/path/to/src.file" "/remote_path/to/dst.dir"',
103
+ proc { [0, '', ''] }
104
+ ]
105
+ ]
106
+ ) do
107
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir', sudo: true)
108
+ end
109
+ end
110
+
111
+ it 'copies files remotely with a different sudo' do
112
+ with_test_platform_for_remote_testing(
113
+ expected_cmds: [
114
+ [
115
+ 'other_sudo --user root cp -r "/path/to/src.file" "/remote_path/to/dst.dir"',
116
+ proc { [0, '', ''] }
117
+ ]
118
+ ],
119
+ additional_config: <<~'EO_CONFIG'
120
+ sudo_for { |user| "other_sudo --user #{user}" }
121
+ EO_CONFIG
122
+ ) do
123
+ test_connector.remote_copy('/path/to/src.file', '/remote_path/to/dst.dir', sudo: true)
124
+ end
125
+ end
126
+
90
127
  it 'copies files remotely with timeout' do
91
128
  with_test_platform_for_remote_testing(
92
129
  timeout: 5
@@ -103,6 +140,35 @@ describe HybridPlatformsConductor::ActionsExecutor do
103
140
  end
104
141
  end
105
142
 
143
+ it 'copies relative files remotely with sudo' do
144
+ with_test_platform_for_remote_testing(
145
+ expected_cmds: [
146
+ [
147
+ 'sudo -u root cp -r "/path/to/src.file" "/tmp/hpc_local_workspaces/node/to/dst.dir"',
148
+ proc { [0, '', ''] }
149
+ ]
150
+ ]
151
+ ) do
152
+ test_connector.remote_copy('/path/to/src.file', 'to/dst.dir', sudo: true)
153
+ end
154
+ end
155
+
156
+ it 'copies relative files remotely with a different sudo' do
157
+ with_test_platform_for_remote_testing(
158
+ expected_cmds: [
159
+ [
160
+ 'other_sudo --user root cp -r "/path/to/src.file" "/tmp/hpc_local_workspaces/node/to/dst.dir"',
161
+ proc { [0, '', ''] }
162
+ ]
163
+ ],
164
+ additional_config: <<~'EO_CONFIG'
165
+ sudo_for { |user| "other_sudo --user #{user}" }
166
+ EO_CONFIG
167
+ ) do
168
+ test_connector.remote_copy('/path/to/src.file', 'to/dst.dir', sudo: true)
169
+ end
170
+ end
171
+
106
172
  end
107
173
 
108
174
  end
@@ -51,6 +51,14 @@ describe HybridPlatformsConductor::CmdRunner do
51
51
  end
52
52
  end
53
53
 
54
+ it 'keeps dynamically set environment' do
55
+ with_repository do
56
+ value = ('a'..'z').to_a.sample(8).join
57
+ ENV['hpc_test_new_variable'] = value
58
+ expect(test_cmd_runner.run_cmd('echo "${hpc_test_new_variable}"')).to eq [0, "#{value}\n", '']
59
+ end
60
+ end
61
+
54
62
  it 'fails when the command does not exit 0' do
55
63
  with_repository do
56
64
  expect { test_cmd_runner.run_cmd 'exit 1' }.to raise_error(HybridPlatformsConductor::CmdRunner::UnexpectedExitCodeError, 'Command \'exit 1\' returned error code 1 (expected 0).')
@@ -12,6 +12,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
12
12
  # * *export* (Boolean): Are we expecting the chef export stage? [default: true]
13
13
  # * *data_bags* (Boolean): Do we expect data bags copy? [default: false]
14
14
  # * *env* (String): Expected environment being packaged [default: 'prod']
15
+ # * *cookbook_metadata* (Hash<String, Hash>): JSON metadata to generate for packaged cookbooks [default: {}]
15
16
  # * *block* (Proc): Code called with mock in place
16
17
  def with_packaging_mocked(
17
18
  repository,
@@ -21,6 +22,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
21
22
  export: true,
22
23
  data_bags: false,
23
24
  env: 'prod',
25
+ cookbook_metadata: {},
24
26
  &block
25
27
  )
26
28
  with_cmd_runner_mocked(
@@ -49,8 +51,14 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
49
51
  [
50
52
  %r{^cd #{Regexp.escape(repository)} &&\s+sudo rm -rf dist/#{Regexp.escape(env)}/#{Regexp.escape(policy)} &&\s+/opt/chef-workstation/bin/chef export #{Regexp.escape(policy_file)} dist/#{Regexp.escape(env)}/#{Regexp.escape(policy)} --chef-license accept#{data_bags ? " && cp -ar data_bags/ dist/#{Regexp.escape(env)}/#{Regexp.escape(policy)}/" : ''}$},
51
53
  proc do
52
- FileUtils.mkdir_p "#{repository}/dist/#{env}/#{policy}"
53
- FileUtils.cp_r("#{repository}/data_bags", "#{repository}/dist/#{env}/#{policy}/") if data_bags
54
+ package_dir = "#{repository}/dist/#{env}/#{policy}"
55
+ FileUtils.mkdir_p package_dir
56
+ FileUtils.cp_r("#{repository}/data_bags", "#{package_dir}/") if data_bags
57
+ cookbook_metadata.each do |cookbook, metadata|
58
+ metadata_file = "#{package_dir}/cookbook_artifacts/#{cookbook}/metadata.json"
59
+ FileUtils.mkdir_p File.dirname(metadata_file)
60
+ File.write(metadata_file, metadata.to_json)
61
+ end
54
62
  [0, 'Chef export done', '']
55
63
  end
56
64
  ]
@@ -80,6 +88,9 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
80
88
  with_serverless_chef_platforms('1_node') do |platform, repository|
81
89
  with_packaging_mocked(repository) do
82
90
  platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
91
+ gems_file = "#{repository}/dist/prod/test_policy/gems.json"
92
+ expect(File.exist?(gems_file)).to eq true
93
+ expect(JSON.parse(File.read(gems_file))).to eq []
83
94
  end
84
95
  end
85
96
  end
@@ -212,6 +223,41 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
212
223
 
213
224
  end
214
225
 
226
+ context 'with a platform having several cookbooks' do
227
+
228
+ it 'generates the gems info to be installed' do
229
+ with_serverless_chef_platforms('several_cookbooks') do |platform, repository|
230
+ with_packaging_mocked(
231
+ repository,
232
+ policy: 'test_policy_1',
233
+ cookbook_metadata: {
234
+ 'test_cookbook_1' => {
235
+ gems: [
236
+ ['my_gem_1', '0.0.1'],
237
+ ['my_gem_2', '0.0.2']
238
+ ]
239
+ },
240
+ 'dependency_cookbook' => {
241
+ gems: [
242
+ ['my_gem_3', '~> 1.3']
243
+ ]
244
+ }
245
+ }
246
+ ) do
247
+ platform.package(services: { 'node1' => %w[test_policy_1] }, secrets: {}, local_environment: false)
248
+ gems_file = "#{repository}/dist/prod/test_policy_1/gems.json"
249
+ expect(File.exist?(gems_file)).to eq true
250
+ expect(JSON.parse(File.read(gems_file)).sort).to eq [
251
+ ['my_gem_1', '0.0.1'],
252
+ ['my_gem_2', '0.0.2'],
253
+ ['my_gem_3', '~> 1.3']
254
+ ].sort
255
+ end
256
+ end
257
+ end
258
+
259
+ end
260
+
215
261
  context 'with a platform having data bags' do
216
262
 
217
263
  it 'packages data bags' do
@@ -6,9 +6,18 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
6
6
  #
7
7
  # Parameters::
8
8
  # * *repository* (String): The repository we package
9
+ # * *env* (String): The environment for which this repository is packaged [default: 'prod']
9
10
  # * *service* (String): The service being packaged in this repository [default: 'test_policy']
10
- def mock_package(repository, service: 'test_policy')
11
- FileUtils.mkdir_p "#{repository}/dist/prod/#{service}"
11
+ # * *gems* (Array<String, String>): The [<name>, <version>] gems info to be installed as generated by the packaging [default: []]
12
+ def mock_package(
13
+ repository,
14
+ env: 'prod',
15
+ service: 'test_policy',
16
+ gems: []
17
+ )
18
+ package_dir = "#{repository}/dist/#{env}/#{service}"
19
+ FileUtils.mkdir_p package_dir
20
+ File.write("#{package_dir}/gems.json", gems.to_json)
12
21
  end
13
22
 
14
23
  # Get expected actions to deploy a service on a given node
@@ -20,6 +29,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
20
29
  # * *env* (String): Environment expected to be packaged [default: 'prod']
21
30
  # * *policy* (String): Expected policy to be packaged [default: 'test_policy']
22
31
  # * *node* (String): Expected node to be deployed [default: 'node']
32
+ # * *gems_install_cmds* (Array<String>): Expected gem install commands [default: []]
23
33
  # Result::
24
34
  # * Array: Expected actions
25
35
  def expected_actions_to_deploy_chef(
@@ -28,7 +38,8 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
28
38
  sudo: 'sudo -u root ',
29
39
  env: 'prod',
30
40
  policy: 'test_policy',
31
- node: 'node'
41
+ node: 'node',
42
+ gems_install_cmds: []
32
43
  )
33
44
  [
34
45
  {
@@ -48,11 +59,14 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
48
59
  scp: { "#{repository}/dist/#{env}/#{policy}" => './hpc_deploy' },
49
60
  remote_bash: [
50
61
  'set -e',
51
- "cd ./hpc_deploy/#{policy}",
52
- "#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/bin/chef-client --local-mode --chef-license accept --json-attributes nodes/#{node}.json#{check_mode ? ' --why-run' : ''}",
53
- 'cd ..',
54
- "#{sudo}rm -rf ./hpc_deploy/#{policy}"
55
- ]
62
+ "cd ./hpc_deploy/#{policy}"
63
+ ] +
64
+ gems_install_cmds.map { |gem_install_cmd| "#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/embedded/bin/#{gem_install_cmd}" } +
65
+ [
66
+ "#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/bin/chef-client --local-mode --chef-license accept --json-attributes nodes/#{node}.json#{check_mode ? ' --why-run' : ''}",
67
+ 'cd ..',
68
+ "#{sudo}rm -rf ./hpc_deploy/#{policy}"
69
+ ]
56
70
  }
57
71
  ]
58
72
  end
@@ -109,6 +123,33 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
109
123
  end
110
124
  end
111
125
 
126
+ it 'returns actions to deploy on this node with gems to be installed' do
127
+ with_serverless_chef_platforms('1_node') do |platform, repository|
128
+ mock_package(
129
+ repository,
130
+ gems: [
131
+ ['my_gem_1', '0.0.1'],
132
+ ['my_gem_2', '0.0.2'],
133
+ ['my_gem_3', '~> 1.3']
134
+ ]
135
+ )
136
+ platform.prepare_for_deploy(
137
+ services: { 'node' => %w[test_policy] },
138
+ secrets: {},
139
+ local_environment: false,
140
+ why_run: false
141
+ )
142
+ expect(platform.actions_to_deploy_on('node', 'test_policy', use_why_run: false)).to eq expected_actions_to_deploy_chef(
143
+ repository,
144
+ gems_install_cmds: [
145
+ 'gem install my_gem_1 --version "0.0.1"',
146
+ 'gem install my_gem_2 --version "0.0.2"',
147
+ 'gem install my_gem_3 --version "~> 1.3"'
148
+ ]
149
+ )
150
+ end
151
+ end
152
+
112
153
  it 'returns actions to deploy on this node with node attributes setup from metadata' do
113
154
  with_serverless_chef_platforms('1_node') do |platform, repository|
114
155
  test_nodes_handler.override_metadata_of 'node', :new_metadata, 'new_value'
@@ -161,7 +202,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
161
202
 
162
203
  it 'returns actions to deploy on this node using local mode' do
163
204
  with_serverless_chef_platforms('1_node') do |platform, repository|
164
- mock_package(repository)
205
+ mock_package(repository, env: 'local')
165
206
  platform.prepare_for_deploy(
166
207
  services: { 'node' => %w[test_policy] },
167
208
  secrets: {},
@@ -174,7 +215,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
174
215
 
175
216
  it 'returns actions to deploy on this node in why-run mode and local mode' do
176
217
  with_serverless_chef_platforms('1_node') do |platform, repository|
177
- mock_package(repository)
218
+ mock_package(repository, env: 'local')
178
219
  platform.prepare_for_deploy(
179
220
  services: { 'node' => %w[test_policy] },
180
221
  secrets: {},
@@ -219,7 +260,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
219
260
 
220
261
  it 'deploys services declared on 1 node on another node if asked' do
221
262
  with_serverless_chef_platforms('several_nodes') do |platform, repository|
222
- mock_package(repository)
263
+ mock_package(repository, service: 'test_policy_1')
223
264
  platform.prepare_for_deploy(
224
265
  services: { 'node2' => %w[test_policy_1] },
225
266
  secrets: {},
@@ -230,9 +271,38 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
230
271
  end
231
272
  end
232
273
 
233
- it 'deploys local nodes' do
274
+ it 'deploys using the local chef workstation when use_local_chef is set' do
234
275
  with_serverless_chef_platforms('several_nodes') do |platform, repository|
235
- mock_package(repository)
276
+ mock_package(repository, service: 'test_policy_1')
277
+ platform.prepare_for_deploy(
278
+ services: { 'local' => %w[test_policy_1] },
279
+ secrets: {},
280
+ local_environment: false,
281
+ why_run: false
282
+ )
283
+ expect(platform.actions_to_deploy_on('local', 'test_policy_1', use_why_run: false)).to eq [
284
+ {
285
+ bash: [
286
+ 'set -e',
287
+ "cd #{repository}/dist/prod/test_policy_1",
288
+ 'sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client --local-mode --chef-license accept --json-attributes nodes/local.json'
289
+ ]
290
+ }
291
+ ]
292
+ end
293
+ end
294
+
295
+ it 'deploys using the local chef workstation with gems to be installed when use_local_chef is set' do
296
+ with_serverless_chef_platforms('several_nodes') do |platform, repository|
297
+ mock_package(
298
+ repository,
299
+ service: 'test_policy_1',
300
+ gems: [
301
+ ['my_gem_1', '0.0.1'],
302
+ ['my_gem_2', '0.0.2'],
303
+ ['my_gem_3', '~> 1.3']
304
+ ]
305
+ )
236
306
  platform.prepare_for_deploy(
237
307
  services: { 'local' => %w[test_policy_1] },
238
308
  secrets: {},
@@ -241,7 +311,14 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
241
311
  )
242
312
  expect(platform.actions_to_deploy_on('local', 'test_policy_1', use_why_run: false)).to eq [
243
313
  {
244
- bash: "cd #{repository}/dist/prod/test_policy_1 && sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client --local-mode --chef-license accept --json-attributes nodes/local.json"
314
+ bash: [
315
+ 'set -e',
316
+ "cd #{repository}/dist/prod/test_policy_1",
317
+ 'sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef gem install my_gem_1 --version "0.0.1"',
318
+ 'sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef gem install my_gem_2 --version "0.0.2"',
319
+ 'sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef gem install my_gem_3 --version "~> 1.3"',
320
+ 'sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client --local-mode --chef-license accept --json-attributes nodes/local.json'
321
+ ]
245
322
  }
246
323
  ]
247
324
  end
@@ -254,7 +331,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
254
331
  it 'deploys a service on a node belonging to another platform' do
255
332
  with_serverless_chef_platforms({ 'p1' => '1_node', 'p2' => 'several_nodes' }) do |repositories|
256
333
  platform_1, repository_1 = repositories.find { |platform, _repository| platform.name == 'p1' }
257
- mock_package(repository_1)
334
+ mock_package(repository_1, service: 'test_policy_1')
258
335
  platform_1.prepare_for_deploy(
259
336
  services: { 'node2' => %w[test_policy_1] },
260
337
  secrets: {},
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hybrid_platforms_conductor
3
3
  version: !ruby/object:Gem::Version
4
- version: 33.0.4
4
+ version: 33.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muriel Salvan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-18 00:00:00.000000000 Z
11
+ date: 2021-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: range_operators
@@ -695,6 +695,7 @@ files:
695
695
  - lib/hybrid_platforms_conductor/config.rb
696
696
  - lib/hybrid_platforms_conductor/confluence.rb
697
697
  - lib/hybrid_platforms_conductor/connector.rb
698
+ - lib/hybrid_platforms_conductor/core_extensions/bundler/without_bundled_env.rb
698
699
  - lib/hybrid_platforms_conductor/core_extensions/cleanroom/fix_kwargs.rb
699
700
  - lib/hybrid_platforms_conductor/core_extensions/symbol/zero.rb
700
701
  - lib/hybrid_platforms_conductor/credentials.rb