mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-06-10 11:00:22 +00:00
package: Update package expression API and fix regressions
- Make terminology more consistent managed vs. possible, resolve vs. actual. - Fix regression in security report caused by comparing package expressions with package names. - Fix regression in package upgrades caused by comparing package expressions with package names. - Update API method names to improve readability and prevent accidental mismatching of package names and package expressions. Update variable names for same reason during usage. Tests: - minetest install successfully in testing. - Security report shows non-zero value in the current vulnerabilities column. - When an unavailable package is added to list of packages in an app, the app can't be installed. - When PackageOr expressions is added to an essential package, running --list-dependencies shows an expressions with '|' in it. - Unit tests succeed. - Find a package with conffile prompt and add that to list of a packages in an app like bepasty and implement a stub force_upgrade() method in the app. Run 'apt update' and that triggers and analysis of packages with conf file prompts. This should call force_upgrade() method in bepasty and with proper argument for list of packages. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
2537ffd64c
commit
2752cf55d3
@ -131,7 +131,7 @@ def _assert_managed_packages(module, packages):
|
||||
app = cls()
|
||||
components = app.get_components_of_type(Packages)
|
||||
for component in components:
|
||||
managed_packages += component.managed_packages()
|
||||
managed_packages += component.possible_packages
|
||||
|
||||
for package in packages:
|
||||
assert package in managed_packages
|
||||
|
||||
@ -132,7 +132,7 @@ def get_apps_report():
|
||||
components = app_.get_components_of_type(Packages)
|
||||
packages = []
|
||||
for component in components:
|
||||
packages += component.packages
|
||||
packages += component.possible_packages
|
||||
|
||||
if not packages:
|
||||
continue # app has no managed packages
|
||||
|
||||
@ -145,23 +145,28 @@ class Packages(app.FollowerComponent):
|
||||
self.conflicts_action = conflicts_action
|
||||
|
||||
@property
|
||||
def packages(self) -> list[PackageExpression]:
|
||||
"""Return the list of packages and package expressions managed by this
|
||||
component."""
|
||||
def package_expressions(self) -> list[PackageExpression]:
|
||||
"""Return the list of managed packages as expressions."""
|
||||
return self._packages
|
||||
|
||||
def managed_packages(self) -> list[str]:
|
||||
@property
|
||||
def possible_packages(self) -> list[str]:
|
||||
"""Return the list of possible packages before resolving."""
|
||||
managed_packages: list[str] = []
|
||||
for package in self.packages:
|
||||
managed_package = package.possible()
|
||||
managed_packages.extend(managed_package)
|
||||
packages: list[str] = []
|
||||
for package_expression in self.package_expressions:
|
||||
packages.extend(package_expression.possible())
|
||||
|
||||
return managed_packages
|
||||
return packages
|
||||
|
||||
def resolve(self) -> list[str]:
|
||||
"""Return the resolved list of packages to install."""
|
||||
return [package.actual() for package in self.packages]
|
||||
def get_actual_packages(self) -> list[str]:
|
||||
"""Return the computed list of packages to install.
|
||||
|
||||
Raise MissingPackageError if a required package is not available.
|
||||
"""
|
||||
return [
|
||||
package_expression.actual()
|
||||
for package_expression in self.package_expressions
|
||||
]
|
||||
|
||||
def setup(self, old_version):
|
||||
"""Install the packages."""
|
||||
@ -169,13 +174,14 @@ class Packages(app.FollowerComponent):
|
||||
module_name = self.app.__module__
|
||||
module = sys.modules[module_name]
|
||||
helper = module.setup_helper
|
||||
helper.install(self.resolve(), skip_recommends=self.skip_recommends)
|
||||
helper.install(self.get_actual_packages(),
|
||||
skip_recommends=self.skip_recommends)
|
||||
|
||||
def diagnose(self):
|
||||
"""Run diagnostics and return results."""
|
||||
results = super().diagnose()
|
||||
cache = apt.Cache()
|
||||
for package_expression in self.packages:
|
||||
for package_expression in self.package_expressions:
|
||||
try:
|
||||
package_name = package_expression.actual()
|
||||
except MissingPackageError:
|
||||
@ -223,7 +229,7 @@ class Packages(app.FollowerComponent):
|
||||
|
||||
# List of all packages from all Package components
|
||||
try:
|
||||
self.resolve()
|
||||
self.get_actual_packages()
|
||||
except MissingPackageError:
|
||||
return True
|
||||
|
||||
|
||||
@ -166,8 +166,8 @@ def list_dependencies(app_ids=None, essential=False):
|
||||
continue
|
||||
|
||||
for component in app.get_components_of_type(Packages):
|
||||
for package_name in component.packages:
|
||||
print(package_name)
|
||||
for package_expression in component.package_expressions:
|
||||
print(package_expression)
|
||||
|
||||
|
||||
def run_setup_in_background():
|
||||
@ -500,9 +500,9 @@ class ForceUpgrader():
|
||||
continue
|
||||
|
||||
for component in app.get_components_of_type(Packages):
|
||||
upgradable_packages.update(component.packages)
|
||||
upgradable_packages.update(component.possible_packages)
|
||||
|
||||
for managed_package in component.packages:
|
||||
for managed_package in component.possible_packages:
|
||||
package_apps_map[managed_package].add(app.app_id)
|
||||
|
||||
return upgradable_packages.intersection(
|
||||
|
||||
@ -53,7 +53,7 @@ class TestPackageExpressions(unittest.TestCase):
|
||||
def test_packages_init():
|
||||
"""Test initialization of packages component."""
|
||||
component = Packages('test-component', ['foo', 'bar'])
|
||||
assert component.managed_packages() == ['foo', 'bar']
|
||||
assert component.possible_packages == ['foo', 'bar']
|
||||
assert component.component_id == 'test-component'
|
||||
assert not component.skip_recommends
|
||||
assert component.conflicts is None
|
||||
@ -65,25 +65,25 @@ def test_packages_init():
|
||||
component = Packages('test-component', [], skip_recommends=True,
|
||||
conflicts=['conflict1', 'conflict2'],
|
||||
conflicts_action=Packages.ConflictsAction.IGNORE)
|
||||
assert component.managed_packages() == []
|
||||
assert component.possible_packages == []
|
||||
assert component.skip_recommends
|
||||
assert component.conflicts == ['conflict1', 'conflict2']
|
||||
assert component.conflicts_action == Packages.ConflictsAction.IGNORE
|
||||
|
||||
|
||||
def test_packages_resolve():
|
||||
"""Test resolving of package expressions."""
|
||||
def test_packages_get_actual_packages():
|
||||
"""Test resolving of package expressions to actual packages."""
|
||||
component = Packages('test-component', ['python3'])
|
||||
assert component.resolve() == ['python3']
|
||||
assert component.get_actual_packages() == ['python3']
|
||||
|
||||
component = Packages('test-component',
|
||||
[Package('unknown-package') | Package('python3')])
|
||||
assert component.resolve() == ['python3']
|
||||
assert component.get_actual_packages() == ['python3']
|
||||
|
||||
component = Packages('test-component', [], skip_recommends=True,
|
||||
conflicts=['conflict1', 'conflict2'],
|
||||
conflicts_action=Packages.ConflictsAction.IGNORE)
|
||||
assert component.resolve() == []
|
||||
assert component.get_actual_packages() == []
|
||||
|
||||
|
||||
def test_packages_setup():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user