-
Notifications
You must be signed in to change notification settings - Fork 253
Expand file tree
/
Copy path_install-windows.rb
More file actions
255 lines (224 loc) · 8.69 KB
/
_install-windows.rb
File metadata and controls
255 lines (224 loc) · 8.69 KB
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
#
# Cookbook:: datadog
# Recipe:: _install-windows
#
# Copyright:: 2011-Present, Datadog
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
if Chef::VERSION < Gem::Version.new(14)
include_recipe 'chef_handler'
end
dd_agent_flavor = Chef::Datadog.agent_flavor(node)
if dd_agent_flavor != 'datadog-agent'
raise "Unsupported agent flavor '#{dd_agent_flavor}' on Windows (only supports 'datadog-agent')"
end
module Windows
class Helper
def clean_user(context)
context.node.run_state['datadog']['windows_ddagentuser_name'] = nil
end
def clean_password(context)
context.node.run_state['datadog']['windows_ddagentuser_password'] = nil
end
def unmute_host(context)
resource = context.resource_collection.lookup('ruby_block[Unmute host after installing]')
resource.run_action(:run)
end
end
end
ddagentuser_name = Chef::Datadog.ddagentuser_name(node)
ddagentuser_password = Chef::Datadog.ddagentuser_password(node)
if ddagentuser_name
Chef.event_handler do
on :run_failed do
Windows::Helper.new.clean_user(Chef.run_context)
end
end
ruby_block 'Store Datadog User Name' do
block do
node.run_state['datadog']['windows_ddagentuser_name'] = ddagentuser_name
end
sensitive true
action :run
end
end
if ddagentuser_password
Chef.event_handler do
on :run_failed do
Windows::Helper.new.clean_password(Chef.run_context)
end
end
ruby_block 'Store Datadog User Password' do
block do
node.run_state['datadog']['windows_ddagentuser_password'] = ddagentuser_password
end
sensitive true
action :run
end
end
dd_agent_version = Chef::Datadog.agent_version(node)
if dd_agent_version.nil?
# Use latest
agent_major_version = Chef::Datadog.agent_major_version(node)
dd_agent_installer_basename = (agent_major_version == 5) ? 'ddagent-cli-latest' : "datadog-agent-#{agent_major_version}-latest.amd64"
else
dd_agent_installer_prefix = (node['datadog']['windows_agent_installer_prefix'] || 'ddagent-cli')
dd_agent_installer_basename = "#{dd_agent_installer_prefix}-#{dd_agent_version}"
end
dd_agent_install_npm = Chef::Datadog.npm_install(node)
temp_file_basename = ::File.join(Chef::Config[:file_cache_path], 'ddagent-cli')
temp_fix_file = ::File.join(Chef::Config[:file_cache_path], 'fix_6_14.ps1')
if node['datadog']['windows_agent_use_exe']
dd_agent_installer = "#{dd_agent_installer_basename}.exe"
temp_file = "#{temp_file_basename}.exe"
resolved_installer_type = :custom
install_options = '/q'
else
dd_agent_installer = "#{dd_agent_installer_basename}.msi"
temp_file = "#{temp_file_basename}.msi"
resolved_installer_type = :msi
# Agent >= 5.12.0 installs per-machine by default, but specifying ALLUSERS=1 shouldn't affect the install
install_options = '/norestart ALLUSERS=1'
# Since 6.11.0, the core and APM/trace components of the Windows Agent run under
# a specific user instead of LOCAL_SYSTEM, check whether the user has provided
# custom credentials and use them if that's the case.
install_options.concat(' DDAGENTUSER_NAME=%DDAGENTUSER_NAME%') if ddagentuser_name
install_options.concat(' DDAGENTUSER_PASSWORD=%DDAGENTUSER_PASSWORD%') if ddagentuser_password
install_options.concat(' ADDLOCAL=MainApplication,NPM') if dd_agent_install_npm
end
package 'Datadog Agent removal' do
package_name 'Datadog Agent'
timeout node['datadog']['windows_msi_timeout']
action :nothing
end
package_retries = node['datadog']['agent_package_retries']
package_retry_delay = node['datadog']['agent_package_retry_delay']
unsafe_hashsums = [
'928b00d2f952219732cda9ae0515351b15f9b9c1ea1d546738f9dc0fda70c336',
'78b2bb2b231bcc185eb73dd367bfb6cb8a5d45ba93a46a7890fd607dc9188194'
]
fix_message = 'The file downloaded matches a known unsafe MSI - Agent versions 6.14.0/1 have been blacklisted. please use a different release. '\
'See http://dtdg.co/win-614-fix'
must_reinstall = Chef::Datadog::WindowsInstallHelpers.must_reinstall?(node)
# Download the installer to a temp location
remote_file temp_file do
source node['datadog']['windows_agent_url'] + dd_agent_installer
checksum node['datadog']['windows_agent_checksum'] if node['datadog']['windows_agent_checksum']
retries package_retries unless package_retries.nil?
retry_delay package_retry_delay unless package_retry_delay.nil?
# validate the downloaded MSI is safe
verify do |path|
require 'digest'
unsafe = unsafe_hashsums.include? Digest::SHA256.file(path).hexdigest
Chef::Log.error("\n#{fix_message}\n") if unsafe
# verify will abort update if false
!unsafe
end unless node['datadog']['windows_blacklist_silent_fail']
# these are notified in order
if must_reinstall
notifies :create, "remote_file[#{temp_fix_file}]", :immediately
notifies :run, 'powershell_script[datadog_6.14.x_fix]', :immediately
end
end
remote_file temp_fix_file do
source "#{node['datadog']['windows_agent_url']}scripts/fix_6_14.ps1"
retries package_retries unless package_retries.nil?
retry_delay package_retry_delay unless package_retry_delay.nil?
action :nothing
end
powershell_script 'datadog_6.14.x_fix' do
# As of v1.37, the windows cookbook doesn't upgrade the package if a newer version is downloaded
# As a workaround uninstall the package first if a new MSI is downloaded
code "&#{temp_fix_file}"
action :nothing
notifies :remove, 'package[Datadog Agent removal]', :immediately
end
if node['datadog']['windows_mute_hosts_during_install']
unless Chef::Datadog.application_key(node)
Chef::Log.error('windows_mute_hosts_during_install requires an application_key but it is not set.')
end
ruby_block 'Mute host while installing' do
block do
require 'net/http'
require 'uri'
require 'json'
hostname = node['datadog']['hostname']
uri = URI.parse("https://api.datadoghq.com/api/v1/host/#{hostname}/mute")
request = Net::HTTP::Post.new(uri)
request.content_type = 'application/json'
request['Dd-Api-Key'] = Chef::Datadog.api_key(node)
request['Dd-Application-Key'] = Chef::Datadog.application_key(node)
request.body = JSON.dump({
'message': 'Muted during install by datadog-chef cookbook',
'end': Time.now.getutc.to_i + (60 * 60), # Set to automatically unmute in 60 minutes
})
response = Net::HTTP.start(uri.hostname, uri.port, { use_ssl: true }) do |http|
http.request(request)
end
if response.code != '200'
Chef::Log.warn("Mute request failed with code #{response.code}: #{response.body}")
end
end
action :nothing
end
ruby_block 'Unmute host after installing' do
block do
require 'net/http'
require 'uri'
require 'json'
hostname = node['datadog']['hostname']
uri = URI.parse("https://api.datadoghq.com/api/v1/host/#{hostname}/unmute")
request = Net::HTTP::Post.new(uri)
request['Dd-Api-Key'] = Chef::Datadog.api_key(node)
request['Dd-Application-Key'] = Chef::Datadog.application_key(node)
response = Net::HTTP.start(uri.hostname, uri.port, { use_ssl: true }) do |http|
http.request(request)
end
if response.code != '200'
Chef::Log.warn("Unmute request failed with code #{response.code}: #{response.body}")
end
end
action :nothing
end
Chef.event_handler do
on :run_failed do
Windows::Helper.new.unmute_host(Chef.run_context)
end
end
end
# Install the package
windows_package 'Datadog Agent' do # ~FC009
source temp_file
installer_type resolved_installer_type
options install_options
timeout node['datadog']['windows_msi_timeout']
action :install
# Before 3.0.0, we adviced users to use the windows cookbook ~> 1.38.0,
# we should probably keep the compatibilty for some time.
if respond_to?(:returns)
returns [0, 3010]
else
success_codes [0, 3010]
end
if node['datadog']['windows_mute_hosts_during_install']
notifies :run, 'ruby_block[Mute host while installing]', :before
notifies :run, 'ruby_block[Unmute host after installing]', :immediately
end
not_if do
require 'digest'
unsafe = File.file?(temp_file) && unsafe_hashsums.include?(Digest::SHA256.file(temp_file).hexdigest)
Chef::Log.warn("\n#{fix_message}\nContinuing without installing Datadog Agent.") if unsafe
unsafe
end
end