win_chocolatey - add ability to pin a package (#53157)
* win_chocolatey - add ability to pin a package * fix typoe in changelog fragment
This commit is contained in:
parent
be7768efc7
commit
b74295d25f
4 changed files with 229 additions and 0 deletions
2
changelogs/fragments/win_chocolatey-pin.yaml
Normal file
2
changelogs/fragments/win_chocolatey-pin.yaml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- win_chocolatey - Added the ability to pin a package using the ``pinned`` option - https://github.com/ansible/ansible/issues/38526
|
|
@ -25,6 +25,7 @@ $spec = @{
|
||||||
force = @{ type = "bool"; default = $false }
|
force = @{ type = "bool"; default = $false }
|
||||||
name = @{ type = "list"; elements = "str"; required = $true }
|
name = @{ type = "list"; elements = "str"; required = $true }
|
||||||
package_params = @{ type = "str"; aliases = "params" }
|
package_params = @{ type = "str"; aliases = "params" }
|
||||||
|
pinned = @{ type = "bool" }
|
||||||
proxy_url = @{ type = "str" }
|
proxy_url = @{ type = "str" }
|
||||||
proxy_username = @{ type = "str" }
|
proxy_username = @{ type = "str" }
|
||||||
proxy_password = @{ type = "str"; no_log = $true }
|
proxy_password = @{ type = "str"; no_log = $true }
|
||||||
|
@ -51,6 +52,7 @@ $ignore_dependencies = $module.Params.ignore_dependencies
|
||||||
$force = $module.Params.force
|
$force = $module.Params.force
|
||||||
$name = $module.Params.name
|
$name = $module.Params.name
|
||||||
$package_params = $module.Params.package_params
|
$package_params = $module.Params.package_params
|
||||||
|
$pinned = $module.Params.pinned
|
||||||
$proxy_url = $module.Params.proxy_url
|
$proxy_url = $module.Params.proxy_url
|
||||||
$proxy_username = $module.Params.proxy_username
|
$proxy_username = $module.Params.proxy_username
|
||||||
$proxy_password = $module.Params.proxy_password
|
$proxy_password = $module.Params.proxy_password
|
||||||
|
@ -342,6 +344,75 @@ Function Get-ChocolateyPackageVersion {
|
||||||
return ,$versions
|
return ,$versions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Function Get-ChocolateyPin {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][String]$choco_path
|
||||||
|
)
|
||||||
|
|
||||||
|
$command = Argv-ToString -arguments @($choco_path, "pin", "list", "--limit-output")
|
||||||
|
$res = Run-Command -command $command
|
||||||
|
if ($res.rc -ne 0) {
|
||||||
|
$module.Result.command = $command
|
||||||
|
$module.Result.rc = $res.rc
|
||||||
|
$module.Result.stdout = $res.stdout
|
||||||
|
$module.Result.stderr = $res.stderr
|
||||||
|
$module.FailJson("Error getting list of pinned packages")
|
||||||
|
}
|
||||||
|
|
||||||
|
$stdout = $res.stdout.Trim()
|
||||||
|
$pins = @{}
|
||||||
|
|
||||||
|
$stdout.Split("`r`n", [System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object {
|
||||||
|
$package = $_.Substring(0, $_.LastIndexOf("|"))
|
||||||
|
$version = $_.Substring($_.LastIndexOf("|") + 1)
|
||||||
|
|
||||||
|
if ($pins.ContainsKey($package)) {
|
||||||
|
$pinned_versions = $pins.$package
|
||||||
|
} else {
|
||||||
|
$pinned_versions = [System.Collections.Generic.List`1[String]]@()
|
||||||
|
}
|
||||||
|
$pinned_versions.Add($version)
|
||||||
|
$pins.$package = $pinned_versions
|
||||||
|
}
|
||||||
|
return ,$pins
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Set-ChocolateyPin {
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory=$true)][String]$choco_path,
|
||||||
|
[Parameter(Mandatory=$true)][String]$name,
|
||||||
|
[Switch]$pin,
|
||||||
|
[String]$version
|
||||||
|
)
|
||||||
|
if ($pin) {
|
||||||
|
$action = "add"
|
||||||
|
$err_msg = "Error pinning package '$name'"
|
||||||
|
} else {
|
||||||
|
$action = "remove"
|
||||||
|
$err_msg = "Error unpinning package '$name'"
|
||||||
|
}
|
||||||
|
|
||||||
|
$arguments = [System.Collections.ArrayList]@($choco_path, "pin", $action, "--name", $name)
|
||||||
|
if ($version) {
|
||||||
|
$err_msg += " at '$version'"
|
||||||
|
$arguments.Add("--version") > $null
|
||||||
|
$arguments.Add($version) > $null
|
||||||
|
}
|
||||||
|
$common_args = Get-CommonChocolateyArguments
|
||||||
|
$arguments.AddRange($common_args)
|
||||||
|
|
||||||
|
$command = Argv-ToString -arguments $arguments
|
||||||
|
$res = Run-Command -command $command
|
||||||
|
if ($res.rc -ne 0) {
|
||||||
|
$module.Result.command = $command
|
||||||
|
$module.Result.rc = $res.rc
|
||||||
|
$module.Result.stdout = $res.stdout
|
||||||
|
$module.Result.stderr = $res.stderr
|
||||||
|
$module.FailJson($err_msg)
|
||||||
|
}
|
||||||
|
$module.result.changed = $true
|
||||||
|
}
|
||||||
|
|
||||||
Function Update-ChocolateyPackage {
|
Function Update-ChocolateyPackage {
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory=$true)][String]$choco_path,
|
[Parameter(Mandatory=$true)][String]$choco_path,
|
||||||
|
@ -646,6 +717,30 @@ if ($state -in @("downgrade", "latest", "present", "reinstalled")) {
|
||||||
Update-ChocolateyPackage -packages $installed_packages @common_args
|
Update-ChocolateyPackage -packages $installed_packages @common_args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Now we want to pin/unpin any packages now that it has been installed/upgraded
|
||||||
|
if ($null -ne $pinned) {
|
||||||
|
$pins = Get-ChocolateyPin -choco_path $choco_path
|
||||||
|
|
||||||
|
foreach ($package in $name) {
|
||||||
|
if ($pins.ContainsKey($package)) {
|
||||||
|
if (-not $pinned -and $null -eq $version) {
|
||||||
|
# No version is set and pinned=no, we want to remove all pins on the package. There is a bug in
|
||||||
|
# 'choco pin remove' with multiple versions where an older version might be pinned but
|
||||||
|
# 'choco pin remove' will still fail without an explicit version. Instead we take the literal
|
||||||
|
# interpretation that pinned=no and no version means the package has no pins at all
|
||||||
|
foreach ($v in $pins.$package) {
|
||||||
|
Set-ChocolateyPin -choco_path $choco_path -name $package -version $v
|
||||||
|
}
|
||||||
|
} elseif ($null -ne $version -and $pins.$package.Contains($version) -ne $pinned) {
|
||||||
|
Set-ChocolateyPin -choco_path $choco_path -name $package -pin:$pinned -version $version
|
||||||
|
}
|
||||||
|
} elseif ($pinned) {
|
||||||
|
# Package had no pins but pinned=yes is set.
|
||||||
|
Set-ChocolateyPin -choco_path $choco_path -name $package -pin -version $version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$module.ExitJson()
|
$module.ExitJson()
|
||||||
|
|
|
@ -101,6 +101,17 @@ options:
|
||||||
type: str
|
type: str
|
||||||
version_added: '2.1'
|
version_added: '2.1'
|
||||||
aliases: [ params ]
|
aliases: [ params ]
|
||||||
|
pinned:
|
||||||
|
description:
|
||||||
|
- Whether to pin the Chocolatey package or not.
|
||||||
|
- If omitted then no checks on package pins are done.
|
||||||
|
- Will pin/unpin the specific version if I(version) is set.
|
||||||
|
- Will pin the latest version of a package if C(yes), I(version) is not set
|
||||||
|
and and no pin already exists.
|
||||||
|
- Will unpin all versions of a package if C(no) and I(version) is not set.
|
||||||
|
- This is ignored when C(state=absent).
|
||||||
|
type: bool
|
||||||
|
version_added: '2.8'
|
||||||
proxy_url:
|
proxy_url:
|
||||||
description:
|
description:
|
||||||
- Proxy URL used to install chocolatey and the package.
|
- Proxy URL used to install chocolatey and the package.
|
||||||
|
@ -328,6 +339,19 @@ EXAMPLES = r'''
|
||||||
become: yes
|
become: yes
|
||||||
become_user: Administrator
|
become_user: Administrator
|
||||||
become_method: runas
|
become_method: runas
|
||||||
|
|
||||||
|
- name: install and pin Notepad++ at 7.6.3
|
||||||
|
win_chocolatey:
|
||||||
|
name: notepadplusplus
|
||||||
|
version: 7.6.3
|
||||||
|
pinned: yes
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: remove all pins for Notepad++ on all versions
|
||||||
|
win_chocolatey:
|
||||||
|
name: notepadplusplus
|
||||||
|
pinned: no
|
||||||
|
state: present
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = r'''
|
RETURN = r'''
|
||||||
|
|
|
@ -474,6 +474,114 @@
|
||||||
- allow_multiple is changed
|
- allow_multiple is changed
|
||||||
- allow_multiple_actual.stdout == "ansible|0.1.0\r\nansible|0.0.1\r\n"
|
- allow_multiple_actual.stdout == "ansible|0.1.0\r\nansible|0.0.1\r\n"
|
||||||
|
|
||||||
|
- name: pin 2 packages (check mode)
|
||||||
|
win_chocolatey:
|
||||||
|
name:
|
||||||
|
- '{{ test_choco_package1 }}'
|
||||||
|
- '{{ test_choco_package2 }}'
|
||||||
|
state: present
|
||||||
|
pinned: yes
|
||||||
|
register: pin_multiple_check
|
||||||
|
check_mode: True
|
||||||
|
|
||||||
|
- name: get result of pin 2 packages (check mode)
|
||||||
|
win_command: choco.exe pin list --limit-output
|
||||||
|
register: pin_multiple_actual_check
|
||||||
|
|
||||||
|
- name: assert pin 2 packages (check mode)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pin_multiple_check is changed
|
||||||
|
- pin_multiple_actual_check.stdout == ""
|
||||||
|
|
||||||
|
- name: pin 2 packages
|
||||||
|
win_chocolatey:
|
||||||
|
name:
|
||||||
|
- '{{ test_choco_package1 }}'
|
||||||
|
- '{{ test_choco_package2 }}'
|
||||||
|
state: present
|
||||||
|
pinned: yes
|
||||||
|
register: pin_multiple
|
||||||
|
|
||||||
|
- name: get result of pin 2 packages
|
||||||
|
win_command: choco.exe pin list --limit-output
|
||||||
|
register: pin_multiple_actual
|
||||||
|
|
||||||
|
- name: assert pin 2 packages
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pin_multiple is changed
|
||||||
|
- pin_multiple_actual.stdout_lines == ["ansible|0.1.0", "ansible-test|1.0.1-beta1"]
|
||||||
|
|
||||||
|
- name: pin 2 packages (idempotent)
|
||||||
|
win_chocolatey:
|
||||||
|
name:
|
||||||
|
- '{{ test_choco_package1 }}'
|
||||||
|
- '{{ test_choco_package2 }}'
|
||||||
|
state: present
|
||||||
|
pinned: yes
|
||||||
|
register: pin_multiple_again
|
||||||
|
|
||||||
|
- name: assert pin 2 packages (idempoent)
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- not pin_multiple_again is changed
|
||||||
|
|
||||||
|
- name: pin specific older version
|
||||||
|
win_chocolatey:
|
||||||
|
name: '{{ test_choco_package1 }}'
|
||||||
|
state: present
|
||||||
|
pinned: yes
|
||||||
|
version: '0.0.1'
|
||||||
|
register: pin_older
|
||||||
|
|
||||||
|
- name: get result of pin specific older version
|
||||||
|
win_command: choco.exe pin list --limit-output
|
||||||
|
register: pin_older_actual
|
||||||
|
|
||||||
|
- name: assert pin specific older version
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pin_older is changed
|
||||||
|
- pin_older_actual.stdout_lines == ["ansible|0.1.0", "ansible|0.0.1", "ansible-test|1.0.1-beta1"]
|
||||||
|
|
||||||
|
- name: unpin package at version
|
||||||
|
win_chocolatey:
|
||||||
|
name: '{{ test_choco_package1 }}'
|
||||||
|
state: present
|
||||||
|
pinned: no
|
||||||
|
version: '0.1.0'
|
||||||
|
register: unpin_version
|
||||||
|
|
||||||
|
- name: get result of unpin package at version
|
||||||
|
win_command: choco.exe pin list --limit-output
|
||||||
|
register: unpin_version_actual
|
||||||
|
|
||||||
|
- name: assert unpin package at version
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unpin_version is changed
|
||||||
|
- unpin_version_actual.stdout_lines == ["ansible|0.0.1", "ansible-test|1.0.1-beta1"]
|
||||||
|
|
||||||
|
- name: unpin multiple packages without a version
|
||||||
|
win_chocolatey:
|
||||||
|
name:
|
||||||
|
- '{{ test_choco_package1 }}'
|
||||||
|
- '{{ test_choco_package2 }}'
|
||||||
|
state: present
|
||||||
|
pinned: no
|
||||||
|
register: unpin_multiple
|
||||||
|
|
||||||
|
- name: get result of unpin multiple packages without a version
|
||||||
|
win_command: choco.exe pin list --limit-output
|
||||||
|
register: unpin_multiple_actual
|
||||||
|
|
||||||
|
- name: assert unpin multiple packages without a version
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- unpin_multiple is changed
|
||||||
|
- unpin_multiple_actual.stdout == ""
|
||||||
|
|
||||||
- name: uninstall specific version installed with allow_multiple
|
- name: uninstall specific version installed with allow_multiple
|
||||||
win_chocolatey:
|
win_chocolatey:
|
||||||
name: '{{ test_choco_package1 }}'
|
name: '{{ test_choco_package1 }}'
|
||||||
|
|
Loading…
Reference in a new issue