Skip to content

Commit

Permalink
Use package resource, remote_file
Browse files Browse the repository at this point in the history
Previously a Powershell exec was used to install packages. This commit
converts that task to a package-based resource. It allows cleaner,
easier to read code.

Switch from download_file to remote_file. This allows for better
subscribe/notify of the dotnet defined type as remote_file does not have
any intermediate file fragment resources which may be used or changed
even if the file to download is not changed. The remote_file resource is
also platform agnostic, unlike download_file, more meaning it may be
accessible and familar to a wider range of potential users/contributors.

Update for Puppet 4 and remove deps

Use Puppet 4's type system to deal with validation and remove dependency
on stdlib. Use the $::os fact to get Windows release version and remove
dependency on windowsfacts.

Add logic to prevent incompatible versions

Some versions of .NET are in-place upgrades of others. Installation of
.NET 4.5, for example, will replace the 4.0 package. In order to
disallow Puppet from continuously trying to install .NET 4.0 in the
event dotnet resources for both 4.0 and 4.5 have been added to the
catalog, create a package=absent resource for each conflicting version.
This will cause the conflict to be caught when a catalog is compiled for
the node.

Add ability to recognize built-in .NET versions

Some OSes have some versions of .NET built in and so do not need to have
it installed via package. It seems likely this was auto-detected based
on registry key presence/absence via exec previously. Because we're now
managing the package directly, we should be more explicit about whether
or not the package actually needs to be installed.

Clean up installation type detection

Regex adjustments to make it easier to read which versions support which
installation types.

Only test on 4.x/future parser

Set gemfile to use PUPPET_GEM_VERSION and set default to 4.0

Adjust tests to match updates

This is not a comprehensive test overhaul, but does update the
functional tests to work with the updated code.

Logic correction - For 2008, .NET 3.5 is a package

Previously the dotnet define logic would attempt to install .NET 3.5 as
a feature on Server 2008. This was incorrect, as in Server 2008 .NET 3.5
was not available as a feature and needed the package installation.

Add Dism install type for Windows 7

Windows 7 does not install .NET as a package, nor does it have the
ServerManager module. Therefore provide an alternative means of managing
the feature via DISM.

Fix non-functional onlyif in powershell exec

The Puppet Exec resource uses the return code of command, unless, and
onlyif to determine success/failure or if action is necessary.
Previously, the onlyif in dotnet::install::feature would never exit with
a non-zero exit code, even if the Test-Path command returned a False
object. Return object and exit code are not the same thing.

This commit modifies the onlyif to ensure that if the Test-Path command
returns false a non-zero exit code will occur.

(style) Line up case blocks

Add feature parameter to dotnet::install::feature

This will allow specification of different feature names. Necessary
specifically because the feature name to install .NET 3.5 on Server 2012
is not the same feature as to install 4.5.

The feature name for .NET 3.5 in Server 2012 is not AS-NET-Framework,
which we use as the default feature. This commit also updates the dotnet
type to attempt installation of the correct feature when 3.5 is
specified on Server 2012.
  • Loading branch information
reidmv committed Feb 8, 2016
1 parent 1db0742 commit 2ddda63
Show file tree
Hide file tree
Showing 14 changed files with 351 additions and 622 deletions.
3 changes: 1 addition & 2 deletions .fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ fixtures:
repositories:
stdlib: https://github.com/puppetlabs/puppetlabs-stdlib
powershell: https://github.com/puppetlabs/puppetlabs-powershell
win_facts: https://github.com/liamjbennett/puppet-win_facts
download_file: https://github.com/opentable/puppet-download_file
remote_file: https://github.com/lwf/puppet-remote_file
symlinks:
dotnet: "#{source_dir}"
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ matrix:
fast_finish: true
include:
- rvm: 1.9.3
env: PUPPET_VERSION="~> 3.0" STRICT_VARIABLES="yes" CHECK=test
env: PUPPET_VERSION="~> 3.0" STRICT_VARIABLES="yes" CHECK=test FUTURE_PARSER="yes"
- rvm: 2.1.6
env: PUPPET_VERSION="~> 3.0" STRICT_VARIABLES="yes" CHECK=test
env: PUPPET_VERSION="~> 3.0" STRICT_VARIABLES="yes" CHECK=test FUTURE_PARSER="yes"
- rvm: 2.1.6
env: PUPPET_VERSION="~> 4.0" STRICT_VARIABLES="yes" CHECK=test
- rvm: 2.2.3
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ source 'https://rubygems.org'

