mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-28 08:03:36 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fa77cbe30 | ||
|
|
7988cc737b | ||
|
|
2bb2eaa6ec | ||
|
|
c19d2ab692 | ||
|
|
01da6934be | ||
|
|
6960a57779 | ||
|
|
2237d89745 | ||
|
|
e3b893277c | ||
|
|
6bf95de3bc | ||
|
|
0614b5e509 | ||
|
|
53f7c75d8e |
16
HACKING.md
16
HACKING.md
@ -66,7 +66,7 @@ development environment inside a systemd-nspawn container.
|
|||||||
folder: (This step requires at least 16GB of free disk space)
|
folder: (This step requires at least 16GB of free disk space)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
host$ ./container up
|
host$ ./container start
|
||||||
```
|
```
|
||||||
|
|
||||||
1. To run unit tests:
|
1. To run unit tests:
|
||||||
@ -97,20 +97,20 @@ development environment inside a systemd-nspawn container.
|
|||||||
1. Using an environment variable.
|
1. Using an environment variable.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
host$ DISTRIBUTION=stable ./container up
|
host$ DISTRIBUTION=stable ./container start
|
||||||
host$ DISTRIBUTION=stable ./container ssh
|
host$ DISTRIBUTION=stable ./container ssh
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
host$ export DISTRIBUTION=stable
|
host$ export DISTRIBUTION=stable
|
||||||
host$ ./container up
|
host$ ./container start
|
||||||
host$ ./container ssh
|
host$ ./container ssh
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Using the `--distribution` option for each command.
|
2. Using the `--distribution` option for each command.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
host$ ./container up --distribution=stable
|
host$ ./container start --distribution=stable
|
||||||
host$ ./container ssh --distribution=stable
|
host$ ./container ssh --distribution=stable
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ used simultaneously as they all use different disk images.
|
|||||||
example, to bring up a virtual machine instead of a container run:
|
example, to bring up a virtual machine instead of a container run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
host$ ./container up --machine-type=vm
|
host$ ./container start --machine-type=vm
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Using after Setup
|
#### Using after Setup
|
||||||
@ -164,9 +164,9 @@ Note: This development container has automatic upgrades disabled by default.
|
|||||||
|
|
||||||
#### Troubleshooting
|
#### Troubleshooting
|
||||||
|
|
||||||
* Sometimes `host$ ./container destroy && ./container up` doesn't work. In such
|
* Sometimes `host$ ./container destroy && ./container start` doesn't work. In such
|
||||||
cases, try to delete the hidden `.container` folder and then `host$
|
cases, try to delete the hidden `.container` folder and then `host$
|
||||||
./container up`.
|
./container start`.
|
||||||
* Not all kinds of changes are automatically updated. Try `guest$ sudo mount -o
|
* Not all kinds of changes are automatically updated. Try `guest$ sudo mount -o
|
||||||
remount /freedombox`.
|
remount /freedombox`.
|
||||||
* I am getting an error that says `lo` is not managed by Network Manager
|
* I am getting an error that says `lo` is not managed by Network Manager
|
||||||
@ -178,7 +178,7 @@ Note: This development container has automatic upgrades disabled by default.
|
|||||||
```bash
|
```bash
|
||||||
host$ sudo touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf
|
host$ sudo touch /etc/NetworkManager/conf.d/10-globally-managed-devices.conf
|
||||||
host$ sudo service network-manager restart
|
host$ sudo service network-manager restart
|
||||||
host$ ./container destroy && ./container up
|
host$ ./container destroy && ./container start
|
||||||
```
|
```
|
||||||
* File/directory not found errors when running tests can be fixed by clearing `__pycache__` directories.
|
* File/directory not found errors when running tests can be fixed by clearing `__pycache__` directories.
|
||||||
|
|
||||||
|
|||||||
2
Makefile
2
Makefile
@ -101,7 +101,7 @@ install:
|
|||||||
$(INSTALL) -d $(DESTDIR)$${lib_dir} && \
|
$(INSTALL) -d $(DESTDIR)$${lib_dir} && \
|
||||||
rm -rf $(DESTDIR)$${lib_dir}/plinth $(DESTDIR)$${lib_dir}/plinth*.dist-info && \
|
rm -rf $(DESTDIR)$${lib_dir}/plinth $(DESTDIR)$${lib_dir}/plinth*.dist-info && \
|
||||||
mv $${temp}/plinth $${temp}/plinth*.dist-info $(DESTDIR)$${lib_dir} && \
|
mv $${temp}/plinth $${temp}/plinth*.dist-info $(DESTDIR)$${lib_dir} && \
|
||||||
rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/COPYING.md && \
|
rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/licenses/COPYING.md && \
|
||||||
rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/direct_url.json && \
|
rm -f $(DESTDIR)$${lib_dir}/plinth*.dist-info/direct_url.json && \
|
||||||
$(INSTALL) -D -t $(BIN_DIR) bin/plinth
|
$(INSTALL) -D -t $(BIN_DIR) bin/plinth
|
||||||
$(INSTALL) -D -t $(LIB_DIR)/freedombox bin/freedombox-privileged
|
$(INSTALL) -D -t $(LIB_DIR)/freedombox bin/freedombox-privileged
|
||||||
|
|||||||
4
debian/control
vendored
4
debian/control
vendored
@ -1,6 +1,5 @@
|
|||||||
Source: freedombox
|
Source: freedombox
|
||||||
Section: web
|
Section: web
|
||||||
Priority: optional
|
|
||||||
Maintainer: FreedomBox packaging team <freedombox-pkg-team@lists.alioth.debian.org>
|
Maintainer: FreedomBox packaging team <freedombox-pkg-team@lists.alioth.debian.org>
|
||||||
Uploaders:
|
Uploaders:
|
||||||
Tzafrir Cohen <tzafrir@debian.org>,
|
Tzafrir Cohen <tzafrir@debian.org>,
|
||||||
@ -56,11 +55,10 @@ Build-Depends:
|
|||||||
sshpass,
|
sshpass,
|
||||||
xmlto,
|
xmlto,
|
||||||
xsltproc
|
xsltproc
|
||||||
Standards-Version: 4.6.2
|
Standards-Version: 4.7.3
|
||||||
Homepage: https://salsa.debian.org/freedombox-team/freedombox
|
Homepage: https://salsa.debian.org/freedombox-team/freedombox
|
||||||
Vcs-Git: https://salsa.debian.org/freedombox-team/freedombox.git
|
Vcs-Git: https://salsa.debian.org/freedombox-team/freedombox.git
|
||||||
Vcs-Browser: https://salsa.debian.org/freedombox-team/freedombox
|
Vcs-Browser: https://salsa.debian.org/freedombox-team/freedombox
|
||||||
Rules-Requires-Root: no
|
|
||||||
|
|
||||||
Package: freedombox
|
Package: freedombox
|
||||||
Breaks:
|
Breaks:
|
||||||
|
|||||||
4
debian/copyright
vendored
4
debian/copyright
vendored
@ -2,7 +2,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
|||||||
Source: https://salsa.debian.org/freedombox-team/freedombox
|
Source: https://salsa.debian.org/freedombox-team/freedombox
|
||||||
|
|
||||||
Files: *
|
Files: *
|
||||||
Copyright: 2011-2025 FreedomBox Authors
|
Copyright: 2011-2026 FreedomBox Authors
|
||||||
License: AGPL-3+
|
License: AGPL-3+
|
||||||
|
|
||||||
Files: plinth/modules/jsxc/static/icons/jsxc.png
|
Files: plinth/modules/jsxc/static/icons/jsxc.png
|
||||||
@ -358,7 +358,7 @@ License: LGPL-3+ or CC-BY-SA-3.0
|
|||||||
|
|
||||||
Files: debian/*
|
Files: debian/*
|
||||||
Copyright: 2013 Tzafrir Cohen
|
Copyright: 2013 Tzafrir Cohen
|
||||||
2013-2024 FreedomBox Authors
|
2013-2026 FreedomBox Authors
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
|
||||||
License: AGPL-3+
|
License: AGPL-3+
|
||||||
|
|||||||
4
debian/freedombox.lintian-overrides
vendored
4
debian/freedombox.lintian-overrides
vendored
@ -24,3 +24,7 @@ freedombox: package-contains-documentation-outside-usr-share-doc [usr/lib/python
|
|||||||
# meant for user. However, don't install to /usr/libexec and follow systemd
|
# meant for user. However, don't install to /usr/libexec and follow systemd
|
||||||
# convention instead.
|
# convention instead.
|
||||||
freedombox: executable-in-usr-lib [usr/lib/freedombox/freedombox-privileged]
|
freedombox: executable-in-usr-lib [usr/lib/freedombox/freedombox-privileged]
|
||||||
|
|
||||||
|
# [Install] section is missing for the privileged daemon service because it is
|
||||||
|
# socket activated.
|
||||||
|
freedombox: systemd-service-file-missing-install-key [usr/lib/systemd/system/freedombox-privileged.service]
|
||||||
|
|||||||
43
debian/freedombox.preinst
vendored
43
debian/freedombox.preinst
vendored
@ -1,43 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
upgrade)
|
|
||||||
# Handle removing freedombox-setup-repositories.timer from 20.5.
|
|
||||||
if dpkg --compare-versions "$2" le 20.7; then
|
|
||||||
if [ -x "/usr/bin/deb-systemd-invoke" ]; then
|
|
||||||
deb-systemd-invoke stop freedombox-setup-repositories.timer >/dev/null 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
|
||||||
deb-systemd-helper purge freedombox-setup-repositories.timer >/dev/null || true
|
|
||||||
deb-systemd-helper unmask freedombox-setup-repositories.timer >/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d /run/systemd/system ]; then
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Handle removing freedombox-udiskie.service from 20.9.
|
|
||||||
if dpkg --compare-versions "$2" le 20.9; then
|
|
||||||
if [ -x "/usr/bin/deb-systemd-invoke" ]; then
|
|
||||||
deb-systemd-invoke stop freedombox-udiskie.service >/dev/null 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -x "/usr/bin/deb-systemd-helper" ]; then
|
|
||||||
deb-systemd-helper purge freedombox-udiskie.service >/dev/null || true
|
|
||||||
deb-systemd-helper unmask freedombox-udiskie.service >/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -d /run/systemd/system ]; then
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
#DEBHELPER#
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
3
debian/source/lintian-overrides
vendored
3
debian/source/lintian-overrides
vendored
@ -5,7 +5,4 @@
|
|||||||
very-long-line-length-in-source-file * [doc/manual/*.raw.wiki:*]
|
very-long-line-length-in-source-file * [doc/manual/*.raw.wiki:*]
|
||||||
|
|
||||||
# Misc. files which can't be fixed to have short line lengths.
|
# Misc. files which can't be fixed to have short line lengths.
|
||||||
very-long-line-length-in-source-file * [plinth/modules/deluge/tests/data/sample.torrent:*]
|
|
||||||
very-long-line-length-in-source-file * [plinth/modules/transmission/tests/data/sample.torrent:*]
|
|
||||||
very-long-line-length-in-source-file * [doc/visual_design/FreedomBox-Logo.7z:*]
|
|
||||||
very-long-line-length-in-source-file * [COPYING.md:*]
|
very-long-line-length-in-source-file * [COPYING.md:*]
|
||||||
|
|||||||
@ -10,7 +10,7 @@ msgstr ""
|
|||||||
"Project-Id-Version: FreedomBox UI\n"
|
"Project-Id-Version: FreedomBox UI\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-12-16 01:18+0000\n"
|
"POT-Creation-Date: 2025-12-16 01:18+0000\n"
|
||||||
"PO-Revision-Date: 2025-12-21 10:00+0000\n"
|
"PO-Revision-Date: 2026-01-25 14:02+0000\n"
|
||||||
"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
|
"Last-Translator: Ettore Atalan <atalanttore@googlemail.com>\n"
|
||||||
"Language-Team: German <https://hosted.weblate.org/projects/freedombox/"
|
"Language-Team: German <https://hosted.weblate.org/projects/freedombox/"
|
||||||
"freedombox/de/>\n"
|
"freedombox/de/>\n"
|
||||||
@ -19,7 +19,7 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||||
"X-Generator: Weblate 5.15.1\n"
|
"X-Generator: Weblate 5.16-dev\n"
|
||||||
|
|
||||||
#: plinth/config.py:103
|
#: plinth/config.py:103
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
@ -207,7 +207,7 @@ msgstr "Lokale Netzwerkdomäne"
|
|||||||
|
|
||||||
#: plinth/modules/avahi/manifest.py:14
|
#: plinth/modules/avahi/manifest.py:14
|
||||||
msgid "Auto-discovery"
|
msgid "Auto-discovery"
|
||||||
msgstr ""
|
msgstr "Automatische Erkennung"
|
||||||
|
|
||||||
#: plinth/modules/avahi/manifest.py:14 plinth/modules/backups/manifest.py:17
|
#: plinth/modules/avahi/manifest.py:14 plinth/modules/backups/manifest.py:17
|
||||||
msgid "Local"
|
msgid "Local"
|
||||||
@ -1813,9 +1813,8 @@ msgstr "App: %(app_name)s"
|
|||||||
|
|
||||||
#: plinth/modules/diagnostics/templates/diagnostics_app.html:21
|
#: plinth/modules/diagnostics/templates/diagnostics_app.html:21
|
||||||
#: plinth/modules/diagnostics/templates/diagnostics_full.html:85
|
#: plinth/modules/diagnostics/templates/diagnostics_full.html:85
|
||||||
#, fuzzy
|
|
||||||
msgid "Try to repair"
|
msgid "Try to repair"
|
||||||
msgstr "Versuche, zu reparieren"
|
msgstr "Reparatur versuchen"
|
||||||
|
|
||||||
#: plinth/modules/diagnostics/templates/diagnostics_app.html:29
|
#: plinth/modules/diagnostics/templates/diagnostics_app.html:29
|
||||||
msgid "This app does not support diagnostics"
|
msgid "This app does not support diagnostics"
|
||||||
@ -3754,7 +3753,7 @@ msgstr "Diese App ist experimentell."
|
|||||||
#: plinth/modules/homeassistant/manifest.py:12
|
#: plinth/modules/homeassistant/manifest.py:12
|
||||||
#: plinth/modules/homeassistant/manifest.py:20
|
#: plinth/modules/homeassistant/manifest.py:20
|
||||||
msgid "Home Assistant"
|
msgid "Home Assistant"
|
||||||
msgstr ""
|
msgstr "Heimassistent"
|
||||||
|
|
||||||
#: plinth/modules/homeassistant/manifest.py:62
|
#: plinth/modules/homeassistant/manifest.py:62
|
||||||
msgid "Home Automation"
|
msgid "Home Automation"
|
||||||
@ -3779,7 +3778,7 @@ msgstr "ZigBee"
|
|||||||
|
|
||||||
#: plinth/modules/homeassistant/manifest.py:66
|
#: plinth/modules/homeassistant/manifest.py:66
|
||||||
msgid "Z-Wave"
|
msgid "Z-Wave"
|
||||||
msgstr ""
|
msgstr "Z-Wave"
|
||||||
|
|
||||||
#: plinth/modules/homeassistant/manifest.py:67
|
#: plinth/modules/homeassistant/manifest.py:67
|
||||||
msgid "Thread"
|
msgid "Thread"
|
||||||
@ -8205,7 +8204,7 @@ msgstr "Regelmäßig"
|
|||||||
|
|
||||||
#: plinth/modules/snapshot/manifest.py:14
|
#: plinth/modules/snapshot/manifest.py:14
|
||||||
msgid "Known good state"
|
msgid "Known good state"
|
||||||
msgstr ""
|
msgstr "Bekannter guter Zustand"
|
||||||
|
|
||||||
#: plinth/modules/snapshot/manifest.py:14
|
#: plinth/modules/snapshot/manifest.py:14
|
||||||
msgid "Btrfs"
|
msgid "Btrfs"
|
||||||
@ -10960,10 +10959,8 @@ msgid "Dark"
|
|||||||
msgstr "Dunkel"
|
msgstr "Dunkel"
|
||||||
|
|
||||||
#: plinth/templates/theme-menu.html:41
|
#: plinth/templates/theme-menu.html:41
|
||||||
#, fuzzy
|
|
||||||
#| msgid "Automatic"
|
|
||||||
msgid "Auto"
|
msgid "Auto"
|
||||||
msgstr "Auto"
|
msgstr "Automatisch"
|
||||||
|
|
||||||
#: plinth/templates/toolbar.html:39 plinth/templates/toolbar.html:40
|
#: plinth/templates/toolbar.html:39 plinth/templates/toolbar.html:40
|
||||||
msgid "View Logs"
|
msgid "View Logs"
|
||||||
|
|||||||
@ -56,14 +56,26 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="btn-toolbar">
|
<div class="btn-toolbar">
|
||||||
<a title="{% trans 'Add a new peer' %}"
|
{% if not server.public_key %}
|
||||||
role="button" class="btn btn-default btn-add-client"
|
<form method="post" action="{% url 'wireguard:enable-server' %}">
|
||||||
href="{% url 'wireguard:add-client' %}">
|
{% csrf_token %}
|
||||||
<span class="fa fa-plus" aria-hidden="true"></span>
|
<button type="submit" class="btn btn-primary btn-start-server"
|
||||||
{% trans "Add Allowed Client" %}
|
title="{% trans 'Start WireGuard Server' %}">
|
||||||
</a>
|
<span class="fa fa-rocket" aria-hidden="true"></span>
|
||||||
|
{% trans "Start WireGuard Server" %}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
{% else %}
|
||||||
|
<a title="{% trans 'Add a new peer' %}"
|
||||||
|
role="button" class="btn btn-default btn-add-client"
|
||||||
|
href="{% url 'wireguard:add-client' %}">
|
||||||
|
<span class="fa fa-plus" aria-hidden="true"></span>
|
||||||
|
{% trans "Add Allowed Client" %}
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<h3>{% trans "As a Client" %}</h3>
|
<h3>{% trans "As a Client" %}</h3>
|
||||||
<p>
|
<p>
|
||||||
{% blocktrans trimmed %}
|
{% blocktrans trimmed %}
|
||||||
|
|||||||
@ -67,6 +67,11 @@ class TestWireguardApp(functional.BaseAppTests):
|
|||||||
def _add_client(browser, key):
|
def _add_client(browser, key):
|
||||||
"""Add a client."""
|
"""Add a client."""
|
||||||
functional.nav_to_module(browser, 'wireguard')
|
functional.nav_to_module(browser, 'wireguard')
|
||||||
|
# Start the server on FreedomBox, if needed.
|
||||||
|
start_server_button = browser.find_by_css('.btn-start-server')
|
||||||
|
if start_server_button:
|
||||||
|
start_server_button.first.click()
|
||||||
|
|
||||||
browser.find_by_css('.btn-add-client').first.click()
|
browser.find_by_css('.btn-add-client').first.click()
|
||||||
browser.find_by_id('id_public_key').fill(key)
|
browser.find_by_id('id_public_key').fill(key)
|
||||||
functional.submit(browser, form_class='form-add-client')
|
functional.submit(browser, form_class='form-add-client')
|
||||||
|
|||||||
@ -9,6 +9,8 @@ from plinth.modules.wireguard import views
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(r'^apps/wireguard/$', views.WireguardView.as_view(), name='index'),
|
re_path(r'^apps/wireguard/$', views.WireguardView.as_view(), name='index'),
|
||||||
|
re_path(r'^apps/wireguard/enable-server/$',
|
||||||
|
views.EnableServerView.as_view(), name='enable-server'),
|
||||||
re_path(r'^apps/wireguard/client/add/$', views.AddClientView.as_view(),
|
re_path(r'^apps/wireguard/client/add/$', views.AddClientView.as_view(),
|
||||||
name='add-client'),
|
name='add-client'),
|
||||||
re_path(r'^apps/wireguard/client/(?P<public_key>[^/]+)/show/$',
|
re_path(r'^apps/wireguard/client/(?P<public_key>[^/]+)/show/$',
|
||||||
|
|||||||
@ -11,7 +11,7 @@ from django.http import Http404
|
|||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
from django.views.generic import FormView, TemplateView
|
from django.views.generic import FormView, TemplateView, View
|
||||||
|
|
||||||
from plinth import network
|
from plinth import network
|
||||||
from plinth.modules.names.components import DomainName
|
from plinth.modules.names.components import DomainName
|
||||||
@ -252,3 +252,19 @@ class DeleteServerView(SuccessMessageMixin, TemplateView):
|
|||||||
network.delete_connection(connection.get_uuid())
|
network.delete_connection(connection.get_uuid())
|
||||||
messages.success(request, _('Server deleted.'))
|
messages.success(request, _('Server deleted.'))
|
||||||
return redirect('wireguard:index')
|
return redirect('wireguard:index')
|
||||||
|
|
||||||
|
|
||||||
|
class EnableServerView(SuccessMessageMixin, View):
|
||||||
|
"""View to enable the WireGuard server."""
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
"""Create server interface."""
|
||||||
|
try:
|
||||||
|
utils.setup_server()
|
||||||
|
messages.success(request,
|
||||||
|
_('WireGuard server started successfully.'))
|
||||||
|
except Exception as error:
|
||||||
|
messages.error(
|
||||||
|
request,
|
||||||
|
_('Failed to start WireGuard server: {}').format(error))
|
||||||
|
return redirect('wireguard:index')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user