-
Notifications
You must be signed in to change notification settings - Fork 2.5k
/
chocolatey_installer.rb
207 lines (168 loc) · 8.63 KB
/
chocolatey_installer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
class Chef
class Resource
class ChocolateyInstaller < Chef::Resource
provides :chocolatey_installer
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."
introduced "18.3"
examples <<~DOC
**Install Chocolatey**
```ruby
chocolatey_installer 'latest' do
action :install
end
```
**Uninstall Chocolatey**
```ruby
chocolatey_installer 'Some random verbiage' do
action :uninstall
end
```
**Install Chocolatey with Parameters**
```ruby
chocolatey_installer 'latest' do
action :install
download_url "https://www.contoso.com/foo"
chocolatey_version '2.12.24'
end
```
```ruby
chocolatey_installer 'latest' do
action :install
download_url "c:\\foo\foo.nupkg"
chocolatey_version '2.12.24'
end
```
**Upgrade Chocolatey with Parameters**
```ruby
chocolatey_installer 'latest' do
action :upgrade
chocolatey_version '2.12.24'
end
```
DOC
allowed_actions :install, :uninstall, :upgrade
property :download_url, String,
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."
property :chocolatey_version, String,
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."
property :use_native_unzip, [TrueClass, FalseClass], default: false,
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."
property :ignore_proxy, [TrueClass, FalseClass], default: false,
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'."
property :proxy_url, String,
description: "Specifies the proxy URL to use during the download."
property :proxy_user, String,
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"
property :proxy_password, String,
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"
load_current_value do
current_state = is_choco_installed?
current_value_does_not_exist! if current_state == false
current_state
end
def is_choco_installed?
::File.exist?("#{ENV["ALLUSERSPROFILE"]}\\chocolatey\\bin\\choco.exe")
end
def get_choco_version
powershell_exec("choco --version").result
end
def existing_version
Gem::Version.new(get_choco_version)
end
def define_resource_requirements
requirements.assert(:install, :upgrade).each do |a|
a.assertion do
# This is an exclusive OR - XOR - we're trying to coax an error out if one, but not both,
# parameters are empty.
new_resource.proxy_user.nil? != new_resource.proxy_password.nil?
end
a.failure_message(Chef::Exceptions::ValidationFailed, "You must specify both a proxy_user and a proxy_password")
a.whyrun("Assuming that if you have configured a 'proxy_user' you must also supply a 'proxy_password'")
end
end
action :install, description: "Installs Chocolatey package manager" do
if new_resource.download_url
powershell_exec("Set-Item -path env:ChocolateyDownloadUrl -Value #{new_resource.download_url}")
end
if new_resource.chocolatey_version
powershell_exec("Set-Item -path env:ChocolateyVersion -Value #{new_resource.chocolatey_version}")
end
if new_resource.use_native_unzip
powershell_exec("Set-Item -path env:ChocolateyUseWindowsCompression -Value true")
end
if new_resource.ignore_proxy
powershell_exec("Set-Item -path env:ChocolateyIgnoreProxy -Value true")
end
if new_resource.proxy_url
powershell_exec("Set-Item -path env:ChocolateyProxyLocation -Value #{new_resource.proxy_url}")
end
if new_resource.proxy_user && new_resource.proxy_password
powershell_exec("Set-Item -path env:ChocolateyProxyUser -Value #{new_resource.proxy_user}; Set-Item -path env:ChocolateyProxyPassword -Value #{new_resource.proxy_password}")
end
# note that Invoke-Expression is being called on the downloaded script (outer parens),
# not triggering the script download (inner parens)
converge_if_changed do
powershell_exec("Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))").error!
end
end
action :upgrade, description: "Upgrades the Chocolatey package manager" do
if new_resource.chocolatey_version
proposed_version = Gem::Version.new(new_resource.chocolatey_version)
else
proposed_version = nil
end
if new_resource.download_url
powershell_exec("Set-Item -path env:ChocolateyDownloadUrl -Value #{new_resource.download_url}")
end
if new_resource.chocolatey_version
powershell_exec("Set-Item -path env:ChocolateyVersion -Value #{new_resource.chocolatey_version}")
end
if new_resource.use_native_unzip
powershell_exec("Set-Item -path env:ChocolateyUseWindowsCompression -Value true")
end
if new_resource.ignore_proxy
powershell_exec("Set-Item -path env:ChocolateyIgnoreProxy -Value true")
end
if new_resource.proxy_url
powershell_exec("Set-Item -path env:ChocolateyProxyLocation -Value #{new_resource.proxy_url}")
end
if new_resource.proxy_user && new_resource.proxy_password
powershell_exec("Set-Item -path env:ChocolateyProxyUser -Value #{new_resource.proxy_user}; Set-Item -path env:ChocolateyProxyPassword -Value #{new_resource.proxy_password}")
end
if proposed_version && existing_version < proposed_version
powershell_exec("Set-Item -path env:ChocolateyVersion -Value #{proposed_version}")
else
powershell_exec("Remove-Item -path env:ChocolateyVersion")
end
converge_by("upgrade choco version") do
powershell_exec("choco upgrade Chocolatey -y").result
end
end
action :uninstall, description: "Uninstall Chocolatey package manager" do
path = "c:\\programdata\\chocolatey\\bin"
if File.exists?(path)
converge_by("Uninstall Choco") do
powershell_code = <<~CODE
Remove-Item $env:ALLUSERSPROFILE\\chocolatey -Recurse -Force
[Environment]::SetEnvironmentVariable("ChocolateyLastPathUpdate", $null ,"User")
[Environment]::SetEnvironmentVariable("ChocolateyToolsLocation", $null ,"User")
[Environment]::SetEnvironmentVariable("ChocolateyInstall", $null ,"Machine")
$path = [System.Environment]::GetEnvironmentVariable(
'PATH',
'Machine'
)
$path = ($path.Split(';') | Where-Object { $_ -ne "#{path}" }) -join ";"
[System.Environment]::SetEnvironmentVariable(
'PATH',
$path,
'Machine'
)
CODE
powershell_exec(powershell_code).error!
end
end
Chef::Log.warn("Chocolatey is already uninstalled.")
end
end
end
end