mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-08-19 12:36:06 +00:00
packages: Move checking for unavailable packages to component
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
fb40bb7f42
commit
929e7f6dba
@ -6,6 +6,7 @@ Framework for installing and updating distribution packages
|
||||
import enum
|
||||
import json
|
||||
import logging
|
||||
import pathlib
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
@ -84,6 +85,25 @@ class Packages(app.FollowerComponent):
|
||||
|
||||
return packages_installed(self.conflicts)
|
||||
|
||||
def has_unavailable_packages(self):
|
||||
"""Return whether any of the packages are not available.
|
||||
|
||||
Returns True if one or more of the packages is not available in the
|
||||
user's Debian distribution or False otherwise. Returns None if it
|
||||
cannot be reliably determined whether the packages are available or
|
||||
not.
|
||||
"""
|
||||
apt_lists_dir = pathlib.Path('/var/lib/apt/lists/')
|
||||
num_files = len(
|
||||
[child for child in apt_lists_dir.iterdir() if child.is_file()])
|
||||
if num_files < 2: # not counting the lock file
|
||||
return None
|
||||
|
||||
# List of all packages from all Package components
|
||||
cache = apt.Cache()
|
||||
return any(package for package in self.packages
|
||||
if package not in cache)
|
||||
|
||||
|
||||
class PackageException(Exception):
|
||||
"""A package operation has failed."""
|
||||
|
||||
@ -5,7 +5,6 @@ Utilities for performing application setup operations.
|
||||
|
||||
import importlib
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
from collections import defaultdict
|
||||
@ -159,34 +158,6 @@ class Helper(object):
|
||||
models.Module.objects.update_or_create(
|
||||
pk=self.module_name, defaults={'setup_version': version})
|
||||
|
||||
def has_unavailable_packages(self):
|
||||
"""Find if any of the packages managed by the module are not available.
|
||||
|
||||
Returns True if one or more of the packages is not available in the
|
||||
user's Debian distribution or False otherwise.
|
||||
Returns None if it cannot be reliably determined whether the
|
||||
packages are available or not.
|
||||
"""
|
||||
APT_LISTS_DIR = '/var/lib/apt/lists/'
|
||||
num_files = len([
|
||||
name for name in os.listdir(APT_LISTS_DIR)
|
||||
if os.path.isfile(os.path.join(APT_LISTS_DIR, name))
|
||||
])
|
||||
if num_files < 2: # not counting the lock file
|
||||
return None
|
||||
|
||||
pkg_components = list(self.module.app.get_components_of_type(Packages))
|
||||
if not pkg_components: # This app has no packages to install
|
||||
return False
|
||||
|
||||
# List of all packages from all Package components
|
||||
managed_pkgs = (package for component in pkg_components
|
||||
for package in component.packages)
|
||||
cache = apt.Cache()
|
||||
unavailable_pkgs = (pkg_name for pkg_name in managed_pkgs
|
||||
if pkg_name not in cache)
|
||||
return any(unavailable_pkgs)
|
||||
|
||||
|
||||
def init(module_name, module):
|
||||
"""Create a setup helper for a module for later use."""
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
Please wait for a few moments before trying again.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% elif setup_helper.has_unavailable_packages %}
|
||||
{% elif has_unavailable_packages %}
|
||||
<div class="alert alert-warning" role="alert">
|
||||
{% blocktrans trimmed %}
|
||||
This application is currently not available in your distribution.
|
||||
@ -64,7 +64,7 @@
|
||||
{% endif %}
|
||||
|
||||
<input type="submit" class="btn btn-md btn-primary" name="install"
|
||||
{% if package_manager_is_busy or setup_helper.has_unavailable_packages %}
|
||||
{% if package_manager_is_busy or has_unavailable_packages %}
|
||||
disabled="disabled"
|
||||
{% endif %}
|
||||
{% if setup_state == 'needs-setup' %}
|
||||
|
||||
@ -80,6 +80,25 @@ def test_packages_find_conflicts(packages_installed_):
|
||||
assert component.find_conflicts() == ['package1', 'package2']
|
||||
|
||||
|
||||
@patch('apt.Cache')
|
||||
@patch('pathlib.Path')
|
||||
def test_packages_has_unavailable_packages(path_class, cache):
|
||||
"""Test checking for unavailable packages."""
|
||||
path = Mock()
|
||||
path_class.return_value = path
|
||||
path.iterdir.return_value = [Mock()]
|
||||
|
||||
component = Packages('test-component', ['package1', 'package2'])
|
||||
assert component.has_unavailable_packages() is None
|
||||
|
||||
path.iterdir.return_value = [Mock(), Mock()]
|
||||
cache.return_value = ['package1', 'package2']
|
||||
assert not component.has_unavailable_packages()
|
||||
|
||||
cache.return_value = ['package1']
|
||||
assert component.has_unavailable_packages()
|
||||
|
||||
|
||||
def test_packages_installed():
|
||||
"""Test packages_installed()."""
|
||||
# list as input
|
||||
|
||||
@ -288,6 +288,9 @@ class SetupView(TemplateView):
|
||||
if not context['setup_current_operation']:
|
||||
context[
|
||||
'package_manager_is_busy'] = package.is_package_manager_busy()
|
||||
context[
|
||||
'has_unavailable_packages'] = self._has_unavailable_packages(
|
||||
setup_helper.module.app)
|
||||
|
||||
context['refresh_page_sec'] = None
|
||||
if context['setup_state'] == 'up-to-date':
|
||||
@ -335,6 +338,13 @@ class SetupView(TemplateView):
|
||||
|
||||
return conflicts, conflicts_action
|
||||
|
||||
@staticmethod
|
||||
def _has_unavailable_packages(app_):
|
||||
"""Return whether the app has unavailable packages."""
|
||||
components = app_.get_components_of_type(Packages)
|
||||
return any(component for component in components
|
||||
if component.has_unavailable_packages())
|
||||
|
||||
|
||||
def notification_dismiss(request, id):
|
||||
"""Dismiss a notification."""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user