Skip to content

Commit

Permalink
(chocolatey-archiveGH-60) fix upgrade/installation Filestream errors …
Browse files Browse the repository at this point in the history
…on PSv2

Powershell version 2, has several issues in handling output
redirection

This is best documented here:
https://connect.microsoft.com/PowerShell/feedback/details/587165/
powershell-double-redirection-problem

Another obscure bug that occurs in powershell is here.
https://connect.microsoft.com/PowerShell/feedback/details/371321/
benign-errors-for-missing-closing-are-left-in-the-error-variable

These 2 issues are compounded in the provider, because the benign
error sent to $error, then triggers the double redirection issue
within puppet.  This will automatically fail the resource.

This patch is confined to Powershell v2 (Win2008r2/Win7) and
essentially captures the output from running chocolateyInstall.ps1
via a variable. We can now see the errors that are thrown instead
of the FileStream errors in a log stored here:
$env:TEMP\chocoError.log

While this may cause a false positive success to be returned to
puppet, IMHO this is better than a false failure, based on upstream
legacy bugs to be returned, particularly because of the transparency
around the $error content.

This fix leaves the existing logic intact for Powershell versions
greater than 2 as I have not observed this behavior on them.

Additionally write-host calls were switched to write-output as a best
practice to avoid observed Filestream errors within this edge case.

The recommendation to avoid this scenario altogether on Win2008r2
is to install .NET 4.5 and then WMF 4.0, or use Win2012+
  • Loading branch information
rismoney committed Oct 2, 2015
1 parent e9816c9 commit 9f37995
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions templates/InstallChocolatey.ps1.erb
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ $chocTempDir = Join-Path $env:TEMP "chocolatey"
$tempDir = Join-Path $chocTempDir "chocInstall"
if (![System.IO.Directory]::Exists($tempDir)) {[System.IO.Directory]::CreateDirectory($tempDir)}
$file = Join-Path $tempDir "chocolatey.zip"
$chocErrorLog = Join-Path $tempDir "chocError.log"

function Download-File {
param (
[string]$url,
[string]$file
)
Write-Host "Downloading $url to $file"
Write-Output "Downloading $url to $file"
$downloader = new-object System.Net.WebClient
$downloader.Proxy.Credentials=[System.Net.CredentialCache]::DefaultNetworkCredentials;
$downloader.DownloadFile($url, $file)
Expand All @@ -47,13 +48,13 @@ Download-File $url $file

if ($unzipMethod -eq '7zip') {
# download 7zip
Write-Host "Download 7Zip commandline tool"
Write-Output "Download 7Zip commandline tool"
$7zaExe = Join-Path $tempDir '7za.exe'

Download-File 'https://chocolatey.org/7za.exe' "$7zaExe"

# unzip the package
Write-Host "Extracting $file to $tempDir..."
Write-Output "Extracting $file to $tempDir..."
Start-Process "$7zaExe" -ArgumentList "x -o`"$tempDir`" -y `"$file`"" -Wait -NoNewWindow
} else {
$shellApplication = new-object -com shell.application
Expand All @@ -63,13 +64,21 @@ if ($unzipMethod -eq '7zip') {
}

# call chocolatey install
Write-Host "Installing chocolatey on this machine"
Write-Output "Installing chocolatey on this machine"
$toolsFolder = Join-Path $tempDir "tools"
$chocInstallPS1 = Join-Path $toolsFolder "chocolateyInstall.ps1"

& $chocInstallPS1
if ($PSVersionTable.psversion.Major -gt 2) {
& $chocInstallPS1
}
else {
$output = Invoke-Expression $chocInstallPS1
$output
write-output "Any errors that occured during install or upgrade are logged here: $chocoErrorLog"
$error | out-file $chocErrorLog
}

Write-Host 'Ensuring chocolatey commands are on the path'
Write-Output 'Ensuring chocolatey commands are on the path'
$chocInstallVariableName = "ChocolateyInstall"
$chocoPath = [Environment]::GetEnvironmentVariable($chocInstallVariableName, [System.EnvironmentVariableTarget]::User)
if ($chocoPath -eq $null -or $chocoPath -eq '') {
Expand All @@ -82,7 +91,7 @@ if ($($env:Path).ToLower().Contains($($chocoBinPath).ToLower()) -eq $false) {
$env:Path = [Environment]::GetEnvironmentVariable('Path',[System.EnvironmentVariableTarget]::Machine);
}

Write-Host 'Ensuring chocolatey.nupkg is in the lib folder'
Write-Output 'Ensuring chocolatey.nupkg is in the lib folder'
$chocoPkgDir = Join-Path $chocoPath 'lib\chocolatey'
$nupkg = Join-Path $chocoPkgDir 'chocolatey.nupkg'
if (![System.IO.Directory]::Exists($chocoPkgDir)) { [System.IO.Directory]::CreateDirectory($chocoPkgDir); }
Expand Down

0 comments on commit 9f37995

Please sign in to comment.