mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-26 22:51:23 -07:00
win_chocolatey - move over to AnsibleModule and add allow_multiple (#48370)
This commit is contained in:
parent
d6bd842c5f
commit
9ac89af355
5 changed files with 246 additions and 125 deletions
3
changelogs/fragments/win_chocolatey-allow-multiple.yaml
Normal file
3
changelogs/fragments/win_chocolatey-allow-multiple.yaml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
minor_changes:
|
||||||
|
- win_chocolatey - added the allow_multiple module option to allow side by side installs of the same package
|
||||||
|
- win_chocolatey - support bootstrapping Chocolatey from other URLs with any PS script that ends with ``.ps1``, originally this script had to be ``install.ps1``
|
|
@ -7,44 +7,63 @@
|
||||||
|
|
||||||
#Requires -Module Ansible.ModuleUtils.ArgvParser
|
#Requires -Module Ansible.ModuleUtils.ArgvParser
|
||||||
#Requires -Module Ansible.ModuleUtils.CommandUtil
|
#Requires -Module Ansible.ModuleUtils.CommandUtil
|
||||||
#Requires -Module Ansible.ModuleUtils.Legacy
|
#AnsibleRequires -CSharpUtil Ansible.Basic
|
||||||
|
|
||||||
$ErrorActionPreference = 'Stop'
|
|
||||||
|
|
||||||
# As of chocolatey 0.9.10, non-zero success exit codes can be returned
|
# As of chocolatey 0.9.10, non-zero success exit codes can be returned
|
||||||
# See https://github.com/chocolatey/choco/issues/512#issuecomment-214284461
|
# See https://github.com/chocolatey/choco/issues/512#issuecomment-214284461
|
||||||
$successexitcodes = (0, 1605, 1614, 1641, 3010)
|
$successexitcodes = (0, 1605, 1614, 1641, 3010)
|
||||||
|
|
||||||
$params = Parse-Args $args -supports_check_mode $true
|
$spec = @{
|
||||||
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
|
options = @{
|
||||||
$verbosity = Get-AnsibleParam -obj $params -name "_ansible_verbosity" -type "int" -default 0
|
allow_empty_checksums = @{ type = "bool"; default = $false }
|
||||||
|
allow_multiple = @{ type = "bool"; default = $false }
|
||||||
$name = Get-AnsibleParam -obj $params -name "name" -type "list" -failifempty $true
|
allow_prerelease = @{ type = "bool"; default = $false }
|
||||||
|
architecture = @{ type = "str"; default = "default"; choices = "default", "x86" }
|
||||||
$allow_empty_checksums = Get-AnsibleParam -obj $params -name "allow_empty_checksums" -type "bool" -default $false
|
install_args = @{ type = "str" }
|
||||||
$allow_prerelease = Get-AnsibleParam -obj $params -name "allow_prerelease" -type "bool" -default $false
|
ignore_checksums = @{ type = "bool"; default = $false }
|
||||||
$architecture = Get-AnsibleParam -obj $params -name "architecture" -type "str" -default "default" -validateset "default", "x86"
|
ignore_dependencies = @{ type = "bool"; default = $false }
|
||||||
$install_args = Get-AnsibleParam -obj $params -name "install_args" -type "str"
|
force = @{ type = "bool"; default = $false }
|
||||||
$ignore_checksums = Get-AnsibleParam -obj $params -name "ignore_checksums" -type "bool" -default $false
|
name = @{ type = "list"; elements = "str"; required = $true }
|
||||||
$ignore_dependencies = Get-AnsibleParam -obj $params -name "ignore_dependencies" -type "bool" -default $false
|
package_params = @{ type = "str"; aliases = "params" }
|
||||||
$force = Get-AnsibleParam -obj $params -name "force" -type "bool" -default $false
|
proxy_url = @{ type = "str" }
|
||||||
$package_params = Get-AnsibleParam -obj $params -name "package_params" -type "str" -aliases "params"
|
proxy_username = @{ type = "str" }
|
||||||
$proxy_url = Get-AnsibleParam -obj $params -name "proxy_url" -type "str"
|
proxy_password = @{ type = "str"; no_log = $true }
|
||||||
$proxy_username = Get-AnsibleParam -obj $params -name "proxy_username" -type "str"
|
skip_scripts = @{ type = "bool"; default = $false }
|
||||||
$proxy_password = Get-AnsibleParam -obj $params -name "proxy_password" -type "str" -failifempty ($null -ne $proxy_username)
|
source = @{ type = "str" }
|
||||||
$skip_scripts = Get-AnsibleParam -obj $params -name "skip_scripts" -type "bool" -default $false
|
source_username = @{ type = "str" }
|
||||||
$source = Get-AnsibleParam -obj $params -name "source" -type "str"
|
source_password = @{ type = "str"; no_log = $true }
|
||||||
$source_username = Get-AnsibleParam -obj $params -name "source_username" -type "str"
|
state = @{ type = "str"; default = "present"; choices = "absent", "downgrade", "latest", "present", "reinstalled" }
|
||||||
$source_password = Get-AnsibleParam -obj $params -name "source_password" -type "str" -failifempty ($null -ne $source_username)
|
timeout = @{ type = "int"; default = 2700; aliases = "execution_timeout" }
|
||||||
$state = Get-AnsibleParam -obj $params -name "state" -type "str" -default "present" -validateset "absent","downgrade","latest","present","reinstalled"
|
validate_certs = @{ type = "bool"; default = $false }
|
||||||
$timeout = Get-AnsibleParam -obj $params -name "timeout" -type "int" -default 2700 -aliases "execution_timeout"
|
version = @{ type = "str" }
|
||||||
$validate_certs = Get-AnsibleParam -obj $params -name "validate_certs" -type "bool" -default $true
|
}
|
||||||
$version = Get-AnsibleParam -obj $params -name "version" -type "str"
|
supports_check_mode = $true
|
||||||
|
|
||||||
$result = @{
|
|
||||||
changed = $false
|
|
||||||
rc = 0
|
|
||||||
}
|
}
|
||||||
|
$module = [Ansible.Basic.AnsibleModule]::Create($args, $spec)
|
||||||
|
|
||||||
|
$allow_empty_checksums = $module.Params.allow_empty_checksums
|
||||||
|
$allow_multiple = $module.Params.allow_multiple
|
||||||
|
$allow_prerelease = $module.Params.allow_prerelease
|
||||||
|
$architecture = $module.Params.architecture
|
||||||
|
$install_args = $module.Params.install_args
|
||||||
|
$ignore_checksums = $module.Params.ignore_checksums
|
||||||
|
$ignore_dependencies = $module.Params.ignore_dependencies
|
||||||
|
$force = $module.Params.force
|
||||||
|
$name = $module.Params.name
|
||||||
|
$package_params = $module.Params.package_params
|
||||||
|
$proxy_url = $module.Params.proxy_url
|
||||||
|
$proxy_username = $module.Params.proxy_username
|
||||||
|
$proxy_password = $module.Params.proxy_password
|
||||||
|
$skip_scripts = $module.Params.skip_scripts
|
||||||
|
$source = $module.Params.source
|
||||||
|
$source_username = $module.Params.source_username
|
||||||
|
$source_password = $module.Params.source_password
|
||||||
|
$state = $module.Params.state
|
||||||
|
$timeout = $module.Params.timeout
|
||||||
|
$validate_certs = $module.Params.validate_certs
|
||||||
|
$version = $module.Params.version
|
||||||
|
|
||||||
|
$module.Result.rc = 0
|
||||||
|
|
||||||
if (-not $validate_certs) {
|
if (-not $validate_certs) {
|
||||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
|
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
|
||||||
|
@ -55,13 +74,13 @@ Function Get-CommonChocolateyArguments {
|
||||||
# run with Chocolatey
|
# run with Chocolatey
|
||||||
$arguments = [System.Collections.ArrayList]@("--yes", "--no-progress")
|
$arguments = [System.Collections.ArrayList]@("--yes", "--no-progress")
|
||||||
# global vars that control the arguments
|
# global vars that control the arguments
|
||||||
if ($check_mode) {
|
if ($module.CheckMode) {
|
||||||
$arguments.Add("--what-if") > $null
|
$arguments.Add("--what-if") > $null
|
||||||
}
|
}
|
||||||
if ($verbosity -gt 4) {
|
if ($module.Verbosity -gt 4) {
|
||||||
$arguments.Add("--debug") > $null
|
$arguments.Add("--debug") > $null
|
||||||
$arguments.Add("--verbose") > $null
|
$arguments.Add("--verbose") > $null
|
||||||
} elseif ($verbosity -gt 3) {
|
} elseif ($module.Verbosity -gt 3) {
|
||||||
$arguments.Add("--verbose") > $null
|
$arguments.Add("--verbose") > $null
|
||||||
} else {
|
} else {
|
||||||
$arguments.Add("--limit-output") > $null
|
$arguments.Add("--limit-output") > $null
|
||||||
|
@ -74,6 +93,7 @@ Function Get-InstallChocolateyArguments {
|
||||||
param(
|
param(
|
||||||
[bool]$allow_downgrade,
|
[bool]$allow_downgrade,
|
||||||
[bool]$allow_empty_checksums,
|
[bool]$allow_empty_checksums,
|
||||||
|
[bool]$allow_multiple,
|
||||||
[bool]$allow_prerelease,
|
[bool]$allow_prerelease,
|
||||||
[String]$architecture,
|
[String]$architecture,
|
||||||
[bool]$force,
|
[bool]$force,
|
||||||
|
@ -102,6 +122,9 @@ Function Get-InstallChocolateyArguments {
|
||||||
if ($allow_empty_checksums) {
|
if ($allow_empty_checksums) {
|
||||||
$arguments.Add("--allow-empty-checksums") > $null
|
$arguments.Add("--allow-empty-checksums") > $null
|
||||||
}
|
}
|
||||||
|
if ($allow_multiple) {
|
||||||
|
$arguments.Add("--allow-multiple") > $null
|
||||||
|
}
|
||||||
if ($allow_prerelease) {
|
if ($allow_prerelease) {
|
||||||
$arguments.Add("--prerelease") > $null
|
$arguments.Add("--prerelease") > $null
|
||||||
}
|
}
|
||||||
|
@ -202,8 +225,8 @@ Function Install-Chocolatey {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($source) {
|
if ($source) {
|
||||||
# check if the URL already contains the path to install.ps1
|
# check if the URL already contains the path to PS script
|
||||||
if ($source.EndsWith("install.ps1")) {
|
if ($source.EndsWith(".ps1")) {
|
||||||
$script_url = $source
|
$script_url = $source
|
||||||
} else {
|
} else {
|
||||||
# chocolatey server automatically serves a script at
|
# chocolatey server automatically serves a script at
|
||||||
|
@ -230,19 +253,19 @@ Function Install-Chocolatey {
|
||||||
try {
|
try {
|
||||||
$install_script = $client.DownloadString($script_url)
|
$install_script = $client.DownloadString($script_url)
|
||||||
} catch {
|
} catch {
|
||||||
Fail-Json -obj $result -message "Failed to download Chocolatey script from '$script_url': $($_.Exception.Message)"
|
$module.FailJson("Failed to download Chocolatey script from '$script_url'; $($_.Exception.Message)", $_)
|
||||||
}
|
}
|
||||||
if (-not $check_mode) {
|
if (-not $module.CheckMode) {
|
||||||
$res = Run-Command -command "powershell.exe -" -stdin $install_script -environment $environment
|
$res = Run-Command -command "powershell.exe -" -stdin $install_script -environment $environment
|
||||||
if ($res.rc -ne 0) {
|
if ($res.rc -ne 0) {
|
||||||
$result.rc = $res.rc
|
$module.Result.rc = $res.rc
|
||||||
$result.stdout = $res.stdout
|
$module.Result.stdout = $res.stdout
|
||||||
$result.stderr = $res.stderr
|
$module.Result.stderr = $res.stderr
|
||||||
Fail-Json -obj $result -message "Chocolatey bootstrap installation failed."
|
$module.FailJson("Chocolatey bootstrap installation failed.")
|
||||||
}
|
}
|
||||||
Add-Warning -obj $result -message "Chocolatey was missing from this system, so it was installed during this task run."
|
$module.Warn("Chocolatey was missing from this system, so it was installed during this task run.")
|
||||||
}
|
}
|
||||||
$result.changed = $true
|
$module.Result.changed = $true
|
||||||
|
|
||||||
# locate the newly installed choco.exe
|
# locate the newly installed choco.exe
|
||||||
$choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue
|
$choco_app = Get-Command -Name choco.exe -CommandType Application -ErrorAction SilentlyContinue
|
||||||
|
@ -257,24 +280,24 @@ Function Install-Chocolatey {
|
||||||
$choco_app = Get-Command -Name $choco_path -CommandType Application -ErrorAction SilentlyContinue
|
$choco_app = Get-Command -Name $choco_path -CommandType Application -ErrorAction SilentlyContinue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($check_mode -and $null -eq $choco_app) {
|
if ($module.CheckMode -and $null -eq $choco_app) {
|
||||||
$result.skipped = $true
|
$module.Result.skipped = $true
|
||||||
$result.msg = "Skipped check mode run on win_chocolatey as choco.exe cannot be found on the system"
|
$module.Result.msg = "Skipped check mode run on win_chocolatey as choco.exe cannot be found on the system"
|
||||||
Exit-Json -obj $result
|
$module.ExitJson()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (-not (Test-Path -Path $choco_app.Path)) {
|
if (-not (Test-Path -Path $choco_app.Path)) {
|
||||||
Fail-Json -obj $result -message "Failed to find choco.exe, make sure it is added to the PATH or the env var 'ChocolateyInstall' is set"
|
$module.FailJson("Failed to find choco.exe, make sure it is added to the PATH or the env var 'ChocolateyInstall' is set")
|
||||||
}
|
}
|
||||||
|
|
||||||
$actual_version = Get-ChocolateyPackageVersion -choco_path $choco_app.Path -name chocolatey
|
$actual_version = (Get-ChocolateyPackageVersion -choco_path $choco_app.Path -name chocolatey)[0]
|
||||||
if ([Version]$actual_version -lt [Version]"0.10.5") {
|
if ([Version]$actual_version -lt [Version]"0.10.5") {
|
||||||
if ($check_mode) {
|
if ($module.CheckMode) {
|
||||||
$result.skipped = $true
|
$module.Result.skipped = $true
|
||||||
$result.msg = "Skipped check mode run on win_chocolatey as choco.exe is too old, a real run would have upgraded the executable. Actual: '$actual_version', Minimum Version: '0.10.5'"
|
$module.Result.msg = "Skipped check mode run on win_chocolatey as choco.exe is too old, a real run would have upgraded the executable. Actual: '$actual_version', Minimum Version: '0.10.5'"
|
||||||
Exit-Json -obj $result
|
$module.ExitJson()
|
||||||
}
|
}
|
||||||
Add-Warning -obj $result -message "Chocolatey was older than v0.10.5 so it was upgraded during this task run."
|
$module.Warn("Chocolatey was older than v0.10.5 so it was upgraded during this task run.")
|
||||||
Update-ChocolateyPackage -choco_path $choco_app.Path -packages @("chocolatey") `
|
Update-ChocolateyPackage -choco_path $choco_app.Path -packages @("chocolatey") `
|
||||||
-proxy_url $proxy_url -proxy_username $proxy_username `
|
-proxy_url $proxy_url -proxy_username $proxy_username `
|
||||||
-proxy_password $proxy_password -source $source `
|
-proxy_password $proxy_password -source $source `
|
||||||
|
@ -290,25 +313,24 @@ Function Get-ChocolateyPackageVersion {
|
||||||
[Parameter(Mandatory=$true)][String]$name
|
[Parameter(Mandatory=$true)][String]$name
|
||||||
)
|
)
|
||||||
|
|
||||||
$command = Argv-ToString -arguments @($choco_path, "list", "--local-only", "--exact", "--limit-output", $name)
|
$command = Argv-ToString -arguments @($choco_path, "list", "--local-only", "--exact", "--limit-output", "--all-versions", $name)
|
||||||
$res = Run-Command -command $command
|
$res = Run-Command -command $command
|
||||||
if ($res.rc -ne 0) {
|
if ($res.rc -ne 0) {
|
||||||
$result.command = $command
|
$module.Result.command = $command
|
||||||
$result.rc = $res.rc
|
$module.Result.rc = $res.rc
|
||||||
$result.stdout = $res.stdout
|
$module.Result.stdout = $res.stdout
|
||||||
$result.stderr = $res.stderr
|
$module.Result.stderr = $res.stderr
|
||||||
Fail-Json -obj $result -message "Error checking installation status for the package '$name'"
|
$module.FailJson("Error checking installation status for the package '$name'")
|
||||||
}
|
}
|
||||||
$stdout = $res.stdout.Trim()
|
$stdout = $res.stdout.Trim()
|
||||||
$version = $null
|
$versions = $null
|
||||||
if ($stdout) {
|
if ($stdout) {
|
||||||
# if a match occurs it is in the format of "package|version" we split
|
# 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
|
# by the last | to get the version in case package contains a pipe char
|
||||||
$pipe_index = $stdout.LastIndexOf("|")
|
$versions = @($stdout.Split("`r`n", [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { $_.Substring($_.LastIndexOf("|") + 1) })
|
||||||
$version = $stdout.Substring($pipe_index + 1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $version
|
return ,$versions
|
||||||
}
|
}
|
||||||
|
|
||||||
Function Update-ChocolateyPackage {
|
Function Update-ChocolateyPackage {
|
||||||
|
@ -317,6 +339,7 @@ Function Update-ChocolateyPackage {
|
||||||
[Parameter(Mandatory=$true)][String[]]$packages,
|
[Parameter(Mandatory=$true)][String[]]$packages,
|
||||||
[bool]$allow_downgrade,
|
[bool]$allow_downgrade,
|
||||||
[bool]$allow_empty_checksums,
|
[bool]$allow_empty_checksums,
|
||||||
|
[bool]$allow_multiple,
|
||||||
[bool]$allow_prerelease,
|
[bool]$allow_prerelease,
|
||||||
[String]$architecture,
|
[String]$architecture,
|
||||||
[bool]$force,
|
[bool]$force,
|
||||||
|
@ -337,37 +360,52 @@ Function Update-ChocolateyPackage {
|
||||||
|
|
||||||
$arguments = [System.Collections.ArrayList]@($choco_path, "upgrade")
|
$arguments = [System.Collections.ArrayList]@($choco_path, "upgrade")
|
||||||
$arguments.AddRange($packages)
|
$arguments.AddRange($packages)
|
||||||
$common_args = Get-InstallChocolateyArguments -allow_downgrade $allow_downgrade `
|
|
||||||
-allow_empty_checksums $allow_empty_checksums -allow_prerelease $allow_prerelease `
|
$common_params = @{
|
||||||
-architecture $architecture -force $force -ignore_checksums $ignore_checksums `
|
allow_downgrade = $allow_downgrade
|
||||||
-ignore_dependencies $ignore_dependencies -install_args $install_args `
|
allow_empty_checksums = $allow_empty_checksums
|
||||||
-package_params $package_params -proxy_url $proxy_url -proxy_username $proxy_username `
|
allow_multiple = $allow_multiple
|
||||||
-proxy_password $proxy_password -skip_scripts $skip_scripts -source $source `
|
allow_prerelease = $allow_prerelease
|
||||||
-source_username $source_username -source_password $source_password -timeout $timeout `
|
architecture = $architecture
|
||||||
-version $version
|
force = $force
|
||||||
|
ignore_checksums = $ignore_checksums
|
||||||
|
ignore_dependencies = $ignore_dependencies
|
||||||
|
install_args = $install_args
|
||||||
|
package_params = $package_params
|
||||||
|
proxy_url = $proxy_url
|
||||||
|
proxy_username = $proxy_username
|
||||||
|
proxy_password = $proxy_password
|
||||||
|
skip_scripts = $skip_scripts
|
||||||
|
source = $source
|
||||||
|
source_username = $source_username
|
||||||
|
source_password = $source_password
|
||||||
|
timeout = $timeout
|
||||||
|
version = $version
|
||||||
|
}
|
||||||
|
$common_args = Get-InstallChocolateyArguments @common_params
|
||||||
$arguments.AddRange($common_args)
|
$arguments.AddRange($common_args)
|
||||||
|
|
||||||
$command = Argv-ToString -arguments $arguments
|
$command = Argv-ToString -arguments $arguments
|
||||||
$res = Run-Command -command $command
|
$res = Run-Command -command $command
|
||||||
$result.rc = $res.rc
|
$module.Result.rc = $res.rc
|
||||||
if ($res.rc -notin $successexitcodes) {
|
if ($res.rc -notin $successexitcodes) {
|
||||||
$result.command = $command
|
$module.Result.command = $command
|
||||||
$result.stdout = $res.stdout
|
$module.Result.stdout = $res.stdout
|
||||||
$result.stderr = $res.stderr
|
$module.Result.stderr = $res.stderr
|
||||||
Fail-Json -obj $result -message "Error updating package(s) '$($packages -join ", ")'"
|
$module.FailJson("Error updating package(s) '$($packages -join ", ")'")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($verbosity -gt 1) {
|
if ($module.Verbosity -gt 1) {
|
||||||
$result.stdout = $res.stdout
|
$module.Result.stdout = $res.stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($res.stdout -match ' upgraded (\d+)/\d+ package') {
|
if ($res.stdout -match ' upgraded (\d+)/\d+ package') {
|
||||||
if ($Matches[1] -gt 0) {
|
if ($Matches[1] -gt 0) {
|
||||||
$result.changed = $true
|
$module.Result.changed = $true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# need to set to false in case the rc is not 0 and a failure didn't actually occur
|
# need to set to false in case the rc is not 0 and a failure didn't actually occur
|
||||||
$result.failed = $false
|
$module.Result.failed = $false
|
||||||
}
|
}
|
||||||
|
|
||||||
Function Install-ChocolateyPackage {
|
Function Install-ChocolateyPackage {
|
||||||
|
@ -376,6 +414,7 @@ Function Install-ChocolateyPackage {
|
||||||
[Parameter(Mandatory=$true)][String[]]$packages,
|
[Parameter(Mandatory=$true)][String[]]$packages,
|
||||||
[bool]$allow_downgrade,
|
[bool]$allow_downgrade,
|
||||||
[bool]$allow_empty_checksums,
|
[bool]$allow_empty_checksums,
|
||||||
|
[bool]$allow_multiple,
|
||||||
[bool]$allow_prerelease,
|
[bool]$allow_prerelease,
|
||||||
[String]$architecture,
|
[String]$architecture,
|
||||||
[bool]$force,
|
[bool]$force,
|
||||||
|
@ -396,33 +435,47 @@ Function Install-ChocolateyPackage {
|
||||||
|
|
||||||
$arguments = [System.Collections.ArrayList]@($choco_path, "install")
|
$arguments = [System.Collections.ArrayList]@($choco_path, "install")
|
||||||
$arguments.AddRange($packages)
|
$arguments.AddRange($packages)
|
||||||
$common_args = Get-InstallChocolateyArguments -allow_downgrade $allow_downgrade `
|
$common_params = @{
|
||||||
-allow_empty_checksums $allow_empty_checksums -allow_prerelease $allow_prerelease `
|
allow_downgrade = $allow_downgrade
|
||||||
-architecture $architecture -force $force -ignore_checksums $ignore_checksums `
|
allow_empty_checksums = $allow_empty_checksums
|
||||||
-ignore_dependencies $ignore_dependencies -install_args $install_args `
|
allow_multiple = $allow_multiple
|
||||||
-package_params $package_params -proxy_url $proxy_url -proxy_username $proxy_username `
|
allow_prerelease = $allow_prerelease
|
||||||
-proxy_password $proxy_password -skip_scripts $skip_scripts -source $source `
|
architecture = $architecture
|
||||||
-source_username $source_username -source_password $source_password -timeout $timeout `
|
force = $force
|
||||||
-version $version
|
ignore_checksums = $ignore_checksums
|
||||||
|
ignore_dependencies = $ignore_dependencies
|
||||||
|
install_args = $install_args
|
||||||
|
package_params = $package_params
|
||||||
|
proxy_url = $proxy_url
|
||||||
|
proxy_username = $proxy_username
|
||||||
|
proxy_password = $proxy_password
|
||||||
|
skip_scripts = $skip_scripts
|
||||||
|
source = $source
|
||||||
|
source_username = $source_username
|
||||||
|
source_password = $source_password
|
||||||
|
timeout = $timeout
|
||||||
|
version = $version
|
||||||
|
}
|
||||||
|
$common_args = Get-InstallChocolateyArguments @common_params
|
||||||
$arguments.AddRange($common_args)
|
$arguments.AddRange($common_args)
|
||||||
|
|
||||||
$command = Argv-ToString -arguments $arguments
|
$command = Argv-ToString -arguments $arguments
|
||||||
$res = Run-Command -command $command
|
$res = Run-Command -command $command
|
||||||
$result.rc = $res.rc
|
$module.Result.rc = $res.rc
|
||||||
if ($res.rc -notin $successexitcodes) {
|
if ($res.rc -notin $successexitcodes) {
|
||||||
$result.command = $command
|
$module.Result.command = $command
|
||||||
$result.stdout = $res.stdout
|
$module.Result.stdout = $res.stdout
|
||||||
$result.stderr = $res.stderr
|
$module.Result.stderr = $res.stderr
|
||||||
Fail-Json -obj $result -message "Error installing package(s) '$($packages -join ', ')'"
|
$module.FailJson("Error installing package(s) '$($packages -join ', ')'")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($verbosity -gt 1) {
|
if ($module.Verbosity -gt 1) {
|
||||||
$result.stdout = $res.stdout
|
$module.Result.stdout = $res.stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
$result.changed = $true
|
$module.Result.changed = $true
|
||||||
# need to set to false in case the rc is not 0 and a failure didn't actually occur
|
# need to set to false in case the rc is not 0 and a failure didn't actually occur
|
||||||
$result.failed = $false
|
$module.Result.failed = $false
|
||||||
}
|
}
|
||||||
|
|
||||||
Function Uninstall-ChocolateyPackage {
|
Function Uninstall-ChocolateyPackage {
|
||||||
|
@ -456,26 +509,30 @@ Function Uninstall-ChocolateyPackage {
|
||||||
$arguments.Add($timeout) > $null
|
$arguments.Add($timeout) > $null
|
||||||
}
|
}
|
||||||
if ($version) {
|
if ($version) {
|
||||||
|
# Need to set allow-multiple to make sure choco doesn't uninstall all versions
|
||||||
|
$arguments.Add("--allow-multiple") > $null
|
||||||
$arguments.Add("--version") > $null
|
$arguments.Add("--version") > $null
|
||||||
$arguments.Add($version) > $null
|
$arguments.Add($version) > $null
|
||||||
|
} else {
|
||||||
|
$arguments.Add("--all-versions") > $null
|
||||||
}
|
}
|
||||||
|
|
||||||
$command = Argv-ToString -arguments $arguments
|
$command = Argv-ToString -arguments $arguments
|
||||||
$res = Run-Command -command $command
|
$res = Run-Command -command $command
|
||||||
$result.rc = $res.rc
|
$module.Result.rc = $res.rc
|
||||||
if ($res.rc -notin $successexitcodes) {
|
if ($res.rc -notin $successexitcodes) {
|
||||||
$result.command = $command
|
$module.Result.command = $command
|
||||||
$result.stdout = $res.stdout
|
$module.Result.stdout = $res.stdout
|
||||||
$result.stderr = $res.stderr
|
$module.Result.stderr = $res.stderr
|
||||||
Fail-Json -obj $result -message "Error uninstalling package(s) '$($packages -join ", ")'"
|
$module.FailJson("Error uninstalling package(s) '$($packages -join ", ")'")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($verbosity -gt 1) {
|
if ($module.Verbosity -gt 1) {
|
||||||
$result.stdout = $res.stdout
|
$module.Result.stdout = $res.stdout
|
||||||
}
|
}
|
||||||
$result.changed = $true
|
$module.Result.changed = $true
|
||||||
# need to set to false in case the rc is not 0 and a failure didn't actually occur
|
# need to set to false in case the rc is not 0 and a failure didn't actually occur
|
||||||
$result.failed = $false
|
$module.Result.failed = $false
|
||||||
}
|
}
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -490,13 +547,13 @@ foreach ($package in $name) {
|
||||||
# a dummy version so absent, latest, and downgrade will run with all
|
# a dummy version so absent, latest, and downgrade will run with all
|
||||||
if ($package -eq "all") {
|
if ($package -eq "all") {
|
||||||
if ($state -in @("present", "reinstalled")) {
|
if ($state -in @("present", "reinstalled")) {
|
||||||
Fail-Json -obj $result -message "Cannot specify the package name as 'all' when state=$state"
|
$module.FailJson("Cannot specify the package name as 'all' when state=$state")
|
||||||
}
|
}
|
||||||
$package_version = "0.0.0"
|
$package_versions = @("0.0.0")
|
||||||
} else {
|
} else {
|
||||||
$package_version = Get-ChocolateyPackageVersion -choco_path $choco_path -name $package
|
$package_versions = Get-ChocolateyPackageVersion -choco_path $choco_path -name $package
|
||||||
}
|
}
|
||||||
$package_info.$package = $package_version
|
$package_info.$package = $package_versions
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($state -in "absent", "reinstalled") {
|
if ($state -in "absent", "reinstalled") {
|
||||||
|
@ -520,16 +577,26 @@ if ($state -in @("downgrade", "latest", "present", "reinstalled")) {
|
||||||
$missing_packages = $name
|
$missing_packages = $name
|
||||||
} else {
|
} else {
|
||||||
# otherwise only install the packages that are not installed
|
# otherwise only install the packages that are not installed
|
||||||
$missing_packages = ($package_info.GetEnumerator() | Where-Object { $null -eq $_.Value }).Key
|
$missing_packages = [System.Collections.ArrayList]@()
|
||||||
|
foreach ($package in $package_info.GetEnumerator()) {
|
||||||
|
if ($null -eq $package.Value) {
|
||||||
|
$missing_packages.Add($package.Key) > $null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# if version is specified and installed version does not match, throw error
|
# if version is specified and installed version does not match or not
|
||||||
# ignore this if force or is set
|
# allow_multiple, throw error ignore this if force is set
|
||||||
if ($state -eq "present" -and $null -ne $version -and -not $force) {
|
if ($state -eq "present" -and $null -ne $version -and -not $force) {
|
||||||
foreach ($package in $name) {
|
foreach ($package in $name) {
|
||||||
$package_version = ($package_info.GetEnumerator() | Where-Object { $name -eq $_.Key -and $null -ne $_.Value }).Value
|
$package_versions = [System.Collections.ArrayList]$package_info.$package
|
||||||
if ($null -ne $package_version -and $package_version -ne $version) {
|
if ($package_versions.Count -gt 0) {
|
||||||
Fail-Json -obj $result -message "Chocolatey package '$package' is already installed at version '$package_version' but was expecting '$version'. Either change the expected version, set state=latest, or set force=yes to continue"
|
if (-not $package_versions.Contains($version) -and -not $allow_multiple) {
|
||||||
|
$module.FailJson("Chocolatey package '$package' is already installed with version(s) '$($package_versions -join "', '")' but was expecting '$version'. Either change the expected version, set state=latest, set allow_multiple=yes, or set force=yes to continue")
|
||||||
|
} elseif ($version -notin $package_versions -and $allow_multiple) {
|
||||||
|
# add the package back into the list of missing packages if installing multiple
|
||||||
|
$missing_packages.Add($package) > $null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -537,6 +604,7 @@ if ($state -in @("downgrade", "latest", "present", "reinstalled")) {
|
||||||
choco_path = $choco_path
|
choco_path = $choco_path
|
||||||
allow_downgrade = ($state -eq "downgrade")
|
allow_downgrade = ($state -eq "downgrade")
|
||||||
allow_empty_checksums = $allow_empty_checksums
|
allow_empty_checksums = $allow_empty_checksums
|
||||||
|
allow_multiple = $allow_multiple
|
||||||
allow_prerelease = $allow_prerelease
|
allow_prerelease = $allow_prerelease
|
||||||
architecture = $architecture
|
architecture = $architecture
|
||||||
force = $force
|
force = $force
|
||||||
|
@ -555,7 +623,7 @@ if ($state -in @("downgrade", "latest", "present", "reinstalled")) {
|
||||||
version = $version
|
version = $version
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($null -ne $missing_packages) {
|
if ($missing_packages) {
|
||||||
Install-ChocolateyPackage -packages $missing_packages @common_args
|
Install-ChocolateyPackage -packages $missing_packages @common_args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,4 +639,5 @@ if ($state -in @("downgrade", "latest", "present", "reinstalled")) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Exit-Json -obj $result
|
$module.ExitJson()
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,14 @@ options:
|
||||||
type: bool
|
type: bool
|
||||||
default: 'no'
|
default: 'no'
|
||||||
version_added: '2.2'
|
version_added: '2.2'
|
||||||
|
allow_multiple:
|
||||||
|
description:
|
||||||
|
- Allow the installation of multiple packages when I(version) is specified.
|
||||||
|
- Having multiple packages at different versions can cause issues if the
|
||||||
|
package doesn't support this. Use at your own risk.
|
||||||
|
type: bool
|
||||||
|
default: no
|
||||||
|
version_added: '2.8'
|
||||||
allow_prerelease:
|
allow_prerelease:
|
||||||
description:
|
description:
|
||||||
- Allow the installation of pre-release packages.
|
- Allow the installation of pre-release packages.
|
||||||
|
@ -194,7 +202,8 @@ options:
|
||||||
version:
|
version:
|
||||||
description:
|
description:
|
||||||
- Specific version of the package to be installed.
|
- Specific version of the package to be installed.
|
||||||
- Ignored when I(state) is set to C(absent).
|
- When I(state) is set to C(absent), will uninstall the specific version
|
||||||
|
otherwise all versions of that package will be removed.
|
||||||
type: str
|
type: str
|
||||||
notes:
|
notes:
|
||||||
- Provide the C(version) parameter value as a string (e.g. C('6.1')), otherwise it
|
- Provide the C(version) parameter value as a string (e.g. C('6.1')), otherwise it
|
||||||
|
|
|
@ -87,7 +87,7 @@ Function Get-ChocolateyPackages {
|
||||||
|
|
||||||
param($choco_app)
|
param($choco_app)
|
||||||
|
|
||||||
$command = Argv-ToString -arguments $choco_app.Path, "list", "--local-only", "-r"
|
$command = Argv-ToString -arguments $choco_app.Path, "list", "--local-only", "--limit-output", "--all-versions"
|
||||||
$res = Run-Command -command $command
|
$res = Run-Command -command $command
|
||||||
if ($res.rc -ne 0) {
|
if ($res.rc -ne 0) {
|
||||||
$result.stdout = $res.stdout
|
$result.stdout = $res.stdout
|
||||||
|
@ -97,7 +97,7 @@ Function Get-ChocolateyPackages {
|
||||||
}
|
}
|
||||||
|
|
||||||
$packages_info = [System.Collections.ArrayList]@()
|
$packages_info = [System.Collections.ArrayList]@()
|
||||||
$res.stdout -split "`r`n" | Where-Object { $_ -ne "" } | ForEach-Object {
|
$res.stdout.Split("`r`n", [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object {
|
||||||
$packages_split = $_ -split "\|"
|
$packages_split = $_ -split "\|"
|
||||||
$package_info = @{
|
$package_info = @{
|
||||||
package = $packages_split[0]
|
package = $packages_split[0]
|
||||||
|
|
|
@ -270,7 +270,7 @@
|
||||||
state: present
|
state: present
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
register: fail_multiple_versions
|
register: fail_multiple_versions
|
||||||
failed_when: fail_multiple_versions.msg != "Chocolatey package '" + test_choco_package1 + "' is already installed at version '0.0.1' but was expecting '0.1.0'. Either change the expected version, set state=latest, or set force=yes to continue"
|
failed_when: fail_multiple_versions.msg != "Chocolatey package '" + test_choco_package1 + "' is already installed with version(s) '0.0.1' but was expecting '0.1.0'. Either change the expected version, set state=latest, set allow_multiple=yes, or set force=yes to continue"
|
||||||
|
|
||||||
- name: force the upgrade of an existing version
|
- name: force the upgrade of an existing version
|
||||||
win_chocolatey:
|
win_chocolatey:
|
||||||
|
@ -450,3 +450,43 @@
|
||||||
that:
|
that:
|
||||||
- all_latest is changed
|
- all_latest is changed
|
||||||
- all_latest_actual.stdout_lines == [test_choco_package1 + "|0.1.0"]
|
- all_latest_actual.stdout_lines == [test_choco_package1 + "|0.1.0"]
|
||||||
|
|
||||||
|
- name: install newer version of package
|
||||||
|
win_chocolatey:
|
||||||
|
name: '{{ test_choco_package1 }}'
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: install older package with allow_multiple
|
||||||
|
win_chocolatey:
|
||||||
|
name: '{{ test_choco_package1 }}'
|
||||||
|
state: present
|
||||||
|
allow_multiple: True
|
||||||
|
version: '0.0.1'
|
||||||
|
register: 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 }}
|
||||||
|
register: allow_multiple_actual
|
||||||
|
|
||||||
|
- name: assert install older package with allow_multiple
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- allow_multiple is changed
|
||||||
|
- allow_multiple_actual.stdout == "ansible|0.1.0\r\nansible|0.0.1\r\n"
|
||||||
|
|
||||||
|
- name: uninstall specific version installed with allow_multiple
|
||||||
|
win_chocolatey:
|
||||||
|
name: '{{ test_choco_package1 }}'
|
||||||
|
state: absent
|
||||||
|
version: '0.0.1'
|
||||||
|
register: remove_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 }}
|
||||||
|
register: remove_multiple_actual
|
||||||
|
|
||||||
|
- name: assert uninstall specific version installed with allow_multiple
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- remove_multiple is changed
|
||||||
|
- remove_multiple_actual.stdout == "ansible|0.1.0\r\n"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue