upgrades: Add first boot step to configure backports

Closes: #1855.

Tests:

- On unstable, first boot step is not shown. Backports are not
  enabled.

- On testing, tested enabling backports at first boot step. Backports
  are enabled.

- On testing, tested not enabling backports. Backports are not enabled
  and can be activated later.

- On testing, confirmed that functional tests can click through the
  first boot step.

- On stable with backports, first boot step is not shown. Backports
  are enabled.

- On stable, tested enabling backports at first boot step. Backports
  are enabled.

- On stable, tested not enabling backports. Backports are not enabled
  and can be activated later.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
[sunil: Avoid two different i18n strings with almost same content]
[sunil: Use box_name instead of hardcoded FreedomBox name]
[sunil: Use consistent terminology 'activate' instead of 'enable']
[sunil: Rename the wizard, form, view, url for consistency with existing code]
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
James Valleroy 2020-07-21 19:41:35 -04:00
parent 2f7b3264d1
commit 65d8f82ae1
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
8 changed files with 145 additions and 19 deletions

View File

@ -22,11 +22,12 @@
</p>
<p>
{% blocktrans trimmed %}
This will allow a very limited set of software, including FreedomBox
service, to be updated to receive newer features regularly instead of
once every 2 years or so. Note that packages with frequent feature
updates do not have support from Debian Security Team. They are instead
maintained by contributors to Debian and the FreedomBox community.
Frequent feature updates allow a very limited set of software, including
{{box_name}} service, to be updated to receive newer features regularly
instead of once every 2 years or so. Note that packages with frequent
feature updates do not have support from Debian Security Team. They are
instead maintained by contributors to Debian and the {{box_name}}
community.
{% endblocktrans %}
</p>
{% endif %}

View File

