chef 18.2.7 → 18.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/chef-universal-mingw-ucrt.gemspec +1 -1
- data/chef.gemspec +3 -3
- data/lib/chef/application/base.rb +2 -0
- data/lib/chef/chef_fs/file_pattern.rb +1 -1
- data/lib/chef/chef_fs/path_utils.rb +7 -9
- data/lib/chef/client.rb +2 -2
- data/lib/chef/cookbook/synchronizer.rb +19 -2
- data/lib/chef/cookbook_version.rb +1 -1
- data/lib/chef/delayed_evaluator.rb +4 -0
- data/lib/chef/file_access_control/windows.rb +4 -1
- data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +2 -0
- data/lib/chef/http/ssl_policies.rb +2 -2
- data/lib/chef/mixin/homebrew_user.rb +15 -5
- data/lib/chef/monkey_patches/net-http.rb +127 -0
- data/lib/chef/node/attribute_collections.rb +10 -1
- data/lib/chef/node/immutable_collections.rb +7 -3
- data/lib/chef/node/mixin/state_tracking.rb +1 -1
- data/lib/chef/node/mixin/state_tracking_array.rb +41 -0
- data/lib/chef/node.rb +22 -0
- data/lib/chef/provider/launchd.rb +1 -1
- data/lib/chef/provider/mount/linux.rb +1 -1
- data/lib/chef/provider/mount/mount.rb +5 -5
- data/lib/chef/provider/package/apt.rb +11 -2
- data/lib/chef/provider/package/chocolatey.rb +239 -18
- data/lib/chef/provider/package/zypper.rb +6 -0
- data/lib/chef/provider/powershell_script.rb +96 -6
- data/lib/chef/provider/remote_file/http.rb +1 -1
- data/lib/chef/provider/service/systemd.rb +23 -8
- data/lib/chef/provider/service/windows.rb +1 -0
- data/lib/chef/provider/service.rb +14 -0
- data/lib/chef/provider/user.rb +5 -1
- data/lib/chef/provider/yum_repository.rb +1 -1
- data/lib/chef/recipe.rb +3 -11
- data/lib/chef/resource/_rest_resource.rb +1 -1
- data/lib/chef/resource/apt_package.rb +19 -0
- data/lib/chef/resource/apt_repository.rb +26 -6
- data/lib/chef/resource/chef_client_systemd_timer.rb +1 -1
- data/lib/chef/resource/chocolatey_installer.rb +207 -0
- data/lib/chef/resource/chocolatey_package.rb +8 -0
- data/lib/chef/resource/homebrew_cask.rb +6 -7
- data/lib/chef/resource/homebrew_package.rb +1 -1
- data/lib/chef/resource/homebrew_tap.rb +5 -5
- data/lib/chef/resource/launchd.rb +5 -1
- data/lib/chef/resource/locale.rb +5 -2
- data/lib/chef/resource/macos_pkg.rb +111 -0
- data/lib/chef/resource/powershell_script.rb +5 -1
- data/lib/chef/resource/service.rb +3 -0
- data/lib/chef/resource/sudo.rb +37 -2
- data/lib/chef/resource/support/ulimit.erb +40 -0
- data/lib/chef/resource/user_ulimit.rb +38 -0
- data/lib/chef/resource/windows_certificate.rb +1 -1
- data/lib/chef/resource/windows_security_policy.rb +2 -2
- data/lib/chef/resource.rb +11 -1
- data/lib/chef/resources.rb +2 -0
- data/lib/chef/version.rb +1 -1
- data/lib/chef/win32/security.rb +7 -1
- data/spec/data/trusted_certs/example.crt +29 -20
- data/spec/data/trusted_certs/example_no_cn.crt +30 -34
- data/spec/functional/resource/chocolatey_package_spec.rb +32 -20
- data/spec/functional/resource/execute_spec.rb +1 -1
- data/spec/functional/resource/windows_certificate_spec.rb +25 -0
- data/spec/functional/resource/zypper_package_spec.rb +10 -0
- data/spec/unit/client_spec.rb +2 -2
- data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +1 -1
- data/spec/unit/delayed_evaluator_spec.rb +35 -0
- data/spec/unit/mixin/homebrew_user_spec.rb +30 -7
- data/spec/unit/node/vivid_mash_spec.rb +42 -0
- data/spec/unit/node_spec.rb +6 -0
- data/spec/unit/provider/apt_repository_spec.rb +17 -7
- data/spec/unit/provider/launchd_spec.rb +2 -2
- data/spec/unit/provider/mount/aix_spec.rb +2 -2
- data/spec/unit/provider/mount/linux_spec.rb +6 -5
- data/spec/unit/provider/mount/mount_spec.rb +8 -8
- data/spec/unit/provider/package/apt_spec.rb +18 -13
- data/spec/unit/provider/package/chocolatey_spec.rb +53 -9
- data/spec/unit/provider/package/rpm_spec.rb +2 -2
- data/spec/unit/provider/package/zypper_spec.rb +10 -0
- data/spec/unit/provider/powershell_script_spec.rb +100 -4
- data/spec/unit/provider/remote_file/http_spec.rb +4 -4
- data/spec/unit/provider/service/systemd_service_spec.rb +1 -0
- data/spec/unit/provider/user/linux_spec.rb +10 -0
- data/spec/unit/resource/apt_repository_spec.rb +5 -0
- data/spec/unit/resource/chef_client_systemd_timer_spec.rb +1 -1
- data/spec/unit/resource/chocolatey_installer_spec.rb +151 -0
- data/spec/unit/resource/macos_pkg_spec.rb +38 -0
- data/spec/unit/resource/powershell_script_spec.rb +2 -2
- data/spec/unit/resource_spec.rb +86 -0
- metadata +29 -16
- /data/spec/functional/assets/chocolatey_feed/{test-A.1.0.nupkg → test-A.1.0.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-A.1.5.nupkg → test-A.1.5.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-A.2.0.nupkg → test-A.2.0.0.nupkg} +0 -0
- /data/spec/functional/assets/chocolatey_feed/{test-B.1.0.nupkg → test-B.1.0.0.nupkg} +0 -0
@@ -351,7 +351,7 @@ action_class do
|
|
351
351
|
Chef.run_context.transport.connection
|
352
352
|
end
|
353
353
|
|
354
|
-
# Remove all empty keys (
|
354
|
+
# Remove all empty keys (recursively) from Hash.
|
355
355
|
# @see https://stackoverflow.com/questions/56457020/#answer-56458673
|
356
356
|
def deep_compact!(hsh)
|
357
357
|
raise TypeError unless hsh.is_a? Hash
|
@@ -52,6 +52,21 @@ class Chef
|
|
52
52
|
options '--no-install-recommends'
|
53
53
|
end
|
54
54
|
```
|
55
|
+
|
56
|
+
**Prevent the apt_package resource from installing packages with pattern matching names**:
|
57
|
+
|
58
|
+
By default, the apt_package resource will install the named package.
|
59
|
+
If it can't find a package with the exact same name, it will treat the package name as regular expression string and match with any package that matches that regular expression.
|
60
|
+
This may lead Chef Infra Client to install one or more packages with names that match that regular expression.
|
61
|
+
|
62
|
+
In this example, `anchor_package_regex true` prevents the apt_package resource from installing matching packages if it can't find the `lua5.3` package.
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
apt_package 'lua5.3' do
|
66
|
+
version '5.3.3-1.1ubuntu2'
|
67
|
+
anchor_package_regex true
|
68
|
+
end
|
69
|
+
```
|
55
70
|
DOC
|
56
71
|
|
57
72
|
description "Use the **apt_package** resource to manage packages on Debian, Ubuntu, and other platforms that use the APT package system."
|
@@ -75,6 +90,10 @@ class Chef
|
|
75
90
|
description: "A Hash of response file variables in the form of {'VARIABLE' => 'VALUE'}.",
|
76
91
|
default: {}, desired_state: false
|
77
92
|
|
93
|
+
property :anchor_package_regex, [TrueClass, FalseClass],
|
94
|
+
introduced: "18.3",
|
95
|
+
description: "A Boolean flag that indicates whether the package name, which can be a regular expression, must match the entire name of the package (true) or if the regular expression is allowed to match a subset of the name (false).",
|
96
|
+
default: false
|
78
97
|
end
|
79
98
|
end
|
80
99
|
end
|
@@ -98,6 +98,19 @@ class Chef
|
|
98
98
|
end
|
99
99
|
```
|
100
100
|
|
101
|
+
**Add repository that needs custom options**:
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
apt_repository 'corretto' do
|
105
|
+
uri 'https://apt.corretto.aws'
|
106
|
+
arch 'amd64'
|
107
|
+
distribution 'stable'
|
108
|
+
components ['main']
|
109
|
+
options ['target-=Contents-deb']
|
110
|
+
key 'https://apt.corretto.aws/corretto.key'
|
111
|
+
end
|
112
|
+
```
|
113
|
+
|
101
114
|
**Remove a repository from the list**:
|
102
115
|
|
103
116
|
```ruby
|
@@ -159,6 +172,10 @@ class Chef
|
|
159
172
|
description: "Determines whether to rebuild the APT package cache.",
|
160
173
|
default: true, desired_state: false
|
161
174
|
|
175
|
+
property :options, [String, Array],
|
176
|
+
description: "Additional options to set for the repository.",
|
177
|
+
default: [], coerce: proc { |x| Array(x) }
|
178
|
+
|
162
179
|
default_action :add
|
163
180
|
allowed_actions :add, :remove
|
164
181
|
|
@@ -388,19 +405,21 @@ class Chef
|
|
388
405
|
# @param [Array] components
|
389
406
|
# @param [Boolean] trusted
|
390
407
|
# @param [String] arch
|
408
|
+
# @param [Array] options
|
391
409
|
# @param [Boolean] add_src
|
392
410
|
#
|
393
411
|
# @return [String] complete repo config text
|
394
|
-
def build_repo(uri, distribution, components, trusted, arch, add_src = false)
|
412
|
+
def build_repo(uri, distribution, components, trusted, arch, options, add_src = false)
|
395
413
|
uri = make_ppa_url(uri) if is_ppa_url?(uri)
|
396
414
|
|
397
415
|
uri = Addressable::URI.parse(uri)
|
398
416
|
components = Array(components).join(" ")
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
417
|
+
options_list = []
|
418
|
+
options_list << "arch=#{arch}" if arch
|
419
|
+
options_list << "trusted=yes" if trusted
|
420
|
+
options_list += options
|
421
|
+
optstr = unless options_list.empty?
|
422
|
+
"[" + options_list.join(" ") + "]"
|
404
423
|
end
|
405
424
|
info = [ optstr, uri.normalize.to_s, distribution, components ].compact.join(" ")
|
406
425
|
repo = "deb #{info}\n"
|
@@ -461,6 +480,7 @@ class Chef
|
|
461
480
|
repo_components,
|
462
481
|
new_resource.trusted,
|
463
482
|
new_resource.arch,
|
483
|
+
new_resource.options,
|
464
484
|
new_resource.deb_src
|
465
485
|
)
|
466
486
|
|
@@ -176,7 +176,7 @@ class Chef
|
|
176
176
|
}
|
177
177
|
|
178
178
|
unit["Service"]["ConditionACPower"] = "true" unless new_resource.run_on_battery
|
179
|
-
unit["Service"]["CPUQuota"] = new_resource.cpu_quota if new_resource.cpu_quota
|
179
|
+
unit["Service"]["CPUQuota"] = "#{new_resource.cpu_quota}%" if new_resource.cpu_quota
|
180
180
|
unit["Service"]["Environment"] = new_resource.environment.collect { |k, v| "\"#{k}=#{v}\"" } unless new_resource.environment.empty?
|
181
181
|
unit
|
182
182
|
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
class Chef
|
2
|
+
class Resource
|
3
|
+
class ChocolateyInstaller < Chef::Resource
|
4
|
+
provides :chocolatey_installer
|
5
|
+
|
6
|
+
description "Use the chocolatey_installer resource to ensure that Chocolatey itself is installed to your specification. Use the Chocolatey Feature resource to customize your install. Then use the Chocolatey Package resource to install packages on Windows via Chocolatey."
|
7
|
+
introduced "18.3"
|
8
|
+
examples <<~DOC
|
9
|
+
**Install Chocolatey**
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
chocolatey_installer 'latest' do
|
13
|
+
action :install
|
14
|
+
end
|
15
|
+
```
|
16
|
+
|
17
|
+
**Uninstall Chocolatey**
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
chocolatey_installer 'Some random verbiage' do
|
21
|
+
action :uninstall
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
**Install Chocolatey with Parameters**
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
chocolatey_installer 'latest' do
|
29
|
+
action :install
|
30
|
+
download_url "https://www.contoso.com/foo"
|
31
|
+
chocolatey_version '2.12.24'
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
chocolatey_installer 'latest' do
|
37
|
+
action :install
|
38
|
+
download_url "c:\\foo\foo.nupkg"
|
39
|
+
chocolatey_version '2.12.24'
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
**Upgrade Chocolatey with Parameters**
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
chocolatey_installer 'latest' do
|
47
|
+
action :upgrade
|
48
|
+
chocolatey_version '2.12.24'
|
49
|
+
end
|
50
|
+
```
|
51
|
+
DOC
|
52
|
+
|
53
|
+
allowed_actions :install, :uninstall, :upgrade
|
54
|
+
|
55
|
+
property :download_url, String,
|
56
|
+
description: "The URL to download Chocolatey from. This sets the value of $env:ChocolateyDownloadUrl and causes the installer to choose an alternate download location. If this is not set, Chocolatey installs fall back to the official Chocolatey community repository to download Chocolatey from. It can also be used for offline installation by providing a path to a Chocolatey.nupkg."
|
57
|
+
|
58
|
+
property :chocolatey_version, String,
|
59
|
+
description: "Specifies a target version of Chocolatey to install. By default, the latest stable version is installed. This will use the value in $env:ChocolateyVersion by default, if that environment variable is present. This parameter is ignored if download_url is set."
|
60
|
+
|
61
|
+
property :use_native_unzip, [TrueClass, FalseClass], default: false,
|
62
|
+
description: "If set, uses built-in Windows decompression tools instead of 7zip when unpacking the downloaded nupkg. This will be set by default if use_native_unzip is set to a value other than 'false' or '0'. This parameter will be ignored in PS 5+ in favour of using the Expand-Archive built in PowerShell cmdlet directly."
|
63
|
+
|
64
|
+
property :ignore_proxy, [TrueClass, FalseClass], default: false,
|
65
|
+
description: "If set, ignores any configured proxy. This will override any proxy environment variables or parameters. This will be set by default if ignore_proxy is set to a value other than 'false' or '0'."
|
66
|
+
|
67
|
+
property :proxy_url, String,
|
68
|
+
description: "Specifies the proxy URL to use during the download."
|
69
|
+
|
70
|
+
property :proxy_user, String,
|
71
|
+
description: "The username to use to build a proxy credential with. Will be consumed by the proxy_credential property if both this property and proxy_password are set"
|
72
|
+
|
73
|
+
property :proxy_password, String,
|
74
|
+
description: "The password to use to build a proxy credential with. Will be consumed by the proxy_credential property if both this property and proxy_user are set"
|
75
|
+
|
76
|
+
load_current_value do
|
77
|
+
current_state = is_choco_installed?
|
78
|
+
current_value_does_not_exist! if current_state == false
|
79
|
+
current_state
|
80
|
+
end
|
81
|
+
|
82
|
+
def is_choco_installed?
|
83
|
+
::File.exist?("#{ENV["ALLUSERSPROFILE"]}\\chocolatey\\bin\\choco.exe")
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_choco_version
|
87
|
+
powershell_exec("choco --version").result
|
88
|
+
end
|
89
|
+
|
90
|
+
def existing_version
|
91
|
+
Gem::Version.new(get_choco_version)
|
92
|
+
end
|
93
|
+
|
94
|
+
def define_resource_requirements
|
95
|
+
requirements.assert(:install, :upgrade).each do |a|
|
96
|
+
a.assertion do
|
97
|
+
# This is an exclusive OR - XOR - we're trying to coax an error out if one, but not both,
|
98
|
+
# parameters are empty.
|
99
|
+
new_resource.proxy_user.nil? != new_resource.proxy_password.nil?
|
100
|
+
end
|
101
|
+
a.failure_message(Chef::Exceptions::ValidationFailed, "You must specify both a proxy_user and a proxy_password")
|
102
|
+
a.whyrun("Assuming that if you have configured a 'proxy_user' you must also supply a 'proxy_password'")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
action :install, description: "Installs Chocolatey package manager" do
|
107
|
+
if new_resource.download_url
|
108
|
+
powershell_exec("Set-Item -path env:ChocolateyDownloadUrl -Value #{new_resource.download_url}")
|
109
|
+
end
|
110
|
+
|
111
|
+
if new_resource.chocolatey_version
|
112
|
+
powershell_exec("Set-Item -path env:ChocolateyVersion -Value #{new_resource.chocolatey_version}")
|
113
|
+
end
|
114
|
+
|
115
|
+
if new_resource.use_native_unzip
|
116
|
+
powershell_exec("Set-Item -path env:ChocolateyUseWindowsCompression -Value true")
|
117
|
+
end
|
118
|
+
|
119
|
+
if new_resource.ignore_proxy
|
120
|
+
powershell_exec("Set-Item -path env:ChocolateyIgnoreProxy -Value true")
|
121
|
+
end
|
122
|
+
|
123
|
+
if new_resource.proxy_url
|
124
|
+
powershell_exec("Set-Item -path env:ChocolateyProxyLocation -Value #{new_resource.proxy_url}")
|
125
|
+
end
|
126
|
+
|
127
|
+
if new_resource.proxy_user && new_resource.proxy_password
|
128
|
+
powershell_exec("Set-Item -path env:ChocolateyProxyUser -Value #{new_resource.proxy_user}; Set-Item -path env:ChocolateyProxyPassword -Value #{new_resource.proxy_password}")
|
129
|
+
end
|
130
|
+
|
131
|
+
# note that Invoke-Expression is being called on the downloaded script (outer parens),
|
132
|
+
# not triggering the script download (inner parens)
|
133
|
+
converge_if_changed do
|
134
|
+
powershell_exec("Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))").error!
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
action :upgrade, description: "Upgrades the Chocolatey package manager" do
|
139
|
+
if new_resource.chocolatey_version
|
140
|
+
proposed_version = Gem::Version.new(new_resource.chocolatey_version)
|
141
|
+
else
|
142
|
+
proposed_version = nil
|
143
|
+
end
|
144
|
+
|
145
|
+
if new_resource.download_url
|
146
|
+
powershell_exec("Set-Item -path env:ChocolateyDownloadUrl -Value #{new_resource.download_url}")
|
147
|
+
end
|
148
|
+
|
149
|
+
if new_resource.chocolatey_version
|
150
|
+
powershell_exec("Set-Item -path env:ChocolateyVersion -Value #{new_resource.chocolatey_version}")
|
151
|
+
end
|
152
|
+
|
153
|
+
if new_resource.use_native_unzip
|
154
|
+
powershell_exec("Set-Item -path env:ChocolateyUseWindowsCompression -Value true")
|
155
|
+
end
|
156
|
+
|
157
|
+
if new_resource.ignore_proxy
|
158
|
+
powershell_exec("Set-Item -path env:ChocolateyIgnoreProxy -Value true")
|
159
|
+
end
|
160
|
+
|
161
|
+
if new_resource.proxy_url
|
162
|
+
powershell_exec("Set-Item -path env:ChocolateyProxyLocation -Value #{new_resource.proxy_url}")
|
163
|
+
end
|
164
|
+
|
165
|
+
if new_resource.proxy_user && new_resource.proxy_password
|
166
|
+
powershell_exec("Set-Item -path env:ChocolateyProxyUser -Value #{new_resource.proxy_user}; Set-Item -path env:ChocolateyProxyPassword -Value #{new_resource.proxy_password}")
|
167
|
+
end
|
168
|
+
|
169
|
+
if proposed_version && existing_version < proposed_version
|
170
|
+
powershell_exec("Set-Item -path env:ChocolateyVersion -Value #{proposed_version}")
|
171
|
+
else
|
172
|
+
powershell_exec("Remove-Item -path env:ChocolateyVersion")
|
173
|
+
end
|
174
|
+
|
175
|
+
converge_by("upgrade choco version") do
|
176
|
+
powershell_exec("choco upgrade Chocolatey -y").result
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
action :uninstall, description: "Uninstall Chocolatey package manager" do
|
181
|
+
path = "c:\\programdata\\chocolatey\\bin"
|
182
|
+
if File.exists?(path)
|
183
|
+
converge_by("Uninstall Choco") do
|
184
|
+
powershell_code = <<~CODE
|
185
|
+
Remove-Item $env:ALLUSERSPROFILE\\chocolatey -Recurse -Force
|
186
|
+
[Environment]::SetEnvironmentVariable("ChocolateyLastPathUpdate", $null ,"User")
|
187
|
+
[Environment]::SetEnvironmentVariable("ChocolateyToolsLocation", $null ,"User")
|
188
|
+
[Environment]::SetEnvironmentVariable("ChocolateyInstall", $null ,"Machine")
|
189
|
+
$path = [System.Environment]::GetEnvironmentVariable(
|
190
|
+
'PATH',
|
191
|
+
'Machine'
|
192
|
+
)
|
193
|
+
$path = ($path.Split(';') | Where-Object { $_ -ne "#{path}" }) -join ";"
|
194
|
+
[System.Environment]::SetEnvironmentVariable(
|
195
|
+
'PATH',
|
196
|
+
$path,
|
197
|
+
'Machine'
|
198
|
+
)
|
199
|
+
CODE
|
200
|
+
powershell_exec(powershell_code).error!
|
201
|
+
end
|
202
|
+
end
|
203
|
+
Chef::Log.warn("Chocolatey is already uninstalled.")
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -67,6 +67,14 @@ class Chef
|
|
67
67
|
description: "The name of the package. Default value: the name of the resource block.",
|
68
68
|
coerce: proc { |x| [x].flatten }
|
69
69
|
|
70
|
+
property :bulk_query, [TrueClass, FalseClass],
|
71
|
+
description: "Bulk query the chocolatey server? This will cause the provider to list all packages instead of doing individual queries.",
|
72
|
+
default: false
|
73
|
+
|
74
|
+
property :use_choco_list, [TrueClass, FalseClass],
|
75
|
+
description: "Use choco list for getting the locally installed packages, rather than reading the nupkg database directly? This defaults to false, since reading the package data is faster.",
|
76
|
+
default: false
|
77
|
+
|
70
78
|
property :version, [String, Array],
|
71
79
|
description: "The version of a package to be installed or upgraded.",
|
72
80
|
coerce: proc { |x| [x].flatten }
|
@@ -45,8 +45,7 @@ class Chef
|
|
45
45
|
default: true
|
46
46
|
|
47
47
|
property :homebrew_path, String,
|
48
|
-
description: "The path to the
|
49
|
-
default: "/usr/local/bin/brew"
|
48
|
+
description: "The path to the Homebrew binary."
|
50
49
|
|
51
50
|
property :owner, [String, Integer],
|
52
51
|
description: "The owner of the Homebrew installation.",
|
@@ -56,14 +55,14 @@ class Chef
|
|
56
55
|
action :install, description: "Install an application that is packaged as a Homebrew cask." do
|
57
56
|
if new_resource.install_cask
|
58
57
|
homebrew_tap "homebrew/cask" do
|
59
|
-
homebrew_path new_resource.homebrew_path
|
58
|
+
homebrew_path homebrew_bin_path(new_resource.homebrew_path)
|
60
59
|
owner new_resource.owner
|
61
60
|
end
|
62
61
|
end
|
63
62
|
|
64
63
|
unless casked?
|
65
64
|
converge_by("install cask #{new_resource.cask_name} #{new_resource.options}") do
|
66
|
-
shell_out!("#{new_resource.homebrew_path} install --cask #{new_resource.cask_name} #{new_resource.options}",
|
65
|
+
shell_out!("#{homebrew_bin_path(new_resource.homebrew_path)} install --cask #{new_resource.cask_name} #{new_resource.options}",
|
67
66
|
user: new_resource.owner,
|
68
67
|
env: { "HOME" => ::Dir.home(new_resource.owner), "USER" => new_resource.owner },
|
69
68
|
cwd: ::Dir.home(new_resource.owner))
|
@@ -74,14 +73,14 @@ class Chef
|
|
74
73
|
action :remove, description: "Remove an application that is packaged as a Homebrew cask." do
|
75
74
|
if new_resource.install_cask
|
76
75
|
homebrew_tap "homebrew/cask" do
|
77
|
-
homebrew_path new_resource.homebrew_path
|
76
|
+
homebrew_path homebrew_bin_path(new_resource.homebrew_path)
|
78
77
|
owner new_resource.owner
|
79
78
|
end
|
80
79
|
end
|
81
80
|
|
82
81
|
if casked?
|
83
82
|
converge_by("uninstall cask #{new_resource.cask_name}") do
|
84
|
-
shell_out!("#{new_resource.homebrew_path} uninstall --cask #{new_resource.cask_name}",
|
83
|
+
shell_out!("#{homebrew_bin_path(new_resource.homebrew_path)} uninstall --cask #{new_resource.cask_name}",
|
85
84
|
user: new_resource.owner,
|
86
85
|
env: { "HOME" => ::Dir.home(new_resource.owner), "USER" => new_resource.owner },
|
87
86
|
cwd: ::Dir.home(new_resource.owner))
|
@@ -99,7 +98,7 @@ class Chef
|
|
99
98
|
# @return [Boolean]
|
100
99
|
def casked?
|
101
100
|
unscoped_name = new_resource.cask_name.split("/").last
|
102
|
-
shell_out!("#{new_resource.homebrew_path} list --cask 2>/dev/null",
|
101
|
+
shell_out!("#{homebrew_bin_path(new_resource.homebrew_path)} list --cask 2>/dev/null",
|
103
102
|
user: new_resource.owner,
|
104
103
|
env: { "HOME" => ::Dir.home(new_resource.owner), "USER" => new_resource.owner },
|
105
104
|
cwd: ::Dir.home(new_resource.owner)).stdout.split.include?(unscoped_name)
|
@@ -63,7 +63,7 @@ class Chef
|
|
63
63
|
allowed_actions :install, :upgrade, :remove, :purge
|
64
64
|
|
65
65
|
property :homebrew_user, [ String, Integer ],
|
66
|
-
description: "The name or
|
66
|
+
description: "The name or UID of the Homebrew owner to be used by #{ChefUtils::Dist::Infra::PRODUCT} when executing a command.\n\n#{ChefUtils::Dist::Infra::PRODUCT}, by default, will attempt to execute a Homebrew command as the owner of the `/usr/local/bin/brew` executable on x86_64 machines or `/opt/homebrew/bin/brew` executable on arm64 machines. If that executable doesn't exist, #{ChefUtils::Dist::Infra::PRODUCT} will attempt to find the user by executing `which brew`. If that executable can't be found, #{ChefUtils::Dist::Infra::PRODUCT} will print an error message: `Couldn't find the 'brew' executable anywhere on the path.`.\n\nSet this property to specify the Homebrew owner for situations where Chef Infra Client cannot automatically detect the correct owner.'"
|
67
67
|
|
68
68
|
end
|
69
69
|
end
|
@@ -41,8 +41,7 @@ class Chef
|
|
41
41
|
description: "The URL of the tap."
|
42
42
|
|
43
43
|
property :homebrew_path, String,
|
44
|
-
description: "The path to the Homebrew binary."
|
45
|
-
default: "/usr/local/bin/brew"
|
44
|
+
description: "The path to the Homebrew binary."
|
46
45
|
|
47
46
|
property :owner, String,
|
48
47
|
description: "The owner of the Homebrew installation.",
|
@@ -52,7 +51,7 @@ class Chef
|
|
52
51
|
action :tap, description: "Add a Homebrew tap." do
|
53
52
|
unless tapped?(new_resource.tap_name)
|
54
53
|
converge_by("tap #{new_resource.tap_name}") do
|
55
|
-
shell_out!("#{new_resource.homebrew_path} tap #{new_resource.tap_name} #{new_resource.url || ""}",
|
54
|
+
shell_out!("#{homebrew_bin_path(new_resource.homebrew_path)} tap #{new_resource.tap_name} #{new_resource.url || ""}",
|
56
55
|
user: new_resource.owner,
|
57
56
|
env: { "HOME" => ::Dir.home(new_resource.owner), "USER" => new_resource.owner },
|
58
57
|
cwd: ::Dir.home(new_resource.owner))
|
@@ -63,7 +62,7 @@ class Chef
|
|
63
62
|
action :untap, description: "Remove a Homebrew tap." do
|
64
63
|
if tapped?(new_resource.tap_name)
|
65
64
|
converge_by("untap #{new_resource.tap_name}") do
|
66
|
-
shell_out!("#{new_resource.homebrew_path} untap #{new_resource.tap_name}",
|
65
|
+
shell_out!("#{homebrew_bin_path(new_resource.homebrew_path)} untap #{new_resource.tap_name}",
|
67
66
|
user: new_resource.owner,
|
68
67
|
env: { "HOME" => ::Dir.home(new_resource.owner), "USER" => new_resource.owner },
|
69
68
|
cwd: ::Dir.home(new_resource.owner))
|
@@ -75,8 +74,9 @@ class Chef
|
|
75
74
|
#
|
76
75
|
# @return [Boolean]
|
77
76
|
def tapped?(name)
|
77
|
+
base_path = ["#{::File.dirname(which("brew"))}/../homebrew", "#{::File.dirname(which("brew"))}/../Homebrew", "/opt/homebrew", "/usr/local/Homebrew", "/home/linuxbrew/.linuxbrew"].uniq.select { |x| Dir.exist?(x) }.first
|
78
78
|
tap_dir = name.gsub("/", "/homebrew-")
|
79
|
-
::File.directory?("/
|
79
|
+
::File.directory?("#{base_path}/Library/Taps/#{tap_dir}")
|
80
80
|
end
|
81
81
|
end
|
82
82
|
end
|
@@ -202,7 +202,11 @@ class Chef
|
|
202
202
|
description: "The first argument of `execvp`, typically the file name associated with the file to be executed. This value must be specified if `program_arguments` is not specified, and vice-versa."
|
203
203
|
|
204
204
|
property :program_arguments, Array,
|
205
|
-
description: "The second argument of `execvp`. If program is not specified, this property must be specified and will be handled as if it were the first argument."
|
205
|
+
description: "The second argument of `execvp`. If program is not specified, this property must be specified and will be handled as if it were the first argument.",
|
206
|
+
coerce: proc { |args|
|
207
|
+
# Cast all values to a string. Launchd only supports string values
|
208
|
+
args.map(&:to_s)
|
209
|
+
}
|
206
210
|
|
207
211
|
property :queue_directories, Array,
|
208
212
|
description: "An array of non-empty directories which, if any are modified, will cause a job to be started."
|
data/lib/chef/resource/locale.rb
CHANGED
@@ -112,8 +112,11 @@ class Chef
|
|
112
112
|
end
|
113
113
|
|
114
114
|
requirements.assert(:all_actions) do |a|
|
115
|
-
|
116
|
-
|
115
|
+
a.assertion do
|
116
|
+
# RHEL/CentOS type platforms don't have locale-gen
|
117
|
+
# Windows has locale-gen as part of the install, but not in the path
|
118
|
+
which("locale-gen") || windows?
|
119
|
+
end
|
117
120
|
a.failure_message(Chef::Exceptions::ProviderNotFound, "The locale resource requires the locale-gen tool")
|
118
121
|
end
|
119
122
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Joshua Timberman (<jtimberman@chef.io>)
|
3
|
+
# Author:: William Theaker (<william.theaker+chef@gusto.com>)
|
4
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
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 "../resource"
|
20
|
+
|
21
|
+
class Chef
|
22
|
+
class Resource
|
23
|
+
class MacosPkg < Chef::Resource
|
24
|
+
provides(:macos_pkg) { true }
|
25
|
+
|
26
|
+
description "Use the **macos_pkg** resource to install a macOS `.pkg` file, optionally downloading it from a remote source. A `package_id` property must be provided for idempotency. Either a `file` or `source` property is required."
|
27
|
+
introduced "18.1"
|
28
|
+
examples <<~DOC
|
29
|
+
**Install osquery**:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
macos_pkg 'osquery' do
|
33
|
+
checksum '1fea8ac9b603851d2e76c5fc73138a468a3075a3002c8cb1fd7fff53b889c4dd'
|
34
|
+
package_id 'io.osquery.agent'
|
35
|
+
source 'https://pkg.osquery.io/darwin/osquery-5.8.2.pkg'
|
36
|
+
action :install
|
37
|
+
end
|
38
|
+
```
|
39
|
+
DOC
|
40
|
+
|
41
|
+
allowed_actions :install
|
42
|
+
default_action :install
|
43
|
+
|
44
|
+
property :checksum, String,
|
45
|
+
description: "The sha256 checksum of the `.pkg` file to download."
|
46
|
+
|
47
|
+
property :file, String,
|
48
|
+
description: "The absolute path to the `.pkg` file on the local system."
|
49
|
+
|
50
|
+
property :headers, Hash,
|
51
|
+
description: "Allows custom HTTP headers (like cookies) to be set on the `remote_file` resource.",
|
52
|
+
desired_state: false
|
53
|
+
|
54
|
+
property :package_id, String,
|
55
|
+
description: "The package ID registered with `pkgutil` when a `pkg` or `mpkg` is installed.",
|
56
|
+
required: true
|
57
|
+
|
58
|
+
property :source, String,
|
59
|
+
description: "The remote URL used to download the `.pkg` file."
|
60
|
+
|
61
|
+
property :target, String,
|
62
|
+
description: "The device to install the package on.",
|
63
|
+
default: "/"
|
64
|
+
|
65
|
+
load_current_value do |new_resource|
|
66
|
+
if shell_out("pkgutil --pkg-info '#{new_resource.package_id}'").exitstatus == 0
|
67
|
+
Chef::Log.debug "#{new_resource.package_id} is already installed. To upgrade, try \"sudo pkgutil --forget '#{new_resource.package_id}'\""
|
68
|
+
else
|
69
|
+
current_value_does_not_exist!
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
action :install, description: "Installs the pkg." do
|
74
|
+
if new_resource.source.nil? && new_resource.file.nil?
|
75
|
+
raise "Must provide either a file or source property for macos_pkg resources."
|
76
|
+
end
|
77
|
+
|
78
|
+
if current_resource.nil?
|
79
|
+
if new_resource.source
|
80
|
+
remote_file pkg_file do
|
81
|
+
source new_resource.source
|
82
|
+
headers new_resource.headers if new_resource.headers
|
83
|
+
checksum new_resource.checksum if new_resource.checksum
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
converge_by "install #{pkg_file}" do
|
88
|
+
install_cmd = "installer -pkg #{pkg_file} -target #{new_resource.target}"
|
89
|
+
|
90
|
+
execute install_cmd do
|
91
|
+
action :run
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
action_class do
|
98
|
+
# @return [String] the path to the pkg file
|
99
|
+
def pkg_file
|
100
|
+
@pkg_file ||= if new_resource.file.nil?
|
101
|
+
uri = URI.parse(new_resource.source)
|
102
|
+
filename = ::File.basename(uri.path)
|
103
|
+
"#{Chef::Config[:file_cache_path]}/#{filename}"
|
104
|
+
else
|
105
|
+
new_resource.file
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -21,7 +21,7 @@ class Chef
|
|
21
21
|
class Resource
|
22
22
|
class PowershellScript < Chef::Resource::WindowsScript
|
23
23
|
|
24
|
-
set_guard_inherited_attributes(:interpreter)
|
24
|
+
set_guard_inherited_attributes(:interpreter, :use_inline_powershell)
|
25
25
|
|
26
26
|
provides :powershell_script, os: "windows"
|
27
27
|
|
@@ -39,6 +39,10 @@ class Chef
|
|
39
39
|
equal_to: %w{powershell pwsh},
|
40
40
|
description: "The interpreter type, `powershell` or `pwsh` (PowerShell Core)"
|
41
41
|
|
42
|
+
property :use_inline_powershell, [true, false],
|
43
|
+
default: false,
|
44
|
+
description: "Use inline powershell.dll rather than shelling out - this is faster, but could have different semantics to the traditional method. In particular, it does not allow for streaming output, nor does it allow for passing custom parameters to the interpreter"
|
45
|
+
|
42
46
|
property :convert_boolean_return, [true, false],
|
43
47
|
default: false,
|
44
48
|
description: <<~DESC
|
@@ -93,6 +93,9 @@ class Chef
|
|
93
93
|
# if the service is masked or not
|
94
94
|
property :masked, [ TrueClass, FalseClass ], skip_docs: true
|
95
95
|
|
96
|
+
# if the service is static or not
|
97
|
+
property :static, [ TrueClass, FalseClass ], skip_docs: true
|
98
|
+
|
96
99
|
# if the service is indirect or not
|
97
100
|
property :indirect, [ TrueClass, FalseClass ], skip_docs: true
|
98
101
|
|