From 83bfc51931e6c1d57b5f077af3948de0d3f6a6b5 Mon Sep 17 00:00:00 2001 From: James Valleroy Date: Tue, 16 Aug 2022 19:44:01 -0400 Subject: [PATCH] upgrades: Add button to test dist-upgrade in development mode Tests: - In non-development mode, button does not appear. - On testing system, button does not appear. - On stable system in development mode, the button appears. - Pressing the button starts a dist-upgrade. Signed-off-by: James Valleroy [sunil: Join strings that fit in the same line] [sunil: Fix indentation in template] [sunil: Change 'dist-upgrade' to 'distribution upgrade' in UI strings] Signed-off-by: Sunil Mohan Adapa Reviewed-by: Sunil Mohan Adapa --- plinth/modules/upgrades/__init__.py | 112 ++++++++++-------- .../templates/upgrades_configure.html | 18 +++ plinth/modules/upgrades/urls.py | 2 + plinth/modules/upgrades/views.py | 10 ++ 4 files changed, 95 insertions(+), 47 deletions(-) diff --git a/plinth/modules/upgrades/__init__.py b/plinth/modules/upgrades/__init__.py index 9eba07745..c58e2bbe3 100644 --- a/plinth/modules/upgrades/__init__.py +++ b/plinth/modules/upgrades/__init__.py @@ -189,54 +189,61 @@ def setup_repositories(_): def check_dist_upgrade(_): """Check for upgrade to new stable release.""" - from plinth.notification import Notification if is_dist_upgrade_enabled(): - output = actions.superuser_run('upgrades', ['start-dist-upgrade']) - result = json.loads(output) - dist_upgrade_started = result['dist_upgrade_started'] - reason = result['reason'] - if 'found-previous' in reason: - logger.info( - 'Found previous dist-upgrade. If it was interrupted, it will ' - 'be restarted.') - elif 'already-' in reason: - logger.info('Skip dist upgrade: System is already up-to-date.') - elif 'codename-not-found' in reason: - logger.warning('Skip dist upgrade: Codename not found in release ' - 'file.') - elif 'upgrades-not-enabled' in reason: - logger.info('Skip dist upgrade: Automatic updates are not ' - 'enabled.') - elif 'test-not-set' in reason: - logger.info('Skip dist upgrade: --test is not set.') - elif 'not-enough-free-space' in reason: - logger.warning('Skip dist upgrade: Not enough free space in /.') - title = gettext_noop('Could not start distribution update') - message = gettext_noop( - 'There is not enough free space in the root partition to ' - 'start the distribution update. Please ensure at least 5 GB ' - 'is free. Distribution update will be retried after 24 hours,' - ' if enabled.') - Notification.update_or_create( - id='upgrades-dist-upgrade-free-space', app_id='upgrades', - severity='warning', title=title, message=message, actions=[{ - 'type': 'dismiss' - }], group='admin') - elif 'started-dist-upgrade' in reason: - logger.info('Started dist upgrade.') - title = gettext_noop('Distribution update started') - message = gettext_noop( - 'Started update to next stable release. This may take a long ' - 'time to complete.') - Notification.update_or_create(id='upgrades-dist-upgrade-started', - app_id='upgrades', severity='info', - title=title, message=message, - actions=[{ - 'type': 'dismiss' - }], group='admin') - else: - logger.warning('Unhandled result of start-dist-upgrade: %s, %s', - dist_upgrade_started, reason) + try_start_dist_upgrade() + + +def try_start_dist_upgrade(test=False): + """Try to start dist upgrade.""" + from plinth.notification import Notification + command = ['start-dist-upgrade'] + if test: + command.append('--test') + + output = actions.superuser_run('upgrades', command) + result = json.loads(output) + dist_upgrade_started = result['dist_upgrade_started'] + reason = result['reason'] + if 'found-previous' in reason: + logger.info( + 'Found previous dist-upgrade. If it was interrupted, it will ' + 'be restarted.') + elif 'already-' in reason: + logger.info('Skip dist upgrade: System is already up-to-date.') + elif 'codename-not-found' in reason: + logger.warning('Skip dist upgrade: Codename not found in release ' + 'file.') + elif 'upgrades-not-enabled' in reason: + logger.info('Skip dist upgrade: Automatic updates are not enabled.') + elif 'test-not-set' in reason: + logger.info('Skip dist upgrade: --test is not set.') + elif 'not-enough-free-space' in reason: + logger.warning('Skip dist upgrade: Not enough free space in /.') + title = gettext_noop('Could not start distribution update') + message = gettext_noop( + 'There is not enough free space in the root partition to ' + 'start the distribution update. Please ensure at least 5 GB ' + 'is free. Distribution update will be retried after 24 hours,' + ' if enabled.') + Notification.update_or_create(id='upgrades-dist-upgrade-free-space', + app_id='upgrades', severity='warning', + title=title, message=message, actions=[{ + 'type': 'dismiss' + }], group='admin') + elif 'started-dist-upgrade' in reason: + logger.info('Started dist upgrade.') + title = gettext_noop('Distribution update started') + message = gettext_noop( + 'Started update to next stable release. This may take a long ' + 'time to complete.') + Notification.update_or_create(id='upgrades-dist-upgrade-started', + app_id='upgrades', severity='info', + title=title, message=message, actions=[{ + 'type': 'dismiss' + }], group='admin') + else: + logger.warning('Unhandled result of start-dist-upgrade: %s, %s', + dist_upgrade_started, reason) def is_backports_requested(): @@ -303,3 +310,14 @@ def can_enable_dist_upgrade(): """Return whether dist upgrade can be enabled.""" release, _ = get_current_release() return release not in ['unstable', 'testing'] + + +def can_test_dist_upgrade(): + """Return whether dist upgrade can be tested.""" + return can_enable_dist_upgrade() and cfg.develop + + +def test_dist_upgrade(): + """Test dist-upgrade from stable to testing.""" + if can_test_dist_upgrade(): + try_start_dist_upgrade(test=True) diff --git a/plinth/modules/upgrades/templates/upgrades_configure.html b/plinth/modules/upgrades/templates/upgrades_configure.html index 19835c4cc..4f3445dc0 100644 --- a/plinth/modules/upgrades/templates/upgrades_configure.html +++ b/plinth/modules/upgrades/templates/upgrades_configure.html @@ -132,4 +132,22 @@

