Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[windows] Add option to support EXE Agent installer #410

Merged
merged 6 commits into from Mar 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 14 additions & 4 deletions README.md
Expand Up @@ -66,10 +66,20 @@ dd-agent
--------
Installs the Datadog agent on the target system, sets the API key, and start the service to report on the local system metrics

**Note for Windows**: With Chef >= 12.6 _and_ the `windows` cookbook >= 1.39.0, Agent upgrades are known to fail.
For Chef>=12.6 users on Windows, we recommend pinning the `windows` cookbook to a lower version (`~> 1.38.0` for instance).
If that's not an option, a known workaround is to use the `remove-dd-agent` recipe (since the `2.5.0` version of the present cookbook) to uninstall the Agent
prior to any Agent upgrade.
**Notes for Windows**:

* With Chef >= 12.6 _and_ the `windows` cookbook >= 1.39.0, Agent upgrades are known to fail.
For Chef>=12.6 users on Windows, we recommend pinning the `windows` cookbook to a lower version (`~> 1.38.0` for instance).

If that's not an option, a known workaround is to use the `remove-dd-agent` recipe (since the `2.5.0` version of the present cookbook) to uninstall the Agent
prior to any Agent upgrade.

* Because of changes in the Windows Agent packaging and install in version 5.12.0, when upgrading the Agent from versions <= 5.10.1 to versions >= 5.12.0,
please set the `windows_agent_use_exe` attribute to `true`.

Once the upgrade is complete, you can leave the attribute to its default value (`false`).

