hybrid_platforms_conductor 33.8.3 → 33.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +48 -0
- data/bin/nodes_to_deploy +19 -9
- data/docs/config_dsl.md +10 -4
- data/lib/hybrid_platforms_conductor/deployer.rb +7 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/dsl_parser.rb +1 -1
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef/recipes_tree_builder.rb +94 -2
- data/lib/hybrid_platforms_conductor/hpc_plugins/platform_handler/serverless_chef.rb +4 -18
- data/lib/hybrid_platforms_conductor/platform_handler.rb +17 -7
- data/lib/hybrid_platforms_conductor/platforms_handler.rb +9 -7
- data/lib/hybrid_platforms_conductor/version.rb +1 -1
- data/spec/hybrid_platforms_conductor_test/api/deployer/deploy_spec.rb +44 -0
- data/spec/hybrid_platforms_conductor_test/api/nodes_handler/nodes_selectors_spec.rb +9 -4
- data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb +53 -0
- data/spec/hybrid_platforms_conductor_test/api/platforms_handler_spec.rb +43 -13
- data/spec/hybrid_platforms_conductor_test/executables/nodes_to_deploy_spec.rb +75 -0
- data/spec/hybrid_platforms_conductor_test/helpers/platforms_handler_helpers.rb +4 -2
- data/spec/hybrid_platforms_conductor_test/platform_handler_plugins/test.rb +2 -1
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/metadata.rb +13 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/31_unknown_recipe_include.rb +2 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/32_unknown_cookbook_include.rb +2 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/33_unknown_include.rb +3 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/34_known_include.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/35_unparsable_include.rb +7 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_1.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_2.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_3.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_4.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_5/recipes/recipe_1.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_5/recipes/recipe_2.rb +1 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node31.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node32.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node33.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node34.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node35.json +10 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_31.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_32.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_33.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_34.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_35.rb +4 -0
- data/spec/hybrid_platforms_conductor_test/test_log_plugin.rb +2 -2
- data/spec/hybrid_platforms_conductor_test.rb +1 -0
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2a6b91bf179fa45f605d1b08d8c21cced9547c0588139b1998fca01a19f75abe
|
4
|
+
data.tar.gz: 5372e49247ba48adf64eed5a9fe3cc5aff5b2e82be8bc834a2283f815cc4c928
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1d886444be942a74153cb834e450b8062356959aaca508e10186bcb444f63295f8fc198b3e49f94babbbb7b6315bed146c1a29c21ab23d9112de94971e18d11
|
7
|
+
data.tar.gz: 31640de82a155dc42128926683fe7ded34039bad1cb639ff6bb8d4571f7f01a191f2103ea6a01c3de60322dc67015e92c833a0e8597b10bb3d6030e10199a864
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,51 @@
|
|
1
|
+
# [v33.9.2](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.9.1...v33.9.2) (2021-09-01 17:46:34)
|
2
|
+
|
3
|
+
## Global changes
|
4
|
+
### Patches
|
5
|
+
|
6
|
+
* [[Fix(nodes_to_deploy)] [#112] Support UTF-8 encoding from log files](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/26a7bd2fd53d387bd972b5e1b60cac9be6541ce5)
|
7
|
+
|
8
|
+
## Changes for nodes_to_deploy
|
9
|
+
### Patches
|
10
|
+
|
11
|
+
* [[Fix(nodes_to_deploy)] [#112] Support UTF-8 encoding from log files](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/26a7bd2fd53d387bd972b5e1b60cac9be6541ce5)
|
12
|
+
|
13
|
+
# [v33.9.1](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.9.0...v33.9.1) (2021-09-01 16:59:59)
|
14
|
+
|
15
|
+
## Global changes
|
16
|
+
### Patches
|
17
|
+
|
18
|
+
* [[Fix(nodes_to_deploy)] [#110] Make sure unknown platforms are taken into account when detecting nodes to be deployed](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/c1b8312c5d473a1c5d044f6cda3ad9bed2b3ca61)
|
19
|
+
|
20
|
+
## Changes for nodes_to_deploy
|
21
|
+
### Patches
|
22
|
+
|
23
|
+
* [[Fix(nodes_to_deploy)] [#110] Make sure unknown platforms are taken into account when detecting nodes to be deployed](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/c1b8312c5d473a1c5d044f6cda3ad9bed2b3ca61)
|
24
|
+
|
25
|
+
# [v33.9.0](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.8.4...v33.9.0) (2021-08-24 13:15:44)
|
26
|
+
|
27
|
+
## Global changes
|
28
|
+
### Patches
|
29
|
+
|
30
|
+
* [[Feature(platform_handler)] [#102] Add the name option when declaring platforms to set the platform name](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/13ada7687f08b3f970521320e2b26ea42d9a6d7f)
|
31
|
+
|
32
|
+
## Changes for platform_handler
|
33
|
+
### Features
|
34
|
+
|
35
|
+
* [[Feature(platform_handler)] [#102] Add the name option when declaring platforms to set the platform name](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/13ada7687f08b3f970521320e2b26ea42d9a6d7f)
|
36
|
+
|
37
|
+
# [v33.8.4](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.8.3...v33.8.4) (2021-08-20 15:45:41)
|
38
|
+
|
39
|
+
## Global changes
|
40
|
+
### Patches
|
41
|
+
|
42
|
+
* [[Fix(platform_handler_serverless_chef)] [#99] Make sure dynamic or unparsable cookbook/recipe names are considered using metadata for recipes dependencies](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/1d7feb24881f04cd3f31bc1e41712dfc4cfe715f)
|
43
|
+
|
44
|
+
## Changes for platform_handler_serverless_chef
|
45
|
+
### Patches
|
46
|
+
|
47
|
+
* [[Fix(platform_handler_serverless_chef)] [#99] Make sure dynamic or unparsable cookbook/recipe names are considered using metadata for recipes dependencies](https://github.com/sweet-delights/hybrid-platforms-conductor/commit/1d7feb24881f04cd3f31bc1e41712dfc4cfe715f)
|
48
|
+
|
1
49
|
# [v33.8.3](https://github.com/sweet-delights/hybrid-platforms-conductor/compare/v33.8.2...v33.8.3) (2021-08-16 14:18:52)
|
2
50
|
|
3
51
|
## Global changes
|
data/bin/nodes_to_deploy
CHANGED
@@ -17,6 +17,7 @@ executable = HybridPlatformsConductor::Executable.new(deploy_options: false) do
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
nodes_handler = executable.nodes_handler
|
20
|
+
platforms_handler = executable.platforms_handler
|
20
21
|
deployer = executable.deployer
|
21
22
|
|
22
23
|
executable.parse_options!
|
@@ -72,20 +73,29 @@ unless ignore_deploy_info
|
|
72
73
|
commit_id = node_deploy_info[:deployment_info]["commit_id_#{repo_idx}".to_sym]
|
73
74
|
impacted_nodes = cache_impacted_nodes.dig(repo_name, commit_id)
|
74
75
|
if impacted_nodes.nil?
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
76
|
+
if platforms_handler.platform(repo_name)
|
77
|
+
begin
|
78
|
+
impacted_nodes, _single_impacted_nodes, _impacted_services, _impact_global = nodes_handler.impacted_nodes_from_git_diff(
|
79
|
+
repo_name,
|
80
|
+
from_commit: commit_id,
|
81
|
+
to_commit: 'master'
|
82
|
+
)
|
83
|
+
rescue HybridPlatformsConductor::NodesHandler::GitError
|
84
|
+
# Consider the node was deployed with a non-release branch commit (as it is missing)
|
85
|
+
# So we have to make sure we deploy it again
|
86
|
+
executable.log_warn "[ #{node} ] - Unknown commit ID from deployment logs: #{repo_name} / #{commit_id}."
|
87
|
+
impacted_nodes = :unknown
|
88
|
+
end
|
89
|
+
else
|
90
|
+
# Consider the node was deployed with an obdsolete platform (as it is unknown)
|
83
91
|
# So we have to make sure we deploy it again
|
84
|
-
|
92
|
+
executable.log_warn "[ #{node} ] - Unknown platform from deployment logs: #{repo_name}."
|
93
|
+
impacted_nodes = :unknown
|
85
94
|
end
|
86
95
|
cache_impacted_nodes[repo_name] = {} unless cache_impacted_nodes.key?(repo_name)
|
87
96
|
cache_impacted_nodes[repo_name][commit_id] = impacted_nodes
|
88
97
|
end
|
98
|
+
impacted_nodes = [node] if impacted_nodes == :unknown
|
89
99
|
if impacted_nodes.include?(node)
|
90
100
|
executable.log_debug "[ #{node} ] - Diffs on #{repo_name} between #{commit_id} and master are impacting this node."
|
91
101
|
node_impacted = true
|
data/docs/config_dsl.md
CHANGED
@@ -28,19 +28,25 @@ This DSL can also be completed by plugins. Check [the plugins documentations](pl
|
|
28
28
|
Declare a new platform of type `<platform_type>`, providing either a local path to it (using `path: '/path/to/files'`) or a git repository to it (using `git: 'git_url'`). The possible platform types are the names of the [`platform_handler` plugins](plugins.md#platform_handler).
|
29
29
|
|
30
30
|
Git branches can also be specified using `branch: 'branch_name'`.
|
31
|
+
|
32
|
+
The name of the platform (as used for example by the [`for_nodes`](#for_nodes) DSL) defaults to the base name of the directory in case of a local path, or the base name of the first remote in case of a git repository. It can be enforced to a given name using `name: 'platform_name'` (useful to avoid name conflicts and keep consistency with the rest of your configuration among the team).
|
33
|
+
|
31
34
|
An optional code block taking the local repository path as parameter can also be specified to add configuration that is specific to this platform.
|
32
35
|
|
33
36
|
Examples:
|
34
37
|
```ruby
|
35
|
-
# Declare a platform of type Chef, located in a distant git repository
|
38
|
+
# Declare a platform of type Chef, located in a distant git repository (its name will be my-chef-repo)
|
36
39
|
chef_platform git: 'https://my-git.domain.com/project/my-chef-repo.git'
|
37
40
|
|
38
|
-
# Declare a platform located in a local path
|
39
|
-
chef_platform path: '/path/to/my-chef-repo'
|
41
|
+
# Declare a platform located in a local path (its name will be my-other-chef-repo)
|
42
|
+
chef_platform path: '/path/to/my-other-chef-repo'
|
43
|
+
|
44
|
+
# Declare a platform located in a local path and forces its name (its name will be my-platform)
|
45
|
+
chef_platform path: '/path/to/my-repo', name: 'my-platform'
|
40
46
|
|
41
47
|
# Declare a platform from a git branch, and apply some configuration to it
|
42
48
|
chef_platform(
|
43
|
-
git: 'https://my-git.domain.com/project/
|
49
|
+
git: 'https://my-git.domain.com/project/devops-chef-repo.git',
|
44
50
|
branch: 'my-branch'
|
45
51
|
) do |path|
|
46
52
|
# Here path will be a local path containing a checkout of the branch my-branch of the git repo.
|
@@ -475,9 +475,15 @@ module HybridPlatformsConductor
|
|
475
475
|
progress_name: 'Read deployment logs'
|
476
476
|
)
|
477
477
|
nodes.map do |node|
|
478
|
+
exit_code, stdout, stderr = read_actions_results[node] || [nil, nil, nil]
|
478
479
|
[
|
479
480
|
node,
|
480
|
-
@log_plugins[log_plugins_for(node).first].logs_for(
|
481
|
+
@log_plugins[log_plugins_for(node).first].logs_for(
|
482
|
+
node,
|
483
|
+
exit_code,
|
484
|
+
stdout&.force_encoding(Encoding::UTF_8),
|
485
|
+
stderr&.force_encoding(Encoding::UTF_8)
|
486
|
+
)
|
481
487
|
]
|
482
488
|
end.to_h
|
483
489
|
end
|
@@ -105,8 +105,59 @@ module HybridPlatformsConductor
|
|
105
105
|
recipe_content = File.read("#{@platform.repository_path}/#{cookbook_dir}/#{cookbook}/recipes/#{recipe}.rb")
|
106
106
|
# Check for include_recipe
|
107
107
|
used_recipes = recipe_content.
|
108
|
-
scan(/include_recipe\
|
109
|
-
map
|
108
|
+
scan(/include_recipe(\((.+)\)|\s+(.+)|\((.*))$/).
|
109
|
+
map do |(_match, match_1, match_2, match_3)|
|
110
|
+
case match_1 || match_2 || match_3
|
111
|
+
when /^["']([^:'"]+(::[^'"]+)?)["']$/
|
112
|
+
# The recipe definition is given in a String
|
113
|
+
used_cookbook, used_recipe = Regexp.last_match(1).split('::')
|
114
|
+
used_recipe = 'default' if used_recipe.nil?
|
115
|
+
if used_cookbook =~ /^\w+$/
|
116
|
+
# Find the cookbook it belongs to
|
117
|
+
used_cookbook_dir = @platform.known_cookbook_paths.find { |cookbook_path| File.exist?("#{@platform.repository_path}/#{cookbook_path}/#{used_cookbook}") }
|
118
|
+
if used_recipe =~ /^\w+$/
|
119
|
+
# Check that the recipe exists if we know the cookbook dir
|
120
|
+
raise "Unknown recipe #{used_cookbook}::#{used_recipe} from cookbook #{@platform.repository_path}/#{used_cookbook_dir}/#{used_cookbook}." if !used_cookbook_dir.nil? && !File.exist?("#{@platform.repository_path}/#{used_cookbook_dir}/#{used_cookbook}/recipes/#{used_recipe}.rb")
|
121
|
+
|
122
|
+
[
|
123
|
+
[used_cookbook_dir, used_cookbook.to_sym, used_recipe.to_sym]
|
124
|
+
]
|
125
|
+
elsif used_cookbook_dir
|
126
|
+
# We are dealing with a dynamically named recipe.
|
127
|
+
# Return all recipes of the cookbook if we know the cookbook dir
|
128
|
+
Dir.glob("#{@platform.repository_path}/#{used_cookbook_dir}/#{used_cookbook}/recipes/*.rb").map do |used_recipe_file_path|
|
129
|
+
[
|
130
|
+
used_cookbook_dir,
|
131
|
+
used_cookbook.to_sym,
|
132
|
+
File.basename(used_recipe_file_path, '.rb').to_sym
|
133
|
+
]
|
134
|
+
end
|
135
|
+
else
|
136
|
+
# We are dealing with a dynamically named recipe.
|
137
|
+
# We have no cookbook dir - certainly comes from the supermarket.
|
138
|
+
[]
|
139
|
+
end
|
140
|
+
elsif used_recipe =~ /^\w+$/
|
141
|
+
# We are dealing with a dynamically named cookbook, but the recipe name is known.
|
142
|
+
# Look for this recipe in all cookbooks that are part of the metadata.
|
143
|
+
dependent_cookbooks(cookbook_dir, cookbook).map do |dependent_cookbook|
|
144
|
+
dependent_cookbook_dir = @platform.known_cookbook_paths.find { |cookbook_path| File.exist?("#{@platform.repository_path}/#{cookbook_path}/#{dependent_cookbook}") }
|
145
|
+
if !dependent_cookbook_dir.nil? && File.exist?("#{@platform.repository_path}/#{dependent_cookbook_dir}/#{dependent_cookbook}/recipes/#{used_recipe}.rb")
|
146
|
+
# Found a matching recipe name
|
147
|
+
[dependent_cookbook_dir, dependent_cookbook, used_recipe.to_sym]
|
148
|
+
end
|
149
|
+
end.compact
|
150
|
+
else
|
151
|
+
# We are dealing with cynamically named cookbooks and recipes.
|
152
|
+
# Consider we depend on all recipes of our dependent cookbooks.
|
153
|
+
all_dependent_recipes(cookbook_dir, cookbook)
|
154
|
+
end
|
155
|
+
else
|
156
|
+
# The recipe definition is much more complex, so treat it as unparsable and consider we depnd on all recipes of our dependent cookbooks from metadata.
|
157
|
+
all_dependent_recipes(cookbook_dir, cookbook)
|
158
|
+
end
|
159
|
+
end.
|
160
|
+
flatten(1)
|
110
161
|
# Check for some helpers we know include some recipes
|
111
162
|
@config.known_helpers_including_recipes.each do |helper_name, used_recipes_by_helper|
|
112
163
|
if recipe_content =~ Regexp.new(/(\W|^)#{Regexp.escape(helper_name)}(\W|$)/)
|
@@ -222,6 +273,47 @@ module HybridPlatformsConductor
|
|
222
273
|
end
|
223
274
|
end
|
224
275
|
|
276
|
+
# Get the list of dependent cookbooks from a cookbook's metadata
|
277
|
+
#
|
278
|
+
# Parameters::
|
279
|
+
# * *cookbook_dir* (String): The cookbook directory
|
280
|
+
# * *cookbook* (Symbol): The cookbook name
|
281
|
+
# Result::
|
282
|
+
# * Array<Symbol>: List of dependent cookbooks
|
283
|
+
def dependent_cookbooks(cookbook_dir, cookbook)
|
284
|
+
# Read the metadata file
|
285
|
+
dsl_parser = DslParser.new
|
286
|
+
dsl_parser.parse("#{@platform.repository_path}/#{cookbook_dir}/#{cookbook}/metadata.rb")
|
287
|
+
dsl_parser.
|
288
|
+
calls.
|
289
|
+
map { |call_info| call_info[:method] == :depends ? call_info[:args].first.to_sym : nil }.
|
290
|
+
compact
|
291
|
+
end
|
292
|
+
|
293
|
+
# Get all recipes from all cookbooks that are a metadata dependency from a given cookbook.
|
294
|
+
#
|
295
|
+
# Parameters::
|
296
|
+
# * *cookbook_dir* (String): The cookbook directory
|
297
|
+
# * *cookbook* (Symbol): The cookbook name
|
298
|
+
# Result::
|
299
|
+
# * Array< [String, Symbol, Symbol] >: List of tuples [cookbook_dir, cookbook, recipe] used by this recipe
|
300
|
+
def all_dependent_recipes(cookbook_dir, cookbook)
|
301
|
+
dependent_cookbooks(cookbook_dir, cookbook).map do |dependent_cookbook|
|
302
|
+
dependent_cookbook_dir = @platform.known_cookbook_paths.find { |cookbook_path| File.exist?("#{@platform.repository_path}/#{cookbook_path}/#{dependent_cookbook}") }
|
303
|
+
if dependent_cookbook_dir.nil?
|
304
|
+
nil
|
305
|
+
else
|
306
|
+
Dir.glob("#{@platform.repository_path}/#{dependent_cookbook_dir}/#{dependent_cookbook}/recipes/*.rb").map do |used_recipe_file_path|
|
307
|
+
[
|
308
|
+
dependent_cookbook_dir,
|
309
|
+
dependent_cookbook,
|
310
|
+
File.basename(used_recipe_file_path, '.rb').to_sym
|
311
|
+
]
|
312
|
+
end
|
313
|
+
end
|
314
|
+
end.compact.flatten(1)
|
315
|
+
end
|
316
|
+
|
225
317
|
end
|
226
318
|
|
227
319
|
end
|
@@ -47,24 +47,10 @@ module HybridPlatformsConductor
|
|
47
47
|
end
|
48
48
|
extend_config_dsl_with MyDSLExtension, :init_serverless_chef
|
49
49
|
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
|
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
|
50
|
+
# Initialize a new instance of this platform handler.
|
51
|
+
# [API] - This method is optional.
|
52
|
+
# [API] - @cmd_runner is accessible.
|
53
|
+
def init
|
68
54
|
# Mutex for getting the full recipes tree
|
69
55
|
@recipes_tree_mutex = Mutex.new
|
70
56
|
end
|
@@ -17,13 +17,13 @@ module HybridPlatformsConductor
|
|
17
17
|
# Make sure we define automatically a helper for such a platform
|
18
18
|
mixin = Module.new
|
19
19
|
platform_type = subclass.name.split('::').last.gsub(/([a-z\d])([A-Z\d])/, '\1_\2').downcase.to_sym
|
20
|
-
mixin.define_method("#{platform_type}_platform".to_sym) do |path: nil, git: nil, branch: 'master', &platform_config_code|
|
20
|
+
mixin.define_method("#{platform_type}_platform".to_sym) do |path: nil, git: nil, branch: 'master', name: nil, &platform_config_code|
|
21
21
|
repository_path =
|
22
22
|
if !path.nil?
|
23
23
|
path
|
24
24
|
elsif !git.nil?
|
25
25
|
# Clone in a local repository
|
26
|
-
local_repository_path = "#{@git_platforms_dir}/#{File.basename(git)[0..-File.extname(git).size - 1]}"
|
26
|
+
local_repository_path = "#{@git_platforms_dir}/#{name.nil? ? File.basename(git)[0..-File.extname(git).size - 1] : name}"
|
27
27
|
unless File.exist?(local_repository_path)
|
28
28
|
branch = "refs/heads/#{branch}" unless branch.include?('/')
|
29
29
|
local_ref = "refs/remotes/origin/#{branch.split('/').last}"
|
@@ -37,8 +37,10 @@ module HybridPlatformsConductor
|
|
37
37
|
else
|
38
38
|
raise 'The platform has to be defined with either a path or a git URL'
|
39
39
|
end
|
40
|
-
@
|
41
|
-
@
|
40
|
+
@platforms_info[platform_type] = {} unless @platforms_info.key?(platform_type)
|
41
|
+
raise "Platform repository path #{repository_path} is declared several times." if @platforms_info.values.any? { |known_platforms_info| known_platforms_info.key?(repository_path) }
|
42
|
+
|
43
|
+
@platforms_info[platform_type][repository_path] = name.nil? ? {} : { name: name }
|
42
44
|
platform_config_code&.call(repository_path)
|
43
45
|
end
|
44
46
|
# Register this new mixin in the Config DSL
|
@@ -66,18 +68,21 @@ module HybridPlatformsConductor
|
|
66
68
|
# * *logger_stderr* (Logger): Logger to be used for stderr [default: Logger.new(STDERR)]
|
67
69
|
# * *config* (Config): Config to be used. [default: Config.new]
|
68
70
|
# * *cmd_runner* (CmdRunner): Command executor to be used. [default: CmdRunner.new]
|
71
|
+
# * *name* (String or nil): Platform name, or nil for defaults (based on path or git remote) [default: nil]
|
69
72
|
def initialize(
|
70
73
|
platform_type,
|
71
74
|
repository_path,
|
72
75
|
logger: Logger.new($stdout),
|
73
76
|
logger_stderr: Logger.new($stderr),
|
74
77
|
config: Config.new,
|
75
|
-
cmd_runner: CmdRunner.new
|
78
|
+
cmd_runner: CmdRunner.new,
|
79
|
+
name: nil
|
76
80
|
)
|
77
81
|
super(logger: logger, logger_stderr: logger_stderr, config: config)
|
78
82
|
@platform_type = platform_type
|
79
83
|
@repository_path = repository_path
|
80
84
|
@cmd_runner = cmd_runner
|
85
|
+
@name = name
|
81
86
|
init if respond_to?(:init)
|
82
87
|
end
|
83
88
|
|
@@ -142,7 +147,12 @@ module HybridPlatformsConductor
|
|
142
147
|
git_status = git.status
|
143
148
|
git_commit = git.log.first
|
144
149
|
{
|
145
|
-
repo_name:
|
150
|
+
repo_name:
|
151
|
+
if @name.nil?
|
152
|
+
git.remotes.empty? ? File.basename(@repository_path) : File.basename(git.remotes.first.url).gsub(/\.git$/, '')
|
153
|
+
else
|
154
|
+
@name
|
155
|
+
end,
|
146
156
|
commit: {
|
147
157
|
id: git_commit.sha,
|
148
158
|
ref: git_commit.name,
|
@@ -162,7 +172,7 @@ module HybridPlatformsConductor
|
|
162
172
|
}
|
163
173
|
else
|
164
174
|
{
|
165
|
-
repo_name: File.basename(@repository_path)
|
175
|
+
repo_name: @name.nil? ? File.basename(@repository_path) : @name
|
166
176
|
}
|
167
177
|
end
|
168
178
|
end
|
@@ -9,13 +9,14 @@ module HybridPlatformsConductor
|
|
9
9
|
# Add some config DSL
|
10
10
|
module ConfigDSLExtension
|
11
11
|
|
12
|
-
# List of platforms repository directories, per platform type
|
13
|
-
# Hash<Symbol,
|
14
|
-
|
12
|
+
# List of platforms repository directories and their associated info, per platform type
|
13
|
+
# Hash<Symbol, Hash<String, Hash<Symbol,Object> > >
|
14
|
+
# Hash<platform_type, Hash<repository_path, Hash<Symbol,Object> > >
|
15
|
+
attr_reader :platforms_info
|
15
16
|
|
16
17
|
# Mixin initializer
|
17
18
|
def init_platforms_handler
|
18
|
-
@
|
19
|
+
@platforms_info = {}
|
19
20
|
# Directory in which platforms are cloned
|
20
21
|
@git_platforms_dir = "#{@hybrid_platforms_dir}/cloned_platforms"
|
21
22
|
end
|
@@ -46,15 +47,16 @@ module HybridPlatformsConductor
|
|
46
47
|
# Hash<Symbol, Array<PlatformHandler> >
|
47
48
|
@platform_handlers = {}
|
48
49
|
# Read all platforms from the config
|
49
|
-
@config.
|
50
|
-
|
50
|
+
@config.platforms_info.each do |platform_type, repositories_info|
|
51
|
+
repositories_info.each do |repository_path, repository_info|
|
51
52
|
platform_handler = @platform_types[platform_type].new(
|
52
53
|
platform_type,
|
53
54
|
repository_path,
|
54
55
|
logger: @logger,
|
55
56
|
logger_stderr: @logger_stderr,
|
56
57
|
config: @config,
|
57
|
-
cmd_runner: @cmd_runner
|
58
|
+
cmd_runner: @cmd_runner,
|
59
|
+
name: repository_info[:name]
|
58
60
|
)
|
59
61
|
# Check that this platform has unique name
|
60
62
|
raise "Platform name #{platform_handler.name} is declared several times." if @platform_handlers.values.flatten.any? { |known_platform| known_platform.name == platform_handler.name }
|
@@ -196,6 +196,50 @@ describe HybridPlatformsConductor::Deployer do
|
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
199
|
+
it 'gets deployment info from log plugins returning UTF-8 characters' do
|
200
|
+
with_test_platform_for_deploy_tests({ nodes: { 'node' => {} } }) do
|
201
|
+
HybridPlatformsConductorTest::TestLogPlugin.mocked_logs = {
|
202
|
+
'node' => {
|
203
|
+
deployment_info: { user: 'test_user' },
|
204
|
+
exit_status: 666,
|
205
|
+
services: %w[unknown],
|
206
|
+
stderr: 'stderrの展開テストログ',
|
207
|
+
stdout: 'stdoutの展開テストログ'
|
208
|
+
}
|
209
|
+
}
|
210
|
+
expect_actions_executor_runs [
|
211
|
+
# Expect the actions to get log files
|
212
|
+
proc do |actions_per_nodes|
|
213
|
+
expect(actions_per_nodes).to eq('node' => [{ bash: 'echo Read logs for node' }])
|
214
|
+
# Simulate the fact that data returned by the ssh system calls can contain UTF-8 chars, but is perceived as binary
|
215
|
+
{ 'node' => [42, 'ログファイルはstdoutを読み取ります'.force_encoding('BINARY'), 'ログファイルはstderrを読み取ります'.force_encoding('BINARY')] }
|
216
|
+
end
|
217
|
+
]
|
218
|
+
expect(test_deployer.deployment_info_from('node')).to eq(
|
219
|
+
'node' => {
|
220
|
+
deployment_info: { user: 'test_user' },
|
221
|
+
exit_status: 666,
|
222
|
+
services: %w[unknown],
|
223
|
+
stderr: 'stderrの展開テストログ',
|
224
|
+
stdout: 'stdoutの展開テストログ'
|
225
|
+
}
|
226
|
+
)
|
227
|
+
expect(HybridPlatformsConductorTest::TestLogPlugin.calls).to eq [
|
228
|
+
{
|
229
|
+
method: :actions_to_read_logs,
|
230
|
+
node: 'node'
|
231
|
+
},
|
232
|
+
{
|
233
|
+
method: :logs_for,
|
234
|
+
node: 'node',
|
235
|
+
exit_status: 42,
|
236
|
+
stdout: 'ログファイルはstdoutを読み取ります',
|
237
|
+
stderr: 'ログファイルはstderrを読み取ります'
|
238
|
+
}
|
239
|
+
]
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
199
243
|
it 'gets deployment info from log plugins not having actions_to_read_logs' do
|
200
244
|
with_test_platform_for_deploy_tests({ nodes: { 'node' => {} } }, additional_config: 'send_logs_to :test_log_no_read') do
|
201
245
|
expect(test_deployer.deployment_info_from('node')).to eq(
|
@@ -15,6 +15,10 @@ describe HybridPlatformsConductor::NodesHandler do
|
|
15
15
|
},
|
16
16
|
'platform2' => {
|
17
17
|
nodes: { 'node4' => {}, 'node5' => { services: %w[service3 service1] }, 'node6' => {} }
|
18
|
+
},
|
19
|
+
'platform3' => {
|
20
|
+
nodes: { 'node7' => {} },
|
21
|
+
name: 'other_platform'
|
18
22
|
}
|
19
23
|
},
|
20
24
|
&block
|
@@ -24,12 +28,13 @@ describe HybridPlatformsConductor::NodesHandler do
|
|
24
28
|
# List all tests of nodes selectors, and the corresponding nodes list they should be resolved into
|
25
29
|
{
|
26
30
|
[] => [],
|
27
|
-
[{ all: true }] => %w[node1 node2 node3 node4 node5 node6],
|
31
|
+
[{ all: true }] => %w[node1 node2 node3 node4 node5 node6 node7],
|
28
32
|
'node1' => %w[node1],
|
29
33
|
'/node[12]/' => %w[node1 node2],
|
30
34
|
[{ list: 'nodeslist1' }] => %w[node1 node3],
|
31
35
|
[{ list: 'nodeslist2' }] => %w[node1 node2],
|
32
36
|
[{ platform: 'platform2' }] => %w[node4 node5 node6],
|
37
|
+
[{ platform: 'other_platform' }] => %w[node7],
|
33
38
|
[{ service: 'service1' }] => %w[node2 node5],
|
34
39
|
['/node[12]/', { service: 'service1' }] => %w[node1 node2 node5],
|
35
40
|
[{ git_diff: { platform: 'platform2' } }] => %w[node4 node5 node6]
|
@@ -45,13 +50,13 @@ describe HybridPlatformsConductor::NodesHandler do
|
|
45
50
|
|
46
51
|
it 'fails when selecting unknown nodes' do
|
47
52
|
with_test_platform_for_nodes do
|
48
|
-
expect { test_nodes_handler.select_nodes('node1', '
|
53
|
+
expect { test_nodes_handler.select_nodes('node1', 'unknown_node') }.to raise_error(RuntimeError, 'Unknown nodes: unknown_node')
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
52
57
|
it 'ignore unknown nodes when asked' do
|
53
58
|
with_test_platform_for_nodes do
|
54
|
-
expect(test_nodes_handler.select_nodes(%w[node1
|
59
|
+
expect(test_nodes_handler.select_nodes(%w[node1 unknown_node], ignore_unknowns: true).sort).to eq %w[node1 unknown_node].sort
|
55
60
|
end
|
56
61
|
end
|
57
62
|
|
@@ -105,7 +110,7 @@ describe HybridPlatformsConductor::NodesHandler do
|
|
105
110
|
|
106
111
|
it 'considers all nodes for en empty nodes selector stack' do
|
107
112
|
with_test_platform_for_nodes do
|
108
|
-
expect(test_nodes_handler.select_from_nodes_selector_stack([]).sort).to eq %w[node1 node2 node3 node4 node5 node6].sort
|
113
|
+
expect(test_nodes_handler.select_from_nodes_selector_stack([]).sort).to eq %w[node1 node2 node3 node4 node5 node6 node7].sort
|
109
114
|
end
|
110
115
|
end
|
111
116
|
|
data/spec/hybrid_platforms_conductor_test/api/platform_handlers/serverless_chef/diff_impacts_spec.rb
CHANGED
@@ -235,6 +235,59 @@ describe HybridPlatformsConductor::HpcPlugins::PlatformHandler::ServerlessChef d
|
|
235
235
|
end
|
236
236
|
end
|
237
237
|
|
238
|
+
it 'returns impacted service due to a usage of another cookbook\'s recipe using parenthesis' do
|
239
|
+
with_serverless_chef_platforms('recipes') do |platform, repository|
|
240
|
+
File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EO_RECIPE)
|
241
|
+
include_recipe('test_cookbook_2::other_recipe')
|
242
|
+
EO_RECIPE
|
243
|
+
expect(platform.impacts_from('cookbooks/test_cookbook_2/recipes/other_recipe.rb' => {})).to eq [
|
244
|
+
[],
|
245
|
+
%w[test_policy_1],
|
246
|
+
false
|
247
|
+
]
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'returns impacted service due to a usage of another cookbook\'s recipe using dynamic recipe name' do
|
252
|
+
with_serverless_chef_platforms('recipes') do |platform|
|
253
|
+
expect(platform.impacts_from('cookbooks/test_cookbook_4/recipes/recipe_1.rb' => {})).to eq [
|
254
|
+
[],
|
255
|
+
%w[test_policy_31 test_policy_33 test_policy_35],
|
256
|
+
false
|
257
|
+
]
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
it 'returns impacted service due to a usage of another cookbook\'s recipe using dynamic cookbook name' do
|
262
|
+
with_serverless_chef_platforms('recipes') do |platform|
|
263
|
+
expect(platform.impacts_from('cookbooks/test_cookbook_4/recipes/recipe_2.rb' => {})).to eq [
|
264
|
+
[],
|
265
|
+
%w[test_policy_31 test_policy_32 test_policy_33 test_policy_35],
|
266
|
+
false
|
267
|
+
]
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'returns impacted service due to a usage of another cookbook\'s recipe using dynamic cookbook and recipe names' do
|
272
|
+
with_serverless_chef_platforms('recipes') do |platform|
|
273
|
+
expect(platform.impacts_from('cookbooks/test_cookbook_4/recipes/recipe_3.rb' => {})).to eq [
|
274
|
+
[],
|
275
|
+
%w[test_policy_31 test_policy_33 test_policy_35],
|
276
|
+
false
|
277
|
+
]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
it 'returns impacted service due to a usage of another cookbook\'s recipe using dynamic or unparsable cookbook and recipe names, using metadata' do
|
282
|
+
with_serverless_chef_platforms('recipes') do |platform|
|
283
|
+
expect(platform.impacts_from('cookbooks/test_cookbook_5/recipes/recipe_1.rb' => {})).to eq [
|
284
|
+
[],
|
285
|
+
%w[test_policy_33 test_policy_35],
|
286
|
+
false
|
287
|
+
]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
238
291
|
it 'ignores cookbooks from cookbook paths that are not configured' do
|
239
292
|
with_serverless_chef_platforms('several_cookbooks') do |platform, repository|
|
240
293
|
File.write("#{repository}/cookbooks/test_cookbook_1/recipes/default.rb", <<~EO_RECIPE)
|
@@ -2,22 +2,22 @@ describe HybridPlatformsConductor::PlatformsHandler do
|
|
2
2
|
|
3
3
|
context 'when checking config specific DSL' do
|
4
4
|
|
5
|
-
it 'returns
|
5
|
+
it 'returns platforms info' do
|
6
6
|
with_test_platforms(
|
7
7
|
{
|
8
8
|
'platform1' => { platform_type: :test },
|
9
9
|
'platform2' => { platform_type: :test_2 },
|
10
|
-
'platform3' => { platform_type: :test }
|
10
|
+
'platform3' => { platform_type: :test, name: 'other_platform' }
|
11
11
|
}
|
12
12
|
) do |repositories|
|
13
|
-
expect(test_config.
|
14
|
-
expect(test_config.
|
15
|
-
repositories['platform1'],
|
16
|
-
repositories['platform3']
|
17
|
-
|
18
|
-
expect(test_config.
|
19
|
-
repositories['platform2']
|
20
|
-
|
13
|
+
expect(test_config.platforms_info.keys.sort).to eq %i[test test_2].sort
|
14
|
+
expect(test_config.platforms_info[:test]).to eq(
|
15
|
+
repositories['platform1'] => {},
|
16
|
+
repositories['platform3'] => { name: 'other_platform' }
|
17
|
+
)
|
18
|
+
expect(test_config.platforms_info[:test_2]).to eq(
|
19
|
+
repositories['platform2'] => {}
|
20
|
+
)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -55,27 +55,57 @@ describe HybridPlatformsConductor::PlatformsHandler do
|
|
55
55
|
{
|
56
56
|
'platform1' => { platform_type: :test },
|
57
57
|
'platform2' => { platform_type: :test_2 },
|
58
|
-
'platform3' => { platform_type: :test }
|
58
|
+
'platform3' => { platform_type: :test, name: 'other_platform' }
|
59
59
|
}
|
60
60
|
) do
|
61
|
-
expect(test_platforms_handler.known_platforms.map(&:name).sort).to eq %w[platform1 platform2
|
61
|
+
expect(test_platforms_handler.known_platforms.map(&:name).sort).to eq %w[platform1 platform2 other_platform].sort
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
65
|
it 'fails if several platforms share the same name' do
|
66
66
|
with_repository('platform1') do |repository|
|
67
|
+
FileUtils.mkdir_p "#{repository}/platform1"
|
67
68
|
with_test_platforms(
|
68
69
|
{
|
69
70
|
'platform1' => { platform_type: :test },
|
70
71
|
'platform2' => { platform_type: :test_2 }
|
71
72
|
},
|
72
|
-
additional_config: "test_2_platform path: \'#{repository}\'"
|
73
|
+
additional_config: "test_2_platform path: \'#{repository}/platform1\'"
|
73
74
|
) do
|
74
75
|
expect { test_platforms_handler.known_platforms }.to raise_error 'Platform name platform1 is declared several times.'
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end
|
78
79
|
|
80
|
+
it 'fails if several platforms share the same path' do
|
81
|
+
with_repository('platform1') do |repository|
|
82
|
+
with_test_platforms(
|
83
|
+
{
|
84
|
+
'platform1' => { platform_type: :test },
|
85
|
+
'platform2' => { platform_type: :test_2 }
|
86
|
+
},
|
87
|
+
additional_config: "test_2_platform path: \'#{repository}\', name: 'other_platform'"
|
88
|
+
) do
|
89
|
+
expect { test_platforms_handler.known_platforms }.to raise_error "Platform repository path #{repository} is declared several times."
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'can differentiate several platforms sharing the same path ending but with different explicit names' do
|
95
|
+
with_repository('platform1') do |repository|
|
96
|
+
FileUtils.mkdir_p "#{repository}/platform1"
|
97
|
+
with_test_platforms(
|
98
|
+
{
|
99
|
+
'platform1' => { platform_type: :test },
|
100
|
+
'platform2' => { platform_type: :test_2 }
|
101
|
+
},
|
102
|
+
additional_config: "test_platform path: \'#{repository}/platform1\', name: 'other_platform'"
|
103
|
+
) do
|
104
|
+
expect(test_platforms_handler.known_platforms.map(&:name).sort).to eq %w[platform1 platform2 other_platform].sort
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
79
109
|
it 'returns defined platforms filtered by platform type' do
|
80
110
|
with_test_platforms(
|
81
111
|
{
|
@@ -190,6 +190,81 @@ describe 'nodes_to_deploy executable' do
|
|
190
190
|
end
|
191
191
|
end
|
192
192
|
|
193
|
+
it 'considers nodes having the same invalid commit ids in their logs to be deployed' do
|
194
|
+
with_test_platform_for_nodes_to_deploy do
|
195
|
+
expect(test_deployer).to receive(:deployment_info_from).with(%w[node1 node2]).and_return(
|
196
|
+
'node1' => {
|
197
|
+
services: %w[service1],
|
198
|
+
deployment_info: {
|
199
|
+
repo_name_0: 'platform',
|
200
|
+
commit_id_0: 'abcdef1',
|
201
|
+
exit_status: 0
|
202
|
+
},
|
203
|
+
exit_status: 0,
|
204
|
+
stdout: '',
|
205
|
+
stderr: ''
|
206
|
+
},
|
207
|
+
'node2' => {
|
208
|
+
services: %w[service2],
|
209
|
+
deployment_info: {
|
210
|
+
repo_name_0: 'platform',
|
211
|
+
commit_id_0: 'abcdef1',
|
212
|
+
exit_status: 0
|
213
|
+
},
|
214
|
+
exit_status: 0,
|
215
|
+
stdout: '',
|
216
|
+
stderr: ''
|
217
|
+
}
|
218
|
+
)
|
219
|
+
expect(test_nodes_handler).to receive(:impacted_nodes_from_git_diff).with('platform', from_commit: 'abcdef1', to_commit: 'master') do
|
220
|
+
raise HybridPlatformsConductor::NodesHandler::GitError, 'Mocked git error due to an invalid commit id'
|
221
|
+
end
|
222
|
+
exit_code, stdout = run 'nodes_to_deploy'
|
223
|
+
expect(exit_code).to eq 0
|
224
|
+
expect(stdout).to eq <<~EO_STDOUT
|
225
|
+
===== Nodes to deploy =====
|
226
|
+
node1
|
227
|
+
node2
|
228
|
+
EO_STDOUT
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'considers nodes having unknown platforms in their logs to be deployed' do
|
233
|
+
with_test_platform_for_nodes_to_deploy do
|
234
|
+
expect(test_deployer).to receive(:deployment_info_from).with(%w[node1 node2]).and_return(
|
235
|
+
'node1' => {
|
236
|
+
services: %w[service1],
|
237
|
+
deployment_info: {
|
238
|
+
repo_name_0: 'unknown_platform',
|
239
|
+
commit_id_0: 'abcdef1',
|
240
|
+
exit_status: 0
|
241
|
+
},
|
242
|
+
exit_status: 0,
|
243
|
+
stdout: '',
|
244
|
+
stderr: ''
|
245
|
+
},
|
246
|
+
'node2' => {
|
247
|
+
services: %w[service2],
|
248
|
+
deployment_info: {
|
249
|
+
repo_name_0: 'platform',
|
250
|
+
commit_id_0: 'abcdef2',
|
251
|
+
exit_status: 0
|
252
|
+
},
|
253
|
+
exit_status: 0,
|
254
|
+
stdout: '',
|
255
|
+
stderr: ''
|
256
|
+
}
|
257
|
+
)
|
258
|
+
expect(test_nodes_handler).to receive(:impacted_nodes_from_git_diff).with('platform', from_commit: 'abcdef2', to_commit: 'master').and_return [%w[], [], [], false]
|
259
|
+
exit_code, stdout = run 'nodes_to_deploy'
|
260
|
+
expect(exit_code).to eq 0
|
261
|
+
expect(stdout).to eq <<~EO_STDOUT
|
262
|
+
===== Nodes to deploy =====
|
263
|
+
node1
|
264
|
+
EO_STDOUT
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
193
268
|
it 'ignores impacts if asked' do
|
194
269
|
with_test_platform_for_nodes_to_deploy do
|
195
270
|
exit_code, stdout = run 'nodes_to_deploy', '--ignore-deployed-info'
|
@@ -73,7 +73,9 @@ module HybridPlatformsConductorTest
|
|
73
73
|
# Clean-up at the end.
|
74
74
|
#
|
75
75
|
# Parameters::
|
76
|
-
# * *platforms_info* (Hash<String,Object>): Platforms info for the test platform
|
76
|
+
# * *platforms_info* (Hash<String,Object>): Platforms info for the test platform:
|
77
|
+
# * *platform_type* (Symbol): Name of the platform handler plugin for this platform
|
78
|
+
# * *name* (String): Optional name to give the platform [optional]
|
77
79
|
# * *as_git* (Boolean): Do we initialize those repositories as Git repositories? [default: false]
|
78
80
|
# * *additional_config* (String): Additional config to be added [default: '']
|
79
81
|
# * Proc: Code called with the environment ready
|
@@ -86,7 +88,7 @@ module HybridPlatformsConductorTest
|
|
86
88
|
repositories.map do |platform, dir|
|
87
89
|
platform_type = platforms_info[platform].key?(:platform_type) ? platforms_info[platform][:platform_type] : :test
|
88
90
|
platform_types << platform_type unless platform_types.include?(platform_type)
|
89
|
-
"#{platform_type}_platform path: '#{dir}'"
|
91
|
+
"#{platform_type}_platform path: '#{dir}'#{platforms_info[platform].key?(:name) ? ", name: '#{platforms_info[platform][:name]}'" : ''}"
|
90
92
|
end.join("\n") + "\n#{additional_config}"
|
91
93
|
) do
|
92
94
|
register_platform_handlers(platform_types.map do |platform_type|
|
@@ -200,10 +200,11 @@ module HybridPlatformsConductorTest
|
|
200
200
|
# Result::
|
201
201
|
# * Hash<Symbol, Object>: Platform info (check TestPlatformHandler#platforms_info to know about properties)
|
202
202
|
def platform_info
|
203
|
+
_repo_base_name, found_platform_info = HybridPlatformsConductorTest::PlatformHandlerPlugins::Test.platforms_info.find { |search_repo_base_name, search_platform_info| (search_platform_info[:name] || search_repo_base_name) == name }
|
203
204
|
{
|
204
205
|
nodes: {},
|
205
206
|
nodes_lists: {}
|
206
|
-
}.merge(
|
207
|
+
}.merge(found_platform_info)
|
207
208
|
end
|
208
209
|
|
209
210
|
# Return the node info of a given node
|
@@ -0,0 +1,13 @@
|
|
1
|
+
name 'test_cookbook_3'
|
2
|
+
maintainer 'Muriel Salvan'
|
3
|
+
maintainer_email 'muriel@x-aeon.com'
|
4
|
+
supports 'debian'
|
5
|
+
chef_version '>= 14.8'
|
6
|
+
source_url 'https://x-aeon.com'
|
7
|
+
issues_url 'https://x-aeon.com'
|
8
|
+
license 'BSD'
|
9
|
+
description 'Installs/Configures test_cookbook_3'
|
10
|
+
long_description ''
|
11
|
+
version '0.1.0'
|
12
|
+
depends 'test_cookbook_4'
|
13
|
+
depends 'test_cookbook_5'
|
@@ -0,0 +1 @@
|
|
1
|
+
include_recipe 'test_cookbook_4::recipe_4'
|
@@ -0,0 +1 @@
|
|
1
|
+
# Recipe code
|
@@ -0,0 +1 @@
|
|
1
|
+
# Recipe code
|
@@ -0,0 +1 @@
|
|
1
|
+
# Recipe code
|
@@ -0,0 +1 @@
|
|
1
|
+
# Recipe code
|
@@ -0,0 +1 @@
|
|
1
|
+
# Recipe code
|
@@ -0,0 +1 @@
|
|
1
|
+
# Recipe code
|
@@ -5,7 +5,7 @@ module HybridPlatformsConductorTest
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
|
8
|
-
attr_accessor
|
8
|
+
attr_accessor(*%i[calls mocked_logs])
|
9
9
|
|
10
10
|
end
|
11
11
|
|
@@ -89,7 +89,7 @@ module HybridPlatformsConductorTest
|
|
89
89
|
stdout: stdout,
|
90
90
|
stderr: stderr
|
91
91
|
}
|
92
|
-
{
|
92
|
+
TestLogPlugin.mocked_logs[node] || {
|
93
93
|
services: %w[unknown],
|
94
94
|
deployment_info: {
|
95
95
|
user: 'test_user'
|
@@ -145,6 +145,7 @@ module HybridPlatformsConductorTest
|
|
145
145
|
HybridPlatformsConductorTest::TestPlugins::NodeCheck.only_on_nodes = nil
|
146
146
|
HybridPlatformsConductorTest::TestPlugins::SeveralChecks.runs = []
|
147
147
|
HybridPlatformsConductorTest::TestLogPlugin.calls = []
|
148
|
+
HybridPlatformsConductorTest::TestLogPlugin.mocked_logs = {}
|
148
149
|
HybridPlatformsConductorTest::TestLogNoReadPlugin.calls = []
|
149
150
|
HybridPlatformsConductorTest::TestSecretsReaderPlugin.calls = []
|
150
151
|
HybridPlatformsConductorTest::TestSecretsReaderPlugin.deployer = nil
|
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.
|
4
|
+
version: 33.9.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-
|
11
|
+
date: 2021-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: range_operators
|
@@ -1003,10 +1003,32 @@ files:
|
|
1003
1003
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/default.rb
|
1004
1004
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/recipes/other_recipe.rb
|
1005
1005
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_2/resources/my_resource.rb
|
1006
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/metadata.rb
|
1007
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/31_unknown_recipe_include.rb
|
1008
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/32_unknown_cookbook_include.rb
|
1009
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/33_unknown_include.rb
|
1010
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/34_known_include.rb
|
1011
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_3/recipes/35_unparsable_include.rb
|
1012
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_1.rb
|
1013
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_2.rb
|
1014
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_3.rb
|
1015
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_4/recipes/recipe_4.rb
|
1016
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_5/recipes/recipe_1.rb
|
1017
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/cookbooks/test_cookbook_5/recipes/recipe_2.rb
|
1006
1018
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node1.json
|
1007
1019
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node2.json
|
1020
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node31.json
|
1021
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node32.json
|
1022
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node33.json
|
1023
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node34.json
|
1024
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/nodes/node35.json
|
1008
1025
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_1.rb
|
1009
1026
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_2.rb
|
1027
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_31.rb
|
1028
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_32.rb
|
1029
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_33.rb
|
1030
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_34.rb
|
1031
|
+
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/recipes/policyfiles/test_policy_35.rb
|
1010
1032
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/config.rb
|
1011
1033
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/cookbooks/test_cookbook_1/recipes/default.rb
|
1012
1034
|
- spec/hybrid_platforms_conductor_test/serverless_chef_repositories/several_cookbooks/nodes/node1.json
|