hybrid_platforms_conductor 32.14.0 → 32.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/docs/plugins/platform_handler/serverless_chef.md +6 -0
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +104 -9
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +4 -43
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb +85 -6
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/services_deployment_spec.rb +8 -4
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/chef_versions.yml +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/cookbooks/hpc_test/recipes/after_run.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/cookbooks/hpc_test/recipes/before_run.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/nodes/node.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/policyfiles/test_policy.rb +3 -0
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c01fcd515c7641751b265f34747561465570795cb75fb0287a75c61915055a2c
|
|
4
|
+
data.tar.gz: c249eb8d612bdc9b6a09467f195c71c607619e9aea278df4ff5b2bf061b968ed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 571f2e0effa2d3489eb8c948f90bcf23cc8890ac71a0e6bc4b2ec805dea5d9bd74a608de3d5f6a8d327015058f6c2adf8a23f07aea4f82f1c6445b4b943cd3bd
|
|
7
|
+
data.tar.gz: 749df7363532aec2976b1b070462288ee8bed7596fe419d1871390022e337ad0472570fe98a513661f95e47366bd4df3a72d022ec0595cdc73ac051ff000dbb3
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# [v32.15.0](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v32.14.0...v32.15.0) (2021-05-31 14:43:32)
|
|
2
|
+
|
|
3
|
+
## Global changes
|
|
4
|
+
### Patches
|
|
5
|
+
|
|
6
|
+
* [[Feature(platform_handler_serverless_chef)] Use user-defined cookbook hpc_test to tune chef-client runs in test environments](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/2cfa010997b562a599308ceaaf62a8740ff51468)
|
|
7
|
+
|
|
8
|
+
## Changes for platform_handler_serverless_chef
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* [[Feature(platform_handler_serverless_chef)] Use user-defined cookbook hpc_test to tune chef-client runs in test environments](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/2cfa010997b562a599308ceaaf62a8740ff51468)
|
|
12
|
+
|
|
1
13
|
# [v32.14.0](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v32.13.4...v32.14.0) (2021-05-31 09:05:45)
|
|
2
14
|
|
|
3
15
|
## Global changes
|
|
@@ -64,6 +64,12 @@ Services are being deployed by packaging the policy using [`chef install`](https
|
|
|
64
64
|
|
|
65
65
|
Then packaged services are uploaded on the node to configured and deployment is done remotely using [Chef Infra Client in local mode](https://docs.chef.io/ctl_chef_client/#run-in-local-mode) on the remote node.
|
|
66
66
|
|
|
67
|
+
## Test-wrapping cookbook `hpc_test`
|
|
68
|
+
|
|
69
|
+
If you have a cookbook named `hpc_test` in your Chef repository, then this plugin will wrap any run-list run in a local environment mode (used in tests) with the recipes `hpc_test::before_run` and `hpc_test::after_run`.
|
|
70
|
+
|
|
71
|
+
This way you can implement such recipes to adapt your Chef client runs to your test environment (like lack of connectivity, failing resources to be ignored...).
|
|
72
|
+
|
|
67
73
|
## Config DSL extension
|
|
68
74
|
|
|
69
75
|
### `helpers_including_recipes`
|
|
@@ -47,6 +47,28 @@ module HybridPlatformsConductor
|
|
|
47
47
|
end
|
|
48
48
|
self.extend_config_dsl_with MyDSLExtension, :init_serverless_chef
|
|
49
49
|
|
|
50
|
+
# Constructor
|
|
51
|
+
#
|
|
52
|
+
# Parameters::
|
|
53
|
+
# * *platform_type* (Symbol): Platform type
|
|
54
|
+
# * *repository_path* (String): Repository path
|
|
55
|
+
# * *logger* (Logger): Logger to be used [default: Logger.new(STDOUT)]
|
|
56
|
+
# * *logger_stderr* (Logger): Logger to be used for stderr [default: Logger.new(STDERR)]
|
|
57
|
+
# * *config* (Config): Config to be used. [default: Config.new]
|
|
58
|
+
# * *cmd_runner* (CmdRunner): Command executor to be used. [default: CmdRunner.new]
|
|
59
|
+
def initialize(
|
|
60
|
+
platform_type,
|
|
61
|
+
repository_path,
|
|
62
|
+
logger: Logger.new(STDOUT),
|
|
63
|
+
logger_stderr: Logger.new(STDERR),
|
|
64
|
+
config: Config.new,
|
|
65
|
+
cmd_runner: CmdRunner.new
|
|
66
|
+
)
|
|
67
|
+
super
|
|
68
|
+
# Mutex for getting the full recipes tree
|
|
69
|
+
@recipes_tree_mutex = Mutex.new
|
|
70
|
+
end
|
|
71
|
+
|
|
50
72
|
# Setup the platform, install dependencies...
|
|
51
73
|
# [API] - This method is optional.
|
|
52
74
|
# [API] - @cmd_runner is accessible.
|
|
@@ -139,12 +161,25 @@ module HybridPlatformsConductor
|
|
|
139
161
|
current_package_info = File.exist?(package_info_file) ? JSON.parse(File.read(package_info_file)).transform_keys(&:to_sym) : {}
|
|
140
162
|
unless current_package_info == package_info
|
|
141
163
|
Bundler.with_unbundled_env do
|
|
164
|
+
policy_file = "policyfiles/#{service}.rb"
|
|
165
|
+
if local_environment
|
|
166
|
+
local_policy_file = "policyfiles/#{service}.local.rb"
|
|
167
|
+
# In local mode, we always regenerate the lock file as we may modify the run list
|
|
168
|
+
run_list = known_cookbook_paths.any? { |cookbook_path| File.exist?("#{@repository_path}/#{cookbook_path}/hpc_test/recipes/before_run.rb") } ? ['hpc_test::before_run'] : []
|
|
169
|
+
dsl_parser = DslParser.new
|
|
170
|
+
dsl_parser.parse("#{@repository_path}/#{policy_file}")
|
|
171
|
+
run_list.concat dsl_parser.calls.find { |call_info| call_info[:method] == :run_list }[:args].flatten
|
|
172
|
+
run_list << 'hpc_test::after_run' if known_cookbook_paths.any? { |cookbook_path| File.exist?("#{@repository_path}/#{cookbook_path}/hpc_test/recipes/after_run.rb") }
|
|
173
|
+
File.write("#{@repository_path}/#{local_policy_file}", File.read("#{@repository_path}/#{policy_file}") + "\nrun_list #{run_list.map { |recipe| "'#{recipe}'" }.join(', ')}\n")
|
|
174
|
+
policy_file = local_policy_file
|
|
175
|
+
end
|
|
176
|
+
lock_file = "#{File.dirname(policy_file)}/#{File.basename(policy_file, '.rb')}.lock.json"
|
|
142
177
|
# If the policy lock file does not exist, generate it
|
|
143
|
-
@cmd_runner.run_cmd "cd #{@repository_path} && /opt/chef-workstation/bin/chef install
|
|
178
|
+
@cmd_runner.run_cmd "cd #{@repository_path} && /opt/chef-workstation/bin/chef install #{policy_file}" unless File.exist?("#{@repository_path}/#{lock_file}")
|
|
144
179
|
extra_cp_data_bags = File.exist?("#{@repository_path}/data_bags") ? " && cp -ar data_bags/ #{package_dir}/" : ''
|
|
145
180
|
@cmd_runner.run_cmd "cd #{@repository_path} && \
|
|
146
181
|
sudo rm -rf #{package_dir} && \
|
|
147
|
-
/opt/chef-workstation/bin/chef export
|
|
182
|
+
/opt/chef-workstation/bin/chef export #{policy_file} #{package_dir}#{extra_cp_data_bags}"
|
|
148
183
|
end
|
|
149
184
|
unless @cmd_runner.dry_run
|
|
150
185
|
# Create secrets file
|
|
@@ -193,9 +228,15 @@ module HybridPlatformsConductor
|
|
|
193
228
|
FileUtils.mkdir_p "#{package_dir}/nodes"
|
|
194
229
|
File.write("#{package_dir}/nodes/#{node}.json", (known_nodes.include?(node) ? metadata_for(node) : {}).merge(@nodes_handler.metadata_of(node)).to_json)
|
|
195
230
|
end
|
|
231
|
+
client_options = [
|
|
232
|
+
'--local-mode',
|
|
233
|
+
'--chef-license', 'accept',
|
|
234
|
+
'--json-attributes', "nodes/#{node}.json"
|
|
235
|
+
]
|
|
236
|
+
client_options << '--why-run' if use_why_run
|
|
196
237
|
if @nodes_handler.get_use_local_chef_of(node)
|
|
197
238
|
# Just run the chef-client directly from the packaged repository
|
|
198
|
-
[{ bash: "cd #{package_dir} && sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client
|
|
239
|
+
[{ bash: "cd #{package_dir} && sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client #{client_options.join(' ')}" }]
|
|
199
240
|
else
|
|
200
241
|
# Upload the package and run it from the node
|
|
201
242
|
package_name = File.basename(package_dir)
|
|
@@ -211,7 +252,11 @@ module HybridPlatformsConductor
|
|
|
211
252
|
'set -o pipefail',
|
|
212
253
|
"if [ -n \"$(command -v apt)\" ]; then #{sudo}apt update && #{sudo}apt install -y curl build-essential ; else #{sudo}yum groupinstall 'Development Tools' && #{sudo}yum install -y curl ; fi",
|
|
213
254
|
'mkdir -p ./hpc_deploy',
|
|
214
|
-
|
|
255
|
+
'rm -rf ./hpc_deploy/tmp',
|
|
256
|
+
'mkdir -p ./hpc_deploy/tmp',
|
|
257
|
+
'curl --location https://omnitruck.chef.io/install.sh --output ./hpc_deploy/install.sh',
|
|
258
|
+
'chmod a+x ./hpc_deploy/install.sh',
|
|
259
|
+
"#{sudo}TMPDIR=./hpc_deploy/tmp ./hpc_deploy/install.sh -d /opt/artefacts -v #{required_chef_client_version} -s once"
|
|
215
260
|
]
|
|
216
261
|
},
|
|
217
262
|
{
|
|
@@ -219,10 +264,9 @@ module HybridPlatformsConductor
|
|
|
219
264
|
remote_bash: [
|
|
220
265
|
'set -e',
|
|
221
266
|
"cd ./hpc_deploy/#{package_name}",
|
|
222
|
-
"#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/bin/chef-client
|
|
223
|
-
'cd ..'
|
|
224
|
-
|
|
225
|
-
]
|
|
267
|
+
"#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/bin/chef-client #{client_options.join(' ')}",
|
|
268
|
+
'cd ..'
|
|
269
|
+
] + (log_debug? ? [] : ["#{sudo}rm -rf ./hpc_deploy/#{package_name}"])
|
|
226
270
|
}
|
|
227
271
|
]
|
|
228
272
|
end
|
|
@@ -371,7 +415,7 @@ module HybridPlatformsConductor
|
|
|
371
415
|
impacted_recipes.uniq!
|
|
372
416
|
log_debug "* #{impacted_recipes.size} impacted recipes:\n#{impacted_recipes.map { |(cookbook, recipe)| "#{cookbook}::#{recipe}" }.sort.join("\n")}"
|
|
373
417
|
|
|
374
|
-
recipes_tree =
|
|
418
|
+
recipes_tree = full_recipes_tree
|
|
375
419
|
[
|
|
376
420
|
impacted_nodes,
|
|
377
421
|
(
|
|
@@ -419,6 +463,45 @@ module HybridPlatformsConductor
|
|
|
419
463
|
@cookbook_paths
|
|
420
464
|
end
|
|
421
465
|
|
|
466
|
+
# Get the run list of a given policy
|
|
467
|
+
#
|
|
468
|
+
# Parameters::
|
|
469
|
+
# * *policy* (String): Policy to get the run list from
|
|
470
|
+
# Result::
|
|
471
|
+
# * Array<[String or nil, Symbol, Symbol]>: Run list of the given policy, as [cookbook_dir, cookbook, recipe]
|
|
472
|
+
def policy_run_list(policy)
|
|
473
|
+
# Read the policy file
|
|
474
|
+
dsl_parser = DslParser.new
|
|
475
|
+
policy_file = "#{@repository_path}/policyfiles/#{policy}.rb"
|
|
476
|
+
dsl_parser.parse(policy_file)
|
|
477
|
+
run_list_call = dsl_parser.calls.find { |call_info| call_info[:method] == :run_list }
|
|
478
|
+
raise "Policy #{policy} has no run list defined in #{policy_file}" if run_list_call.nil?
|
|
479
|
+
run_list_call[:args].map { |recipe_def| decode_recipe(recipe_def) }
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
# Return the cookbook directory, cookbook name and recipe name from which a recipe definition is found.
|
|
483
|
+
# The following forms are handled:
|
|
484
|
+
# * cookbook
|
|
485
|
+
# * cookbook::recipe
|
|
486
|
+
# * recipe[cookbook]
|
|
487
|
+
# * recipe[cookbook::recipe]
|
|
488
|
+
#
|
|
489
|
+
# Parameters::
|
|
490
|
+
# * *recipe_def* (String): Recipe definition (cookbook or cookbook::recipe).
|
|
491
|
+
# Result::
|
|
492
|
+
# * String: The cookbook directory, or nil if unknown
|
|
493
|
+
# * Symbol: The cookbook name
|
|
494
|
+
# * Symbol: The recipe name
|
|
495
|
+
def decode_recipe(recipe_def)
|
|
496
|
+
recipe_def = $1 if recipe_def =~ /^recipe\[(.+)\]$/
|
|
497
|
+
cookbook, recipe = recipe_def.split('::').map(&:to_sym)
|
|
498
|
+
recipe = :default if recipe.nil?
|
|
499
|
+
# Find the cookbook it belongs to
|
|
500
|
+
cookbook_dir = known_cookbook_paths.find { |cookbook_path| File.exist?("#{@repository_path}/#{cookbook_path}/#{cookbook}") }
|
|
501
|
+
raise "Unknown recipe #{cookbook}::#{recipe} from cookbook #{@repository_path}/#{cookbook_dir}/#{cookbook}." if !cookbook_dir.nil? && !File.exist?("#{@repository_path}/#{cookbook_dir}/#{cookbook}/recipes/#{recipe}.rb")
|
|
502
|
+
return cookbook_dir, cookbook, recipe
|
|
503
|
+
end
|
|
504
|
+
|
|
422
505
|
private
|
|
423
506
|
|
|
424
507
|
# Return the JSON associated to a node
|
|
@@ -431,6 +514,18 @@ module HybridPlatformsConductor
|
|
|
431
514
|
JSON.parse(File.read("#{@repository_path}/nodes/#{node}.json"))
|
|
432
515
|
end
|
|
433
516
|
|
|
517
|
+
# Get the full recipes tree.
|
|
518
|
+
# Keep it in a cache for performance.
|
|
519
|
+
#
|
|
520
|
+
# Result::
|
|
521
|
+
# * Hash: The recipes tree. See RecipesTreeBuilder#full_recipes_tree for the detailed signature
|
|
522
|
+
def full_recipes_tree
|
|
523
|
+
@recipes_tree_mutex.synchronize do
|
|
524
|
+
@recipes_tree = RecipesTreeBuilder.new(@config, self).full_recipes_tree unless defined?(@recipes_tree)
|
|
525
|
+
end
|
|
526
|
+
@recipes_tree
|
|
527
|
+
end
|
|
528
|
+
|
|
434
529
|
end
|
|
435
530
|
|
|
436
531
|
end
|
|
@@ -36,12 +36,12 @@ module HybridPlatformsConductor
|
|
|
36
36
|
def full_recipes_tree
|
|
37
37
|
@recipes_tree = {}
|
|
38
38
|
@platform.deployable_services.each do |service|
|
|
39
|
-
policy_run_list(service).each do |(cookbook_dir, cookbook, recipe)|
|
|
39
|
+
@platform.policy_run_list(service).each do |(cookbook_dir, cookbook, recipe)|
|
|
40
40
|
add_recipe_in_tree(cookbook_dir, cookbook, recipe)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
@platform.deployable_services.each do |service|
|
|
44
|
-
policy_run_list(service).each do |(cookbook_dir, cookbook, recipe)|
|
|
44
|
+
@platform.policy_run_list(service).each do |(cookbook_dir, cookbook, recipe)|
|
|
45
45
|
mark_recipe_used_by_policy(cookbook, recipe, service)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -50,45 +50,6 @@ module HybridPlatformsConductor
|
|
|
50
50
|
|
|
51
51
|
private
|
|
52
52
|
|
|
53
|
-
# Get the run list of a given policy
|
|
54
|
-
#
|
|
55
|
-
# Parameters::
|
|
56
|
-
# * *policy* (String): Policy to get the run list from
|
|
57
|
-
# Result::
|
|
58
|
-
# * Array<[String or nil, Symbol,Symbol]>: Run list of the given policy, as [cookbook_dir, cookbook, recipe]
|
|
59
|
-
def policy_run_list(policy)
|
|
60
|
-
# Read the policy file
|
|
61
|
-
dsl_parser = DslParser.new
|
|
62
|
-
policy_file = "#{@platform.repository_path}/policyfiles/#{policy}.rb"
|
|
63
|
-
dsl_parser.parse(policy_file)
|
|
64
|
-
run_list_call = dsl_parser.calls.find { |call_info| call_info[:method] == :run_list }
|
|
65
|
-
raise "Policy #{policy} has no run list defined in #{policy_file}" if run_list_call.nil?
|
|
66
|
-
run_list_call[:args].map { |recipe_def| decode_recipe(recipe_def) }
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Return the cookbook directory, cookbook name and recipe name from which a recipe definition is found.
|
|
70
|
-
# The following forms are handled:
|
|
71
|
-
# * cookbook
|
|
72
|
-
# * cookbook::recipe
|
|
73
|
-
# * recipe[cookbook]
|
|
74
|
-
# * recipe[cookbook::recipe]
|
|
75
|
-
#
|
|
76
|
-
# Parameters::
|
|
77
|
-
# * *recipe_def* (String): Recipe definition (cookbook or cookbook::recipe).
|
|
78
|
-
# Result::
|
|
79
|
-
# * String: The cookbook directory, or nil if unknown
|
|
80
|
-
# * Symbol: The cookbook name
|
|
81
|
-
# * Symbol: The recipe name
|
|
82
|
-
def decode_recipe(recipe_def)
|
|
83
|
-
recipe_def = $1 if recipe_def =~ /^recipe\[(.+)\]$/
|
|
84
|
-
cookbook, recipe = recipe_def.split('::').map(&:to_sym)
|
|
85
|
-
recipe = :default if recipe.nil?
|
|
86
|
-
# Find the cookbook it belongs to
|
|
87
|
-
cookbook_dir = @platform.known_cookbook_paths.find { |cookbook_path| File.exist?("#{@platform.repository_path}/#{cookbook_path}/#{cookbook}") }
|
|
88
|
-
raise "Unknown recipe #{cookbook}::#{recipe} from cookbook #{@platform.repository_path}/#{cookbook_dir}/#{cookbook}." if !cookbook_dir.nil? && !File.exist?("#{@platform.repository_path}/#{cookbook_dir}/#{cookbook}/recipes/#{recipe}.rb")
|
|
89
|
-
return cookbook_dir, cookbook, recipe
|
|
90
|
-
end
|
|
91
|
-
|
|
92
53
|
# Fill the tree with a recipe and all its dependencies
|
|
93
54
|
#
|
|
94
55
|
# Parameters::
|
|
@@ -142,11 +103,11 @@ module HybridPlatformsConductor
|
|
|
142
103
|
# Check for include_recipe
|
|
143
104
|
used_recipes = recipe_content.
|
|
144
105
|
scan(/include_recipe\s+["'](\w+(::\w+)?)["']/).
|
|
145
|
-
map { |(recipe_def, _sub_grp)| decode_recipe(recipe_def) }
|
|
106
|
+
map { |(recipe_def, _sub_grp)| @platform.decode_recipe(recipe_def) }
|
|
146
107
|
# Check for some helpers we know include some recipes
|
|
147
108
|
@config.known_helpers_including_recipes.each do |helper_name, used_recipes_by_helper|
|
|
148
109
|
if recipe_content =~ Regexp.new(/(\W|^)#{Regexp.escape(helper_name)}(\W|$)/)
|
|
149
|
-
used_recipes.concat(used_recipes_by_helper.map { |recipe_def| decode_recipe(recipe_def) })
|
|
110
|
+
used_recipes.concat(used_recipes_by_helper.map { |recipe_def| @platform.decode_recipe(recipe_def) })
|
|
150
111
|
used_recipes.uniq!
|
|
151
112
|
end
|
|
152
113
|
end
|
data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/packaging_spec.rb
CHANGED
|
@@ -7,24 +7,34 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
|
7
7
|
# Parameters::
|
|
8
8
|
# * *repository* (String): Repository to be packaged
|
|
9
9
|
# * *policy* (String): Expected policy to be packaged [default: 'test_policy']
|
|
10
|
+
# * *policy_file* (String): Expected policy file used [default: "policyfiles/#{policy}.rb"]
|
|
10
11
|
# * *install* (Boolean): Are we expecting the chef install stage? [default: true]
|
|
11
12
|
# * *export* (Boolean): Are we expecting the chef export stage? [default: true]
|
|
12
13
|
# * *data_bags* (Boolean): Do we expect data bags copy? [default: false]
|
|
14
|
+
# * *env* (String): Expected environment being packaged [default: 'prod']
|
|
13
15
|
# * Proc: Code called with mock in place
|
|
14
16
|
def with_packaging_mocked(
|
|
15
17
|
repository,
|
|
16
18
|
policy: 'test_policy',
|
|
19
|
+
policy_file: "policyfiles/#{policy}.rb",
|
|
17
20
|
install: true,
|
|
18
21
|
export: true,
|
|
19
|
-
data_bags: false
|
|
22
|
+
data_bags: false,
|
|
23
|
+
env: 'prod'
|
|
20
24
|
)
|
|
21
25
|
with_cmd_runner_mocked(
|
|
22
26
|
if install
|
|
23
27
|
[
|
|
24
28
|
[
|
|
25
|
-
"cd #{repository} && /opt/chef-workstation/bin/chef install
|
|
29
|
+
"cd #{repository} && /opt/chef-workstation/bin/chef install #{policy_file}",
|
|
26
30
|
proc do
|
|
27
|
-
|
|
31
|
+
# Mock the run_list stored in the lock file
|
|
32
|
+
File.write(
|
|
33
|
+
"#{repository}/#{policy_file.gsub(/.rb$/, '.lock.json')}",
|
|
34
|
+
{
|
|
35
|
+
run_list: eval("[#{File.read("#{repository}/#{policy_file}").split("\n").select { |line| line =~ /^run_list.+$/ }.last.match(/^run_list(.+)$/)[1]}]").flatten
|
|
36
|
+
}.to_json
|
|
37
|
+
)
|
|
28
38
|
[0, 'Chef install done', '']
|
|
29
39
|
end
|
|
30
40
|
]
|
|
@@ -35,10 +45,10 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
|
35
45
|
if export
|
|
36
46
|
[
|
|
37
47
|
[
|
|
38
|
-
/^cd #{Regexp.escape(repository)} &&\s+sudo rm -rf dist
|
|
48
|
+
/^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)}#{data_bags ? " && cp -ar data_bags/ dist/#{Regexp.escape(env)}/#{Regexp.escape(policy)}/" : ''}$/,
|
|
39
49
|
proc do
|
|
40
|
-
FileUtils.mkdir_p "#{repository}/dist
|
|
41
|
-
FileUtils.cp_r("#{repository}/data_bags", "#{repository}/dist
|
|
50
|
+
FileUtils.mkdir_p "#{repository}/dist/#{env}/#{policy}"
|
|
51
|
+
FileUtils.cp_r("#{repository}/data_bags", "#{repository}/dist/#{env}/#{policy}/") if data_bags
|
|
42
52
|
[0, 'Chef export done', '']
|
|
43
53
|
end
|
|
44
54
|
]
|
|
@@ -96,6 +106,26 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
|
96
106
|
end
|
|
97
107
|
end
|
|
98
108
|
|
|
109
|
+
it 'packages the repository for a given node and service in local mode' do
|
|
110
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
|
111
|
+
with_packaging_mocked(repository, policy_file: 'policyfiles/test_policy.local.rb', env: 'local') do
|
|
112
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: true)
|
|
113
|
+
local_policy_file = "#{repository}/policyfiles/test_policy.local.lock.json"
|
|
114
|
+
expect(File.exist?(local_policy_file)).to eq true
|
|
115
|
+
expect(JSON.parse(File.read(local_policy_file))).to eq('run_list' => ['recipe[test_cookbook]'])
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'packages the repository without resolving dependencies when the lock file already exists' do
|
|
121
|
+
with_serverless_chef_platforms('1_node') do |platform, repository|
|
|
122
|
+
File.write("#{repository}/policyfiles/test_policy.lock.json", '{}')
|
|
123
|
+
with_packaging_mocked(repository, install: false) do
|
|
124
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: false)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
99
129
|
it 'does not package the repository twice for the same config' do
|
|
100
130
|
with_serverless_chef_platforms('1_node', as_git: true) do |platform, repository|
|
|
101
131
|
with_packaging_mocked(repository) do
|
|
@@ -208,6 +238,55 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
|
208
238
|
|
|
209
239
|
end
|
|
210
240
|
|
|
241
|
+
context 'with a platform having hpc_test cookbook' do
|
|
242
|
+
|
|
243
|
+
it 'packages the repository with before_run and after_run recipes wrapping the run list' do
|
|
244
|
+
with_serverless_chef_platforms('hpc_test') do |platform, repository|
|
|
245
|
+
with_packaging_mocked(repository, policy_file: 'policyfiles/test_policy.local.rb', env: 'local') do
|
|
246
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: true)
|
|
247
|
+
local_policy_file = "#{repository}/policyfiles/test_policy.local.lock.json"
|
|
248
|
+
expect(File.exist?(local_policy_file)).to eq true
|
|
249
|
+
expect(JSON.parse(File.read(local_policy_file))).to eq('run_list' => [
|
|
250
|
+
'hpc_test::before_run',
|
|
251
|
+
'recipe[test_cookbook]',
|
|
252
|
+
'hpc_test::after_run'
|
|
253
|
+
])
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it 'packages the repository with before_run only recipe' do
|
|
259
|
+
with_serverless_chef_platforms('hpc_test') do |platform, repository|
|
|
260
|
+
File.unlink "#{repository}/cookbooks/hpc_test/recipes/after_run.rb"
|
|
261
|
+
with_packaging_mocked(repository, policy_file: 'policyfiles/test_policy.local.rb', env: 'local') do
|
|
262
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: true)
|
|
263
|
+
local_policy_file = "#{repository}/policyfiles/test_policy.local.lock.json"
|
|
264
|
+
expect(File.exist?(local_policy_file)).to eq true
|
|
265
|
+
expect(JSON.parse(File.read(local_policy_file))).to eq('run_list' => [
|
|
266
|
+
'hpc_test::before_run',
|
|
267
|
+
'recipe[test_cookbook]'
|
|
268
|
+
])
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it 'packages the repository with after_run only recipe' do
|
|
274
|
+
with_serverless_chef_platforms('hpc_test') do |platform, repository|
|
|
275
|
+
File.unlink "#{repository}/cookbooks/hpc_test/recipes/before_run.rb"
|
|
276
|
+
with_packaging_mocked(repository, policy_file: 'policyfiles/test_policy.local.rb', env: 'local') do
|
|
277
|
+
platform.package(services: { 'node' => %w[test_policy] }, secrets: {}, local_environment: true)
|
|
278
|
+
local_policy_file = "#{repository}/policyfiles/test_policy.local.lock.json"
|
|
279
|
+
expect(File.exist?(local_policy_file)).to eq true
|
|
280
|
+
expect(JSON.parse(File.read(local_policy_file))).to eq('run_list' => [
|
|
281
|
+
'recipe[test_cookbook]',
|
|
282
|
+
'hpc_test::after_run'
|
|
283
|
+
])
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
end
|
|
289
|
+
|
|
211
290
|
end
|
|
212
291
|
|
|
213
292
|
end
|
|
@@ -37,7 +37,11 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
|
37
37
|
'set -o pipefail',
|
|
38
38
|
"if [ -n \"$(command -v apt)\" ]; then #{sudo}apt update && #{sudo}apt install -y curl build-essential ; else #{sudo}yum groupinstall 'Development Tools' && #{sudo}yum install -y curl ; fi",
|
|
39
39
|
'mkdir -p ./hpc_deploy',
|
|
40
|
-
|
|
40
|
+
'rm -rf ./hpc_deploy/tmp',
|
|
41
|
+
'mkdir -p ./hpc_deploy/tmp',
|
|
42
|
+
'curl --location https://omnitruck.chef.io/install.sh --output ./hpc_deploy/install.sh',
|
|
43
|
+
'chmod a+x ./hpc_deploy/install.sh',
|
|
44
|
+
"#{sudo}TMPDIR=./hpc_deploy/tmp ./hpc_deploy/install.sh -d /opt/artefacts -v 17.0 -s once"
|
|
41
45
|
]
|
|
42
46
|
},
|
|
43
47
|
{
|
|
@@ -45,9 +49,9 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
|
45
49
|
remote_bash: [
|
|
46
50
|
'set -e',
|
|
47
51
|
"cd ./hpc_deploy/#{policy}",
|
|
48
|
-
"#{sudo}SSL_CERT_DIR=/etc/ssl/certs /opt/chef/bin/chef-client --local-mode --chef-license
|
|
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' : ''}",
|
|
49
53
|
'cd ..',
|
|
50
|
-
"#{sudo}rm -rf
|
|
54
|
+
"#{sudo}rm -rf ./hpc_deploy/#{policy}"
|
|
51
55
|
]
|
|
52
56
|
}
|
|
53
57
|
]
|
|
@@ -237,7 +241,7 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
|
237
241
|
)
|
|
238
242
|
expect(platform.actions_to_deploy_on('local', 'test_policy_1', use_why_run: false)).to eq [
|
|
239
243
|
{
|
|
240
|
-
bash: "cd #{repository}/dist/prod/test_policy_1 && sudo SSL_CERT_DIR=/etc/ssl/certs /opt/chef-workstation/bin/chef-client --local-mode --json-attributes nodes/local.json"
|
|
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"
|
|
241
245
|
}
|
|
242
246
|
]
|
|
243
247
|
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Recipe
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Recipe
|
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: 32.
|
|
4
|
+
version: 32.15.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Muriel Salvan
|
|
@@ -873,6 +873,11 @@ files:
|
|
|
873
873
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/data_bags/my_bag/my_item.json
|
|
874
874
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/nodes/node.json
|
|
875
875
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/data_bags/policyfiles/test_policy.rb
|
|
876
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/chef_versions.yml
|
|
877
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/cookbooks/hpc_test/recipes/after_run.rb
|
|
878
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/cookbooks/hpc_test/recipes/before_run.rb
|
|
879
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/nodes/node.json
|
|
880
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/hpc_test/policyfiles/test_policy.rb
|
|
876
881
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_1/recipes/default.rb
|
|
877
882
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/libraries/default.rb
|
|
878
883
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/default.rb
|