Skip to content

Commit dccc6a7

Browse files
committed
asu: build: rework default packages management
Use the .packageinfo file included in imagebuilder bundles as information source for checks about which default packages can be included without conflicting with others included in the full package list provided by ASU clients. Keep the previous "absolute" mode of operation where default packages not included in the user request are removed, and improve the "additional" mode where default packages are included unless they conflict with others requested by the user. Flip the logic and default value of the "diff_packages" flag to True to activate the "additional" mode by default, while still allowing users to select the "absolute" mode if needed. (Allow old ASU clients use this) Fixes: openwrt/openwrt#19749 Fixes: all issues related with changes in default packages lists Fixes: ath10 fixes Fixes: fitblk inclusion Fixes: ...
1 parent e502b67 commit dccc6a7

2 files changed

Lines changed: 45 additions & 8 deletions

File tree

asu/build.py

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ def _build(build_request: BuildRequest, job=None):
191191
report_error(job, "Could not set up ImageBuilder")
192192

193193
returncode, job.meta["stdout"], job.meta["stderr"] = run_cmd(
194-
container, ["make", "info"]
194+
container, ["make", "info"],
195+
copy=[".packageinfo", bin_dir],
195196
)
196197

197198
job.meta["imagebuilder_status"] = "validate_revision"
@@ -206,12 +207,11 @@ def _build(build_request: BuildRequest, job=None):
206207
f"Received incorrect version {version_code} (requested {requested})",
207208
)
208209

209-
default_packages = set(
210+
target_default_packages = set(
210211
re.search(r"Default Packages: (.*)\n", job.meta["stdout"]).group(1).split()
211-
)
212-
log.debug(f"Default packages: {default_packages}")
212+
)
213213

214-
profile_packages = set(
214+
profile_default_packages = set(
215215
re.search(
216216
r"{}:\n .+\n Packages: (.*?)\n".format(build_request.profile),
217217
job.meta["stdout"],
@@ -221,13 +221,50 @@ def _build(build_request: BuildRequest, job=None):
221221
.split()
222222
)
223223

224+
default_packages = target_default_packages | profile_default_packages
225+
log.debug(f"Default packages: {default_packages}")
226+
224227
apply_package_changes(build_request)
225228

226229
build_cmd_packages = build_request.packages
227230

228231
if build_request.diff_packages:
232+
# additional mode - keep default packages which not conflict with user requested packages
233+
# Get information about package conflicts and provides from .packageinfo
234+
packages_db: dict[str, dict[str, list[str]]] = {}
235+
packages_with_conflicts: set[str] = set()
236+
with open(str(bin_dir / ".packageinfo"), 'r') as file:
237+
pack_blocks = re.findall(
238+
r"Package: (.*?)\n.*?\nConflicts: (.*?)\n.*?\nProvides: (.*?)\n",
239+
file.read(),
240+
re.DOTALL,
241+
)
242+
for p_name, p_conflicts, p_provides in pack_blocks:
243+
packages_db.update({p_name: {"conflicts": p_conflicts.split(), "provides": p_provides.split()}})
244+
245+
# Do not include default packages with potential conflicts (conflicts or provides)
246+
for package in default_packages:
247+
for package_user in set(build_request.packages) - default_packages:
248+
if package in packages_db.get(package_user, []).get("provides", []):
249+
log.debug(f"{package}\tNOT INCLUDED (Provided by: {package_user})")
250+
packages_with_conflicts.add(package)
251+
if set(packages_db.get(package, []).get("provides", [])) & set(packages_db.get(package_user, []).get("provides", [])):
252+
log.debug(f"{package}\tNOT INCLUDED (Common provides with: {package_user})")
253+
packages_with_conflicts.add(package)
254+
if package in packages_db.get(package_user, []).get("conflicts", []) or package_user in packages_db.get(package, []).get("conflicts", []):
255+
log.debug(f"{package}\tNOT INCLUDED (Conflict with: {package_user})")
256+
packages_with_conflicts.add(package)
257+
258+
for p in packages_with_conflicts:
259+
build_cmd_packages.remove(p)
260+
build_cmd_packages.insert(0, f"-{p}")
261+
262+
log.debug(f"List of packages removing default packages with conflicts: {build_cmd_packages}")
263+
264+
else:
265+
# absolute mode - remove default packages not in requested list
229266
build_cmd_packages: list[str] = diff_packages(
230-
build_request.packages, default_packages | profile_packages
267+
build_request.packages, default_packages
231268
)
232269
log.debug(f"Diffed packages: {build_cmd_packages}")
233270

asu/build_request.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,15 @@ class BuildRequest(BaseModel):
9898
Field(
9999
description="""
100100
This parameter determines if requested packages are seen as
101-
*additional* or *absolute*. If set to `true` the packages are
101+
*additional* or *absolute*. If set to `false` the packages are
102102
seen as *absolute* and all default packages outside the
103103
requested packages are removed. \n\n It is possible to brick
104104
devices when requesting an incomplete list with this parameter
105105
enabled since it may remove WiFi drivers or other essential
106106
packages.
107107
""".strip(),
108108
),
109-
] = False
109+
] = True
110110
defaults: Annotated[
111111
str | None,
112112
Field(

0 commit comments

Comments
 (0)