chef 18.1.29-x64-mingw-ucrt → 18.3.0-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/chef-universal-mingw-ucrt.gemspec +2 -2
  3. data/chef.gemspec +1 -2
  4. data/distro/powershell/chef/chef.psm1 +459 -0
  5. data/lib/chef/application/base.rb +2 -0
  6. data/lib/chef/client.rb +2 -2
  7. data/lib/chef/cookbook/synchronizer.rb +20 -2
  8. data/lib/chef/cookbook_version.rb +1 -1
  9. data/lib/chef/http/authenticator.rb +2 -2
  10. data/lib/chef/http/ssl_policies.rb +2 -2
  11. data/lib/chef/mixin/homebrew_user.rb +12 -5
  12. data/lib/chef/mixin/proxified_socket.rb +1 -1
  13. data/lib/chef/monkey_patches/net-http.rb +127 -0
  14. data/lib/chef/node/attribute_collections.rb +8 -0
  15. data/lib/chef/node/immutable_collections.rb +5 -2
  16. data/lib/chef/node/mixin/state_tracking.rb +1 -1
  17. data/lib/chef/platform/query_helpers.rb +4 -2
  18. data/lib/chef/provider/launchd.rb +1 -1
  19. data/lib/chef/provider/mount/linux.rb +1 -1
  20. data/lib/chef/provider/mount/mount.rb +5 -5
  21. data/lib/chef/provider/package/chocolatey.rb +18 -1
  22. data/lib/chef/provider/package/zypper.rb +1 -0
  23. data/lib/chef/provider/remote_file/http.rb +1 -1
  24. data/lib/chef/provider/yum_repository.rb +1 -1
  25. data/lib/chef/resource/apt_repository.rb +25 -6
  26. data/lib/chef/resource/homebrew_cask.rb +6 -7
  27. data/lib/chef/resource/homebrew_package.rb +1 -1
  28. data/lib/chef/resource/homebrew_tap.rb +5 -5
  29. data/lib/chef/resource/launchd.rb +5 -1
  30. data/lib/chef/resource/macos_userdefaults.rb +9 -5
  31. data/lib/chef/resource/selinux_login.rb +129 -0
  32. data/lib/chef/resource/selinux_user.rb +137 -0
  33. data/lib/chef/resource/windows_certificate.rb +1 -1
  34. data/lib/chef/resource/windows_security_policy.rb +2 -2
  35. data/lib/chef/resource.rb +11 -1
  36. data/lib/chef/resources.rb +2 -0
  37. data/lib/chef/version.rb +1 -1
  38. data/lib/chef/win32/security.rb +7 -1
  39. data/spec/data/trusted_certs/intermediate.pem +38 -27
  40. data/spec/data/trusted_certs/opscode.pem +33 -54
  41. data/spec/functional/resource/chocolatey_package_spec.rb +32 -20
  42. data/spec/functional/resource/execute_spec.rb +1 -1
  43. data/spec/functional/resource/macos_userdefaults_spec.rb +4 -4
  44. data/spec/functional/resource/windows_certificate_spec.rb +25 -0
  45. data/spec/unit/client_spec.rb +2 -2
  46. data/spec/unit/mixin/homebrew_user_spec.rb +30 -7
  47. data/spec/unit/node/vivid_mash_spec.rb +42 -0
  48. data/spec/unit/provider/apt_repository_spec.rb +17 -7
  49. data/spec/unit/provider/launchd_spec.rb +2 -2
  50. data/spec/unit/provider/mount/aix_spec.rb +2 -2
  51. data/spec/unit/provider/mount/linux_spec.rb +6 -5
  52. data/spec/unit/provider/mount/mount_spec.rb +8 -8
  53. data/spec/unit/provider/package/chocolatey_spec.rb +19 -3
  54. data/spec/unit/provider/package/rpm_spec.rb +2 -2
  55. data/spec/unit/provider/package/zypper_spec.rb +10 -0
  56. data/spec/unit/provider/remote_file/http_spec.rb +4 -4
  57. data/spec/unit/resource/apt_repository_spec.rb +5 -0
  58. data/spec/unit/resource/macos_user_defaults_spec.rb +4 -4
  59. data/spec/unit/resource/selinux_login_spec.rb +73 -0
  60. data/spec/unit/resource/selinux_user_spec.rb +92 -0
  61. data/spec/unit/resource_spec.rb +86 -0
  62. metadata +22 -17
  63. data/lib/chef/powershell.rb +0 -81
  64. /data/spec/functional/assets/chocolatey_feed/{test-A.1.0.nupkg → test-A.1.0.0.nupkg} +0 -0
  65. /data/spec/functional/assets/chocolatey_feed/{test-A.1.5.nupkg → test-A.1.5.0.nupkg} +0 -0
  66. /data/spec/functional/assets/chocolatey_feed/{test-A.2.0.nupkg → test-A.2.0.0.nupkg} +0 -0
  67. /data/spec/functional/assets/chocolatey_feed/{test-B.1.0.nupkg → test-B.1.0.0.nupkg} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 937611f440a583a253b01525212c4d6214da8f25aee63891ab928b9a3d53de67
