win_chocolatey - honour version when bootstrapping chocolatey and fix package listing (#57208)

* win_chocolatey - honour version when bootstrapping chocolatey

* skip upgrade all step

* Fix install latest step

* Remove test changes now that Chocolatey is released

* tweak the package version detection
This commit is contained in:
Jordan Borean 2019-06-05 09:10:10 +10:00 committed by GitHub
parent b1e6ad9754
commit b5b75daaa5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 99 additions and 47 deletions

View file

@ -0,0 +1,3 @@
bugfixes:
- win_chocolatey - Install the specific Chocolatey version if the ``version`` option is set.
- win_chocolatey - Better support detecting multiple packages installed at different versions on newer Chocolatey releases

View file

@ -194,7 +194,8 @@ Function Install-Chocolatey {
[String]$proxy_password, [String]$proxy_password,
[String]$source, [String]$source,
[String]$source_username, [String]$source_username,
[String]$source_password [String]$source_password,
[String]$version
) )
$choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue $choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue
@ -211,21 +212,31 @@ Function Install-Chocolatey {
[Net.ServicePointManager]::SecurityProtocol = $security_protocols [Net.ServicePointManager]::SecurityProtocol = $security_protocols
$client = New-Object -TypeName System.Net.WebClient $client = New-Object -TypeName System.Net.WebClient
$environment = @{} $new_environment = @{}
if ($proxy_url) { if ($proxy_url) {
# the env values are used in the install.ps1 script when getting # the env values are used in the install.ps1 script when getting
# external dependencies # external dependencies
$environment = [Environment]::GetEnvironmentVariables() $new_environment.chocolateyProxyLocation = $proxy_url
$environment.chocolateyProxyLocation = $proxy_url
$web_proxy = New-Object -TypeName System.Net.WebProxy -ArgumentList $proxy_url, $true $web_proxy = New-Object -TypeName System.Net.WebProxy -ArgumentList $proxy_url, $true
$client.Proxy = $web_proxy $client.Proxy = $web_proxy
if ($proxy_username -and $proxy_password) { if ($proxy_username -and $proxy_password) {
$environment.chocolateyProxyUser = $proxy_username $new_environment.chocolateyProxyUser = $proxy_username
$environment.chocolateyProxyPassword = $proxy_password $new_environment.chocolateyProxyPassword = $proxy_password
$sec_proxy_password = ConvertTo-SecureString -String $proxy_password -AsPlainText -Force $sec_proxy_password = ConvertTo-SecureString -String $proxy_password -AsPlainText -Force
$web_proxy.Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $proxy_username, $sec_proxy_password $web_proxy.Credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $proxy_username, $sec_proxy_password
} }
} }
if ($version) {
# Set the chocolateyVersion environment variable when bootstrapping Chocolatey to install that specific
# version.
$new_environment.chocolateyVersion = $version
}
$environment = @{}
if ($new_environment.Count -gt 0) {
$environment = [Environment]::GetEnvironmentVariables()
$environment += $new_environment
}
if ($source) { if ($source) {
# check if the URL already contains the path to PS script # check if the URL already contains the path to PS script
@ -319,12 +330,21 @@ Function Install-Chocolatey {
} }
Function Get-ChocolateyPackageVersion { Function Get-ChocolateyPackageVersion {
param( Param (
[Parameter(Mandatory=$true)][String]$choco_path, [Parameter(Mandatory=$true)]
[Parameter(Mandatory=$true)][String]$name [System.String]
$choco_path,
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[System.String]
$name
) )
$command = Argv-ToString -arguments @($choco_path, "list", "--local-only", "--exact", "--limit-output", "--all-versions", $name) Begin {
# Due to https://github.com/chocolatey/choco/issues/1843, we get a list of all the installed packages and
# filter it ourselves. This has the added benefit of being quicker when dealing with multiple packages as we
# only call choco.exe once.
$command = Argv-ToString -arguments @($choco_path, 'list', '--local-only', '--limit-output', '--all-versions')
$res = Run-Command -command $command $res = Run-Command -command $command
# Chocolatey v0.10.12 introduced enhanced exit codes, 2 means no results, e.g. no package # Chocolatey v0.10.12 introduced enhanced exit codes, 2 means no results, e.g. no package
@ -333,17 +353,39 @@ Function Get-ChocolateyPackageVersion {
$module.Result.rc = $res.rc $module.Result.rc = $res.rc
$module.Result.stdout = $res.stdout $module.Result.stdout = $res.stdout
$module.Result.stderr = $res.stderr $module.Result.stderr = $res.stderr
$module.FailJson("Error checking installation status for the package '$name'") $module.FailJson('Error checking installation status for chocolatey packages')
}
$stdout = $res.stdout.Trim()
$versions = $null
if ($stdout) {
# if a match occurs it is in the format of "package|version" we split
# by the last | to get the version in case package contains a pipe char
$versions = @($stdout.Split("`r`n", [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { $_.Substring($_.LastIndexOf("|") + 1) })
} }
return ,$versions # Parse the stdout to get a list of all packages installed and their versions.
$installed_packages = $res.stdout.Trim().Split([System.Environment]::NewLine) | ForEach-Object -Process {
if ($_.Contains('|')) { # Sanity in case further output is added in the future.
$package_split = $_.Split('|', 2)
@{ Name = $package_split[0]; Version = $package_split[1] }
}
}
# Create a hashtable that will store our package version info.
$installed_info = @{}
}
Process {
if ($name -eq 'all') {
# All is a special package name that means all installed packages, we set a dummy version so absent, latest
# and downgrade will run with all.
$installed_info.'all' = @('0.0.0')
} else {
$package_info = $installed_packages | Where-Object { $_.Name -eq $name }
if ($null -eq $package_info) {
$installed_info.$name = $null
} else {
$installed_info.$name = @($package_info.Version)
}
}
}
End {
return $installed_info
}
} }
Function Get-ChocolateyPin { Function Get-ChocolateyPin {
@ -618,25 +660,27 @@ Function Uninstall-ChocolateyPackage {
} }
# get the full path to choco.exe, otherwise install/upgrade to at least 0.10.5 # get the full path to choco.exe, otherwise install/upgrade to at least 0.10.5
$choco_path = Install-Chocolatey -proxy_url $proxy_url -proxy_username $proxy_username ` $install_params = @{
-proxy_password $proxy_password -source $source -source_username $source_username ` proxy_url = $proxy_url
-source_password $source_password proxy_username = $proxy_username
proxy_password = $proxy_password
source = $source
source_username = $source_username
source_password = $source_password
}
if ($version -and "chocolatey" -in $name) {
# If a version is set and chocolatey is in the package list, pass the chocolatey version to the bootstrapping
# process.
$install_params.version = $version
}
$choco_path = Install-Chocolatey @install_params
# get the version of all specified packages if ('all' -in $name -and $state -in @('present', 'reinstalled')) {
$package_info = @{}
foreach ($package in $name) {
# all is a special package name that means all installed packages, we set
# a dummy version so absent, latest, and downgrade will run with all
if ($package -eq "all") {
if ($state -in @("present", "reinstalled")) {
$module.FailJson("Cannot specify the package name as 'all' when state=$state") $module.FailJson("Cannot specify the package name as 'all' when state=$state")
} }
$package_versions = @("0.0.0")
} else { # get the version of all specified packages
$package_versions = Get-ChocolateyPackageVersion -choco_path $choco_path -name $package $package_info = $name | Get-ChocolateyPackageVersion -choco_path $choco_path
}
$package_info.$package = $package_versions
}
if ($state -in "absent", "reinstalled") { if ($state -in "absent", "reinstalled") {
$installed_packages = ($package_info.GetEnumerator() | Where-Object { $null -ne $_.Value }).Key $installed_packages = ($package_info.GetEnumerator() | Where-Object { $null -ne $_.Value }).Key

View file

@ -211,6 +211,9 @@ options:
- Provide as a string (e.g. C('6.1')), otherwise it is considered to be - Provide as a string (e.g. C('6.1')), otherwise it is considered to be
a floating-point number and depending on the locale could become C(6,1), a floating-point number and depending on the locale could become C(6,1),
which will cause a failure. which will cause a failure.
- If I(name) is set to C(chocolatey) and Chocolatey is not installed on the
host, this will be the version of Chocolatey that is installed. You can
also set the C(chocolateyVersion) environment var.
type: str type: str
notes: notes:
- This module will install or upgrade Chocolatey when needed. - This module will install or upgrade Chocolatey when needed.

View file

@ -468,14 +468,15 @@
register: allow_multiple register: allow_multiple
- name: get result of install older package with allow_multiple - name: get result of install older package with allow_multiple
win_command: choco.exe list --local-only --limit-output --all-versions --exact {{ test_choco_package1|quote }} win_command: choco.exe list --local-only --limit-output --all-versions
register: allow_multiple_actual register: allow_multiple_actual
- name: assert install older package with allow_multiple - name: assert install older package with allow_multiple
assert: assert:
that: that:
- allow_multiple is changed - allow_multiple is changed
- allow_multiple_actual.stdout == "ansible|0.1.0\r\nansible|0.0.1\r\n" - '"ansible|0.1.0" in allow_multiple_actual.stdout_lines'
- '"ansible|0.0.1" in allow_multiple_actual.stdout_lines'
- name: pin 2 packages (check mode) - name: pin 2 packages (check mode)
win_chocolatey: win_chocolatey:
@ -593,11 +594,12 @@
register: remove_multiple register: remove_multiple
- name: get result of uninstall specific version installed with allow_multiple - name: get result of uninstall specific version installed with allow_multiple
win_command: choco.exe list --local-only --limit-output --all-versions --exact {{ test_choco_package1|quote }} win_command: choco.exe list --local-only --limit-output --all-versions
register: remove_multiple_actual register: remove_multiple_actual
- name: assert uninstall specific version installed with allow_multiple - name: assert uninstall specific version installed with allow_multiple
assert: assert:
that: that:
- remove_multiple is changed - remove_multiple is changed
- remove_multiple_actual.stdout == "ansible|0.1.0\r\n" - '"ansible|0.0.1" not in remove_multiple_actual.stdout_lines'
- '"ansible|0.1.0" in remove_multiple_actual.stdout_lines'