chef-utils 18.2.5 → 18.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +201 -201
  3. data/Rakefile +15 -15
  4. data/chef-utils.gemspec +50 -50
  5. data/lib/chef-utils/dist.rb +154 -154
  6. data/lib/chef-utils/dsl/architecture.rb +150 -150
  7. data/lib/chef-utils/dsl/cloud.rb +155 -155
  8. data/lib/chef-utils/dsl/default_paths.rb +60 -60
  9. data/lib/chef-utils/dsl/introspection.rb +134 -134
  10. data/lib/chef-utils/dsl/os.rb +58 -58
  11. data/lib/chef-utils/dsl/path_sanity.rb +39 -39
  12. data/lib/chef-utils/dsl/platform.rb +387 -387
  13. data/lib/chef-utils/dsl/platform_family.rb +360 -360
  14. data/lib/chef-utils/dsl/platform_version.rb +41 -41
  15. data/lib/chef-utils/dsl/service.rb +112 -112
  16. data/lib/chef-utils/dsl/train_helpers.rb +87 -87
  17. data/lib/chef-utils/dsl/virtualization.rb +272 -272
  18. data/lib/chef-utils/dsl/which.rb +123 -123
  19. data/lib/chef-utils/dsl/windows.rb +86 -86
  20. data/lib/chef-utils/internal.rb +114 -114
  21. data/lib/chef-utils/mash.rb +263 -263
  22. data/lib/chef-utils/parallel_map.rb +131 -131
  23. data/lib/chef-utils/version.rb +20 -20
  24. data/lib/chef-utils/version_string.rb +160 -160
  25. data/lib/chef-utils.rb +53 -53
  26. data/spec/spec_helper.rb +100 -100
  27. data/spec/unit/dsl/architecture_spec.rb +151 -151
  28. data/spec/unit/dsl/cloud_spec.rb +93 -93
  29. data/spec/unit/dsl/dsl_spec.rb +34 -34
  30. data/spec/unit/dsl/introspection_spec.rb +201 -201
  31. data/spec/unit/dsl/os_spec.rb +175 -175
  32. data/spec/unit/dsl/path_sanity_spec.rb +86 -86
  33. data/spec/unit/dsl/platform_family_spec.rb +235 -235
  34. data/spec/unit/dsl/platform_spec.rb +252 -252
  35. data/spec/unit/dsl/service_spec.rb +117 -117
  36. data/spec/unit/dsl/virtualization_spec.rb +75 -75
  37. data/spec/unit/dsl/which_spec.rb +171 -171
  38. data/spec/unit/dsl/windows_spec.rb +84 -84
  39. data/spec/unit/mash_spec.rb +51 -51
  40. data/spec/unit/parallel_map_spec.rb +156 -156
  41. metadata +2 -2