group :test do
gem 'rake'
gem 'puppet', ENV['PUPPET_VERSION'] || '~> 3.8.0'
gem 'puppet', ENV['PUPPET_VERSION'] || '~> 4.0'
gem 'rspec-puppet', git: 'https://github.com/rodjek/rspec-puppet.git'
gem 'puppetlabs_spec_helper'
gem 'metadata-json-lint'
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ Ensures the state of .net on the system. Present or Absent.
The version of .net that you want to be managed by this definition.

#####`package_dir`
If installing .NET from a directory or a mounted network location then this is that directory
If installing .NET from a directory or a mounted network location then this is
that directory. If the version of .NET being installed is a Windows feature, it
may sometimes be necessary to specify package\_dir as the path to installation
media, such as `D:\sources\sxs`.

##Reference

Expand Down
103 changes: 72 additions & 31 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -31,54 +31,95 @@
# }
#
define dotnet(
$ensure = 'present',
$version = '',
$package_dir = ''
) {
Enum['3.5', '4.0', '4.5', '4.5.1', '4.5.2']
$version,

Enum['present', 'absent']
$ensure = 'present',

validate_re($ensure,['^(present|absent)$'])
validate_re($version,['^(3.5|4\.0|4\.5(\.\d)?)$'])
Variant[String, Undef]
$package_dir = undef,
) {

include dotnet::params

if $::os['family'] != 'windows' {
fail("dotnet ${version} is not supported on ${::os['family']}")
}

$windows_version = $::os['release']['full']

case $version {
'3.5': {
case $::operatingsystemversion {
/^Windows.Server.(2008|2012).?(R2)?.*/: { $type = 'feature' }
/^Windows (XP|Vista|7|8|8.1).*/: { $type = 'package' }
default: { $type = 'err' err("dotnet ${version} is not support on this version of windows") }
case $windows_version {
/^2012/: {
$type = 'feature'
$feature = 'NET-Framework-Features'
}
'2008 R2': { $type = 'feature' }
'7', '8', '8.1': { $type = 'dism' }
/^2003/, '2008', 'XP', 'Vista': { $type = 'package' }
default: { $type = 'err' }
}
}
'4.0': {
case $::operatingsystemversion {
/^Windows.(Server)?.?(2003|2008|2012|XP|Vista|7|8.*).?(R2)?.*/: { $type = 'package' }
default: { $type = 'err' err("dotnet ${version} is not support on this version of windows") }
case $windows_version {
/^2012/, '8', '8.1': { $type = 'builtin' }
/^2003/, /^2008/, 'XP', 'Vista', '7': { $type = 'package' }
default: { $type = 'err' }
}
}
/4\.5(\.\d)?/: {
case $::operatingsystemversion {
/^Windows.(Server)?.?(2008|2012|Vista|7|8.*).?(R2)?.*/: { $type = 'package' }
default: { $type = 'err' err("dotnet ${version} is not support on this version of windows") }
'4.5': {
case $windows_version {
/^2012/, '8', '8.1': { $type = 'builtin' }
/^2003/, /^2008/, 'XP', 'Vista', '7': { $type = 'package' }
default: { $type = 'err' }
}
}
default: {
$type = 'err'
err("dotnet does not have a version: ${version}")
'4.5.1': {
case $windows_version {
'2012 R2', '8.1': { $type = 'builtin' }
/^2003/, /^2008/, '2012', 'XP', 'Vista', '7', '8': { $type = 'package' }
default: { $type = 'err' }
}
}
'4.5.2': {
case $windows_version {
/^2003/, /^2008/, /^2012/, 'XP', 'Vista', '7', '8', '8.1': { $type = 'package' }
default: { $type = 'err' }
}
}
default: { $type = 'err' }
}

if $type == 'feature' {
dotnet::install::feature { "dotnet-feature-${version}":
ensure => $ensure,
version => $version
case $type {
'feature': {
dotnet::install::feature { "dotnet-feature-${version}":
ensure => $ensure,
version => $version,
feature => $feature,
source => $package_dir,
}
}
} elsif $type == 'package' {
dotnet::install::package { "dotnet-package-${version}":
ensure => $ensure,
version => $version,
package_dir => $package_dir
'dism': {
dotnet::install::dism { "dotnet-dism-${version}":
ensure => $ensure,
version => $version,
}
}
'package': {
dotnet::install::package { "dotnet-package-${version}":
ensure => $ensure,
version => $version,
package_dir => $package_dir,
}
}
'builtin': {
# This .NET version is built into the OS. No configuration required.
}
default: {
fail("dotnet ${version} is not supported on windows ${windows_version}")
}
} else {

}

}
23 changes: 23 additions & 0 deletions manifests/install/dism.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
define dotnet::install::dism (
$ensure = 'present',
$version = '',
) {

if $ensure == 'present' {
exec { "install-dotnet-dism-${version}":
command => 'DISM /Online /Enable-Feature /FeatureName:NetFx3 /NoRestart',
creates => "C:/Windows/Microsoft.NET/Framework/v${version}",
provider => powershell,
logoutput => true,
}
} else {
exec { "uninstall-dotnet-dism-${version}":
command => 'DISM /Online /Disable-Feature /FeatureName:NetFx3 /NoRestart',
onlyif => "If (-Not(Test-Path C:/Windows/Microsoft.NET/Framework/v${version})) { Exit 1 }",
provider => powershell,
logoutput => true,
}
}

}
23 changes: 15 additions & 8 deletions manifests/install/feature.pp
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
#
define dotnet::install::feature(
$ensure = 'present',
$version = ''
$version,
$ensure = 'present',
$feature = 'AS-NET-Framework',
$source = undef,
) {

$source_flag = $source ? {
undef => '',
default => "-source ${source}",
}

if $ensure == 'present' {
exec { "install-feature-${version}":
command => 'Import-Module ServerManager; Add-WindowsFeature as-net-framework',
exec { "install-dotnet-feature-${version}":
command => "Import-Module ServerManager; Add-WindowsFeature ${feature} ${source_flag}",
provider => powershell,
logoutput => true,
unless => "Test-Path C:\\Windows\\Microsoft.NET\\Framework\\v${version}",
creates => "C:/Windows/Microsoft.NET/Framework/v${version}",
}
} else {
exec { "uninstall-feature-${version}":
command => 'Import-Module ServerManager; Remove-WindowsFeature as-net-framework',
exec { "uninstall-dotnet-feature-${version}":
command => "Import-Module ServerManager; Remove-WindowsFeature ${feature}",
provider => powershell,
logoutput => true,
onlyif => "Test-Path C:\\Windows\\Microsoft.NET\\Framework\\v${version}",
onlyif => "If (-Not(Test-Path C:/Windows/Microsoft.NET/Framework/v${version})) { Exit 1 }",
}
}

Expand Down
59 changes: 30 additions & 29 deletions manifests/install/package.pp
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
#
define dotnet::install::package(
$ensure = 'present',
$version = '',
$ensure = 'present',
$version = '',
$package_dir = ''
) {

include dotnet::params

$url = $dotnet::params::version[$version]['url']
$exe = $dotnet::params::version[$version]['exe']
$key = $dotnet::params::version[$version]['key']

$url = $dotnet::params::version[$version]['url']
$exe = $dotnet::params::version[$version]['exe']
$package = $dotnet::params::version[$version]['package']
$conflicts = $dotnet::params::version[$version]['conflicts']

if "x${package_dir}x" == 'xx' {
$source_dir = 'C:\Windows\Temp'
if $ensure == 'present' {
download_file { "download-dotnet-${version}" :
url => $url,
destination_directory => $source_dir
}
} else {
file { "C:/Windows/Temp/${exe}":
ensure => absent
}
$source_file = "C:/Windows/Temp/${exe}"
remote_file { $source_file:
ensure => $ensure,
source => $url,
}
} else {
$source_dir = $package_dir
$source_file = "${package_dir}/${exe}"
}

package { $package:
ensure => $ensure,
source => $source_file,
install_options => ['/q', '/norestart'],
uninstall_options => ['/x', '/q', '/norestart'],
}

if $ensure == 'present' {
exec { "install-dotnet-${version}":
command => "& ${source_dir}\\${exe} /q /norestart",
provider => powershell,
logoutput => true,
unless => "if ((Get-Item -LiteralPath \'${key}\' -ErrorAction SilentlyContinue).GetValue(\'DisplayVersion\')) { exit 0 }"
}
} else {
exec { "uninstall-dotnet-${version}":
command => "& ${source_dir}\\${exe} /x /q /norestart",
provider => powershell,
logoutput => true,
unless => "if ((Get-Item -LiteralPath \'${key}\' -ErrorAction SilentlyContinue).GetValue(\'DisplayVersion\')) { exit 1 }"
# Some versions of .NET are in-place upgrades of others. Installation of
# .NET 4.5, for example, will replace the 4.0 package. In order to disallow
# Puppet from continuously trying to install .NET 4.0 in the event dotnet
# resources for both 4.0 and 4.5 have been added to the catalog, create a
# package=absent resource for each conflicting version. This will cause the
# conflict to be caught when a catalog is compiled for the node.
$conflicts.each |$conflict| {
package { $dotnet::params::version[$conflict]['package']:
ensure => absent,
before => Package[$package],
uninstall_options => ['/x', '/q', '/norestart'],
}
}
}

Expand Down
41 changes: 25 additions & 16 deletions manifests/params.pp
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,38 @@

$version = {
'3.5' => {
'url' => 'http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe',
'exe' => 'dotNetFx35setup.exe',
'key' => 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{CE2CDD62-0124-36CA-84D3-9F4DCF5C5BD9}'
'url' => 'http://download.microsoft.com/download/7/0/3/703455ee-a747-4cc8-bd3e-98a615c3aedb/dotNetFx35setup.exe',
'exe' => 'dotNetFx35setup.exe',
'conflicts' => [ ],
'package' => 'Microsoft .NET Framework 3.5',
},
'4.0' => {
'url' => 'http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe',
'exe' => 'dotNetFx40_Full_x86_x64.exe',
'key' => 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{8E34682C-8118-31F1-BC4C-98CD9675E1C2}'
'url' => 'http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe',
'exe' => 'dotNetFx40_Full_x86_x64.exe',
'conflicts' => ['4.5', '4.5.1', '4.5.2'],
'package' => [
'Microsoft .NET Framework 4 Extended',
'Microsoft .NET Framework 4 Client Profile',
],
},
'4.5' => {
'url' => 'http://download.microsoft.com/download/b/a/4/ba4a7e71-2906-4b2d-a0e1-80cf16844f5f/dotnetfx45_full_x86_x64.exe',
'exe' => 'dotnetfx45_full_x86_x64.exe',
'key' => 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1AD147D0-BE0E-3D6C-AC11-64F6DC4163F1}'
'4.5' => {
'url' => 'http://download.microsoft.com/download/b/a/4/ba4a7e71-2906-4b2d-a0e1-80cf16844f5f/dotnetfx45_full_x86_x64.exe',
'exe' => 'dotnetfx45_full_x86_x64.exe',
'conflicts' => ['4.0', '4.5.1', '4.5.2'],
'package' => 'Microsoft .NET Framework 4.5',
},
'4.5.1' => {
'url' => 'http://download.microsoft.com/download/1/6/7/167F0D79-9317-48AE-AEDB-17120579F8E2/NDP451-KB2858728-x86-x64-AllOS-ENU.exe',
'exe' => 'NDP451-KB2858728-x86-x64-AllOS-ENU.exe',
'key' => 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{7DEBE4EB-6B40-3766-BB35-5CBBC385DA37}'
'url' => 'http://download.microsoft.com/download/1/6/7/167F0D79-9317-48AE-AEDB-17120579F8E2/NDP451-KB2858728-x86-x64-AllOS-ENU.exe',
'exe' => 'NDP451-KB2858728-x86-x64-AllOS-ENU.exe',
'conflicts' => ['4.0', '4.5', '4.5.2'],
'package' => 'Microsoft .NET Framework 4.5.1',
},
'4.5.2' => {
'url' => 'http://download.microsoft.com/download/E/2/1/E21644B5-2DF2-47C2-91BD-63C560427900/NDP452-KB2901907-x86-x64-AllOS-ENU.exe',
'exe' => 'NDP452-KB2901907-x86-x64-AllOS-ENU.exe',
'key' => 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{26784146-6E05-3FF9-9335-786C7C0FB5BE}'
'url' => 'http://download.microsoft.com/download/E/2/1/E21644B5-2DF2-47C2-91BD-63C560427900/NDP452-KB2901907-x86-x64-AllOS-ENU.exe',
'exe' => 'NDP452-KB2901907-x86-x64-AllOS-ENU.exe',
'conflicts' => ['4.0', '4.5', '4.5.1'],
'package' => 'Microsoft .NET Framework 4.5.2',
}
}

}
Loading

0 comments on commit 2ddda63

Please sign in to comment.