Sunil Mohan Adapa b12d994760
upgrades: Separate concepts for backports enabled vs. requested
It is confusing to combine the user's intent of wanting to have backports
activated with whether they have actually been configured in the system.

- Separate out checking for requested which is a key in the kvstore from enabled
which is about checking system configuration for backports.

- Implement convenience method for setting whether user requested backports.

- Do not base the status display (in security and upgrades modules) on the
configuration status and instead focus on user intent.

  - If user requested backports but they have not been enabled yet due to not
  being available, show as activated. System will keep trying the background and
  configure eventually.

  - If user requested backports but their configuration is outdated yet due to
  newer release, show as activated. System will keep trying in the background
  and configure latest settings eventually.

- In all places where backports enabling is being checked, split the logic for
'can be activated' from 'already activated' and 'user requested activation'
properly.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
2020-09-11 10:55:10 -04:00

129 lines
4.5 KiB
Python

# SPDX-License-Identifier: AGPL-3.0-or-later
"""
FreedomBox app for upgrades.
"""
from django.contrib import messages
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.utils.translation import ugettext as _
from django.views.generic.edit import FormView
from plinth import actions, package
from plinth.errors import ActionError
from plinth.modules import first_boot, upgrades
from plinth.views import AppView
from .forms import BackportsFirstbootForm, ConfigureForm
class UpgradesConfigurationView(AppView):
"""Serve configuration page."""
form_class = ConfigureForm
success_url = reverse_lazy('upgrades:index')
template_name = "upgrades_configure.html"
app_id = 'upgrades'
def get_initial(self):
return {'auto_upgrades_enabled': upgrades.is_enabled()}
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['can_activate_backports'] = upgrades.can_activate_backports()
context['is_backports_requested'] = upgrades.is_backports_requested()
context['is_busy'] = package.is_package_manager_busy()
context['log'] = get_log()
context['refresh_page_sec'] = 3 if context['is_busy'] else None
return context
def form_valid(self, form):
"""Apply the form changes."""
old_status = form.initial
new_status = form.cleaned_data
if old_status['auto_upgrades_enabled'] \
!= new_status['auto_upgrades_enabled']:
try:
if new_status['auto_upgrades_enabled']:
upgrades.enable()
else:
upgrades.disable()
except ActionError as exception:
error = exception.args[2]
messages.error(
self.request,
_('Error when configuring unattended-upgrades: {error}').
format(error=error))
if new_status['auto_upgrades_enabled']:
messages.success(self.request, _('Automatic upgrades enabled'))
else:
messages.success(self.request,
_('Automatic upgrades disabled'))
return super().form_valid(form)
def get_log():
"""Return the current log for unattended upgrades."""
return actions.superuser_run('upgrades', ['get-log'])
def upgrade(request):
"""Serve the upgrade page."""
if request.method == 'POST':
try:
actions.superuser_run('upgrades', ['run'])
messages.success(request, _('Upgrade process started.'))
except ActionError:
messages.error(request, _('Starting upgrade failed.'))
return redirect(reverse_lazy('upgrades:index'))
def activate_backports(request):
"""Activate backports."""
if request.method == 'POST':
upgrades.set_backports_requested(True)
upgrades.setup_repositories(None)
messages.success(request, _('Frequent feature updates activated.'))
return redirect(reverse_lazy('upgrades:index'))
class BackportsFirstbootView(FormView):
"""View to configure backports during first boot wizard."""
template_name = 'backports-firstboot.html'
form_class = BackportsFirstbootForm
def dispatch(self, request, *args, **kwargs):
"""Show backports configuration form only if it can be activated."""
if upgrades.is_backports_enabled():
# Backports is already enabled. Record this preference and
# skip first boot step.
upgrades.set_backports_requested(True)
first_boot.mark_step_done('backports_wizard')
return HttpResponseRedirect(reverse_lazy(first_boot.next_step()))
if not upgrades.can_activate_backports():
# Skip first boot step.
upgrades.set_backports_requested(False)
first_boot.mark_step_done('backports_wizard')
return HttpResponseRedirect(reverse_lazy(first_boot.next_step()))
return super().dispatch(request, *args, *kwargs)
def get_success_url(self):
"""Return next firstboot step."""
return reverse_lazy(first_boot.next_step())
def form_valid(self, form):
"""Mark the first wizard step as done, save value and redirect."""
enabled = form.cleaned_data['backports_enabled']
upgrades.set_backports_requested(enabled)
upgrades.setup_repositories(None)
first_boot.mark_step_done('backports_wizard')
return super().form_valid(form)