upgrades: Refactor code to disable snapshots

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2025-03-04 07:38:19 -08:00 committed by James Valleroy
parent 1d8e406528
commit e97e1fc725
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808

View File

@ -1,10 +1,12 @@
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
"""Perform distribution upgrade.""" """Perform distribution upgrade."""
import contextlib
import logging import logging
import pathlib import pathlib
import subprocess import subprocess
import time import time
from typing import Generator
from plinth.action_utils import (apt_hold, apt_hold_freedombox, from plinth.action_utils import (apt_hold, apt_hold_freedombox,
debconf_set_selections, run_apt_command, debconf_set_selections, run_apt_command,
@ -123,12 +125,21 @@ def check(test_upgrade=False) -> tuple[bool, str]:
return (True, 'started-dist-upgrade') return (True, 'started-dist-upgrade')
def _take_snapshot_and_disable() -> bool: @contextlib.contextmanager
def _snapshot_run_and_disable() -> Generator[None, None, None]:
"""Take a snapshot if supported and enabled, then disable snapshots. """Take a snapshot if supported and enabled, then disable snapshots.
Return whether snapshots shall be re-enabled at the end. Snapshots shall be re-enabled, if originally enabled, on exiting this
context manager..
""" """
if snapshot_module.is_supported(): if not snapshot_module.is_supported():
print('Snapshots are not supported, skipping taking a snapshot.',
flush=True)
yield
return
reenable = False
try:
print('Taking a snapshot before dist upgrade...', flush=True) print('Taking a snapshot before dist upgrade...', flush=True)
subprocess.run([ subprocess.run([
'/usr/share/plinth/actions/actions', 'snapshot', 'create', '/usr/share/plinth/actions/actions', 'snapshot', 'create',
@ -136,36 +147,31 @@ def _take_snapshot_and_disable() -> bool:
], check=True) ], check=True)
aug = snapshot_module.load_augeas() aug = snapshot_module.load_augeas()
if snapshot_module.is_apt_snapshots_enabled(aug): if snapshot_module.is_apt_snapshots_enabled(aug):
print('Disable apt snapshots during dist upgrade...', flush=True) print('Disabling apt snapshots during dist upgrade...', flush=True)
subprocess.run([ subprocess.run([
'/usr/share/plinth/actions/actions', '/usr/share/plinth/actions/actions',
'snapshot', 'snapshot',
'disable_apt_snapshot', 'disable_apt_snapshot',
], input='{"args": ["yes"], "kwargs": {}}'.encode(), check=True) ], input='{"args": ["yes"], "kwargs": {}}'.encode(), check=True)
return True reenable = True
else: else:
print('Apt snapshots already disabled.', flush=True) print('Apt snapshots already disabled.', flush=True)
else:
print('Snapshots are not supported, skip taking a snapshot.',
flush=True)
return False yield
finally:
def _restore_snapshots_config(reenable=False):
"""Restore original snapshots configuration."""
if reenable: if reenable:
print('Re-enable apt snapshots...', flush=True) print('Re-enabling apt snapshots...', flush=True)
subprocess.run([ subprocess.run([
'/usr/share/plinth/actions/actions', 'snapshot', '/usr/share/plinth/actions/actions', 'snapshot',
'disable_apt_snapshot' 'disable_apt_snapshot'
], input='{"args": ["no"], "kwargs": {}}'.encode(), check=True) ], input='{"args": ["no"], "kwargs": {}}'.encode(), check=True)
else:
print('Not re-enabling apt snapshots, as they were disabled '
'before dist upgrade.')
def perform(): def perform():
"""Perform upgrade to next release of Debian.""" """Perform upgrade to next release of Debian."""
reenable_snapshots = _take_snapshot_and_disable()
# If quassel is running during dist upgrade, it may be restarted # If quassel is running during dist upgrade, it may be restarted
# several times. This causes IRC users to rapidly leave/join # several times. This causes IRC users to rapidly leave/join
# channels. Stop quassel for the duration of the dist upgrade. # channels. Stop quassel for the duration of the dist upgrade.
@ -177,7 +183,7 @@ def perform():
# Hold freedombox package during entire dist upgrade. # Hold freedombox package during entire dist upgrade.
print('Holding freedombox package...', flush=True) print('Holding freedombox package...', flush=True)
with apt_hold_freedombox(): with apt_hold_freedombox(), _snapshot_run_and_disable():
print('Updating Apt cache...', flush=True) print('Updating Apt cache...', flush=True)
run_apt_command(['update']) run_apt_command(['update'])
@ -224,8 +230,6 @@ def perform():
print('Running unattended-upgrade...', flush=True) print('Running unattended-upgrade...', flush=True)
subprocess.run(['unattended-upgrade', '--verbose'], check=False) subprocess.run(['unattended-upgrade', '--verbose'], check=False)
_restore_snapshots_config(reenable_snapshots)
# Restart FreedomBox service to ensure it is using the latest # Restart FreedomBox service to ensure it is using the latest
# dependencies. # dependencies.
print('Restarting FreedomBox service...', flush=True) print('Restarting FreedomBox service...', flush=True)