mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-28 08:03:36 +00:00
- This is to capture stdout and stderr and transmit that from privileged daemon back to the service to be displayed in HTML. Tests: - Unit tests and code checks pass. - Some of the modified actions work as expected. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: Veiko Aasa <veiko17@disroot.org>
127 lines
3.7 KiB
Python
127 lines
3.7 KiB
Python
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
"""Utilities for regular updates and dist-upgrades."""
|
|
|
|
import pathlib
|
|
import re
|
|
|
|
import augeas
|
|
|
|
from plinth import action_utils
|
|
from plinth.modules.apache.components import check_url
|
|
|
|
RELEASE_FILE_URL = \
|
|
'https://deb.debian.org/debian/dists/{}/Release'
|
|
|
|
DIST_UPGRADE_REQUIRED_FREE_SPACE = 5000000
|
|
|
|
sources_list = pathlib.Path('/etc/apt/sources.list')
|
|
|
|
|
|
def check_auto() -> bool:
|
|
"""Return whether automatic updates are enabled."""
|
|
arguments = [
|
|
'apt-config', 'shell', 'UpdateInterval',
|
|
'APT::Periodic::Update-Package-Lists'
|
|
]
|
|
output = action_utils.run(arguments, check=True).stdout.decode()
|
|
update_interval = 0
|
|
match = re.match(r"UpdateInterval='(.*)'", output)
|
|
if match:
|
|
update_interval = int(match.group(1))
|
|
|
|
return bool(update_interval)
|
|
|
|
|
|
def get_http_protocol() -> str:
|
|
"""Return the protocol to use for newly added repository sources."""
|
|
try:
|
|
from plinth.modules.torproxy import utils
|
|
if utils.is_apt_transport_tor_enabled():
|
|
return 'tor+http'
|
|
except Exception:
|
|
pass
|
|
|
|
return 'http'
|
|
|
|
|
|
def is_release_file_available(protocol: str, dist: str,
|
|
backports=False) -> bool:
|
|
"""Return whether the release for dist[-backports] is available."""
|
|
wrapper = None
|
|
if protocol == 'tor+http':
|
|
wrapper = 'torsocks'
|
|
|
|
if backports:
|
|
dist += '-backports'
|
|
|
|
try:
|
|
return check_url(RELEASE_FILE_URL.format(dist), wrapper=wrapper)
|
|
except FileNotFoundError:
|
|
return False
|
|
|
|
|
|
def is_sufficient_free_space() -> bool:
|
|
"""Return whether there is sufficient free space for dist upgrade."""
|
|
output = action_utils.run(['df', '--output=avail', '/'], check=True).stdout
|
|
free_space = int(output.decode().split('\n')[1])
|
|
return free_space >= DIST_UPGRADE_REQUIRED_FREE_SPACE
|
|
|
|
|
|
def get_sources_list_codename() -> str | None:
|
|
"""Return the codename set in the /etc/apt/sources.list file."""
|
|
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +
|
|
augeas.Augeas.NO_MODL_AUTOLOAD)
|
|
aug.transform('aptsources', str(sources_list))
|
|
aug.set('/augeas/context', '/files' + str(sources_list))
|
|
aug.load()
|
|
|
|
dists = set()
|
|
for match_ in aug.match('*'):
|
|
dist = aug.get(match_ + '/distribution')
|
|
if not dist:
|
|
continue
|
|
|
|
dist = dist.removesuffix('-updates')
|
|
dist = dist.removesuffix('-security')
|
|
dists.add(dist)
|
|
|
|
if 'unstable' in dists or 'sid' in dists:
|
|
return 'unstable'
|
|
|
|
if 'testing' in dists:
|
|
return 'testing'
|
|
|
|
# Multiple distributions are not understood.
|
|
if len(dists) != 1:
|
|
return None
|
|
|
|
return dists.pop()
|
|
|
|
|
|
def get_current_release():
|
|
"""Return current release and codename as a tuple."""
|
|
output = action_utils.run(
|
|
['lsb_release', '--release', '--codename', '--short'],
|
|
check=True).stdout.decode().strip()
|
|
lines = output.split('\n')
|
|
return lines[0], lines[1]
|
|
|
|
|
|
def is_distribution_unstable() -> bool:
|
|
"""Return whether the current distribution is unstable.
|
|
|
|
There is no way to distinguish between 'testing' and 'unstable'
|
|
distributions in Debian using commands like lsb_release (powered by
|
|
/etc/os-release). See: https://lwn.net/Articles/984635/ . So, use the value
|
|
set in /etc/apt/sources.list.
|
|
"""
|
|
codename = get_sources_list_codename()
|
|
return codename in ['unstable', 'sid']
|
|
|
|
|
|
def is_distribution_rolling() -> bool:
|
|
"""Return whether the current distribution is testing or unstable."""
|
|
# Release will be 'n/a' in latest unstable and testing distributions.
|
|
release, _ = get_current_release()
|
|
return release in ['unstable', 'testing', 'n/a']
|