diff --git a/actions/backports b/actions/backports deleted file mode 100755 index 353b65313..000000000 --- a/actions/backports +++ /dev/null @@ -1,116 +0,0 @@ -#!/usr/bin/python3 -# -*- mode: python -*- -# -# This file is part of FreedomBox. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -""" -Script to check for availability of buster-backports and create an -apt sources list for backports if available. -""" - -import argparse -import os -import requests - -from plinth import action_utils - -BUSTER_BACKPORTS_RELEASE_FILE_URL = "http://cdn-fastly.deb.debian.org/debian/dists/buster-backports/Release" - - -def parse_arguments(): - """Return parsed command line arguments as dictionary.""" - parser = argparse.ArgumentParser() - subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - - subparsers.add_parser('enable', help='Enable buster backports check') - subparsers.add_parser('disable', help='Disable buster backports check') - subparsers.add_parser('check-backports', - help='Check whether buster backports are available') - - subparsers.required = True - return parser.parse_args() - - -def add_buster_backports_sources(): - backports_list = '/etc/apt/sources.list.d/freedombox-backports.list' - - conf = \ -"""deb http://deb.debian.org/debian buster-backports main -deb-src http://deb.debian.org/debian buster-backports main -""" - - components = {"main"} - - # Use tor+http if download over tor is enabled in sources.list - with open('/etc/apt/sources.list', 'r') as sources_list: - sources = sources_list.readlines() - for line in sources: - if not line.startswith("#") and "tor+http" in line: - conf = conf.replace("http", "tor+http") - # Check for contrib and nonfree components - if "contrib" in line: - components.add("contrib") - if "nonfree" in line: - components.add("nonfree") - break - - conf = conf.replace("main", " ".join(components)) - - if not os.path.exists(backports_list): - try: - with open(backports_list, 'w') as file_handle: - file_handle.write(conf) - except PermissionError: - print(("Failed adding sources list for buster-backports." - "Try running as a superuser.")) - - -def subcommand_check_backports(_): - """Check whether buster backports is available. - Add a sources file if it's available. - """ - response = requests.get(BUSTER_BACKPORTS_RELEASE_FILE_URL) - - if response.status_code == 404: - print("Release file for Buster backports is not available yet.") - else: - print("Buster backports is now available. Adding to sources...") - add_buster_backports_sources() - - -def subcommand_enable(_): - """Enable systemd service for the daily job buster-backports-check.""" - action_utils.service_enable('buster-backports-check.timer') - action_utils.service_start('buster-backports-check.timer') - - -def subcommand_disable(_): - """Disable systemd service for the daily job buster-backports-check.""" - action_utils.service_stop('buster-backports-check.timer') - action_utils.service_disable('buster-backports-check.timer') - - -def main(): - """Parse arguments and perform all duties.""" - arguments = parse_arguments() - - subcommand = arguments.subcommand.replace('-', '_') - subcommand_method = globals()['subcommand_' + subcommand] - subcommand_method(arguments) - - -if __name__ == '__main__': - main() diff --git a/actions/upgrades b/actions/upgrades index 69a5f3875..e2666e9c1 100755 --- a/actions/upgrades +++ b/actions/upgrades @@ -20,12 +20,16 @@ Configures or runs unattended-upgrades """ import argparse +import os import re import subprocess import sys +from plinth import action_utils + AUTO_CONF_FILE = '/etc/apt/apt.conf.d/20auto-upgrades' LOG_FILE = '/var/log/unattended-upgrades/unattended-upgrades.log' +BUSTER_BACKPORTS_RELEASE_FILE_URL = 'https://deb.debian.org/debian/dists/buster-backports/Release' def parse_arguments(): @@ -40,6 +44,9 @@ def parse_arguments(): subparsers.add_parser('disable-auto', help='Disable automatic upgrades.') subparsers.add_parser('get-log', help='Print the automatic upgrades log') + subparsers.add_parser('setup-repositories', + help='Setup software repositories for FreedomBox') + subparsers.required = True return parser.parse_args() @@ -102,6 +109,91 @@ def subcommand_get_log(_): pass +def _get_protocol(): + """Return the protocol to use for newly added repository sources.""" + try: + from plinth.modules.tor import utils + if utils.is_apt_transport_tor_enabled(): + return 'tor+http' + except Exception: + pass + + return 'http' + + +def _is_release_file_available(protocol): + """Return whether the release for backports is available.""" + wrapper = None + if protocol == 'tor+http': + wrapper = 'torsocks' + + result = action_utils.check_url(BUSTER_BACKPORTS_RELEASE_FILE_URL, + wrapper=wrapper) + return result == 'passed' + + +def _add_buster_backports_sources(sources_list, protocol): + """Add buster backports sources to freedombox repositories list.""" + sources = '''# This file is managed by FreedomBox, do not edit. +# Allow carefully selected updates to 'freedombox' from backports. + +deb {protocol}://deb.debian.org/debian buster-backports main +deb-src {protocol}://deb.debian.org/debian buster-backports main +''' + sources = sources.format(protocol=protocol) + with open(sources_list, 'w') as file_handle: + file_handle.write(sources) + + +def _check_and_backports_sources(): + """Add buster backports sources after checking if it is available.""" + sources_list = '/etc/apt/sources.list.d/freedombox.list' + if os.path.exists(sources_list): + print('Repositories list up-to-date. Skipping update.') + return + + protocol = _get_protocol() + if protocol == 'tor+http': + print('Package download over Tor is enabled.') + + if not _is_release_file_available(protocol): + print('Release file for Buster backports is not available yet.') + return + + print('Buster backports is now available. Adding to sources.') + _add_buster_backports_sources(sources_list, protocol) + + +def _add_apt_preferences(): + """Setup APT preferences to upgrade selected packages from backports.""" + preferences_file = '/etc/apt/preferences.d/50freedombox.pref' + if os.path.exists(preferences_file): + print('Preferences up-to-date. Skipping update') + return + + preferences = '''Explanation: This file is managed by FreedomBox, do not edit. +Explanation: Allow carefully selected updates to 'freedombox' from backports. +Package: freedombox +Pin: release a=buster-backports +Pin-Priority: 800 +''' + + print('Updating APT preferences.') + with open(preferences_file, 'w') as file_handle: + file_handle.write(preferences) + + +def subcommand_setup_repositories(_): + """Setup software repositories needed for FreedomBox. + + Repositories list for now only contains the backports. If the file exists, + assume that it contains backports. + + """ + _check_and_backports_sources() + _add_apt_preferences() + + def main(): """Parse arguments and perform all duties""" arguments = parse_arguments() diff --git a/data/etc/apt/apt.conf.d/60unattended-upgrades b/data/etc/apt/apt.conf.d/60unattended-upgrades index 68290c1bc..eaa4f7233 100644 --- a/data/etc/apt/apt.conf.d/60unattended-upgrades +++ b/data/etc/apt/apt.conf.d/60unattended-upgrades @@ -5,3 +5,12 @@ Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; // Do automatic removal of new unused dependencies after the upgrade // (equivalent to apt-get autoremove) Unattended-Upgrade::Remove-Unused-Dependencies "true"; + +// Allow upgrading from backports repository. This origin pattern is added to +// other configured patterns. This only works if the current distribution is a +// stable release. Also all backuports packages have a priority of 100 which is +// ignored. Only packages that have higher priority set explicitly will get +// upgraded. Only selected FreedomBox packages have high priority set on them. +Unattended-Upgrade::Origins-Pattern { + "o=Debian Backports,a=${distro_codename}-backports,l=Debian Backports"; +}; diff --git a/data/etc/apt/preferences.d/freedombox.pref b/data/etc/apt/preferences.d/freedombox.pref deleted file mode 100644 index f298825a3..000000000 --- a/data/etc/apt/preferences.d/freedombox.pref +++ /dev/null @@ -1,3 +0,0 @@ -Package: freedombox -Pin: release a=buster-backports -Pin-Priority: 800 diff --git a/data/etc/plinth/modules-enabled/backports b/data/etc/plinth/modules-enabled/backports deleted file mode 100644 index 0b329653d..000000000 --- a/data/etc/plinth/modules-enabled/backports +++ /dev/null @@ -1,2 +0,0 @@ -plinth.modules.backports - diff --git a/data/lib/systemd/system/buster-backports-check.service b/data/lib/systemd/system/buster-backports-check.service deleted file mode 100644 index 31cb98928..000000000 --- a/data/lib/systemd/system/buster-backports-check.service +++ /dev/null @@ -1,24 +0,0 @@ -# -# This file is part of FreedomBox. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# - -[Unit] -Description=Service to check for buster backports and enable them -ConditionPathExists=!/etc/apt/sources.list.d/freedombox-backports.list - -[Service] -ExecStart=/usr/share/plinth/actions/backports check-backports - diff --git a/plinth/modules/backports/urls.py b/data/lib/systemd/system/freedombox-setup-repositories.service similarity index 82% rename from plinth/modules/backports/urls.py rename to data/lib/systemd/system/freedombox-setup-repositories.service index 21fc6a4ac..dfb20a3a7 100644 --- a/plinth/modules/backports/urls.py +++ b/data/lib/systemd/system/freedombox-setup-repositories.service @@ -14,8 +14,10 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -""" -URLs for the Backports module. -""" -urlpatterns = [] +[Unit] +Description=FreedomBox: Setup software repositories + +[Service] +ExecStart=/usr/share/plinth/actions/upgrades setup-repositories +Type=oneshot diff --git a/data/lib/systemd/system/buster-backports-check.timer b/data/lib/systemd/system/freedombox-setup-repositories.timer similarity index 91% rename from data/lib/systemd/system/buster-backports-check.timer rename to data/lib/systemd/system/freedombox-setup-repositories.timer index e06b71748..7f9896f21 100644 --- a/data/lib/systemd/system/buster-backports-check.timer +++ b/data/lib/systemd/system/freedombox-setup-repositories.timer @@ -16,7 +16,7 @@ # [Unit] -Description=Daily check of whether buster backports are available yet +Description=FreedomBox: Daily check for setting up software repositories [Timer] OnCalendar=daily diff --git a/debian/postrm b/debian/postrm index fb7db5b7b..b5573a366 100755 --- a/debian/postrm +++ b/debian/postrm @@ -4,16 +4,20 @@ set -e case "$1" in purge) - deluser --system --quiet plinth || true - rm -rf /var/lib/plinth + deluser --system --quiet plinth || true + rm -rf /var/lib/plinth - # Remove legacy directory too - rm -rf /var/log/plinth + # Remove legacy directory too + rm -rf /var/log/plinth - if [ -e '/etc/apt/sources.list.d/freedombox-backports.list' ]; then - rm /etc/apt/sources.list.d/freedombox-backports.list - fi - ;; + if [ -e '/etc/apt/sources.list.d/freedombox.list' ]; then + rm -f /etc/apt/sources.list.d/freedombox.list + fi + + if [ -e '/etc/apt/preferences.d/50freedombox.pref' ]; then + rm -f /etc/apt/preferences.d/50freedombox.pref + fi + ;; esac #DEBHELPER# diff --git a/plinth/modules/backports/__init__.py b/plinth/modules/backports/__init__.py deleted file mode 100644 index 06357928e..000000000 --- a/plinth/modules/backports/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -# -# This file is part of FreedomBox. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -""" -FreedomBox app to manage Debian backports. -""" - -from plinth import actions - -is_essential = True - -version = 1 - - -def setup(helper, old_version=None): - """Configure the module.""" - helper.call('post', actions.superuser_run, 'backports', ['enable']) diff --git a/setup.py b/setup.py index 920c0913c..b7bab5163 100755 --- a/setup.py +++ b/setup.py @@ -238,8 +238,6 @@ setuptools.setup( glob.glob('data/etc/apache2/includes/*.conf')), ('/etc/apt/apt.conf.d', glob.glob('data/etc/apt/apt.conf.d/60unattended-upgrades')), - ('/etc/apt/preferences.d', - glob.glob('data/etc/apt/preferences.d/freedombox.pref')), ('/etc/avahi/services/', glob.glob('data/etc/avahi/services/*.service')), ('/etc/ikiwiki', glob.glob('data/etc/ikiwiki/*.setup')),