train-core 3.12.7 → 3.13.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aec52fd6612726e12c5f2cabae1a8f45eea7602c87dc2e7d230f579d16f0ac5d
4
- data.tar.gz: e19c22f689bfb0cc0d4ded96f808cc68976866bf934b53d8bca293036532a192
3
+ metadata.gz: 8c6ced29649aad99b00f786b6cbef4777bd154195b676fea83eb16cb4fa1961f
4
+ data.tar.gz: 9c75c2a466e43432fa793a1342fa509b660750ba42350fcada2ec1953d001168
5
5
  SHA512:
6
- metadata.gz: b2ee00b9ab8590acb2a1c87bbbbc653141f276a2b8be5a306f7ba497b15f5010d297f9f06fadd62d5573e01de70eb967800aa529b6507d5755ce86df82ed0e8b
7
- data.tar.gz: 26dbb3b68b1ec9697d20b129b64fa0eab4421b7a717b21ac234bc4d32756783f60a085221a5b70e11281d5671a15359c70c4e903a72e26118ff69805c75949e5
6
+ metadata.gz: 57e3ceede17d733f9f3705cc07330a3a04b1facb8ff304ffc69a1f6cc4c1b3d0441edb43e0a13f13610071befc83da1f9fef861c25452d2174f9ba59ce325053
7
+ data.tar.gz: 36315a4aaac156242353457b9f7a0dbf2e8c35905f71308cfd7a3986f0bb7cef0cdea66b6ae6e5cca9960acbe38ab8a071b5d9d448b13b30f690e9e521d4c18f
@@ -8,7 +8,7 @@ module Train::Platforms::Detect::Helpers
8
8
  include Train::Platforms::Detect::Helpers::Windows
9
9
 
10
10
  def ruby_host_os(regex)
11
- ::RbConfig::CONFIG["host_os"] =~ regex
11
+ regex.match?(::RbConfig::CONFIG["host_os"])
12
12
  end
13
13
 
14
14
  def winrm?
@@ -35,8 +35,9 @@ module Train::Platforms::Detect::Helpers
35
35
 
36
36
  def command_output(cmd)
37
37
  res = @backend.run_command(cmd)
38
- stdout = res.stdout
39
- stderr = res.stderr
38
+ # To suppress warning: literal string will be frozen in the future
39
+ stdout = String.new(res.stdout)
40
+ stderr = String.new(res.stderr)
40
41
  # When you try to execute command using ssh connection as root user and you have provided ssh user identity file
41
42
  # it gives standard output to login as authorized user other than root. To show this standard output as an error
42
43
  # to user we are matching the string of stdout and raising the error here so that user gets exact information.
@@ -25,6 +25,9 @@ module Train::Platforms::Detect::Helpers
25
25
  @platform[:name] = "Windows #{@platform[:release]}"
26
26
  end
27
27
 
28
+ # `Get-CimInstance` is a PowerShell-specific command and is not available in Command Prompt.
29
+ # Since the logic has always relied on `read_wmic` at this point, we are skipping the conditional check for `wmic_available?`
30
+ # and directly invoking `read_wmic` to maintain the existing behavior.
28
31
  read_wmic
29
32
  true
30
33
  end
@@ -42,7 +45,9 @@ module Train::Platforms::Detect::Helpers
42
45
  @platform[:release] = payload["Version"]
43
46
  @platform[:name] = payload["Caption"]
44
47
 
45
- read_wmic
48
+ # Prefer retrieving the OS details via `wmic` if available on the system to retain existing behavior.
49
+ # If `wmic` is not available, fall back to using CIM as an alternative method.
50
+ wmic_available? ? read_wmic : read_cim_os
46
51
  true
47
52
  rescue
48
53
  false
@@ -108,7 +113,7 @@ module Train::Platforms::Detect::Helpers
108
113
  def windows_uuid
109
114
  uuid = windows_uuid_from_chef
110
115
  uuid = windows_uuid_from_machine_file if uuid.nil?
111
- uuid = windows_uuid_from_wmic if uuid.nil?
116
+ uuid = windows_uuid_from_wmic_or_cim if uuid.nil?
112
117
  uuid = windows_uuid_from_registry if uuid.nil?
113
118
  raise Train::TransportError, "Cannot find a UUID for your node." if uuid.nil?
114
119
 
@@ -134,11 +139,51 @@ module Train::Platforms::Detect::Helpers
134
139
  json["node_uuid"]
135
140
  end
136
141
 
142
+ def windows_uuid_from_wmic_or_cim
143
+ # Retrieve the Windows UUID using `wmic` if it is available and not marked as deprecated, maintaining compatibility with older systems.
144
+ # If `wmic` is unavailable or deprecated, use the `Get-CimInstance` command, which is the modern and recommended approach by Microsoft.
145
+ wmic_available? ? windows_uuid_from_wmic : windows_uuid_from_cim
146
+ end
147
+
137
148
  def windows_uuid_from_wmic
