/
product.py
113 lines (88 loc) · 3.32 KB
/
product.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
"""
Handles installation of SUSE products using zypper
Only supported with :mod:`zypper <salt.modules.zypper>`
"""
import logging
from salt.utils.versions import version_cmp
from salt.exceptions import CommandExecutionError
log = logging.getLogger(__name__)
__virtualname__ = "product"
# pylint: disable-next=invalid-name
def __virtual__():
"""
Only work on SUSE platforms with zypper
"""
# pylint: disable-next=undefined-variable
if __grains__.get("os_family", "") != "Suse":
return (False, "Module product: non SUSE OS not supported")
# Not all versions of SUSE use zypper, check that it is available
try:
# pylint: disable-next=undefined-variable
zypp_info = __salt__["pkg.info_installed"]("zypper")["zypper"]
except CommandExecutionError:
return (False, "Module product: zypper package manager not found")
# Minimum version that supports 'zypper search --provides'
if version_cmp(zypp_info["version"], "1.8.13") < 0:
return (False, "Module product: zypper 1.8.13 or greater required")
return __virtualname__
def _get_missing_products(refresh):
# Search for not installed products
products = []
try:
products = list(
# pylint: disable-next=undefined-variable
__salt__["pkg.search"](
"product()",
refresh=refresh,
match="exact",
provides=True,
not_installed_only=True,
)
)
log.debug(
"The following products are not yet installed: %s", ", ".join(products)
)
except CommandExecutionError:
# No search results
return None
# Exclude products that are already provided by another to prevent conflicts
to_install = []
for pkg in products:
try:
# pylint: disable-next=undefined-variable
res = list(__salt__["pkg.search"](pkg, match="exact", provides=True))
if pkg in res:
res.remove(pkg)
if not res:
# No other providers than the package itself
to_install.append(pkg)
else:
log.debug(
"The product '%s' is already provided by '%s'. Skipping.",
pkg,
", ".join(res),
)
except CommandExecutionError:
# No search results
# Not provided by any installed package, add it to the list
to_install.append(pkg)
return to_install
# pylint: disable-next=unused-argument
def all_installed(name, refresh=False, **kwargs):
"""
Ensure that all the subscribed products are installed.
refresh
force a refresh if set to True.
If set to False (default) it depends on zypper if a refresh is
executed.
"""
ret = {"name": name, "changes": {}, "result": True, "comment": ""}
to_install = _get_missing_products(refresh)
if not to_install:
# All product packages are already installed
ret["comment"] = "All subscribed products are already installed"
ret["result"] = True
log.debug("All products are already installed. Nothing to do.")
return ret
# pylint: disable-next=undefined-variable
return __states__["pkg.installed"](name, pkgs=to_install, no_recommends=True)