@ -23,6 +23,14 @@ is_essential = True
managed_packages = ['unattended-upgrades', 'needrestart']
first_boot_steps = [
{
'id': 'backports_wizard',
'url': 'upgrades:backports-firstboot',
'order': 5,
},
]
_description = [
_('Check for and apply the latest software and security updates.'),
_('Updates are run at 06:00 everyday according to local time zone. Set '
@ -34,6 +42,8 @@ _description = [
app = None
BACKPORTS_ENABLED_KEY = 'upgrades_backports_enabled'
SOURCES_LIST = '/etc/apt/sources.list.d/freedombox2.list'
@ -129,11 +139,13 @@ def disable():
def setup_repositories(data):
"""Setup apt backport repositories."""
command = ['setup-repositories']
if cfg.develop:
command += ['--develop']
from plinth import kvstore
if kvstore.get_default(BACKPORTS_ENABLED_KEY, False):
command = ['setup-repositories']
if cfg.develop:
command += ['--develop']
actions.superuser_run('upgrades', command)
actions.superuser_run('upgrades', command)
def is_backports_enabled():

View File

@ -12,3 +12,10 @@ class ConfigureForm(forms.Form):
auto_upgrades_enabled = forms.BooleanField(
label=_('Enable auto-update'), required=False, help_text=_(
'When enabled, FreedomBox automatically updates once a day.'))
class BackportsFirstbootForm(forms.Form):
"""Form to configure backports during first boot wizard."""
backports_enabled = forms.BooleanField(
label=_('Activate frequent feature updates (recommended)'),
required=False)

View File

@ -0,0 +1,47 @@
{% extends "base_firstboot.html" %}
{% comment %}
# SPDX-License-Identifier: AGPL-3.0-or-later
{% endcomment %}
{% load bootstrap %}
{% load i18n %}
{% load static %}
{% block content %}
<h1>{% trans "Frequent Feature Updates" %}</h1>
<p>
{% blocktrans trimmed %}
Frequent feature updates allow a very limited set of software, including
{{box_name}} service, to be updated to receive newer features regularly
instead of once every 2 years or so. Note that packages with frequent
feature updates do not have support from Debian Security Team. They are
instead maintained by contributors to Debian and the {{box_name}}
community.
{% endblocktrans %}
</p>
<p>
{% blocktrans trimmed %}
It is strongly recommended to activate frequent feature updates. If not
activated now, they can be activated later.
{% endblocktrans %}
</p>
<div class="alert alert-warning" role="alert">
{% blocktrans trimmed %}
<strong>Note:</strong> Once frequent feature updates are activated,
they cannot be deactivated.
{% endblocktrans %}
</div>
<form class="form" method="post">
{% csrf_token %}
{{ form|bootstrap }}
<input type="submit" class="btn btn-primary pull-right" name="next"
value="{% trans "Next" %}"/>
</form>
{% endblock %}

View File

@ -29,11 +29,12 @@
<p>
{% if can_activate_backports or is_backports_enabled %}
{% blocktrans trimmed %}
This will allow a very limited set of software, including FreedomBox
service, to be updated to receive newer features regularly instead of
once every 2 years or so. Note that packages with frequent feature
updates do not have support from Debian Security Team. They are instead
maintained by contributors to Debian and the FreedomBox community.
Frequent feature updates allow a very limited set of software, including
{{box_name}} service, to be updated to receive newer features regularly
instead of once every 2 years or so. Note that packages with frequent
feature updates do not have support from Debian Security Team. They are
instead maintained by contributors to Debian and the {{box_name}}
community.
{% endblocktrans %}
{% endif %}
</p>

View File

@ -12,5 +12,7 @@ urlpatterns = [
name='index'),
url(r'^sys/upgrades/activate-backports/$', views.activate_backports,
name='activate-backports'),
url(r'^sys/upgrades/firstboot/backports/$',
views.BackportsFirstbootView.as_view(), name='backports-firstboot'),
url(r'^sys/upgrades/upgrade/$', views.upgrade, name='upgrade'),
]

View File

@ -3,17 +3,23 @@
FreedomBox app for upgrades.
"""
import logging
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 import actions, kvstore, package
from plinth.errors import ActionError
from plinth.modules import upgrades
from plinth.modules import first_boot, upgrades
from plinth.views import AppView
from .forms import ConfigureForm
from .forms import BackportsFirstbootForm, ConfigureForm
logger = logging.getLogger(__name__)
class UpgradesConfigurationView(AppView):
@ -84,7 +90,54 @@ def upgrade(request):
def activate_backports(request):
"""Activate backports."""
if request.method == 'POST':
kvstore.set(upgrades.BACKPORTS_ENABLED_KEY, 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.
kvstore.set(upgrades.BACKPORTS_ENABLED_KEY, 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.
first_boot.mark_step_done('backports_wizard')
return HttpResponseRedirect(reverse_lazy(first_boot.next_step()))
return super().dispatch(request, *args, *kwargs)
def get_initial(self):
"""Get initial form data."""
return {
'backports_enabled':
kvstore.get_default(upgrades.BACKPORTS_ENABLED_KEY, True)
}
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']
kvstore.set(upgrades.BACKPORTS_ENABLED_KEY, enabled)
if enabled:
upgrades.setup_repositories(None)
logger.info('Backports enabled.')
else:
logger.info('Backports not enabled.')
first_boot.mark_step_done('backports_wizard')
return super().form_valid(form)

View File

@ -13,8 +13,8 @@ from contextlib import contextmanager
import pytest
import requests
from selenium.common.exceptions import (WebDriverException,
StaleElementReferenceException)
from selenium.common.exceptions import (StaleElementReferenceException,
WebDriverException)
from selenium.webdriver.support.ui import WebDriverWait
config = configparser.ConfigParser()
@ -261,6 +261,9 @@ def login(browser, url, username, password):
if '/internet-connection-type' in browser.url:
submit(browser, element=browser.find_by_name('skip')[0])
if '/firstboot/backports' in browser.url:
submit(browser, element=browser.find_by_name('next')[0])
#################
# App utilities #