138
- result = @backend.run_command("wmic csproduct get UUID")
149
+ # Switched from `wmic csproduct get UUID` to `wmic csproduct get UUID /value`
150
+ # to make the parsing of the UUID more reliable and consistent.
151
+ #
152
+ # When using the original `wmic csproduct get UUID` command, the output includes
153
+ # a header line and spacing that can vary depending on the system, making it harder
154
+ # to reliably extract the UUID. In some cases, splitting by line and taking the last
155
+ # element returns an empty string, even when exit_status is 0.
156
+ #
157
+ # Example:
158
+ #
159
+ # (byebug) result = @backend.run_command("wmic csproduct get UUID")
160
+ # #<struct Train::Extras::CommandResult stdout="UUID \r\r\nEC20EBD7-8E03-06A8-645F-2D22E5A3BA4B \r\r\n\r\r\n", stderr="", exit_status=0>
161
+ # (byebug) result.stdout
162
+ # "UUID \r\r\nEC20EBD7-8E03-06A8-645F-2D22E5A3BA4B \r\r\n\r\r\n"
163
+ # (byebug) result.exit_status
164
+ # 0
165
+ # (byebug) result.stdout.split("\r\n")[-1].strip
166
+ # ""
167
+ #
168
+ # In contrast, `wmic csproduct get UUID /value` returns a consistent `UUID=<value>` format,
169
+ # which is more suitable for regex matching.
170
+ #
171
+ # Example:
172
+ #
173
+ # byebug) result = @backend.run_command("wmic csproduct get UUID /value")
174
+ # #<struct Train::Extras::CommandResult stdout="\r\r\n\r\r\nUUID=EC20EBD7-8E03-06A8-645F-2D22E5A3BA4B\r\r\n\r\r\n\r\r\n\r\r\n", stderr="", exit_status=0>
175
+ # (byebug) result.stdout
176
+ # "\r\r\n\r\r\nUUID=EC20EBD7-8E03-06A8-645F-2D22E5A3BA4B\r\r\n\r\r\n\r\r\n\r\r\n"
177
+ # (byebug) result.stdout&.match(/UUID=([A-F0-9\-]+)/i)&.captures&.first
178
+ # "EC20EBD7-8E03-06A8-645F-2D22E5A3BA4B"
179
+ #
180
+ # This change improves parsing reliability and handles edge cases where the previous
181
+ # approach would return `nil` or raise errors on empty output lines.
182
+
183
+ result = @backend.run_command("wmic csproduct get UUID /value")
139
184
  return unless result.exit_status == 0
140
185
 
141
- result.stdout.split("\r\n")[-1].strip
186
+ result.stdout&.match(/UUID=([A-F0-9\-]+)/i)&.captures&.first
142
187
  end
143
188
 
144
189
  def windows_uuid_from_registry
@@ -148,5 +193,63 @@ module Train::Platforms::Detect::Helpers
148
193
 
149
194
  result.stdout.chomp
150
195
  end
196
+
197
+ # Checks if `wmic` is available and not deprecated
198
+ def wmic_available?
199
+ # Return memoized value if already checked
200
+ return @wmic_available unless @wmic_available.nil?
201
+
202
+ # Runs the `wmic /?`` command, which provides help information for the WMIC (Windows Management Instrumentation Command-line) tool.
203
+ # It displays a list of available global switches and aliases, as well as details about their usage.
204
+ # The output also includes information about deprecated status for the 'wmic' tool.
205
+ result = @backend.run_command("wmic /?")
206
+
207
+ # Check if command ran successfully and output does not contain 'wmic is deprecated'
208
+ @wmic_available = result.exit_status == 0 && !(result.stdout.downcase.include?("wmic is deprecated"))
209
+ end
210
+
211
+ def read_cim_os
212
+ cmd = 'powershell -Command "Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber | ConvertTo-Json"'
213
+ res = @backend.run_command(cmd)
214
+ return unless res.exit_status == 0
215
+
216
+ begin
217
+ sys_info = JSON.parse(res.stdout)
218
+ @platform[:release] = sys_info["Version"]
219
+ @platform[:build] = sys_info["BuildNumber"]
220
+ @platform[:name] = sys_info["Caption"]
221
+ @platform[:name] = @platform[:name].gsub("Microsoft", "").strip unless @platform[:name].empty?
222
+ @platform[:arch] = read_cim_cpu
223
+ rescue
224
+ nil
225
+ end
226
+ end
227
+
228
+ def read_cim_cpu
229
+ cmd = 'powershell -Command "(Get-CimInstance Win32_Processor).Architecture"'
230
+ res = @backend.run_command(cmd)
231
+ return unless res.exit_status == 0
232
+
233
+ arch_map = {
234
+ 0 => "i386",
235
+ 1 => "mips",
236
+ 2 => "alpha",
237
+ 3 => "powerpc",
238
+ 5 => "arm",
239
+ 6 => "ia64",
240
+ 9 => "x86_64",
241
+ }
242
+
243
+ arch_map[res.stdout.strip.to_i]
244
+ end
245
+
246
+ def windows_uuid_from_cim
247
+ cmd = 'powershell -Command "(Get-CimInstance -Class Win32_ComputerSystemProduct).UUID"'
248
+ res = @backend.run_command(cmd)
249
+ return unless res.exit_status == 0
250
+
251
+ res.stdout.strip
252
+ end
253
+
151
254
  end
152
255
  end
data/lib/train/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
3
3
 
4
4
  module Train
5
- VERSION = "3.12.7".freeze
5
+ VERSION = "3.13.2".freeze
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: train-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.12.7
4
+ version: 3.13.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef InSpec Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-21 00:00:00.000000000 Z
11
+ date: 2025-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: ffi
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "!="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 1.13.0
33
+ version: 1.16.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "!="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 1.13.0
40
+ version: 1.16.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: json
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -183,14 +183,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
183
183
  requirements:
184
184
  - - ">="
185
185
  - !ruby/object:Gem::Version
186
- version: '2.7'
186
+ version: 3.1.0
187
187
  required_rubygems_version: !ruby/object:Gem::Requirement
188
188
  requirements:
189
189
  - - ">="
190
190
  - !ruby/object:Gem::Version
191
191
  version: '0'
192
192
  requirements: []
193
- rubygems_version: 3.2.3
193
+ rubygems_version: 3.3.27
194
194
  signing_key:
195
195
  specification_version: 4
196
196
  summary: Transport interface to talk to a selected set of backends.