Skip to content

Commit 277a8a3

Browse files
vzhestkovm-czernek
andcommitted
Add DEB822 apt source format support
Co-authored-by: Marek Czernek <[email protected]>
1 parent f906ca5 commit 277a8a3

File tree

2 files changed

+1018
-96
lines changed

2 files changed

+1018
-96
lines changed

salt/modules/aptpkg.py

Lines changed: 117 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@
4444
SaltInvocationError,
4545
)
4646
from salt.modules.cmdmod import _parse_env
47-
from salt.utils.pkg.deb import SourceEntry, SourcesList
47+
from salt.utils.pkg.deb import (
48+
Deb822SourceEntry,
49+
Section,
50+
SourceEntry,
51+
SourcesList,
52+
_invalid,
53+
)
4854

4955
log = logging.getLogger(__name__)
5056

@@ -1633,21 +1639,41 @@ def list_repos(**kwargs):
16331639
"""
16341640
repos = {}
16351641
sources = SourcesList()
1636-
for source in sources.list:
1642+
for source in sources:
16371643
if _skip_source(source):
16381644
continue
16391645
signedby = source.signedby
16401646
repo = {}
16411647
repo["file"] = source.file
1642-
repo["comps"] = getattr(source, "comps", [])
1648+
repo_comps = getattr(source, "comps", [])
1649+
repo_dists = source.dist.split(" ")
1650+
repo["comps"] = repo_comps
16431651
repo["disabled"] = source.disabled
1644-
repo["dist"] = source.dist
1652+
repo["enabled"] = not repo[
1653+
"disabled"
1654+
] # This is for compatibility with the other modules
1655+
repo["dist"] = repo_dists.pop(0)
1656+
repo["suites"] = list(source.suites)
16451657
repo["type"] = source.type
16461658
repo["uri"] = source.uri
1647-
repo["line"] = source.line.strip()
1659+
if "Types: " in source.line and "\n" in source.line:
1660+
repo["line"] = (
1661+
f"{source.type} {source.uri} {repo['dist']} {' '.join(repo_comps)}"
1662+
)
1663+
else:
1664+
repo["line"] = source.line.strip()
16481665
repo["architectures"] = getattr(source, "architectures", [])
16491666
repo["signedby"] = signedby
16501667
repos.setdefault(source.uri, []).append(repo)
1668+
if len(repo_dists):
1669+
for dist in repo_dists:
1670+
repo_copy = repo.copy()
1671+
repo_copy["dist"] = dist
1672+
if "Types: " in source.line and "\n" in source.line:
1673+
repo_copy["line"] = (
1674+
f"{source.type} {source.uri} {repo_copy['dist']} {' '.join(repo_comps)}"
1675+
)
1676+
repos[source.uri].append(repo_copy)
16511677
return repos
16521678

16531679

@@ -1656,12 +1682,17 @@ def get_repo(repo, **kwargs):
16561682
Display a repo from the sources.list / sources.list.d
16571683
16581684
The repo passed in needs to be a complete repo entry.
1685+
When system uses repository in the deb822 format,
1686+
get_repo uses a partial match of distributions.
1687+
1688+
In that case, include any distribution of the deb822
1689+
repository in the repo name to match that repo.
16591690
16601691
CLI Examples:
16611692
16621693
.. code-block:: bash
16631694
1664-
salt '*' pkg.get_repo "myrepo definition"
1695+
salt '*' pkg.get_repo "deb URL noble main"
16651696
"""
16661697
ppa_auth = kwargs.get("ppa_auth", None)
16671698
# we have to be clever about this since the repo definition formats
@@ -1720,11 +1751,17 @@ def del_repo(repo, **kwargs):
17201751
The repo passed in must be a fully formed repository definition
17211752
string.
17221753
1754+
When system uses repository in the deb822 format,
1755+
del_repo uses a partial match of distributions.
1756+
1757+
In that case, include any distribution of the deb822
1758+
repository in the repo name to match that repo.
1759+
17231760
CLI Examples:
17241761
17251762
.. code-block:: bash
17261763
1727-
salt '*' pkg.del_repo "myrepo definition"
1764+
salt '*' pkg.del_repo "deb URL noble main"
17281765
"""
17291766
is_ppa = False
17301767
if repo.startswith("ppa:") and __grains__["os"] in ("Ubuntu", "Mint", "neon"):
@@ -1755,11 +1792,22 @@ def del_repo(repo, **kwargs):
17551792
source.type == repo_entry["type"]
17561793
and source.architectures == repo_entry["architectures"]
17571794
and source.uri.rstrip("/") == repo_entry["uri"].rstrip("/")
1758-
and source.dist == repo_entry["dist"]
1795+
and repo_entry["dist"] in source.suites
17591796
):
1760-
17611797
s_comps = set(source.comps)
17621798
r_comps = set(repo_entry["comps"])
1799+
if s_comps == r_comps:
1800+
r_suites = list(source.suites)
1801+
r_suites.remove(repo_entry["dist"])
1802+
source.suites = r_suites
1803+
deleted_from[source.file] = 0
1804+
if not source.suites:
1805+
try:
1806+
sources.remove(source)
1807+
except ValueError:
1808+
pass
1809+
sources.save()
1810+
continue
17631811
if s_comps.intersection(r_comps) or (not s_comps and not r_comps):
17641812
deleted_from[source.file] = 0
17651813
source.comps = list(s_comps.difference(r_comps))
@@ -1776,11 +1824,23 @@ def del_repo(repo, **kwargs):
17761824
and repo_entry["type"] == "deb"
17771825
and source.type == "deb-src"
17781826
and source.uri == repo_entry["uri"]
1779-
and source.dist == repo_entry["dist"]
1827+
and repo_entry["dist"] in source.suites
17801828
):
17811829

17821830
s_comps = set(source.comps)
17831831
r_comps = set(repo_entry["comps"])
1832+
if s_comps == r_comps:
1833+
r_suites = list(source.suites)
1834+
r_suites.remove(repo_entry["dist"])
1835+
source.suites = r_suites
1836+
deleted_from[source.file] = 0
1837+
if not source.suites:
1838+
try:
1839+
sources.remove(source)
1840+
except ValueError:
1841+
pass
1842+
sources.save()
1843+
continue
17841844
if s_comps.intersection(r_comps) or (not s_comps and not r_comps):
17851845
deleted_from[source.file] = 0
17861846
source.comps = list(s_comps.difference(r_comps))
@@ -1793,6 +1853,8 @@ def del_repo(repo, **kwargs):
17931853
if deleted_from:
17941854
ret = ""
17951855
for source in sources:
1856+
if source.invalid:
1857+
continue
17961858
if source.file in deleted_from:
17971859
deleted_from[source.file] += 1
17981860
for repo_file, count in deleted_from.items():
@@ -2232,6 +2294,12 @@ def mod_repo(repo, saltenv="base", aptkey=True, **kwargs):
22322294
``ppa:<project>/repo`` format is acceptable. ``ppa:`` format can only be
22332295
used to create a new repository.
22342296
2297+
When system uses repository in the deb822 format, mod_repo uses a partial
2298+
match of distributions.
2299+
2300+
In that case, include any distribution of the deb822 repository in the
2301+
repo definition to match that repo.
2302+
22352303
The following options are available to modify a repo definition:
22362304
22372305
architectures
@@ -2286,8 +2354,8 @@ def mod_repo(repo, saltenv="base", aptkey=True, **kwargs):
22862354
22872355
.. code-block:: bash
22882356
2289-
salt '*' pkg.mod_repo 'myrepo definition' uri=http://new/uri
2290-
salt '*' pkg.mod_repo 'myrepo definition' comps=main,universe
2357+
salt '*' pkg.mod_repo 'deb URL noble main' uri=http://new/uri
2358+
salt '*' pkg.mod_repo 'deb URL noble main' comps=main,universe
22912359
"""
22922360
if "refresh_db" in kwargs:
22932361
refresh = kwargs["refresh_db"]
@@ -2407,6 +2475,13 @@ def mod_repo(repo, saltenv="base", aptkey=True, **kwargs):
24072475