@@ -1,123 +1,123 @@
1
- # frozen_string_literal: true
2
- #
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require_relative "../internal"
20
-
21
- module ChefUtils
22
- module DSL
23
- module Which
24
- include Internal
25
-
26
- # Lookup an executable through the systems search PATH. Allows specifying an array
27
- # of executables to look for. The first executable that is found, along any path entry,
28
- # will be the preferred one and returned first. The extra_path will override any default
29
- # extra_paths which are added (allowing the user to pass an empty array to remove them).
30
- #
31
- # When passed a block the block will be called with the full pathname of any executables
32
- # which are found, and the block should return truthy or falsey values to further filter
33
- # the executable based on arbitrary criteria.
34
- #
35
- # This is syntactic sugar for `where(...).first`
36
- #
37
- # This helper can be used in target mode in chef or with train using the appropriate
38
- # wiring externally.
39
- #
40
- # @example Find the most appropriate python executable, searching through the system PATH
41
- # plus additionally the "/usr/libexec" directory, which has the dnf libraries
42
- # installed and available.
43
- #
44
- # cmd = which("platform-python", "python", "python3", "python2", "python2.7", extra_path: "/usr/libexec") do |f|
45
- # shell_out("#{f} -c 'import dnf'").exitstatus == 0
46
- # end
47
- #
48
- # @param [Array<String>] list of commands to search for
49
- # @param [String,Array<String>] array of extra paths to search through
50
- # @return [String] the first match
51
- #
52
- def which(*cmds, extra_path: nil, &block)
53
- where(*cmds, extra_path: extra_path, &block).first || false
54
- end
55
-
56
- # Lookup all the instances of an an executable that can be found through the systems search PATH.
57
- # Allows specifying an array of executables to look for. All the instances of the first executable
58
- # that is found will be returned first. The extra_path will override any default extra_paths
59
- # which are added (allowing the user to pass an empty array to remove them).
60
- #
61
- # When passed a block the block will be called with the full pathname of any executables
62
- # which are found, and the block should return truthy or falsey values to further filter
63
- # the executable based on arbitrary criteria.
64
- #
65
- # This helper can be used in target mode in chef or with train using the appropriate
66
- # wiring externally.
67
- #
68
- # @example Find all the python executables, searching through the system PATH plus additionally
69
- # the "/usr/libexec" directory, which have the dnf libraries installed and available.
70
- #
71
- # cmds = where("platform-python", "python", "python3", "python2", "python2.7", extra_path: "/usr/libexec") do |f|
72
- # shell_out("#{f} -c 'import dnf'").exitstatus == 0
73
- # end
74
- #
75
- # @param [Array<String>] list of commands to search for
76
- # @param [String,Array<String>] array of extra paths to search through
77
- # @return [String] the first match
78
- #
79
- def where(*cmds, extra_path: nil, &block)
80
- extra_path ||= __extra_path
81
- paths = __env_path.split(File::PATH_SEPARATOR) + Array(extra_path)
82
- paths.uniq!
83
- exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : []
84
- exts.unshift("")
85
- cmds.map do |cmd|
86
- paths.map do |path|
87
- exts.map do |ext|
88
- filename = File.join(path, "#{cmd}#{ext}")
89
- filename if __valid_executable?(filename, &block)
90
- end.compact
91
- end
92
- end.flatten
93
- end
94
-
95
- private
96
-
97
- # This is for injecting common extra_paths into the search PATH. The chef-client codebase overrides this into its
98
- # own custom mixin to ensure that /usr/sbin, /sbin, etc are in the search PATH for chef-client.
99
- #
100
- # @api private
101
- def __extra_path
102
- nil
103
- end
104
-
105
- # Windows compatible and train/target-mode-enhanced helper to determine if an executable is valid.
106
- #
107
- # @api private
108
- def __valid_executable?(filename, &block)
109
- is_executable =
110
- if __transport_connection
111
- __transport_connection.file(filename).stat[:mode] & 1 && !__transport_connection.file(filename).directory?
112
- else
113
- File.executable?(filename) && !File.directory?(filename)
114
- end
115
- return false unless is_executable
116
-
117
- block ? yield(filename) : true
118
- end
119
-
120
- extend self
121
- end
122
- end
123
- end
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "../internal"
20
+
21
+ module ChefUtils
22
+ module DSL
23
+ module Which
24
+ include Internal
25
+
26
+ # Lookup an executable through the systems search PATH. Allows specifying an array
27
+ # of executables to look for. The first executable that is found, along any path entry,
28
+ # will be the preferred one and returned first. The extra_path will override any default
29
+ # extra_paths which are added (allowing the user to pass an empty array to remove them).
30
+ #
31
+ # When passed a block the block will be called with the full pathname of any executables
32
+ # which are found, and the block should return truthy or falsey values to further filter
33
+ # the executable based on arbitrary criteria.
34
+ #
35
+ # This is syntactic sugar for `where(...).first`
36
+ #
37
+ # This helper can be used in target mode in chef or with train using the appropriate
38
+ # wiring externally.
39
+ #
40
+ # @example Find the most appropriate python executable, searching through the system PATH
41
+ # plus additionally the "/usr/libexec" directory, which has the dnf libraries
42
+ # installed and available.
43
+ #
44
+ # cmd = which("platform-python", "python", "python3", "python2", "python2.7", extra_path: "/usr/libexec") do |f|
45
+ # shell_out("#{f} -c 'import dnf'").exitstatus == 0
46
+ # end
47
+ #
48
+ # @param [Array<String>] list of commands to search for
49
+ # @param [String,Array<String>] array of extra paths to search through
50
+ # @return [String] the first match
51
+ #
52
+ def which(*cmds, extra_path: nil, &block)
53
+ where(*cmds, extra_path: extra_path, &block).first || false
54
+ end
55
+
56
+ # Lookup all the instances of an an executable that can be found through the systems search PATH.
57
+ # Allows specifying an array of executables to look for. All the instances of the first executable
58
+ # that is found will be returned first. The extra_path will override any default extra_paths
59
+ # which are added (allowing the user to pass an empty array to remove them).
60
+ #
61
+ # When passed a block the block will be called with the full pathname of any executables
62
+ # which are found, and the block should return truthy or falsey values to further filter
63
+ # the executable based on arbitrary criteria.
64
+ #
65
+ # This helper can be used in target mode in chef or with train using the appropriate
66
+ # wiring externally.
67
+ #
68
+ # @example Find all the python executables, searching through the system PATH plus additionally
69
+ # the "/usr/libexec" directory, which have the dnf libraries installed and available.
70
+ #
71
+ # cmds = where("platform-python", "python", "python3", "python2", "python2.7", extra_path: "/usr/libexec") do |f|
72
+ # shell_out("#{f} -c 'import dnf'").exitstatus == 0
73
+ # end
74
+ #
75
+ # @param [Array<String>] list of commands to search for
76
+ # @param [String,Array<String>] array of extra paths to search through
77
+ # @return [String] the first match
78
+ #
79
+ def where(*cmds, extra_path: nil, &block)
80
+ extra_path ||= __extra_path
81
+ paths = __env_path.split(File::PATH_SEPARATOR) + Array(extra_path)
82
+ paths.uniq!
83
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(";") : []
84
+ exts.unshift("")
85
+ cmds.map do |cmd|
86
+ paths.map do |path|
87
+ exts.map do |ext|
88
+ filename = File.join(path, "#{cmd}#{ext}")
89
+ filename if __valid_executable?(filename, &block)
90
+ end.compact
91
+ end
92
+ end.flatten
93
+ end
94
+
95
+ private
96
+
97
+ # This is for injecting common extra_paths into the search PATH. The chef-client codebase overrides this into its
98
+ # own custom mixin to ensure that /usr/sbin, /sbin, etc are in the search PATH for chef-client.
99
+ #
100
+ # @api private
101
+ def __extra_path
102
+ nil
103
+ end
104
+
105
+ # Windows compatible and train/target-mode-enhanced helper to determine if an executable is valid.
106
+ #
107
+ # @api private
108
+ def __valid_executable?(filename, &block)
109
+ is_executable =
110
+ if __transport_connection
111
+ __transport_connection.file(filename).stat[:mode] & 1 && !__transport_connection.file(filename).directory?
112
+ else
113
+ File.executable?(filename) && !File.directory?(filename)
114
+ end
115
+ return false unless is_executable
116
+
117
+ block ? yield(filename) : true
118
+ end
119
+
120
+ extend self
121
+ end
122
+ end
123
+ end
@@ -1,86 +1,86 @@
1
- # frozen_string_literal: true
2
- #
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require_relative "../internal"
20
-
21
- module ChefUtils
22
- module DSL
23
- module Windows
24
- require_relative "../version_string"
25
-
26
- include Internal
27
-
28
- # Determine if the current node is Windows Server Core.
29
- #
30
- # @param [Chef::Node] node the node to check
31
- # @since 15.7
32
- #
33
- # @return [Boolean]
34
- #
35
- def windows_server_core?(node = __getnode)
36
- node["kernel"]["server_core"] == true
37
- end
38
-
39
- # Determine if the current node is Windows Workstation.
40
- #
41
- # @param [Chef::Node] node the node to check
42
- # @since 15.7
43
- #
44
- # @return [Boolean]
45
- #
46
- def windows_workstation?(node = __getnode)
47
- node["kernel"]["product_type"] == "Workstation"
48
- end
49
-
50
- # Determine if the current node is Windows Server.
51
- #
52
- # @param [Chef::Node] node the node to check
53
- # @since 15.7
54
- #
55
- # @return [Boolean]
56
- #
57
- def windows_server?(node = __getnode)
58
- node["kernel"]["product_type"] == "Server"
59
- end
60
-
61
- # Determine the current Windows NT version. The NT version often differs from the marketing version, but offers a good way to find desktop and server releases that are based on the same codebase. For example NT 6.3 corresponds to Windows 8.1 and Windows 2012 R2.
62
- #
63
- # @param [Chef::Node] node the node to check
64
- # @since 15.8
65
- #
66
- # @return [ChefUtils::VersionString]
67
- #
68
- def windows_nt_version(node = __getnode)
69
- ChefUtils::VersionString.new(node["os_version"])
70
- end
71
-
72
- # Determine the installed version of PowerShell.
73
- #
74
- # @param [Chef::Node] node the node to check
75
- # @since 15.8
76
- #
77
- # @return [ChefUtils::VersionString]
78
- #
79
- def powershell_version(node = __getnode)
80
- ChefUtils::VersionString.new(node["languages"]["powershell"]["version"])
81
- end
82
-
83
- extend self
84
- end
85
- end
86
- end
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "../internal"
20
+
21
+ module ChefUtils
22
+ module DSL
23
+ module Windows
24
+ require_relative "../version_string"
25
+
26
+ include Internal
27
+
28
+ # Determine if the current node is Windows Server Core.
29
+ #
30
+ # @param [Chef::Node] node the node to check
31
+ # @since 15.7
32
+ #
33
+ # @return [Boolean]
34
+ #
35
+ def windows_server_core?(node = __getnode)
36
+ node["kernel"]["server_core"] == true
37
+ end
38
+
39
+ # Determine if the current node is Windows Workstation.
40
+ #
41
+ # @param [Chef::Node] node the node to check
42
+ # @since 15.7
43
+ #
44
+ # @return [Boolean]
45
+ #
46
+ def windows_workstation?(node = __getnode)
47
+ node["kernel"]["product_type"] == "Workstation"
48
+ end
49
+
50
+ # Determine if the current node is Windows Server.
51
+ #
52
+ # @param [Chef::Node] node the node to check
53
+ # @since 15.7
54
+ #
55
+ # @return [Boolean]
56
+ #
57
+ def windows_server?(node = __getnode)
58
+ node["kernel"]["product_type"] == "Server"
59
+ end
60
+
61
+ # Determine the current Windows NT version. The NT version often differs from the marketing version, but offers a good way to find desktop and server releases that are based on the same codebase. For example NT 6.3 corresponds to Windows 8.1 and Windows 2012 R2.
62
+ #
63
+ # @param [Chef::Node] node the node to check
64
+ # @since 15.8
65
+ #
66
+ # @return [ChefUtils::VersionString]
67
+ #
68
+ def windows_nt_version(node = __getnode)
69
+ ChefUtils::VersionString.new(node["os_version"])
70
+ end
71
+
72
+ # Determine the installed version of PowerShell.
73
+ #
74
+ # @param [Chef::Node] node the node to check
75
+ # @since 15.8
76
+ #
77
+ # @return [ChefUtils::VersionString]
78
+ #
79
+ def powershell_version(node = __getnode)
80
+ ChefUtils::VersionString.new(node["languages"]["powershell"]["version"])
81
+ end
82
+
83
+ extend self
84
+ end
85
+ end
86
+ end
@@ -1,114 +1,114 @@
1
- # frozen_string_literal: true
2
- #
3
- # Copyright:: Copyright (c) Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- module ChefUtils
20
- #
21
- # This is glue code to make the helpers work when called as ChefUtils.helper? from inside of chef-client.
22
- #
23
- # This also is glue code to make the helpers work when mixed into classes that have node/run_context methods that
24
- # provide those objects.
25
- #
26
- # It should not be assumed that any of this code runs from within chef-client and that the
27
- # Chef class or run_context, etc exists.
28
- #
29
- # This gem may be used by gems like mixlib-shellout which can be consumed by external non-Chef utilities,
30
- # so including brittle code here which depends on the existence of the chef-client will cause broken
31
- # behavior downstream. You must practice defensive coding, and not make assumptions about running within chef-client.
32
- #
33
- # Other consumers may mix in the helper classes and then override the methods here and provide their own custom
34
- # wiring and override what is provided here. They are marked as private because no downstream user should ever touch
35
- # them -- they are intended to be subclassable and overridable by Chef developers in other projects. Chef Software
36
- # reserves the right to change the implementation details of this class in minor revs which is what "api private" means,
37
- # so external persons should subclass and override only when necessary (submit PRs and issues upstream if this is a problem).
38
- #
39
- module Internal
40
- extend self
41
-
42
- private
43
-
44
- # This should be set to a Chef::Node instance or to some Hash/Mash-like configuration object with the same keys. It needs to
45
- # expose keys like `:os`, `:platform`, `:platform_version` and `:platform_family` at least to be useful. It will automatically
46
- # pick up a `node` method when mixed into an object that has that as a method (which is the encouraged "public" API to use
47
- # for dependency injection rather than overriding the method in this case.
48
- #
49
- # @return [Hash] hash-like config object
50
- #
51
- # @api private
52
- def __getnode(skip_global = false)
53
- # Software developers should feel free to rely on the default wiring here to the node method by implementing the node method in their
54
- # own class. For anything more complicated they should completely override the method (overriding the whole method is never wrong and
55
- # is safer).
56
- return node if respond_to?(:node) && node
57
-
58
- return run_context&.node if respond_to?(:run_context) && run_context&.node
59
-
60
- unless skip_global
61
- return Chef.run_context&.node if defined?(Chef) && Chef.respond_to?(:run_context) && Chef.run_context&.node
62
- end
63
-
64
- nil
65
- end
66
-
67
- # Just a helper to pull the ENV["PATH"] in a train-independent way
68
- #
69
- # @api private
70
- #
71
- def __env_path
72
- if __transport_connection
73
- __transport_connection.run_command("echo $PATH").stdout.chomp || ""
74
- else
75
- ENV["PATH"] || ""
76
- end
77
- end
78
-
79
- # This should be set to a Train::Plugins::Transport instance. You should wire this up to nil for not using a train transport connection.
80
- #
81
- # @return [Train::Plugins::Transport]
82
- #
83
- # @api private
84
- #
85
- def __transport_connection
86
- # Software consumers MUST override this method with their own implementation. The default behavior here is subject to change.
87
- return Chef.run_context.transport_connection if defined?(Chef) && Chef.respond_to?(:run_context) && Chef&.run_context&.transport_connection
88
-
89
- nil
90
- end
91
-
92
- # This should be set to Chef::Config or to some Hash/Mash-like configuration object with the same keys. It must not be nil.
93
- #
94
- # @return [Hash] hash-like config object
95
- #
96
- # @api private
97
- #
98
- def __config
99
- raise NotImplementedError
100
- end
101
-
102
- # This should be set to Chef::Log or something that duck-types like it. It must not be nil.
103
- #
104
- # @return [Chef::Log] logger-like logging object
105
- #
106
- # @api private
107
- #
108
- def __log
109
- raise NotImplementedError
110
- end
111
-
112
- extend self
113
- end
114
- end
1
+ # frozen_string_literal: true
2
+ #
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module ChefUtils
20
+ #
21
+ # This is glue code to make the helpers work when called as ChefUtils.helper? from inside of chef-client.
22
+ #
23
+ # This also is glue code to make the helpers work when mixed into classes that have node/run_context methods that
24
+ # provide those objects.
25
+ #
26
+ # It should not be assumed that any of this code runs from within chef-client and that the
27
+ # Chef class or run_context, etc exists.
28
+ #
29
+ # This gem may be used by gems like mixlib-shellout which can be consumed by external non-Chef utilities,
30
+ # so including brittle code here which depends on the existence of the chef-client will cause broken
31
+ # behavior downstream. You must practice defensive coding, and not make assumptions about running within chef-client.
32
+ #
33
+ # Other consumers may mix in the helper classes and then override the methods here and provide their own custom
34
+ # wiring and override what is provided here. They are marked as private because no downstream user should ever touch
35
+ # them -- they are intended to be subclassable and overridable by Chef developers in other projects. Chef Software
36
+ # reserves the right to change the implementation details of this class in minor revs which is what "api private" means,
37
+ # so external persons should subclass and override only when necessary (submit PRs and issues upstream if this is a problem).
38
+ #
39
+ module Internal
40
+ extend self
41
+
42
+ private
43
+
44
+ # This should be set to a Chef::Node instance or to some Hash/Mash-like configuration object with the same keys. It needs to
45
+ # expose keys like `:os`, `:platform`, `:platform_version` and `:platform_family` at least to be useful. It will automatically
46
+ # pick up a `node` method when mixed into an object that has that as a method (which is the encouraged "public" API to use
47
+ # for dependency injection rather than overriding the method in this case.
48
+ #
49
+ # @return [Hash] hash-like config object
50
+ #
51
+ # @api private
52
+ def __getnode(skip_global = false)
53
+ # Software developers should feel free to rely on the default wiring here to the node method by implementing the node method in their
54
+ # own class. For anything more complicated they should completely override the method (overriding the whole method is never wrong and
55
+ # is safer).
56
+ return node if respond_to?(:node) && node
57
+
58
+ return run_context&.node if respond_to?(:run_context) && run_context&.node
59
+
60
+ unless skip_global
61
+ return Chef.run_context&.node if defined?(Chef) && Chef.respond_to?(:run_context) && Chef.run_context&.node
62
+ end
63
+
64
+ nil
65
+ end
66
+
67
+ # Just a helper to pull the ENV["PATH"] in a train-independent way
68
+ #
69
+ # @api private
70
+ #
71
+ def __env_path
72
+ if __transport_connection
73
+ __transport_connection.run_command("echo $PATH").stdout.chomp || ""
74
+ else
75
+ ENV["PATH"] || ""
76
+ end
77
+ end
78
+
79
+ # This should be set to a Train::Plugins::Transport instance. You should wire this up to nil for not using a train transport connection.
80
+ #
81
+ # @return [Train::Plugins::Transport]
82
+ #
83
+ # @api private
84
+ #
85
+ def __transport_connection
86
+ # Software consumers MUST override this method with their own implementation. The default behavior here is subject to change.
87
+ return Chef.run_context.transport_connection if defined?(Chef) && Chef.respond_to?(:run_context) && Chef&.run_context&.transport_connection
88
+
89
+ nil
90
+ end
91
+
92
+ # This should be set to Chef::Config or to some Hash/Mash-like configuration object with the same keys. It must not be nil.
93
+ #
94
+ # @return [Hash] hash-like config object
95
+ #
96
+ # @api private
97
+ #
98
+ def __config
99
+ raise NotImplementedError
100
+ end
101
+
102
+ # This should be set to Chef::Log or something that duck-types like it. It must not be nil.
103
+ #
104
+ # @return [Chef::Log] logger-like logging object
105
+ #
106
+ # @api private
107
+ #
108
+ def __log
109
+ raise NotImplementedError
110
+ end
111
+
112
+ extend self
113
+ end
114
+ end