4
- data.tar.gz: 7d69aeb9e4df6f13d76b464c08178f9935bc9be01eed136539d5d123315f0fea
3
+ metadata.gz: 034b891e91a35febfaea15c74c7236eba8d503221d7f4aaa8ac8cca985b296e7
4
+ data.tar.gz: 84a49732354b3f8b2c11d2713093c5317b6c6d8e335d1f850458cf9abbf5038d
5
5
  SHA512:
6
- metadata.gz: 2bc789e6367a7ba5277f905d460f7b5390854f62c98f0ba07270e6659e7e70bb92b2d4fc64c8d87e524a972da75657f64022d3f01305558e00f90348f8d6811a
7
- data.tar.gz: dea177b817a903ef86d7b8bacef0aca894ca778c26615339a041186276da976eb23abede8c47c1a3b9ee459a392961ff75fbc8532475186a1d21d77a1a528fde
6
+ metadata.gz: 781e2665ae7cc103a9140bf5f024dca9222dae1aa00d7119bab296007409e77a6854102e6367caa48b65ad0e1546e349453b57865ace723216259f9acdb48d6f
7
+ data.tar.gz: ffa726a2dd3f8f9228b08dc8741d92ae96f4b2703484dcd4ab9c72ba8eefdef9ad89230d15d669dbf2eeda017d0e2842241d8bb1a7e080d754906d01b00ebbdf
@@ -15,9 +15,9 @@ gemspec.add_dependency "wmi-lite", "~> 1.0"
15
15
  gemspec.add_dependency "win32-taskscheduler", "~> 2.0"
16
16
  gemspec.add_dependency "iso8601", ">= 0.12.1", "< 0.14" # validate 0.14 when it comes out
17
17
  gemspec.add_dependency "win32-certstore", "~> 0.6.15" # 0.5+ required for specifying user vs. system store
18
- gemspec.add_dependency "chef-powershell", "~> 1.0.12" # The guts of the powershell_exec code have been moved to its own gem, chef-powershell. It's part of the chef-powershell-shim repo.
18
+ gemspec.add_dependency "chef-powershell", "~> 18.1.0" # The guts of the powershell_exec code have been moved to its own gem, chef-powershell. It's part of the chef-powershell-shim repo.
19
19
 
20
20
  gemspec.extensions << "ext/win32-eventlog/Rakefile"
21
21
  gemspec.files += Dir.glob("{distro,ext}/**/*")
22
22
 
23
- gemspec
23
+ gemspec
data/chef.gemspec CHANGED
@@ -49,8 +49,7 @@ Gem::Specification.new do |s|
49
49
  s.add_dependency "net-ftp" # remote_file resource
50
50
  s.add_dependency "erubis", "~> 2.7" # template resource / cookbook syntax check
51
51
  s.add_dependency "diff-lcs", ">= 1.2.4", "!= 1.4.0", "< 1.6.0" # 1.4 breaks output. Used in lib/chef/util/diff
52
- # s.add_dependency "ffi-libarchive", "~> 1.0", ">= 1.0.3" # archive_file resource
53
- s.add_dependency "ffi-libarchive", "~> 1.1", ">= 1.1.3"
52
+ s.add_dependency "ffi-libarchive", "~> 1.0", ">= 1.0.3" # archive_file resource
54
53
  s.add_dependency "chef-zero", ">= 14.0.11"
55
54
  s.add_dependency "chef-vault" # chef-vault resources and helpers
56
55
 
