Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/68932.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed aptpkg.install so APT multiarch package names are preserved when ``split_arch`` is disabled.
27 changes: 26 additions & 1 deletion salt/modules/aptpkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,7 @@ def install(
reinstall=False,
downloadonly=False,
ignore_epoch=False,
normalize=True,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a description of this argument in the docstring?

**kwargs,
):
"""
Expand Down Expand Up @@ -743,6 +744,10 @@ def install(
A list of packages to install from a software repository. Must be
passed as a python list.

For multiarch packages, use the arch-qualified package name (for
example ``name:amd64``) when you need Salt to target that exact APT
package name.

CLI Example:

.. code-block:: bash
Expand Down Expand Up @@ -828,7 +833,11 @@ def install(

try:
pkg_params, pkg_type = __salt__["pkg_resource.parse_targets"](
name, pkgs, sources, **kwargs
name,
pkgs,
sources,
normalize=normalize and kwargs.get("split_arch", True),
**kwargs,
)
except MinionError as exc:
raise CommandExecutionError(exc)
Expand Down Expand Up @@ -1362,6 +1371,10 @@ def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
name
The name of the package, e.g., 'tmux'

For multiarch packages, dpkg may record the held package name with an
architecture suffix such as ``:amd64``. In those cases, the
arch-qualified package name may need to be used.

CLI Example:

.. code-block:: bash
Expand All @@ -1371,6 +1384,10 @@ def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
pkgs
A list of packages to hold. Must be passed as a python list.

For multiarch packages, dpkg may record the held package name with an
architecture suffix such as ``:amd64``. In those cases, the
arch-qualified package name may need to be used.

CLI Example:

.. code-block:: bash
Expand Down Expand Up @@ -1427,6 +1444,10 @@ def unhold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W06
name
The name of the package, e.g., 'tmux'

For multiarch packages, dpkg may record the held package name with an
architecture suffix such as ``:amd64``. In those cases, the
arch-qualified package name may need to be used.

CLI Example:

.. code-block:: bash
Expand All @@ -1436,6 +1457,10 @@ def unhold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W06
pkgs
A list of packages to unhold. Must be passed as a python list.

For multiarch packages, dpkg may record the held package name with an
architecture suffix such as ``:amd64``. In those cases, the
arch-qualified package name may need to be used.

CLI Example:

.. code-block:: bash
Expand Down
8 changes: 8 additions & 0 deletions salt/states/pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1481,6 +1481,10 @@ def installed(
package, the held package(s) will be skipped and the state will fail.
By default, this parameter is set to ``False``.

Package naming rules for held packages may vary by package manager.
See the documentation for your platform's ``pkg`` module for any
provider-specific requirements.

Supported on YUM/DNF & APT based systems.

.. versionadded:: 2016.11.0
Expand Down Expand Up @@ -3867,6 +3871,10 @@ def unheld(name, version=None, pkgs=None, all=False, **kwargs):
For ``unheld`` there is no need to specify the exact version
to be unheld.

Package naming rules for held packages may vary by package manager.
See the documentation for your platform's ``pkg`` module for any
provider-specific requirements.

:param bool all:
Force removing of all existings locks.
By default, this parameter is set to ``False``.
Expand Down
34 changes: 34 additions & 0 deletions tests/pytests/unit/modules/test_aptpkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,40 @@ def test_install(install_var):
assert expected_call in mock_call_apt.mock_calls


def test_install_preserves_multiarch_pkg_names_when_split_arch_is_false():
"""
Test aptpkg.install preserves explicit multiarch package names.
"""
patch_kwargs = {
"__salt__": {
"pkg_resource.parse_targets": MagicMock(
return_value=({"libnvidia-cfg1-570-server:amd64": None}, "repository")
),
"pkg_resource.sort_pkglist": MagicMock(),
"pkg_resource.stringify": MagicMock(),
"cmd.run_stdout": MagicMock(return_value=""),
}
}
mock_call_apt = MagicMock(return_value={"retcode": 0, "stdout": "", "stderr": ""})
mock_parse_targets = patch_kwargs["__salt__"]["pkg_resource.parse_targets"]

with patch.multiple(
aptpkg, list_pkgs=MagicMock(side_effect=[{}, {}]), **patch_kwargs
):
with patch(
"salt.modules.aptpkg.get_selections", MagicMock(return_value={"hold": []})
):
with patch("salt.modules.aptpkg._call_apt", mock_call_apt):
aptpkg.install(
pkgs=["libnvidia-cfg1-570-server:amd64"],
refresh=False,
split_arch=False,
)

assert mock_parse_targets.call_args.kwargs["normalize"] is False
assert "libnvidia-cfg1-570-server:amd64" in mock_call_apt.mock_calls[0].args[0]


def test_remove(uninstall_var):
"""
Test - Remove packages.
Expand Down