From 1a0b86243406026fa2d8e388fb0464b1378f3a3e Mon Sep 17 00:00:00 2001 From: Amade Kovacs Date: Fri, 13 Jul 2018 17:06:37 +0200 Subject: [PATCH 1/3] Fixing issues when puppet runs as service If puppet runs as service the following exceptions are raised: The server threw an exception. (Exception from HRESULT: 0x80010105 (RPC_E_SERVERFAULT)) You cannot call a method on a null-valued expression. Surrunded the method with try-catch and added better error handling logic Added a "virtual" provider and .NET based method, which is available from windows .NET 4.5 (Windows 8) and made it default. But left the original as a fallback. --- manifests/unzip.pp | 18 +++++++++++++++--- templates/unzip.ps1.erb | 25 ++++++++++++++++++++++--- templates/unzip_dotnet.ps1.erb | 21 +++++++++++++++++++++ 3 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 templates/unzip_dotnet.ps1.erb diff --git a/manifests/unzip.pp b/manifests/unzip.pp index e8686da..f519c31 100644 --- a/manifests/unzip.pp +++ b/manifests/unzip.pp @@ -50,10 +50,10 @@ $refreshonly = false, $unless = undef, $zipfile = $name, - $provider = 'powershell', + $provider = 'dotnet', $options = '20', - $command_template = 'windows/unzip.ps1.erb', $timeout = 300, + $logoutput = on_failure, ) { validate_absolute_path($destination) @@ -61,12 +61,24 @@ fail("Must set one of creates, refreshonly, or unless parameters.\n") } + unless( $provider == 'dotnet' or $provider == 'com'){ + fail("Wrong provider: `${provider}', choices are: dotnet or com!\n") + } + + if ($provider == 'dotnet'){ + $command_template = 'windows/unzip_dotnet.ps1.erb' + }else{ + $command_template = 'windows/unzip.ps1.erb' + } + + exec { "unzip-${name}": command => template($command_template), creates => $creates, refreshonly => $refreshonly, unless => $unless, - provider => $provider, + provider => powershell, timeout => $timeout, + logoutput => $logoutput, } } diff --git a/templates/unzip.ps1.erb b/templates/unzip.ps1.erb index 553728c..6ac1632 100644 --- a/templates/unzip.ps1.erb +++ b/templates/unzip.ps1.erb @@ -1,3 +1,22 @@ -$shell = New-Object -COMObject Shell.Application; -$zipfile = $shell.NameSpace("<%= @zipfile %>"); -foreach($item in $zipfile.Items()){ $shell.NameSpace("<%= @destination %>").CopyHere($item, <%= @options %>) }; \ No newline at end of file +$zipFile="<%= @zipfile %>" +$dst="<%= @destination %>" + +if ( ! (Test-Path $zipfile) ) { + write-error "ZIP file does not exists: `$zipFile'" + exit 1 +} + +if ( ! (Test-Path $dst) ) { + write-error "Missing destination folder: `$dst'" + exit 1 +} + +try { + $shell = New-Object -COMObject Shell.Application; + $zipfile = $shell.NameSpace("<%= @zipfile %>"); + foreach($item in $zipfile.Items()){ $shell.NameSpace("<%= @destination %>").CopyHere($item, <%= @options %>) }; +} +catch { + write-error $_ + exit 1 +} diff --git a/templates/unzip_dotnet.ps1.erb b/templates/unzip_dotnet.ps1.erb new file mode 100644 index 0000000..f38fcd8 --- /dev/null +++ b/templates/unzip_dotnet.ps1.erb @@ -0,0 +1,21 @@ +$zipFile="<%= @zipfile %>" +$dst="<%= @destination %>" + +if ( ! (Test-Path $zipfile) ) { + write-error "ZIP file does not exists: ``$zipFile'" + exit 1 +} + +if ( ! (Test-Path $dst) ) { + write-error "Missing destination folder: ``$dst'" + exit 1 +} + +try { + Add-Type -A System.IO.Compression.FileSystem + [IO.Compression.ZipFile]::ExtractToDirectory($zipFile, $dst) +} +catch { + write-error $_ + exit 1 +} From f05caf0a342dcab7a8395e0ba8eaa30e89cb5ceb Mon Sep 17 00:00:00 2001 From: Amade Kovacs Date: Mon, 16 Jul 2018 12:49:08 +0200 Subject: [PATCH 2/3] Updated readme and fixed spacing. --- README.md | 10 ++++++++++ manifests/unzip.pp | 6 +++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ba49636..5a749fe 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,16 @@ windows::unzip { 'C:\compressed.zip': } ``` +If you don't have .NET 4.5 installed you can fallback to COM based method but it can fail if puppet runs as service. + +```puppet +windows::unzip { 'C:\compressed.zip': + destination => 'C:\dest', + creates => 'C:\dest\uncompressed.txt', + provider => 'com' +} +``` + This assumes that the file `uncompressed.txt` exists in `C:\compressed.zip` License diff --git a/manifests/unzip.pp b/manifests/unzip.pp index f519c31..d87c150 100644 --- a/manifests/unzip.pp +++ b/manifests/unzip.pp @@ -61,13 +61,13 @@ fail("Must set one of creates, refreshonly, or unless parameters.\n") } - unless( $provider == 'dotnet' or $provider == 'com'){ + unless ($provider == 'dotnet' or $provider == 'com'){ fail("Wrong provider: `${provider}', choices are: dotnet or com!\n") } - if ($provider == 'dotnet'){ + if ($provider == 'dotnet'){ $command_template = 'windows/unzip_dotnet.ps1.erb' - }else{ + } else{ $command_template = 'windows/unzip.ps1.erb' } From a2f3e5bbf46bb7a2368bcab5c9fd847d60785dea Mon Sep 17 00:00:00 2001 From: Amade Kovacs Date: Mon, 16 Jul 2018 21:05:28 +0200 Subject: [PATCH 3/3] Set provider back to original implementation to not to break existing deployments. Modified readme to match with the ipmlementation. --- README.md | 2 +- manifests/unzip.pp | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5a749fe..a124769 100644 --- a/README.md +++ b/README.md @@ -138,7 +138,7 @@ If you don't have .NET 4.5 installed you can fallback to COM based method but it windows::unzip { 'C:\compressed.zip': destination => 'C:\dest', creates => 'C:\dest\uncompressed.txt', - provider => 'com' + fallback => true, } ``` diff --git a/manifests/unzip.pp b/manifests/unzip.pp index d87c150..bcaa58a 100644 --- a/manifests/unzip.pp +++ b/manifests/unzip.pp @@ -50,10 +50,11 @@ $refreshonly = false, $unless = undef, $zipfile = $name, - $provider = 'dotnet', + $provider = 'powershell', $options = '20', $timeout = 300, $logoutput = on_failure, + $fallback = false, ) { validate_absolute_path($destination) @@ -61,23 +62,18 @@ fail("Must set one of creates, refreshonly, or unless parameters.\n") } - unless ($provider == 'dotnet' or $provider == 'com'){ - fail("Wrong provider: `${provider}', choices are: dotnet or com!\n") - } - - if ($provider == 'dotnet'){ - $command_template = 'windows/unzip_dotnet.ps1.erb' - } else{ + if ($fallback){ $command_template = 'windows/unzip.ps1.erb' + } else{ + $command_template = 'windows/unzip_dotnet.ps1.erb' } - exec { "unzip-${name}": command => template($command_template), creates => $creates, refreshonly => $refreshonly, unless => $unless, - provider => powershell, + provider => $provider, timeout => $timeout, logoutput => $logoutput, }