24082476
repos = []
24092477
for source in sources:
2478+
if isinstance(source, Deb822SourceEntry):
2479+
if source.types == [""] or not bool(source.types) or not source.type:
2480+
continue
2481+
else:
2482+
_, invalid, _, _ = _invalid(source.line)
2483+
if invalid:
2484+
continue
24102485
repos.append(source)
24112486

24122487
mod_source = None
@@ -2563,9 +2638,9 @@ def mod_repo(repo, saltenv="base", aptkey=True, **kwargs):
25632638
repo_matches = (
25642639
apt_source.type == repo_entry["type"]
25652640
and apt_source.uri.rstrip("/") == repo_entry["uri"].rstrip("/")
2566-
and apt_source.dist == repo_entry["dist"]
2641+
and repo_entry["dist"] in apt_source.suites
25672642
)
2568-
kw_matches = apt_source.dist == kw_dist and apt_source.type == kw_type
2643+
kw_matches = kw_dist in apt_source.suites and apt_source.type == kw_type
25692644

25702645
if repo_matches or kw_matches:
25712646
for comp in full_comp_list:
@@ -2583,17 +2658,35 @@ def mod_repo(repo, saltenv="base", aptkey=True, **kwargs):
25832658

25842659
repo_source_entry = SourceEntry(repo)
25852660
if not mod_source:
2586-
mod_source = SourceEntry(repo)
2661+
apt_source_file = kwargs.get("file")
2662+
if not apt_source_file:
2663+
raise SaltInvocationError(
2664+
"missing 'file' argument when defining a new repository"
2665+
)
2666+
2667+
if not apt_source_file.endswith(".list"):
2668+
section = Section("")
2669+
section["Types"] = repo_entry["type"]
2670+
section["URIs"] = repo_entry["uri"]
2671+
section["Suites"] = repo_entry["dist"]
2672+
section["Components"] = " ".join(repo_entry["comps"])
2673+
if kwargs.get("trusted") is True or kwargs.get("Trusted") is True:
2674+
section["Trusted"] = "yes"
2675+
mod_source = Deb822SourceEntry(section, apt_source_file)
2676+
else:
2677+
mod_source = SourceEntry(repo)
25872678
if "comments" in kwargs:
25882679
mod_source.comment = kwargs["comments"]
25892680
sources.list.append(mod_source)
25902681
elif "comments" in kwargs:
25912682
mod_source.comment = kwargs["comments"]
25922683