For more information on these Windows packaging changes, see the related [docs on the dd-agent wiki](https://github.com/DataDog/dd-agent/wiki/Windows-Agent-Installation).

dd-handler
----------
Expand Down
7 changes: 7 additions & 0 deletions attributes/default.rb
Expand Up @@ -111,6 +111,13 @@
# Expected checksum to validate correct agent installer is downloaded (Windows only)
default['datadog']['windows_agent_checksum'] = nil

# Set to `true` to use the EXE installer on Windows, recommended to gracefully handle upgrades from per-user
# to per-machine installs on most environments. We recommend setting this option to `true` for Agent upgrades from
# versions <= 5.10.1 to versions >= 5.12.0.
# The EXE installer exists since Agent release 5.12.0
# If you're already using version >= 5.12.0 of the Agent, leave this to false.
default['datadog']['windows_agent_use_exe'] = false

# Values that differ on Windows
# The location of the config folder (containing conf.d)
# The name of the dd agent service
Expand Down
51 changes: 44 additions & 7 deletions recipes/_install-windows.rb
Expand Up @@ -24,29 +24,66 @@
node['datadog']['agent_version']
end

# If no version is specified, select the latest package
dd_agent_msi = dd_agent_version ? "ddagent-cli-#{dd_agent_version}.msi" : 'ddagent-cli.msi'
temp_file = ::File.join(Chef::Config[:file_cache_path], 'ddagent-cli.msi')
# If no version is specified, select the latest package.
# The latest package basename is `ddagent-cli-latest` since Agent version 5.12.0
dd_agent_installer_basename = dd_agent_version ? "ddagent-cli-#{dd_agent_version}" : 'ddagent-cli-latest'
temp_file_basename = ::File.join(Chef::Config[:file_cache_path], 'ddagent-cli')

if node['datadog']['windows_agent_use_exe']
dd_agent_installer = "#{dd_agent_installer_basename}.exe"
temp_file = "#{temp_file_basename}.exe"
installer_type = :custom
install_options = '/q'
else
dd_agent_installer = "#{dd_agent_installer_basename}.msi"
temp_file = "#{temp_file_basename}.msi"
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'
end

# Use a separate resource without a `source` so that it looks in the Registry to find the MSI to use
# for the package removal
# On Chef >= 12.6, we have to use the `package` resource instead of `windows_package` to allow not specifying a source
# (this is related to the way the windows cookbook changes the provider of `windows_package` depending on the
# version of Chef, and to improvements on the `package` resource made in Chef 12.6)
# FIXME: when we remove Chef < 12.6 support on Windows, which should allow using core resources only
use_windows_package_resource = Gem::Version.new(Chef::VERSION) < Gem::Version.new('12.6.0')
if use_windows_package_resource
windows_package 'Datadog Agent removal' do
package_name 'Datadog Agent'
action :nothing
end
else
package 'Datadog Agent removal' do
package_name 'Datadog Agent'
action :nothing
end
end

package_retries = node['datadog']['agent_package_retries']
package_retry_delay = node['datadog']['agent_package_retry_delay']

# Download the installer to a temp location
remote_file temp_file do
source node['datadog']['windows_agent_url'] + dd_agent_msi
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?
# 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
notifies :remove, 'windows_package[Datadog Agent]', :immediately
if use_windows_package_resource
notifies :remove, 'windows_package[Datadog Agent removal]', :immediately
else
notifies :remove, 'package[Datadog Agent removal]', :immediately
end
end

# Install the package
windows_package 'Datadog Agent' do # ~FC009
source temp_file
installer_type :msi
options '/norestart ALLUSERS=1'
installer_type installer_type
options install_options
action :install
success_codes [0, 3010]
end
26 changes: 22 additions & 4 deletions spec/dd-agent_spec.rb
Expand Up @@ -144,7 +144,7 @@ def set_env_var(name, value)
end

context 'on Windows' do
cached(:chef_run) do
cached(:chef_run) do
set_env_var('ProgramData', 'C:\ProgramData')
ChefSpec::SoloRunner.new(
:platform => 'windows',
Expand All @@ -155,7 +155,25 @@ def set_env_var(name, value)
end.converge described_recipe
end

it_behaves_like 'windows Datadog Agent'
it_behaves_like 'windows Datadog Agent', :msi
end

context 'on Windows with EXE installer' do
cached(:chef_run) do
set_env_var('ProgramData', 'C:\ProgramData')
ChefSpec::SoloRunner.new(
:platform => 'windows',
:version => '2012R2',
:file_cache_path => 'C:/chef/cache'
) do |node|
node.set['datadog'] = {
'api_key' => 'somethingnotnil',
'windows_agent_use_exe' => true
}
end.converge described_recipe
end

it_behaves_like 'windows Datadog Agent', :exe
end
end

Expand Down Expand Up @@ -231,7 +249,7 @@ def set_env_var(name, value)

temp_file = ::File.join('C:/chef/cache', 'ddagent-cli.msi')

it_behaves_like 'windows Datadog Agent'
it_behaves_like 'windows Datadog Agent', :msi
# remote_file source gets converted to an array, so we need to do
# some tricky things to be able to regex against it
# Relevant: http://stackoverflow.com/a/12325983
Expand Down Expand Up @@ -286,7 +304,7 @@ def set_env_var(name, value)

temp_file = ::File.join('C:/chef/cache', 'ddagent-cli.msi')

it_behaves_like 'windows Datadog Agent'
it_behaves_like 'windows Datadog Agent', :msi
# remote_file source gets converted to an array, so we need to do
# some tricky things to be able to regex against it
# Relevant: http://stackoverflow.com/a/12325983
Expand Down
15 changes: 10 additions & 5 deletions spec/shared_examples.rb
Expand Up @@ -72,20 +72,25 @@
end
end

shared_examples_for 'windows Datadog Agent' do
shared_examples_for 'windows Datadog Agent' do |installer_extension|
it_behaves_like 'common windows resources'

agent_installer = 'C:/chef/cache/ddagent-cli.msi'
agent_installer = "C:/chef/cache/ddagent-cli.#{installer_extension}"

it 'downloads the remote file only if it\'s changed' do
expect(chef_run).to create_remote_file(agent_installer)
end

it 'notifies the removal of the Datadog Agent' do
expect(chef_run.remote_file(agent_installer)).to notify('windows_package[Datadog Agent]').to(:remove)
it 'doesn\'t remove existing version of the Datadog Agent by default' do
expect(chef_run.package('Datadog Agent removal')).to do_nothing
end

it 'notifies the removal of the Datadog Agent when a remote file is downloaded' do
expect(chef_run.remote_file(agent_installer)).to notify('package[Datadog Agent removal]').to(:remove)
end

it 'installs Datadog Agent' do
expect(chef_run).to install_windows_package('Datadog Agent')
installer_type = installer_extension == :msi ? :msi : :custom
expect(chef_run).to install_windows_package('Datadog Agent').with(installer_type: installer_type)
end
end