{% endif %} + + {% if can_test_dist_upgrade %} +

{% trans "Test Distribution Upgrade" %}

+

+ {% blocktrans trimmed %} + This will attempt to upgrade the system from stable to + testing. It is meant only for development use. + {% endblocktrans %} +

+
+
+ {% csrf_token %} + +
+
+ {% endif %} {% endblock %} diff --git a/plinth/modules/upgrades/urls.py b/plinth/modules/upgrades/urls.py index 2e88747e0..807ebb328 100644 --- a/plinth/modules/upgrades/urls.py +++ b/plinth/modules/upgrades/urls.py @@ -21,4 +21,6 @@ urlpatterns = [ views.UpdateFirstbootProgressView.as_view(), name='update-firstboot-progress'), re_path(r'^sys/upgrades/upgrade/$', views.upgrade, name='upgrade'), + re_path(r'^sys/upgrades/test-dist-upgrade/$', views.test_dist_upgrade, + name='test-dist-upgrade'), ] diff --git a/plinth/modules/upgrades/views.py b/plinth/modules/upgrades/views.py index 4958af928..7d5e6cd23 100644 --- a/plinth/modules/upgrades/views.py +++ b/plinth/modules/upgrades/views.py @@ -45,6 +45,7 @@ class UpgradesConfigurationView(AppView): context['version'] = __version__ context['new_version'] = is_newer_version_available() context['os_release'] = get_os_release() + context['can_test_dist_upgrade'] = upgrades.can_test_dist_upgrade() return context def form_valid(self, form): @@ -213,3 +214,12 @@ class UpdateFirstbootProgressView(TemplateView): context['next_step'] = first_boot.next_step() context['refresh_page_sec'] = 3 if context['is_busy'] else None return context + + +def test_dist_upgrade(request): + """Test dist-upgrade from stable to testing.""" + if request.method == 'POST': + upgrades.test_dist_upgrade() + messages.success(request, _('Starting distribution upgrade test.')) + + return redirect(reverse_lazy('upgrades:index'))