@@ -0,0 +1,459 @@
1
+ 
2
+ function Load-Win32Bindings {
3
+ Add-Type -TypeDefinition @"
4
+ using System;
5
+ using System.Diagnostics;
6
+ using System.Runtime.InteropServices;
7
+
8
+ namespace Chef
9
+ {
10
+
11
+ [StructLayout(LayoutKind.Sequential)]
12
+ public struct PROCESS_INFORMATION
13
+ {
14
+ public IntPtr hProcess;
15
+ public IntPtr hThread;
16
+ public uint dwProcessId;
17
+ public uint dwThreadId;
18
+ }
19
+
20
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
21
+ public struct STARTUPINFO
22
+ {
23
+ public uint cb;
24
+ public string lpReserved;
25
+ public string lpDesktop;
26
+ public string lpTitle;
27
+ public uint dwX;
28
+ public uint dwY;
29
+ public uint dwXSize;
30
+ public uint dwYSize;
31
+ public uint dwXCountChars;
32
+ public uint dwYCountChars;
33
+ public uint dwFillAttribute;
34
+ public STARTF dwFlags;
35
+ public ShowWindow wShowWindow;
36
+ public short cbReserved2;
37
+ public IntPtr lpReserved2;
38
+ public IntPtr hStdInput;
39
+ public IntPtr hStdOutput;
40
+ public IntPtr hStdError;
41
+ }
42
+
43
+ [StructLayout(LayoutKind.Sequential)]
44
+ public struct SECURITY_ATTRIBUTES
45
+ {
46
+ public int length;
47
+ public IntPtr lpSecurityDescriptor;
48
+ public bool bInheritHandle;
49
+ }
50
+
51
+ [Flags]
52
+ public enum CreationFlags : int
53
+ {
54
+ NONE = 0,
55
+ DEBUG_PROCESS = 0x00000001,
56
+ DEBUG_ONLY_THIS_PROCESS = 0x00000002,
57
+ CREATE_SUSPENDED = 0x00000004,
58
+ DETACHED_PROCESS = 0x00000008,
59
+ CREATE_NEW_CONSOLE = 0x00000010,
60
+ CREATE_NEW_PROCESS_GROUP = 0x00000200,
61
+ CREATE_UNICODE_ENVIRONMENT = 0x00000400,
62
+ CREATE_SEPARATE_WOW_VDM = 0x00000800,
63
+ CREATE_SHARED_WOW_VDM = 0x00001000,
64
+ CREATE_PROTECTED_PROCESS = 0x00040000,
65
+ EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
66
+ CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
67
+ CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
68
+ CREATE_DEFAULT_ERROR_MODE = 0x04000000,
69
+ CREATE_NO_WINDOW = 0x08000000,
70
+ }
71
+
72
+ [Flags]
73
+ public enum STARTF : uint
74
+ {
75
+ STARTF_USESHOWWINDOW = 0x00000001,
76
+ STARTF_USESIZE = 0x00000002,
77
+ STARTF_USEPOSITION = 0x00000004,
78
+ STARTF_USECOUNTCHARS = 0x00000008,
79
+ STARTF_USEFILLATTRIBUTE = 0x00000010,
80
+ STARTF_RUNFULLSCREEN = 0x00000020, // ignored for non-x86 platforms
81
+ STARTF_FORCEONFEEDBACK = 0x00000040,
82
+ STARTF_FORCEOFFFEEDBACK = 0x00000080,
83
+ STARTF_USESTDHANDLES = 0x00000100,
84
+ }
85
+
86
+ public enum ShowWindow : short
87
+ {
88
+ SW_HIDE = 0,
89
+ SW_SHOWNORMAL = 1,
90
+ SW_NORMAL = 1,
91
+ SW_SHOWMINIMIZED = 2,
92
+ SW_SHOWMAXIMIZED = 3,
93
+ SW_MAXIMIZE = 3,
94
+ SW_SHOWNOACTIVATE = 4,
95
+ SW_SHOW = 5,
96
+ SW_MINIMIZE = 6,
97
+ SW_SHOWMINNOACTIVE = 7,
98
+ SW_SHOWNA = 8,
99
+ SW_RESTORE = 9,
100
+ SW_SHOWDEFAULT = 10,
101
+ SW_FORCEMINIMIZE = 11,
102
+ SW_MAX = 11
103
+ }
104
+
105
+ public enum StandardHandle : int
106
+ {
107
+ Input = -10,
108
+ Output = -11,
109
+ Error = -12
110
+ }
111
+
112
+ public enum HandleFlags : int
113
+ {
114
+ HANDLE_FLAG_INHERIT = 0x00000001,
115
+ HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002
116
+ }
117
+
118
+ public static class Kernel32
119
+ {
120
+ [DllImport("kernel32.dll", SetLastError=true)]
121
+ [return: MarshalAs(UnmanagedType.Bool)]
122
+ public static extern bool CreateProcess(
123
+ string lpApplicationName,
124
+ string lpCommandLine,
125
+ ref SECURITY_ATTRIBUTES lpProcessAttributes,
126
+ ref SECURITY_ATTRIBUTES lpThreadAttributes,
127
+ [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles,
128
+ CreationFlags dwCreationFlags,
129
+ IntPtr lpEnvironment,
130
+ string lpCurrentDirectory,
131
+ ref STARTUPINFO lpStartupInfo,
132
+ out PROCESS_INFORMATION lpProcessInformation);
133
+
134
+ [DllImport("kernel32.dll", SetLastError=true)]
135
+ public static extern IntPtr GetStdHandle(
136
+ StandardHandle nStdHandle);
137
+
138
+ [DllImport("kernel32.dll")]
139
+ public static extern bool SetHandleInformation(
140
+ IntPtr hObject,
141
+ int dwMask,
142
+ uint dwFlags);
143
+
144
+ [DllImport("kernel32", SetLastError=true)]
145
+ [return: MarshalAs(UnmanagedType.Bool)]
146
+ public static extern bool CloseHandle(
147
+ IntPtr hObject);
148
+
149
+ [DllImport("kernel32", SetLastError=true)]
150
+ [return: MarshalAs(UnmanagedType.Bool)]
151
+ public static extern bool GetExitCodeProcess(
152
+ IntPtr hProcess,
153
+ out int lpExitCode);
154
+
155
+ [DllImport("kernel32.dll", SetLastError = true)]
156
+ public static extern bool CreatePipe(
157
+ out IntPtr phReadPipe,
158
+ out IntPtr phWritePipe,
159
+ IntPtr lpPipeAttributes,
160
+ uint nSize);
161
+
162
+ [DllImport("kernel32.dll", SetLastError = true)]
163
+ public static extern bool ReadFile(
164
+ IntPtr hFile,
165
+ [Out] byte[] lpBuffer,
166
+ uint nNumberOfBytesToRead,
167
+ ref int lpNumberOfBytesRead,
168
+ IntPtr lpOverlapped);
169
+
170
+ [DllImport("kernel32.dll", SetLastError = true)]
171
+ public static extern bool PeekNamedPipe(
172
+ IntPtr handle,
173
+ byte[] buffer,
174
+ uint nBufferSize,
175
+ ref uint bytesRead,
176
+ ref uint bytesAvail,
177
+ ref uint BytesLeftThisMessage);
178
+
179
+ public const int STILL_ACTIVE = 259;
180
+ }
181
+ }
182
+ "@
183
+ }
184
+
185
+ function Run-ExecutableAndWait($AppPath, $ArgumentString) {
186
+ # Use the Win32 API to create a new process and wait for it to terminate.
187
+ $null = Load-Win32Bindings
188
+
189
+ $si = New-Object Chef.STARTUPINFO
190
+ $pi = New-Object Chef.PROCESS_INFORMATION
191
+
192
+ $pSec = New-Object Chef.SECURITY_ATTRIBUTES
193
+ $pSec.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($pSec)
194
+ $pSec.bInheritHandle = $true
195
+ $tSec = New-Object Chef.SECURITY_ATTRIBUTES
196
+ $tSec.Length = [System.Runtime.InteropServices.Marshal]::SizeOf($tSec)
197
+ $tSec.bInheritHandle = $true
198
+
199
+ # Create pipe for process stdout
200
+ $ptr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([System.Runtime.InteropServices.Marshal]::SizeOf($si))
201
+ [System.Runtime.InteropServices.Marshal]::StructureToPtr($pSec, $ptr, $true)
202
+ $hReadOut = [IntPtr]::Zero
203
+ $hWriteOut = [IntPtr]::Zero
204
+ $success = [Chef.Kernel32]::CreatePipe([ref] $hReadOut, [ref] $hWriteOut, $ptr, 0)
205
+ if (-Not $success) {
206
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
207
+ throw "Unable to create output pipe. Error code $reason."
208
+ }
209
+ $success = [Chef.Kernel32]::SetHandleInformation($hReadOut, [Chef.HandleFlags]::HANDLE_FLAG_INHERIT, 0)
210
+ if (-Not $success) {
211
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
212
+ throw "Unable to set output pipe handle information. Error code $reason."
213
+ }
214
+
215
+ $si.cb = [System.Runtime.InteropServices.Marshal]::SizeOf($si)
216
+ $si.wShowWindow = [Chef.ShowWindow]::SW_SHOW
217
+ $si.dwFlags = [Chef.STARTF]::STARTF_USESTDHANDLES
218
+ $si.hStdOutput = $hWriteOut
219
+ $si.hStdError = $hWriteOut
220
+ $si.hStdInput = [Chef.Kernel32]::GetStdHandle([Chef.StandardHandle]::Input)
221
+
222
+ $success = [Chef.Kernel32]::CreateProcess(
223
+ $AppPath,
224
+ $ArgumentString,
225
+ [ref] $pSec,
226
+ [ref] $tSec,
227
+ $true,
228
+ [Chef.CreationFlags]::NONE,
229
+ [IntPtr]::Zero,
230
+ $pwd,
231
+ [ref] $si,
232
+ [ref] $pi
233
+ )
234
+ if (-Not $success) {
235
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
236
+ throw "Unable to create process [$ArgumentString]. Error code $reason."
237
+ }
238
+
239
+ $buffer = New-Object byte[] 1024
240
+
241
+ # Initialize reference variables
242
+ $bytesRead = 0
243
+ $bytesAvailable = 0
244
+ $bytesLeftThisMsg = 0
245
+ $global:LASTEXITCODE = [Chef.Kernel32]::STILL_ACTIVE
246
+
247
+ $isActive = $true
248
+ while ($isActive) {
249
+ $success = [Chef.Kernel32]::GetExitCodeProcess($pi.hProcess, [ref] $global:LASTEXITCODE)
250
+ if (-Not $success) {
251
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
252
+ throw "Process exit code unavailable. Error code $reason."
253
+ }
254
+
255
+ $success = [Chef.Kernel32]::PeekNamedPipe(
256
+ $hReadOut,
257
+ $null,
258
+ $buffer.Length,
259
+ [ref] $bytesRead,
260
+ [ref] $bytesAvailable,
261
+ [ref] $bytesLeftThisMsg
262
+ )
263
+ if (-Not $success) {
264
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
265
+ throw "Output pipe unavailable for peeking. Error code $reason."
266
+ }
267
+
268
+ if ($bytesRead -gt 0) {
269
+ while ([Chef.Kernel32]::ReadFile($hReadOut, $buffer, $buffer.Length, [ref] $bytesRead, 0)) {
270
+ $output = [Text.Encoding]::UTF8.GetString($buffer, 0, $bytesRead)
271
+ if ($output) {
272
+ $output
273
+ }
274
+ if ($bytesRead -lt $buffer.Length) {
275
+ # Partial buffer indicating the end of stream, break out of ReadFile loop
276
+ # ReadFile will block until:
277
+ # The number of bytes requested is read.
278
+ # A write operation completes on the write end of the pipe.
279
+ # An asynchronous handle is being used and the read is occurring asynchronously.
280
+ # An error occurs.
281
+ break
282
+ }
283
+ }
284
+ } else {
285
+ # For some reason, you can't read from the read-end of the read-pipe before the write end has started
286
+ # to write. Otherwise the process just blocks forever and never returns from the read. So we peek
287
+ # at the pipe until there is something. But don't peek too eagerly. This is stupid stupid stupid.
288
+ # There must be a way to do this without having to peek at a pipe first but I have not found it.
289
+ #
290
+ # Note to the future intrepid soul who wants to fix this:
291
+ # 0) This is related to unreasonable CPU usage by the wrapper PS script on a 1 VCPU VM (either Hyper-V
292
+ # or VirtualBox) running a consumer Windows SKU (Windows 10 for example...). Test it there.
293
+ # 1) Maybe this entire script is unnecessary and the bugs mentioned below have been fixed or don't need
294
+ # to be supported.
295
+ # 2) The server and consumer windows schedulers have different defaults. I had a hard time reproducing
296
+ # any issue on a win 2008 on win 2012 server default setup. See the "foreground application scheduler
297
+ # priority" setting to see if it's relevant.
298
+ # 3) This entire endeavor is silly anyway - why are we reimplementing process forking all over? Maybe try
299
+ # to get the folks above to accept patches instead of extending this crazy script.
300
+ Start-Sleep -s 1
301
+ # Start-Sleep -m 100
302
+ }
303
+
304
+ if ($global:LASTEXITCODE -ne [Chef.Kernel32]::STILL_ACTIVE) {
305
+ $isActive = $false
306
+ }
307
+ }
308
+
309
+ # Cleanup handles
310
+ $success = [Chef.Kernel32]::CloseHandle($pi.hProcess)
311
+ if (-Not $success) {
312
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
313
+ throw "Unable to release process handle. Error code $reason."
314
+ }
315
+ $success = [Chef.Kernel32]::CloseHandle($pi.hThread)
316
+ if (-Not $success) {
317
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
318
+ throw "Unable to release thread handle. Error code $reason."
319
+ }
320
+ $success = [Chef.Kernel32]::CloseHandle($hWriteOut)
321
+ if (-Not $success) {
322
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
323
+ throw "Unable to release output write handle. Error code $reason."
324
+ }
325
+ $success = [Chef.Kernel32]::CloseHandle($hReadOut)
326
+ if (-Not $success) {
327
+ $reason = [System.Runtime.InteropServices.Marshal]::GetLastWin32Error()
328
+ throw "Unable to release output read handle. Error code $reason."
329
+ }
330
+ [System.Runtime.InteropServices.Marshal]::FreeHGlobal($ptr)
331
+ }
332
+
333
+ function Get-ScriptDirectory {
334
+ if (!$PSScriptRoot) {
335
+ $Invocation = (Get-Variable MyInvocation -Scope 1).Value
336
+ $PSScriptRoot = Split-Path $Invocation.MyCommand.Path
337
+ }
338
+ $PSScriptRoot
339
+ }
340
+
341
+ function Run-RubyCommand($command, $argList) {
342
+ # This method exists to take the given list of arguments and get it past ruby's command-line
343
+ # interpreter unscathed and untampered. See https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L1582
344
+ # for a list of transformations that ruby attempts to perform with your command-line arguments
345
+ # before passing it onto a script. The most important task is to defeat the globbing
346
+ # and wild-card expansion that ruby performs. Note that ruby does not use MSVCRT's argc/argv
347
+ # and deliberately reparses the raw command-line instead.
348
+ #
349
+ # To stop ruby from interpreting command-line arguments as globs, they need to be enclosed in '
350
+ # Ruby doesn't allow any escape characters inside '. This unfortunately prevents us from sending
351
+ # any strings which themselves contain '. Ruby does allow multi-fragment arguments though.
352
+ # "foo bar"'baz qux'123"foo" is interpreted as 1 argument because there are no un-escaped
353
+ # whitespace there. The argument would be interpreted as the string "foo barbaz qux123foo".
354
+ # This lets us escape ' characters by exiting the ' quoted string, injecting a "'" fragment and
355
+ # then resuming the ' quoted string again.
356
+ #
357
+ # In the process of defeating ruby, one must also defeat the helpfulness of powershell.
358
+ # When arguments come into this method, the standard PS rules for interpreting cmdlet arguments
359
+ # apply. When using & (call operator) and providing an array of arguments, powershell (verified
360
+ # on PS 4.0 on Windows Server 2012R2) will not evaluate them but (contrary to documentation),
361
+ # it will still marginally interpret them. The behavior of PS 5.0 seems to be different but
362
+ # ignore that for now. If any of the provided arguments has a space in it, powershell checks
363
+ # the first and last character to ensure that they are " characters (and that's all it checks).
364
+ # If they are not, it will blindly surround that argument with " characters. It won't do this
365
+ # operation if no space is present, even if other special characters are present. If it notices
366
+ # leading and trailing " characters, it won't actually check to see if there are other "
367
+ # characters in the string. Since PS 5.0 changes this behavior, we could consider using the --%
368
+ # "stop screwing up my arguments" operator, which is available since PS 3.0. When encountered
369
+ # --% indicates that the rest of line is to be sent literally... except if the parser encounters
370
+ # %FOO% cmd style environment variables. Because reasons. And there is no way to escape the
371
+ # % character in *any* waym shape or form.
372
+ # https://connect.microsoft.com/PowerShell/feedback/details/376207/executing-commands-which-require-quotes-and-variables-is-practically-impossible
373
+ #
374
+ # In case you think that you're either reading this incorrectly or that I'm full of shit, here
375
+ # are some examples. These use EchoArgs.exe from the PowerShell Community Extensions package.
376
+ # I have not included the argument parsing output from EchoArgs.exe to prevent confusing you with
377
+ # more details about MSVCRT's parsing algorithm.
378
+ #
379
+ # $x = "foo '' bar `"baz`""
380
+ # & EchoArgs @($x, $x)
381
+ # Command line:
382
+ # "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" "foo '' bar "baz"" "foo '' bar "baz""
383
+ #
384
+ # $x = "abc'123'nospace`"lol`"!!!"
385
+ # & EchoArgs @($x, $x)
386
+ # Command line:
387
+ # "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" abc'123'nospace"lol"!!! abc'123'nospace"lol"!!!
388
+ #
389
+ # $x = "`"`"Look ma! Tonnes of spaces! 'foo' 'bar'`"`""
390
+ # & EchoArgs @($x, $x)
391
+ # Command line:
392
+ # "C:\Program Files (x86)\PowerShell Community Extensions\Pscx3\Pscx\Apps\EchoArgs.exe" ""Look ma! Tonnes of spaces! 'foo' 'bar'"" ""Look ma! Tonnes of spaces! 'foo' 'bar'""
393
+ #
394
+ # Given all this, we can now device a strategy to work around all these immensely helpful, well
395
+ # documented and useful tools by looking at each incoming argument, escaping any ' characters
396
+ # with a '"'"' sequence, surrounding each argument with ' & joining them with a space separating
397
+ # them.
398
+ # There is another bug (https://bugs.ruby-lang.org/issues/11142) that causes ruby to mangle any
399
+ # "" two-character double quote sequence but since we always emit our strings inside ' except for
400
+ # ' characters, this should be ok. Just remember that an argument '' should get translated to
401
+ # ''"'"''"'"'' on the command line. If those intervening empty ''s are not present, the presence
402
+ # of "" will cause ruby to mangle that argument.
403
+ $transformedList = $argList | foreach { "'" + ( $_ -replace "'","'`"'`"'" ) + "'" }
404
+ $fortifiedArgString = $transformedList -join ' '
405
+
406
+ # Use the correct embedded ruby path. We'll be deployed at a path that looks like
407
+ # [C:\opscode or some other prefix]\chef\modules\chef
408
+ $ruby = Join-Path (Get-ScriptDirectory) "..\..\embedded\bin\ruby.exe"
409
+ $commandPath = Join-Path (Get-ScriptDirectory) "..\..\bin\$command"
410
+
411
+ Run-ExecutableAndWait $ruby """$ruby"" '$commandPath' $fortifiedArgString"
412
+ }
413
+
414
+
415
+ function chef-apply {
416
+ Run-RubyCommand 'chef-apply' $args
417
+ }
418
+
419
+ function chef-client {
420
+ Run-RubyCommand 'chef-client' $args
421
+ }
422
+
423
+ function chef-service-manager {
424
+ Run-RubyCommand 'chef-service-manager' $args
425
+ }
426
+
427
+ function chef-shell {
428
+ Run-RubyCommand 'chef-shell' $args
429
+ }
430
+
431
+ function chef-solo {
432
+ Run-RubyCommand 'chef-solo' $args
433
+ }
434
+
435
+ function chef-windows-service {
436
+ Run-RubyCommand 'chef-windows-service' $args
437
+ }
438
+
439
+ function knife {
440
+ Run-RubyCommand 'knife' $args
441
+ }
442
+
443
+ Export-ModuleMember -function chef-apply
444
+ Export-ModuleMember -function chef-client
445
+ Export-ModuleMember -function chef-service-manager
446
+ Export-ModuleMember -function chef-shell
447
+ Export-ModuleMember -function chef-solo
448
+ Export-ModuleMember -function chef-windows-service
449
+ Export-ModuleMember -function knife
450
+
451
+ # To debug this module, uncomment the line below
452
+ # Export-ModuleMember -function Run-RubyCommand
453
+
454
+ # Then run the following to reload the module. Use puts_argv as a helpful debug executable.
455
+ # Remove-Module chef
456
+ # Import-Module chef
457
+ # "puts ARGV" | Out-File C:\opscode\chef\bin\puts_args -Encoding ASCII
458
+ # Copy-Item C:\opscode\chef\bin\ohai.bat C:\opscode\chef\bin\puts_args.bat
459
+ # Run-RubyCommand puts_args 'Here' "are" some '"very interesting"' 'arguments[to]' "`"try out`""
@@ -24,6 +24,8 @@ require "chef-utils/dist" unless defined?(ChefUtils::Dist)
24
24
  require_relative "../daemon"
25
25
  require "chef-config/mixin/dot_d"
26
26
  require "license_acceptance/cli_flags/mixlib_cli"
27
+ require "chef/monkey_patches/net-http"
28
+
27
29
  module Mixlib
28
30
  autoload :Archive, "mixlib/archive"
29
31
  end
data/lib/chef/client.rb CHANGED
@@ -663,7 +663,7 @@ class Chef
663
663
  logger.trace("New client keys created in the Certificate Store - skipping registration")
664
664
  end
665
665
  events.skipping_registration(client_name, config)
666
- elsif File.exists?(config[:client_key])
666
+ elsif File.exist?(config[:client_key])
667
667
  events.skipping_registration(client_name, config)
668
668
  logger.trace("Client key #{config[:client_key]} is present - skipping registration")
669
669
  else
@@ -1069,7 +1069,7 @@ class Chef
1069
1069
  end
1070
1070
 
1071
1071
  def empty_directory?(path)
1072
- !File.exists?(path) || (Dir.entries(path).size <= 2)
1072
+ !File.exist?(path) || (Dir.entries(path).size <= 2)
1073
1073
  end
1074
1074
 
1075
1075
  def is_last_element?(index, object)
@@ -18,6 +18,7 @@ require_relative "../util/threaded_job_queue"
18
18
  require_relative "../server_api"
19
19
  require "singleton" unless defined?(Singleton)
20
20
  require "chef-utils/dist" unless defined?(ChefUtils::Dist)
21
+ require "set" unless defined?(Set)
21
22
 
22
23
  class Chef
23
24
 
@@ -219,14 +220,31 @@ class Chef
219
220
 
220
221
  # remove deleted files in cookbooks that are being used on the node
221
222
  def remove_deleted_files
223
+ cache_file_hash = {}
224
+ @cookbooks_by_name.each_key do |k|
225
+ cache_file_hash[k] = {}
226
+ end
227
+
228
+ # First populate files from cache
222
229
  cache.find(File.join(%w{cookbooks ** {*,.*}})).each do |cache_file|
223
230
  md = cache_file.match(%r{^cookbooks/([^/]+)/([^/]+)/(.*)})
224
231
  next unless md
225
232
 
226
- ( cookbook_name, segment, file ) = md[1..3]
233
+ (cookbook_name, segment, file) = md[1..3]
227
234
  if have_cookbook?(cookbook_name)
235
+ cache_file_hash[cookbook_name][segment] ||= {}
236
+ cache_file_hash[cookbook_name][segment]["#{segment}/#{file}"] = cache_file
237
+ end
238
+ end
239
+ # Determine which files don't match manifest
240
+ @cookbooks_by_name.each_key do |cookbook_name|
241
+ cache_file_hash[cookbook_name].each_key do |segment|
228
242
  manifest_segment = cookbook_segment(cookbook_name, segment)
229
- if manifest_segment.select { |manifest_record| manifest_record["path"] == "#{segment}/#{file}" }.empty?
243
+ manifest_record_paths = manifest_segment.map { |manifest_record| manifest_record["path"] }.to_set
244
+ to_be_removed = cache_file_hash[cookbook_name][segment].keys.to_set - manifest_record_paths
245
+ to_be_removed.each do |path|
246
+ cache_file = cache_file_hash[cookbook_name][segment][path]
247
+
230
248
  Chef::Log.info("Removing #{cache_file} from the cache; its is no longer in the cookbook manifest.")
231
249
  cache.delete(cache_file)
232
250
  @events.removed_cookbook_file(cache_file)
@@ -474,7 +474,7 @@ class Chef
474
474
  end
475
475
 
476
476
  def reload_metadata!
477
- if File.exists?(metadata_json_file)
477
+ if File.exist?(metadata_json_file)
478
478
  metadata.from_json(IO.read(metadata_json_file))
479
479
  end
480
480
  end
@@ -124,11 +124,11 @@ class Chef
124
124
  end
125
125
 
126
126
  def self.get_cert_user
127
- Chef::Config[:auth_key_registry_type] == "user" ? store = "CurrentUser" : store = "LocalMachine"
127
+ Chef::Config[:auth_key_registry_type] == "user" ? "CurrentUser" : "LocalMachine"
128
128
  end
129
129
 
130
130
  def self.get_registry_user
131
- Chef::Config[:auth_key_registry_type] == "user" ? store = "HKEY_CURRENT_USER" : store = "HKEY_LOCAL_MACHINE"
131
+ Chef::Config[:auth_key_registry_type] == "user" ? "HKEY_CURRENT_USER" : "HKEY_LOCAL_MACHINE"
132
132
  end
133
133
 
134
134
  def self.check_certstore_for_key(client_name)
@@ -103,10 +103,10 @@ class Chef
103
103
  unless config[:ssl_client_cert] && config[:ssl_client_key]
104
104
  raise Chef::Exceptions::ConfigurationError, "You must configure ssl_client_cert and ssl_client_key together"
105
105
  end
106
- unless ::File.exists?(config[:ssl_client_cert])
106
+ unless ::File.exist?(config[:ssl_client_cert])
107
107
  raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_cert #{config[:ssl_client_cert]} does not exist"
108
108
  end
109
- unless ::File.exists?(config[:ssl_client_key])
109
+ unless ::File.exist?(config[:ssl_client_key])
110
110
  raise Chef::Exceptions::ConfigurationError, "The configured ssl_client_key #{config[:ssl_client_key]} does not exist"
111
111
  end
112
112
 
@@ -57,18 +57,25 @@ class Chef
57
57
  @homebrew_owner_username
58
58
  end
59
59
 
60
+ def homebrew_bin_path(brew_bin_path = nil)
61
+ if brew_bin_path && ::File.exist?(brew_bin_path)
62
+ brew_bin_path
63
+ else
64
+ brew_bin_path = [which("brew"), "/opt/homebrew/bin/brew", "/usr/local/bin/brew", "/home/linuxbrew/.linuxbrew/bin/brew"].uniq.select { |x| ::File.exist?(x) && ::File.executable?(x) }.first
65
+ brew_bin_path || nil
66
+ end
67
+ end
68
+
60
69
  private
61
70
 
62
71
  def calculate_owner
63
- default_brew_path = "/usr/local/bin/brew"
64
- if ::File.exist?(default_brew_path)
72
+ brew_path = homebrew_bin_path
73
+ if brew_path
65
74
  # By default, this follows symlinks which is what we want
66
- owner = ::File.stat(default_brew_path).uid
67
- elsif (brew_path = shell_out("which brew").stdout.strip) && !brew_path.empty?
68
75
  owner = ::File.stat(brew_path).uid
69
76
  else
70
77
  raise Chef::Exceptions::CannotDetermineHomebrewOwner,
71
- 'Could not find the "brew" executable in /usr/local/bin or anywhere on the path.'
78
+ 'Could not find the "brew" executable anywhere on the path.'
72
79
  end
73
80
 
74
81
  Chef::Log.debug "Found Homebrew owner #{Etc.getpwuid(owner).name}; executing `brew` commands as them"
@@ -15,7 +15,7 @@
15
15
  # limitations under the License.
16
16
  #
17
17
 
18
- require "proxifier2"
18
+ require "proxifier"
19
19
  require "chef-config/mixin/fuzzy_hostname_matcher"
20
20
 
21
21
  class Chef