2593-
mod_source.line = repo_source_entry.line
25942684
if not mod_source.line.endswith("\n"):
25952685
mod_source.line = mod_source.line + "\n"
25962686

2687+
if not kwargs["architectures"] and not mod_source.architectures:
2688+
kwargs.pop("architectures")
2689+
25972690
for key in kwargs:
25982691
if key in _MODIFY_OK and hasattr(mod_source, key):
25992692
setattr(mod_source, key, kwargs[key])
@@ -2609,15 +2702,21 @@ def mod_repo(repo, saltenv="base", aptkey=True, **kwargs):
26092702

26102703
signedby = mod_source.signedby
26112704

2705+
repo_source_line = mod_source.line
2706+
if "Types: " in repo_source_line and "\n" in repo_source_line:
2707+
repo_source_line = f"{mod_source.type} {mod_source.uri} {repo_entry['dist']} {' '.join(mod_source.comps)}"
2708+
26122709
return {
26132710
repo: {
26142711
"architectures": getattr(mod_source, "architectures", []),
2712+
"dist": mod_source.dist,
2713+
"suites": mod_source.suites,
26152714
"comps": mod_source.comps,
26162715
"disabled": mod_source.disabled,
26172716
"file": mod_source.file,
26182717
"type": mod_source.type,
26192718
"uri": mod_source.uri,
2620-
"line": mod_source.line,
2719+
"line": repo_source_line,
26212720
"signedby": signedby,
26222721
}
26232722
}
@@ -2720,7 +2819,7 @@ def _expand_repo_def(os_name, os_codename=None, **kwargs):
27202819
sanitized["dist"] = _source_entry.dist
27212820
sanitized["type"] = _source_entry.type
27222821
sanitized["uri"] = _source_entry.uri
2723-
sanitized["line"] = _source_entry.line.strip()
2822+
sanitized["line"] = getattr(_source_entry, "line", "").strip()
27242823
sanitized["architectures"] = getattr(_source_entry, "architectures", [])
27252824
sanitized["signedby"] = signedby
27262825

0 commit comments

Comments
 (0)