From acb91f8d20ee5d2932c0281f169d4dea46656665 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Doma=20Gerg=C5=91?=
Date: Tue, 13 Aug 2019 00:43:26 +0000
Subject: [PATCH 01/36] Translated using Weblate (Hungarian)
Currently translated at 100.0% (1050 of 1050 strings)
---
plinth/locale/hu/LC_MESSAGES/django.po | 21 ++++++---------------
1 file changed, 6 insertions(+), 15 deletions(-)
diff --git a/plinth/locale/hu/LC_MESSAGES/django.po b/plinth/locale/hu/LC_MESSAGES/django.po
index 9136e6ca8..fe65a271e 100644
--- a/plinth/locale/hu/LC_MESSAGES/django.po
+++ b/plinth/locale/hu/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-12 19:14-0400\n"
-"PO-Revision-Date: 2019-08-02 21:11+0000\n"
+"PO-Revision-Date: 2019-08-14 01:23+0000\n"
"Last-Translator: Doma Gergő \n"
"Language-Team: Hungarian \n"
@@ -1050,7 +1050,7 @@ msgstr "Felhasználók regisztrációja letiltva"
#: plinth/modules/dynamicdns/__init__.py:40
msgid "Dynamic DNS Client"
-msgstr "Dynamic DNS ügyfél"
+msgstr "Dinamikus DNS ügyfél"
#: plinth/modules/dynamicdns/__init__.py:44
#, python-brace-format
@@ -1084,10 +1084,8 @@ msgstr ""
"megkapni."
#: plinth/modules/dynamicdns/__init__.py:78
-#, fuzzy
-#| msgid "Domain Name"
msgid "Dynamic Domain Name"
-msgstr "Domain név"
+msgstr "Dinamikus Domain név"
#: plinth/modules/dynamicdns/forms.py:43
msgid ""
@@ -2807,11 +2805,11 @@ msgstr ""
#: plinth/modules/names/components.py:27
msgid "All"
-msgstr ""
+msgstr "Összes"
#: plinth/modules/names/components.py:31 plinth/modules/names/components.py:35
msgid "All web apps"
-msgstr ""
+msgstr "Összes webalkalmazás"
#: plinth/modules/networks/__init__.py:36
msgid "Networks"
@@ -3593,10 +3591,8 @@ msgstr ""
"használni erre a célra."
#: plinth/modules/pagekite/__init__.py:96
-#, fuzzy
-#| msgid "PageKite Account"
msgid "PageKite Domain"
-msgstr "PageKite fiók"
+msgstr "PageKite domain"
#: plinth/modules/pagekite/forms.py:69
msgid "Enable PageKite"
@@ -5484,11 +5480,6 @@ msgid "Updating..."
msgstr "Frissítés…"
#: plinth/modules/upgrades/templates/upgrades.html:57
-#, fuzzy
-#| msgid ""
-#| "This may take a long time to complete. During an update, "
-#| "you can not install apps. Also, this web interface may be temporarily "
-#| "unavailable and show an error. In that case, refresh the page to continue."
msgid ""
"This may take a long time to complete. During an update, "
"you cannot install apps. Also, this web interface may be temporarily "
From c51882a6f86ae6f29447f3e19dede3f8091fec2d Mon Sep 17 00:00:00 2001
From: nautilusx
Date: Thu, 15 Aug 2019 05:01:04 +0000
Subject: [PATCH 02/36] Translated using Weblate (German)
Currently translated at 99.4% (1044 of 1050 strings)
---
plinth/locale/de/LC_MESSAGES/django.po | 53 ++++++++++----------------
1 file changed, 20 insertions(+), 33 deletions(-)
diff --git a/plinth/locale/de/LC_MESSAGES/django.po b/plinth/locale/de/LC_MESSAGES/django.po
index 334dc8601..2a54907af 100644
--- a/plinth/locale/de/LC_MESSAGES/django.po
+++ b/plinth/locale/de/LC_MESSAGES/django.po
@@ -10,7 +10,7 @@ msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-12 19:14-0400\n"
-"PO-Revision-Date: 2019-07-29 22:36+0000\n"
+"PO-Revision-Date: 2019-08-16 08:23+0000\n"
"Last-Translator: nautilusx \n"
"Language-Team: German \n"
@@ -19,7 +19,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.8-dev\n"
+"X-Generator: Weblate 3.8\n"
#: plinth/action_utils.py:298
#, python-brace-format
@@ -284,34 +284,24 @@ msgstr "SSH-Zugriff verweigert"
#: plinth/modules/backups/templates/backups.html:47
#: plinth/modules/backups/views.py:80
-#, fuzzy
-#| msgid "Create backup"
msgid "Create a new backup"
-msgstr "Sicherung erstellen"
+msgstr "Neue Sicherung erstellen"
#: plinth/modules/backups/templates/backups.html:51
-#, fuzzy
-#| msgid "Create backup"
msgid "Create Backup"
msgstr "Sicherung erstellen"
#: plinth/modules/backups/templates/backups.html:54
-#, fuzzy
-#| msgid "Upload and restore a backup file"
msgid "Upload and restore a backup archive"
-msgstr "Hochladen und Wiederherstellen einer Sicherungsdatei"
+msgstr "Hochladen und Wiederherstellen eines Sicherungsarchives"
#: plinth/modules/backups/templates/backups.html:58
-#, fuzzy
-#| msgid "Upload and restore a backup file"
msgid "Upload and Restore"
-msgstr "Hochladen und Wiederherstellen einer Sicherungsdatei"
+msgstr "Hochladen und Wiederherstellen"
#: plinth/modules/backups/templates/backups.html:61
-#, fuzzy
-#| msgid "Existing backup locations"
msgid "Existing Backups"
-msgstr "Vorhandene Backup-Speicherorte"
+msgstr "Vorhandene Sicherungen"
#: plinth/modules/backups/templates/backups.html:71
#, fuzzy
@@ -477,10 +467,8 @@ msgid "Archive deleted."
msgstr "Archiv gelöscht."
#: plinth/modules/backups/views.py:127
-#, fuzzy
-#| msgid "Upload and restore a backup file"
msgid "Upload and restore a backup"
-msgstr "Hochladen und Wiederherstellen einer Sicherungsdatei"
+msgstr "Hochladen und Wiederherstellen einer Sicherung"
#: plinth/modules/backups/views.py:162
msgid "Restored files from backup."
@@ -1693,10 +1681,8 @@ msgid "%(box_name)s is up to date."
msgstr "%(box_name)s ist auf dem neuesten Stand."
#: plinth/modules/help/templates/help_about.html:94
-#, fuzzy
-#| msgid "Security"
msgid "Security Notice"
-msgstr "Sicherheit"
+msgstr "Sicherheitshinweis"
#: plinth/modules/help/templates/help_about.html:96
msgid ""
@@ -1705,6 +1691,10 @@ msgid ""
"maintained on a best-effort basis by contributors in Debian and FreedomBox "
"community."
msgstr ""
+"Sie verwenden Pakete von Debian-Backports. Bitte beachten Sie, dass diese "
+"Pakete keine Sicherheitsunterstützung von Debian haben. Sie werden jedoch "
+"von Mitwirkenden in der Debian- und FreedomBox-Community bestmöglich "
+"gepflegt."
#: plinth/modules/help/templates/help_base.html:36
#: plinth/modules/help/templates/help_index.html:76
@@ -2823,11 +2813,11 @@ msgstr ""
#: plinth/modules/names/components.py:27
msgid "All"
-msgstr ""
+msgstr "Alle"
#: plinth/modules/names/components.py:31 plinth/modules/names/components.py:35
msgid "All web apps"
-msgstr ""
+msgstr "Alle Webanwendungen"
#: plinth/modules/networks/__init__.py:36
msgid "Networks"
@@ -4408,22 +4398,24 @@ msgid ""
"The installed version of FreedomBox has %(count)s reported security "
"vulnerabilities."
msgstr ""
+"Die installierte Version von FreedomBox weist %(count)s gemeldete "
+"Sicherheitslücken auf."
#: plinth/modules/security/templates/security.html:33
msgid ""
"The following table lists the reported number of security vulnerabilities "
"for each installed app."
msgstr ""
+"Die folgende Tabelle listet die gemeldete Anzahl von Sicherheitslücken für "
+"jede installierte Anwendung auf."
#: plinth/modules/security/templates/security.html:41
-#, fuzzy
-#| msgid "Name"
msgid "App Name"
-msgstr "Name"
+msgstr "Anwendungsname"
#: plinth/modules/security/templates/security.html:42
msgid "Vulnerabilities Reported"
-msgstr ""
+msgstr "Gemeldete Sicherheitslücken"
#: plinth/modules/security/views.py:79
#, python-brace-format
@@ -5505,11 +5497,6 @@ msgid "Updating..."
msgstr "Aktualisierung läuft …"
#: plinth/modules/upgrades/templates/upgrades.html:57
-#, fuzzy
-#| msgid ""
-#| "This may take a long time to complete. During an update, "
-#| "you can not install apps. Also, this web interface may be temporarily "
-#| "unavailable and show an error. In that case, refresh the page to continue."
msgid ""
"This may take a long time to complete. During an update, "
"you cannot install apps. Also, this web interface may be temporarily "
From 7df4219bce26adb855b5345c8b8cd2754e4989fc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Allan=20Nordh=C3=B8y?=
Date: Sat, 17 Aug 2019 02:30:55 +0000
Subject: [PATCH 03/36] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?=
=?UTF-8?q?=20Bokm=C3=A5l)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Currently translated at 98.4% (1033 of 1050 strings)
---
plinth/locale/nb/LC_MESSAGES/django.po | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/plinth/locale/nb/LC_MESSAGES/django.po b/plinth/locale/nb/LC_MESSAGES/django.po
index f8a792328..53b07c177 100644
--- a/plinth/locale/nb/LC_MESSAGES/django.po
+++ b/plinth/locale/nb/LC_MESSAGES/django.po
@@ -16,7 +16,7 @@ msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-08-12 19:14-0400\n"
-"PO-Revision-Date: 2019-08-08 00:23+0000\n"
+"PO-Revision-Date: 2019-08-18 03:23+0000\n"
"Last-Translator: Allan Nordhøy \n"
"Language-Team: Norwegian Bokmål \n"
@@ -25,7 +25,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.8-dev\n"
+"X-Generator: Weblate 3.8\n"
#: plinth/action_utils.py:298
#, python-brace-format
@@ -2797,11 +2797,11 @@ msgstr ""
#: plinth/modules/names/components.py:27
msgid "All"
-msgstr ""
+msgstr "Alle"
#: plinth/modules/names/components.py:31 plinth/modules/names/components.py:35
msgid "All web apps"
-msgstr ""
+msgstr "Alle nettprogrammer"
#: plinth/modules/networks/__init__.py:36
msgid "Networks"
From fe02b9f1e3c53b1483b7e5452f2509684b7a422a Mon Sep 17 00:00:00 2001
From: Joseph Nuthalpati
Date: Fri, 16 Aug 2019 22:53:25 +0530
Subject: [PATCH 04/36] functional_tests: Fix site.is_available not handling
default paths
Sites might have default paths like /mediawiki/Main_Page or /transmission/web.
The tests are doing an exact match on the path which is causing test failures.
Modified the support function site.is_available to handle default paths.
Signed-off-by: Joseph Nuthalapati
Reviewed-by: Sunil Mohan Adapa
---
functional_tests/support/site.py | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/functional_tests/support/site.py b/functional_tests/support/site.py
index 82355d077..bfd831f96 100644
--- a/functional_tests/support/site.py
+++ b/functional_tests/support/site.py
@@ -51,8 +51,9 @@ def is_available(browser, site_name):
time.sleep(3)
browser.reload()
not_404 = '404' not in browser.title
- # A trailing slash might be appended by Apache redirect rules
- no_redirect = url_to_visit.strip('/') == browser.url.strip('/')
+ # The site might have a default path after the sitename,
+ # e.g /mediawiki/Main_Page
+ no_redirect = browser.url.startswith(url_to_visit.strip('/'))
return not_404 and no_redirect
From cd54cd48b8f0288f6b94e2f091e3cb90b9ed4e58 Mon Sep 17 00:00:00 2001
From: Joseph Nuthalpati
Date: Fri, 16 Aug 2019 23:15:20 +0530
Subject: [PATCH 05/36] functional_tests: Fix step definition "When I log out"
Signed-off-by: Joseph Nuthalapati
Reviewed-by: Sunil Mohan Adapa
---
functional_tests/step_definitions/interface.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/functional_tests/step_definitions/interface.py b/functional_tests/step_definitions/interface.py
index b049e5535..916e07532 100644
--- a/functional_tests/step_definitions/interface.py
+++ b/functional_tests/step_definitions/interface.py
@@ -34,7 +34,9 @@ def logged_out_user(browser):
browser.visit(default_url + '/plinth/accounts/logout/')
-log_out = when("I log out")(logged_out_user)
+@when("I log out")
+def log_out_user(browser):
+ browser.visit(default_url + '/plinth/accounts/logout/')
@then(parsers.parse('I should be prompted for login'))
From e157c1f4636ee785bad42fbbf4742b69a5c6d4aa Mon Sep 17 00:00:00 2001
From: James Valleroy
Date: Sat, 17 Aug 2019 11:16:57 -0400
Subject: [PATCH 06/36] security: Hide vulnerability table by default
Signed-off-by: James Valleroy
[sunil@medhas.org Fix 'rol' attribute to 'role']
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Sunil Mohan Adapa
---
.../modules/security/templates/security.html | 37 ++++++++++++-------
1 file changed, 23 insertions(+), 14 deletions(-)
diff --git a/plinth/modules/security/templates/security.html b/plinth/modules/security/templates/security.html
index 7d4ddf20c..07e585ccf 100644
--- a/plinth/modules/security/templates/security.html
+++ b/plinth/modules/security/templates/security.html
@@ -35,20 +35,29 @@
for each installed app.
{% endblocktrans %}
-
-
-
- | {% trans "App Name" %} |
- {% trans "Vulnerabilities Reported" %} |
-
-
-
- {% for app in apps_vulns %}
+
+
+ {% trans "Show security vulnerabilities" %}
+
+
+
+
+
- | {{ app.name }} |
- {{ app.count }} |
+ {% trans "App Name" %} |
+ {% trans "Vulnerabilities Reported" %} |
- {% endfor %}
-
-
+
+
+ {% for app in apps_vulns %}
+
+ | {{ app.name }} |
+ {{ app.count }} |
+
+ {% endfor %}
+
+
+
{% endblock %}
From 9b46d1a661d1ae33ef9a28356bdf6c18c831833f Mon Sep 17 00:00:00 2001
From: Joseph Nuthalpati
Date: Fri, 16 Aug 2019 19:34:58 +0530
Subject: [PATCH 07/36] matrix-synapse: Allow installation of version 1.2 from
backports
Used version pinning instead of release pinning to avoid unexpected upgrades for
users running FreedomBox stable.
Explanation for backports:
This fixes incompatibility issues with newly created rooms on Matrix Synapse
versions 0.99.5 and above. Users on stable using 0.99.2 might not be able to
join those rooms, especially direct chats.
Fixes #1600
Signed-off-by: Joseph Nuthalapati
Reviewed-by: James Valleroy
---
actions/upgrades | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/actions/upgrades b/actions/upgrades
index 4ddfa606d..61bdba698 100755
--- a/actions/upgrades
+++ b/actions/upgrades
@@ -170,22 +170,43 @@ def _check_and_backports_sources():
def _add_apt_preferences():
"""Setup APT preferences to upgrade selected packages from backports."""
- old_preferences_file = '/etc/apt/preferences.d/50freedombox.pref'
- if os.path.exists(old_preferences_file):
- os.remove(old_preferences_file)
+ preferences_path = '/etc/apt/preferences.d'
+ old_preferences_files = map(
+ lambda pref_file: os.path.join(preferences_path, pref_file),
+ ['50freedombox.pref', '50freedombox2.pref'])
- preferences_file = '/etc/apt/preferences.d/50freedombox2.pref'
+ for pref_file in old_preferences_files:
+ os.path.exists(pref_file) and os.remove(pref_file)
+
+ preferences_file = '/etc/apt/preferences.d/50freedombox3.pref'
if os.path.exists(preferences_file):
print('Preferences up-to-date. Skipping update')
return
- preferences = '''Explanation: This file is managed by FreedomBox, do not edit.
+ warning = 'Explanation: This file is managed by FreedomBox, do not edit.'
+
+ freedombox_preference = '''
Explanation: Allow carefully selected updates to 'freedombox' from backports.
Package: freedombox
Pin: release a=buster-backports
Pin-Priority: 500
'''
+ matrix_synapse_preferences = '''
+Explanation: Allow carefully selected updates to 'matrix-synapse' from backports.
+Package: matrix-synapse
+Pin: version 1.2*
+Pin-Priority: 500
+
+Explanation: Allow carefully selected updates to 'python3-service-identity' from backports.
+Package: python3-service-identity
+Pin: version 18.1*
+Pin-Priority: 500
+'''
+
+ preferences = "".join(
+ [warning, freedombox_preference, matrix_synapse_preferences])
+
print('Updating APT preferences.')
with open(preferences_file, 'w') as file_handle:
file_handle.write(preferences)
From 393f4bbc260b89734c39ae74c96b457904d8c9fc Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Tue, 20 Aug 2019 10:09:42 -0700
Subject: [PATCH 08/36] names: Perform better layout of domain names table on
small screens
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Joseph Nuthalapati
---
plinth/modules/names/templates/names.html | 6 +++---
static/themes/default/css/plinth.css | 9 +++++++++
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/plinth/modules/names/templates/names.html b/plinth/modules/names/templates/names.html
index f94664e5f..11cdb7202 100644
--- a/plinth/modules/names/templates/names.html
+++ b/plinth/modules/names/templates/names.html
@@ -23,11 +23,11 @@
{% block configuration %}
-
+
| Type |
- Domain Name |
+ Domain Name |
Services |
|
@@ -36,7 +36,7 @@
{% for domain in status.domains|dictsort:"domain_type.display_name" %}
| {{ domain.domain_type.display_name }} |
- {{ domain.name }} |
+ {{ domain.name }} |
{{ domain.get_readable_services|join:', ' }} |
Date: Tue, 20 Aug 2019 09:16:06 -0700
Subject: [PATCH 09/36] cockpit: Apply domain name changes immediately
Without restarting cockpit, newly added/removed domain in cockpit configuration
file do not immediately work. Either the daemon has to stop itself due to
inactivity (it is socket activated by systemd) or system needs to be restarted.
Without the patch, if cockpit is not currently running (due to socket activation
not having happened yet) the domain name changes would be noticeable
immediately.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: James Valleroy
---
plinth/modules/cockpit/__init__.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/plinth/modules/cockpit/__init__.py b/plinth/modules/cockpit/__init__.py
index ee08955d7..2d55c7e6d 100644
--- a/plinth/modules/cockpit/__init__.py
+++ b/plinth/modules/cockpit/__init__.py
@@ -132,6 +132,7 @@ def on_domain_added(sender, domain_type, name, description='', services=None,
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
actions.superuser_run('cockpit', ['add-domain', name])
+ actions.superuser_run('service', ['try-restart', managed_services[0]])
def on_domain_removed(sender, domain_type, name, **kwargs):
@@ -139,3 +140,4 @@ def on_domain_removed(sender, domain_type, name, **kwargs):
setup_helper = globals()['setup_helper']
if setup_helper.get_state() != 'needs-setup':
actions.superuser_run('cockpit', ['remove-domain', name])
+ actions.superuser_run('service', ['try-restart', managed_services[0]])
From e8e2aaf85bc105b50df249bb489fe814349d702f Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Tue, 20 Aug 2019 09:19:35 -0700
Subject: [PATCH 10/36] ejabberd: Prevent processing empty domain name
When domain name is not set in the config app, currently ejabberd return a list
with an empty string as list of domains. This leads to certificates being copied
to invalid directory. Fix this by making sure domain name is added to the list
only if it is not an empty string.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: James Valleroy
---
plinth/modules/ejabberd/__init__.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/plinth/modules/ejabberd/__init__.py b/plinth/modules/ejabberd/__init__.py
index 53718072c..bac011f6e 100644
--- a/plinth/modules/ejabberd/__init__.py
+++ b/plinth/modules/ejabberd/__init__.py
@@ -162,7 +162,11 @@ def get_domains():
if setup_helper.get_state() == 'needs-setup':
return []
- return [config.get_domainname()]
+ domain_name = config.get_domainname()
+ if domain_name:
+ return [domain_name]
+
+ return []
def on_pre_hostname_change(sender, old_hostname, new_hostname, **kwargs):
From 855a99cc21e24c225eb2560821c4934deb8e0a8a Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Tue, 20 Aug 2019 09:21:47 -0700
Subject: [PATCH 11/36] config: Send hostname change signal only after fully
processing it
If the domain name is not properly set before calling post_hostname_change
signal, then in the signal handlers config.get_domainname() returns an empty
string. So, call the post_hostname_change signal only after fully finishing the
hostname related changes, that is, after setting back the original domain name
too.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: James Valleroy
---
plinth/modules/config/views.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/plinth/modules/config/views.py b/plinth/modules/config/views.py
index a0f264c30..8b2988633 100644
--- a/plinth/modules/config/views.py
+++ b/plinth/modules/config/views.py
@@ -134,12 +134,12 @@ def set_hostname(hostname):
LOGGER.info('Changing hostname to - %s', hostname)
actions.superuser_run('hostname-change', [hostname])
- post_hostname_change.send_robust(
- sender='config', old_hostname=old_hostname, new_hostname=hostname)
-
LOGGER.info('Setting domain name after hostname change - %s', domainname)
actions.superuser_run('domainname-change', [domainname])
+ post_hostname_change.send_robust(
+ sender='config', old_hostname=old_hostname, new_hostname=hostname)
+
def set_domainname(domainname, old_domainname):
"""Sets machine domain name to domainname"""
From 3ba7e961c4aa920619504350f46706d846f48f48 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Tue, 20 Aug 2019 09:24:42 -0700
Subject: [PATCH 12/36] letsencrypt: Don't try to obtain certificates for
.local domains
Replace the check for ignoring .onion domains with a check that ignore any
domain type that can't have certificates.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: James Valleroy
---
plinth/modules/letsencrypt/__init__.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/plinth/modules/letsencrypt/__init__.py b/plinth/modules/letsencrypt/__init__.py
index c65d504ba..5fb061232 100644
--- a/plinth/modules/letsencrypt/__init__.py
+++ b/plinth/modules/letsencrypt/__init__.py
@@ -29,6 +29,7 @@ from plinth import app as app_module
from plinth import cfg, menu
from plinth.errors import ActionError
from plinth.modules import names
+from plinth.modules.names.components import DomainType
from plinth.signals import domain_added, domain_removed, post_module_loading
from plinth.utils import format_lazy
@@ -151,7 +152,7 @@ def certificate_delete(domain):
def on_domain_added(sender, domain_type='', name='', description='',
services=None, **kwargs):
"""Obtain a certificate for the new domain"""
- if domain_type == 'domain-type-tor':
+ if not DomainType.get(domain_type).can_have_certificate:
return False
# Check if a cert if already available
@@ -173,6 +174,9 @@ def on_domain_added(sender, domain_type='', name='', description='',
def on_domain_removed(sender, domain_type, name='', **kwargs):
"""Revoke Let's Encrypt certificate for the removed domain"""
+ if not DomainType.get(domain_type).can_have_certificate:
+ return False
+
try:
# Revoking certs during tests or empty names isn't expected to succeed
if sender != 'test' and name:
From 0c08248c12107c1a3ffd0058d842145c9c346864 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Tue, 20 Aug 2019 09:27:36 -0700
Subject: [PATCH 13/36] avahi: Expose .local domain as a proper domain
When a hostname is set or changed, expose .local as a domain. With
this, daemons can configure themselves to work properly with .local domains.
Cockpit is an example of a daemon that can be configured to allow connections
from .local domains
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: James Valleroy
---
plinth/modules/avahi/__init__.py | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/plinth/modules/avahi/__init__.py b/plinth/modules/avahi/__init__.py
index c963fd834..3cd585667 100644
--- a/plinth/modules/avahi/__init__.py
+++ b/plinth/modules/avahi/__init__.py
@@ -24,11 +24,14 @@ from plinth import actions
from plinth import app as app_module
from plinth import cfg, menu
from plinth.daemon import Daemon
+from plinth.modules.config import get_hostname
from plinth.modules.firewall.components import Firewall
+from plinth.modules.names.components import DomainType
+from plinth.signals import domain_added, domain_removed, post_hostname_change
from plinth.utils import format_lazy
from plinth.views import AppView
-from .manifest import backup # noqa, pylint: disable=unused-import
+from .manifest import backup # noqa, pylint: disable=unused-import
# pylint: disable=C0103
@@ -70,6 +73,11 @@ class AvahiApp(app_module.App):
'avahi:index', parent_url_name='system')
self.add(menu_item)
+ domain_type = DomainType('domain-type-local',
+ _('Local Network Domain'), 'config:index',
+ can_have_certificate=False)
+ self.add(domain_type)
+
firewall = Firewall('firewall-avahi', name, ports=['mdns'],
is_external=False)
self.add(firewall)
@@ -83,8 +91,13 @@ def init():
global app
app = AvahiApp()
if app.is_enabled():
+ domain_added.send_robust(
+ sender='avahi', domain_type='domain-type-local',
+ name=get_hostname() + '.local', services='__all__')
app.set_enabled(True)
+ post_hostname_change.connect(on_post_hostname_change)
+
def setup(helper, old_version=None):
"""Install and configure the module."""
@@ -96,6 +109,17 @@ def setup(helper, old_version=None):
['reload', 'avahi-daemon'])
+def on_post_hostname_change(sender, old_hostname, new_hostname, **kwargs):
+ """Update .local domain after hostname change."""
+ del sender # Unused
+ del kwargs # Unused
+
+ domain_removed.send_robust(sender='avahi', domain_type='domain-type-local',
+ name=old_hostname + '.local')
+ domain_added.send_robust(sender='avahi', domain_type='domain-type-local',
+ name=new_hostname + '.local', services='__all__')
+
+
class AvahiAppView(AppView):
app_id = 'avahi'
name = name
From 49088ef5780d6a3b6d9f7e629d24cd9924f91a79 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Tue, 20 Aug 2019 09:29:22 -0700
Subject: [PATCH 14/36] cockpit: Make essential and install by default
See reasoning in https://salsa.debian.org/freedombox-team/plinth/issues/1629
Closes: #1629
Closes: #1452 (obsolete)
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: James Valleroy
---
plinth/modules/cockpit/__init__.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/plinth/modules/cockpit/__init__.py b/plinth/modules/cockpit/__init__.py
index 2d55c7e6d..b05cd7044 100644
--- a/plinth/modules/cockpit/__init__.py
+++ b/plinth/modules/cockpit/__init__.py
@@ -35,6 +35,8 @@ from .manifest import backup, clients # noqa, pylint: disable=unused-import
version = 1
+is_essential = True
+
managed_services = ['cockpit.socket']
managed_packages = ['cockpit']
From 4b8b2e171c86d754d2095d357dbd72a81c60840f Mon Sep 17 00:00:00 2001
From: bn4t
Date: Wed, 21 Aug 2019 15:17:33 +0000
Subject: [PATCH 15/36] matrix-synapse: Use recommended reverse proxy
configuration
matrix-synapse reverse proxy configuration for Apache according to:
https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.rst
Fixes #1533.
[sunil@medhas.org Fix closing location directive]
Tested-by: Sunil Mohan Adapa
Reviewed-by: Sunil Mohan Adapa
---
.../etc/apache2/conf-available/matrix-synapse-plinth.conf | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/plinth/modules/matrixsynapse/data/etc/apache2/conf-available/matrix-synapse-plinth.conf b/plinth/modules/matrixsynapse/data/etc/apache2/conf-available/matrix-synapse-plinth.conf
index 64217ece9..292ef44ce 100644
--- a/plinth/modules/matrixsynapse/data/etc/apache2/conf-available/matrix-synapse-plinth.conf
+++ b/plinth/modules/matrixsynapse/data/etc/apache2/conf-available/matrix-synapse-plinth.conf
@@ -5,4 +5,8 @@
## 8448. Further, federation requires same TLS public key to be provided to
## Apache and Matrix Synapse server.
##
-ProxyPass /_matrix http://localhost:8008/_matrix
+
+ AllowEncodedSlashes NoDecode
+ ProxyPass /_matrix http://localhost:8008/_matrix nocanon
+ ProxyPassReverse /_matrix http://localhost:8008/_matrix
+
From 20c97c5ce3d81bafb4025cb30d91bea7a83e7f42 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Wed, 21 Aug 2019 15:16:20 -0700
Subject: [PATCH 16/36] tt-rss: Force upgrade to 18.12-1.1 and beyond
Force upgrade to any lower version to version less than or equal to 19.8.*.
config.php is the only configuration file for tt-rss app the FreedomBox
modifies. Comparison of config.php from 19.8 shows that there are no major
changes since 18.12. Changes to the configuration file are likely to be minor
and from Debian packaging. Force upgrading to all versions until 19.8.* should
be okay by retaining new configuration and performing FreedomBox changes on top
everything new configuration file is installed.
Tests:
- Install tt-rss version 18.12-1 using a test repository and custom priority.
Then remove the custom priority and trigger 'apt update'. This will trigger an
force upgrade of tt-rss to version 18.12-1.1. Verify that the tt-rss interface
is available and functional.
- Install tt-rss version 18.12-1.1 freshly. Verify that the tt-rss interface is
available and functional.
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: James Valleroy
---
plinth/modules/ttrss/__init__.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/plinth/modules/ttrss/__init__.py b/plinth/modules/ttrss/__init__.py
index db0633468..fa5ce8dcc 100644
--- a/plinth/modules/ttrss/__init__.py
+++ b/plinth/modules/ttrss/__init__.py
@@ -125,10 +125,9 @@ def force_upgrade(helper, packages):
if 'tt-rss' not in packages:
return False
- # tt-rss 17.4 -> 18.12
+ # Allow tt-rss any lower version to upgrade to 19.8.*
package = packages['tt-rss']
- if Version(package['current_version']) >= Version('18.12') or \
- Version(package['new_version']) < Version('18.12'):
+ if Version(package['new_version']) > Version('19.9~'):
return False
helper.install(['tt-rss'], force_configuration='new')
From 712c51c161bc8f965aa335e43763006ecad1af13 Mon Sep 17 00:00:00 2001
From: Sunil Mohan Adapa
Date: Fri, 23 Aug 2019 11:57:52 -0700
Subject: [PATCH 17/36] doc: Fetch latest manual
Signed-off-by: Sunil Mohan Adapa
Reviewed-by: Joseph Nuthalapati
---
doc/Cockpit.raw.xml | 6 +-
doc/Upgrades.raw.xml | 12 +-
doc/freedombox-manual.raw.xml | 130 +++++++++++++-----
doc/images/freedombox-screenshot-about.png | Bin 0 -> 167497 bytes
doc/images/freedombox-screenshot-apps.png | Bin 0 -> 360881 bytes
doc/images/freedombox-screenshot-home.png | Bin 0 -> 428800 bytes
doc/images/freedombox-screenshot-manual.png | Bin 0 -> 162997 bytes
.../freedombox-screenshot-roundcube.png | Bin 0 -> 191599 bytes
doc/images/freedombox-screenshot-system.png | Bin 0 -> 284592 bytes
doc/images/freedombox-screenshot-tor.png | Bin 0 -> 145535 bytes
doc/images/freedombox-screenshot-ttrss.png | Bin 0 -> 168885 bytes
11 files changed, 108 insertions(+), 40 deletions(-)
create mode 100644 doc/images/freedombox-screenshot-about.png
create mode 100644 doc/images/freedombox-screenshot-apps.png
create mode 100644 doc/images/freedombox-screenshot-home.png
create mode 100644 doc/images/freedombox-screenshot-manual.png
create mode 100644 doc/images/freedombox-screenshot-roundcube.png
create mode 100644 doc/images/freedombox-screenshot-system.png
create mode 100644 doc/images/freedombox-screenshot-tor.png
create mode 100644 doc/images/freedombox-screenshot-ttrss.png
diff --git a/doc/Cockpit.raw.xml b/doc/Cockpit.raw.xml
index beecec3ed..18c8855d1 100644
--- a/doc/Cockpit.raw.xml
+++ b/doc/Cockpit.raw.xml
@@ -2,6 +2,6 @@
-FreedomBox/Manual/Cockpit32019-07-19 00:08:47SunilMohanAdapaAdd informatio about Cockpit needing a proper domain name22019-01-10 21:41:56SunilMohanAdapaWrite manual page for Cockpit12018-03-02 12:57:48JosephNuthalapatiCreate stub for CockpitCockpit (Server Administration)Cockpit is a server manager that makes it easy to administer GNU/Linux servers via a web browser. On a FreedomBox, controls are available for many advanced functions that are not usually required. A web based terminal for console operations is also available. It can be accessed by any user on your FreedomBox belonging to the admin group. Cockpit is only usable when you have proper domain name setup for your FreedomBox and you use that domain name to access Cockpit. See the Troubleshooting section for more information. Use cockpit only if you are an administrator of GNU/Linux systems with advanced skills. FreedomBox tries to coexist with changes to system by system administrators and system administration tools like Cockpit. However, improper changes to the system might causes failures in FreedomBox functions. Using CockpitInstall Cockpit like any other application on FreedomBox. Make sure that Cockpit is enabled after that. cockpit-enable.png Ensure that the user account on FreedomBox that will used for Cockpit is part of the administrators group. cockpit-admin-user.png Launch the Cockpit web interface. Login using the configured user account. cockpit-login.png Start using cockpit. cockpit-system.png Cockpit is usable on mobile interfaces too. cockpit-mobile.png FeaturesThe following features of Cockpit may be useful for advanced FreedomBox users. System DashboardCockpit has a system dashboard that Shows detailed hardware information Shows basic performance metrics of a system Allows changing system time and timezone Allows changing hostname. Please use FreedomBox UI to do this Shows SSH server fingerprints cockpit-system.png Viewing System LogsCockpit allows querying system logs and examining them in full detail. cockpit-logs.png Managing StorageCockpit allows following advanced storage functions: View full disk information Editing disk partitions RAID management cockpit-storage1.png cockpit-storage2.png NetworkingCockpit and FreedomBox both rely on NetworkManager to configure the network. However, Cockpit offers some advanced configuration not available on FreedomBox: Route configuration Configure Bonds, Bridges, VLANs cockpit-network1.png cockpit-network2.png cockpit-network3.png ServicesCockpit allows management of services and periodic jobs (similar to cron). cockpit-services1.png cockpit-services2.png Web TerminalCockpit offers a web based terminal that can be used perform manual system administration tasks. cockpit-terminal.png TroubleshootingCockpit requires a domain name to be properly setup on your FreedomBox and will only work when you access it using a URL with that domain name. Cockpit will not work when using IP address in the URL. Using freedombox.local as the domain name also does not work. For example, the following URLs will not work: To properly access Cockpit, use the domain name configured for your FreedomBox.Cockpit will also work well when using a Tor Hidden Service. The following URLs will work: The reason for this behaviour is that Cockpit uses WebSockets to connect to the backend server. Cross site requests for WebSockets must be prevented for security reasons. To implement this, Cockpit maintains a list of all domains from which requests are allowed. FreedomBox automatically configures this list whenever you add or remove a domain. However, since we can't rely on IP addresses, they are not added by FreedomBox to this domain list. You can see the current list of allowed domains, as managed by FreedomBox, in /etc/cockpit/cockpit.conf. You may edit this, but do so only if you understand web security consequences of this. Back to Features introduction or manual pages. InformationSupportContributeReportsPromote Overview Hardware Live Help Where To Start Translate Calls Talks Features Vision Q&A Design To Do Releases Press Download Manual Code Contributors Blog HELP & DISCUSSIONS: Discussion Forum - Mailing List - #freedombox irc.debian.org | CONTACT Foundation | JOIN Project Next call: Sunday, August 25th at 17:00 UTC Latest news: Announcing Pioneer FreedomBox Kits - 2019-03-26 This page is copyright its contributors and is licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license. CategoryFreedomBox
\ No newline at end of file
+FreedomBox/Manual/Cockpit42019-08-20 18:22:51SunilMohanAdapaUpdate information about .local domain and fix URLs32019-07-19 00:08:47SunilMohanAdapaAdd informatio about Cockpit needing a proper domain name22019-01-10 21:41:56SunilMohanAdapaWrite manual page for Cockpit12018-03-02 12:57:48JosephNuthalapatiCreate stub for CockpitCockpit (Server Administration)Cockpit is a server manager that makes it easy to administer GNU/Linux servers via a web browser. On a FreedomBox, controls are available for many advanced functions that are not usually required. A web based terminal for console operations is also available. It can be accessed by any user on your FreedomBox belonging to the admin group. Cockpit is only usable when you have proper domain name setup for your FreedomBox and you use that domain name to access Cockpit. See the Troubleshooting section for more information. Use cockpit only if you are an administrator of GNU/Linux systems with advanced skills. FreedomBox tries to coexist with changes to system by system administrators and system administration tools like Cockpit. However, improper changes to the system might causes failures in FreedomBox functions. Using CockpitInstall Cockpit like any other application on FreedomBox. Make sure that Cockpit is enabled after that. cockpit-enable.png Ensure that the user account on FreedomBox that will used for Cockpit is part of the administrators group. cockpit-admin-user.png Launch the Cockpit web interface. Login using the configured user account. cockpit-login.png Start using cockpit. cockpit-system.png Cockpit is usable on mobile interfaces too. cockpit-mobile.png FeaturesThe following features of Cockpit may be useful for advanced FreedomBox users. System DashboardCockpit has a system dashboard that Shows detailed hardware information Shows basic performance metrics of a system Allows changing system time and timezone Allows changing hostname. Please use FreedomBox UI to do this Shows SSH server fingerprints cockpit-system.png Viewing System LogsCockpit allows querying system logs and examining them in full detail. cockpit-logs.png Managing StorageCockpit allows following advanced storage functions: View full disk information Editing disk partitions RAID management cockpit-storage1.png cockpit-storage2.png NetworkingCockpit and FreedomBox both rely on NetworkManager to configure the network. However, Cockpit offers some advanced configuration not available on FreedomBox: Route configuration Configure Bonds, Bridges, VLANs cockpit-network1.png cockpit-network2.png cockpit-network3.png ServicesCockpit allows management of services and periodic jobs (similar to cron). cockpit-services1.png cockpit-services2.png Web TerminalCockpit offers a web based terminal that can be used perform manual system administration tasks. cockpit-terminal.png TroubleshootingCockpit requires a domain name to be properly setup on your FreedomBox and will only work when you access it using a URL with that domain name. Cockpit will not work when using IP address in the URL. Using freedombox.local as the domain name also does not work. For example, the following URLs will not work: Starting with FreedomBox version 19.15, using .local domain works. You can access Cockpit using the URL . The .local domain is based on your hostname. If your hostname is mybox, your .local domain name will be mybox.local and the Cockpit URL will be . To properly access Cockpit, use the domain name configured for your FreedomBox.Cockpit will also work well when using a Tor Hidden Service. The following URLs will work: The reason for this behaviour is that Cockpit uses WebSockets to connect to the backend server. Cross site requests for WebSockets must be prevented for security reasons. To implement this, Cockpit maintains a list of all domains from which requests are allowed. FreedomBox automatically configures this list whenever you add or remove a domain. However, since we can't rely on IP addresses, they are not added by FreedomBox to this domain list. You can see the current list of allowed domains, as managed by FreedomBox, in /etc/cockpit/cockpit.conf. You may edit this, but do so only if you understand web security consequences of this. Back to Features introduction or manual pages. InformationSupportContributeReportsPromote Overview Hardware Live Help Where To Start Translate Calls Talks Features Vision Q&A Design To Do Releases Press Download Manual Code Contributors Blog HELP & DISCUSSIONS: Discussion Forum - Mailing List - #freedombox irc.debian.org | CONTACT Foundation | JOIN Project Next call: Sunday, August 25th at 17:00 UTC Latest news: Announcing Pioneer FreedomBox Kits - 2019-03-26 This page is copyright its contributors and is licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license. CategoryFreedomBox
\ No newline at end of file
diff --git a/doc/Upgrades.raw.xml b/doc/Upgrades.raw.xml
index 28281e33b..3a32dd888 100644
--- a/doc/Upgrades.raw.xml
+++ b/doc/Upgrades.raw.xml
@@ -2,7 +2,11 @@
-FreedomBox/Manual/Upgrades62019-06-19 07:42:18fioddorLack of feedback is not specific to manual procedure.52017-03-31 20:11:01DrahtseilScreenshot automatic upgrades42016-09-01 19:20:27Drahtseiladapted title to Plinth wording32016-01-16 07:41:43StacyCockrum22016-01-16 07:35:56StacyCockrum12015-09-16 15:01:05SunilMohanAdapaAdd upgrades manual pageSoftware UpgradesFreedomBox can automatically install security upgrades. On the Upgrades page of the Settings section in Plinth you can turn on automatic upgrades. For FreedomBox versions above 0.5, this feature is enabled by default and there is no manual action necessary. It is strongly recommended that you have this option enabled to keep your FreedomBox secure. Upgrades are performed every day at night. If you wish to shutdown FreedomBox every day after use, keep it running at night once a week or so to let the automatic upgrades happen. Alternatively, you can perform manual upgrades as described below. Note that once the upgrades start, it may take a long time to complete and Plinth may seem to wait for the page to load. upgrades.png Manual UpgradesUnder some circumstances, automatic upgrades may fail and require you perform a manual upgrade action. Even upgrades initiated from Plinth may not finish properly. This may be because the upgrade process requires you to make a decision. In these cases, manual upgrade on the terminal may be the only option. In addition, while the upgrade task is running any application installations will wait until the upgrade task is finished. Depending on the hardware, the upgrade task may take a little time, therefore, giving the impression that the application installation stalled. To perform manual upgrades on the terminal, login into FreedomBox on a terminal or using a remote secure shell (see Secure Shell section). Then run the following commands: This will ask you if it is alright to install/upgrade (or remove) some packages and use (or release) some disk space. Say yes after review. In some cases, during the upgrades process you will be asked questions about modified configuration files, answering with a default Keep current configuration is usually safe. InformationSupportContributeReportsPromote Overview Hardware Live Help Where To Start Translate Calls Talks Features Vision Q&A Design To Do Releases Press Download Manual Code Contributors Blog HELP & DISCUSSIONS: Discussion Forum - Mailing List - #freedombox irc.debian.org | CONTACT Foundation | JOIN Project Next call: Sunday, August 25th at 17:00 UTC Latest news: Announcing Pioneer FreedomBox Kits - 2019-03-26 This page is copyright its contributors and is licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license. CategoryFreedomBox
\ No newline at end of file
+FreedomBox/Manual/Upgrades72019-08-22 02:42:27SunilMohanAdapaProvide information about properly updating FreedomBox62019-06-19 07:42:18fioddorLack of feedback is not specific to manual procedure.52017-03-31 20:11:01DrahtseilScreenshot automatic upgrades42016-09-01 19:20:27Drahtseiladapted title to Plinth wording32016-01-16 07:41:43StacyCockrum22016-01-16 07:35:56StacyCockrum12015-09-16 15:01:05SunilMohanAdapaAdd upgrades manual pageSoftware UpdatesFreedomBox can automatically install security updates. On the Update page of the System section in FreedomBox web interface you can turn on automatic updates. This feature is enabled by default and there is no manual action necessary. It is strongly recommended that you have this option enabled to keep your FreedomBox secure. Updates are performed every day at night. If you wish to shutdown FreedomBox every day after use, keep it running at night once a week or so to let the automatic updates happen. Alternatively, you can perform manual updates as described below. Note that once the updates start, it may take a long time to complete. During automatic update process that runs every night or during manual update process, you will not be able to install apps from FreedomBox web interface. upgrades.png When Will I Get the Latest Features?Although updates are done every day for security reasons, latest features of FreedomBox will not propagate to all the users. The following information should help you understand how new features become available to users. Stable Users: This category of users include users who bought the FreedomBox Pinoeer Edition, installed FreedomBox on a Debian stable distribution or users who downloaded the stable images from freedombox.org. As a general rule, only security updates to various packages are provided to these users. One exception to this rule is where FreedomBox service itself is updated when a release gains high confidence from developers. This means that latest FreedomBox features may become available to these users although not as quickly or frequently as testing users. If an app is available only in testing distribution but not in stable distribution, then that app will show up in the web interface but will not be installable by stable users. Some apps are also provided an exception to the rule of "security updates only" when the app is severely broken otherwise. Every two years, a major release of Debian stable happens with the latest versions of all the software packages and FreedomBox developers will attempt to upgrade these users to the new release without requiring manual intervention. Testing Users: This category of users include users who installed FreedomBox on a Debian testing distribution or users who downloaded the testing images from freedombox.org. Users who use Debian testing are likely to face occasional disruption in the services and may even need manual intervention to fix the issue. As a general rule, these users receive all the latest features and security updates to all the installed packages. Every two weeks, a new version of FreedomBox is released with all the latest features and fixes. These releases will reach testing users approximately 2-3 days after the release. Unstable Users: This category of users include users who installed FreedomBox on a Debian unstable distribution or users who downloaded the unstable images from freedombox.org. Users who use Debian unstable are likely to face occasional disruption in the services and may even need manual intervention to fix the issue. As a general rule, these users receive all the latest features to all the installed packages. Every two weeks, a new version of FreedomBox is released with all the latest features and fixes. Theses releases will reach unstable users on the day of the release. Only developers, testers and other contributors to the FreedomBox project should use the unstable distribution and end users and advised against using it. Manual Updates from Web InterfaceTo get updates immediately and not wait until the end of the day, you may want to trigger updates manually. You can do this by pressing the Update now button in Manual update tab for Update page in System section. Note that this step is not necessary if you have enabled Auto-updates as every night this operation is performed automatically. When installing apps you may receive an error message such as This is typically caused by shutting down FreedomBox while it is installing apps, while performing daily updates or during some other operations. This situation can be rectified immediately by running manual update. Manual Updates from TerminalSome software packages may require manual interaction for updating due to questions related to configuration. In such cases, FreedomBox updates itself and brings in new knowledge necessary to update the package by answering configuration questions. After updating itself, FreedomBox acts on behalf of the user and updates the packages by answering the questions. Until FreedomBox has a chance to update the package, such packages should not be be updated manually. The manual update triggered from the web interface is already mindful of such packages and does not update them. In some rare situations, FreedomBox itself might fail to update or the update mechanism might fall into a situation that might need manual intervention from a terminal. To perform manual upgrades on the terminal, login into FreedomBox on a terminal (if you have monitor and keyboard connected), via a web terminal (using FreedomBox/Manual/Cockpit) or using a remote secure shell (see Secure Shell section). Then run the following commands:
+# dpkg --configure -a
+# apt update
+# apt -f install
+# unattended-upgrade --debug
+# apt install freedombox
+# apt update]]>If apt-get update asks for a confirmation to change Codename or other release information, confirm yes. If during update of freedombox package, if a question about overwriting configuration files is asked, answer to install new configuration files from the latest version of the package. This process will upgrade only packages that don't require configuration file questions (except for freedombox package). After this, let FreedomBox handle the upgrade of remaining packages. Be patient while new releases of FreedomBox are made to handle packages that require manual intervention. If you want to go beyond the recommendation to upgrade all the packages on your FreedomBox and if you are really sure about handling the configuration changes for packages yourself, run the following command: InformationSupportContributeReportsPromote Overview Hardware Live Help Where To Start Translate Calls Talks Features Vision Q&A Design To Do Releases Press Download Manual Code Contributors Blog HELP & DISCUSSIONS: Discussion Forum - Mailing List - #freedombox irc.debian.org | CONTACT Foundation | JOIN Project Next call: Sunday, August 25th at 17:00 UTC Latest news: Announcing Pioneer FreedomBox Kits - 2019-03-26 This page is copyright its contributors and is licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license. CategoryFreedomBox
\ No newline at end of file
diff --git a/doc/freedombox-manual.raw.xml b/doc/freedombox-manual.raw.xml
index 84af05041..b29d81181 100644
--- a/doc/freedombox-manual.raw.xml
+++ b/doc/freedombox-manual.raw.xml
@@ -3879,11 +3879,12 @@ proto udp]]>
Troubleshooting
Cockpit requires a domain name to be properly setup on your FreedomBox and will only work when you access it using a URL with that domain name. Cockpit will not work when using IP address in the URL. Using freedombox.local as the domain name also does not work. For example, the following URLs will not work:
-
+
+ Starting with FreedomBox version 19.15, using .local domain works. You can access Cockpit using the URL . The .local domain is based on your hostname. If your hostname is mybox, your .local domain name will be mybox.local and the Cockpit URL will be .
To properly access Cockpit, use the domain name configured for your FreedomBox.Cockpit will also work well when using a Tor Hidden Service. The following URLs will work:
-
+
The reason for this behaviour is that Cockpit uses WebSockets to connect to the backend server. Cross site requests for WebSockets must be prevented for security reasons. To implement this, Cockpit maintains a list of all domains from which requests are allowed. FreedomBox automatically configures this list whenever you add or remove a domain. However, since we can't rely on IP addresses, they are not added by FreedomBox to this domain list. You can see the current list of allowed domains, as managed by FreedomBox, in /etc/cockpit/cockpit.conf. You may edit this, but do so only if you understand web security consequences of this.
@@ -6578,10 +6579,10 @@ nmcli con modify "" connection.zone internal]]>
- Software Upgrades
- FreedomBox can automatically install security upgrades. On the Upgrades page of the Settings section in Plinth you can turn on automatic upgrades. For FreedomBox versions above 0.5, this feature is enabled by default and there is no manual action necessary. It is strongly recommended that you have this option enabled to keep your FreedomBox secure.
- Upgrades are performed every day at night. If you wish to shutdown FreedomBox every day after use, keep it running at night once a week or so to let the automatic upgrades happen. Alternatively, you can perform manual upgrades as described below.
- Note that once the upgrades start, it may take a long time to complete and Plinth may seem to wait for the page to load.
+ Software Updates
+ FreedomBox can automatically install security updates. On the Update page of the System section in FreedomBox web interface you can turn on automatic updates. This feature is enabled by default and there is no manual action necessary. It is strongly recommended that you have this option enabled to keep your FreedomBox secure.
+ Updates are performed every day at night. If you wish to shutdown FreedomBox every day after use, keep it running at night once a week or so to let the automatic updates happen. Alternatively, you can perform manual updates as described below.
+ Note that once the updates start, it may take a long time to complete. During automatic update process that runs every night or during manual update process, you will not be able to install apps from FreedomBox web interface.
@@ -6593,15 +6594,34 @@ nmcli con modify "" connection.zone internal]]>
- Manual Upgrades
- Under some circumstances, automatic upgrades may fail and require you perform a manual upgrade action. Even upgrades initiated from Plinth may not finish properly. This may be because the upgrade process requires you to make a decision. In these cases, manual upgrade on the terminal may be the only option.
- In addition, while the upgrade task is running any application installations will wait until the upgrade task is finished. Depending on the hardware, the upgrade task may take a little time, therefore, giving the impression that the application installation stalled.
- To perform manual upgrades on the terminal, login into FreedomBox on a terminal or using a remote secure shell (see Secure Shell section). Then run the following commands:
+ When Will I Get the Latest Features?
+ Although updates are done every day for security reasons, latest features of FreedomBox will not propagate to all the users. The following information should help you understand how new features become available to users.
+ Stable Users: This category of users include users who bought the FreedomBox Pinoeer Edition, installed FreedomBox on a Debian stable distribution or users who downloaded the stable images from freedombox.org. As a general rule, only security updates to various packages are provided to these users. One exception to this rule is where FreedomBox service itself is updated when a release gains high confidence from developers. This means that latest FreedomBox features may become available to these users although not as quickly or frequently as testing users. If an app is available only in testing distribution but not in stable distribution, then that app will show up in the web interface but will not be installable by stable users. Some apps are also provided an exception to the rule of "security updates only" when the app is severely broken otherwise. Every two years, a major release of Debian stable happens with the latest versions of all the software packages and FreedomBox developers will attempt to upgrade these users to the new release without requiring manual intervention.
+ Testing Users: This category of users include users who installed FreedomBox on a Debiantesting distribution or users who downloaded the testing images from freedombox.org. Users who use Debian testing are likely to face occasional disruption in the services and may even need manual intervention to fix the issue. As a general rule, these users receive all the latest features and security updates to all the installed packages. Every two weeks, a new version of FreedomBox is released with all the latest features and fixes. These releases will reach testing users approximately 2-3 days after the release.
+ Unstable Users: This category of users include users who installed FreedomBox on a Debianunstable distribution or users who downloaded the unstable images from freedombox.org. Users who use Debian unstable are likely to face occasional disruption in the services and may even need manual intervention to fix the issue. As a general rule, these users receive all the latest features to all the installed packages. Every two weeks, a new version of FreedomBox is released with all the latest features and fixes. Theses releases will reach unstable users on the day of the release. Only developers, testers and other contributors to the FreedomBox project should use the unstable distribution and end users and advised against using it.
+
+
+ Manual Updates from Web Interface
+ To get updates immediately and not wait until the end of the day, you may want to trigger updates manually. You can do this by pressing the Update now button in Manual update tab for Update page in System section. Note that this step is not necessary if you have enabled Auto-updates as every night this operation is performed automatically.
+ When installing apps you may receive an error message such as
+
+ This is typically caused by shutting down FreedomBox while it is installing apps, while performing daily updates or during some other operations. This situation can be rectified immediately by running manual update.
+
+
+ Manual Updates from Terminal
+ Some software packages may require manual interaction for updating due to questions related to configuration. In such cases, FreedomBox updates itself and brings in new knowledge necessary to update the package by answering configuration questions. After updating itself, FreedomBox acts on behalf of the user and updates the packages by answering the questions. Until FreedomBox has a chance to update the package, such packages should not be be updated manually. The manual update triggered from the web interface is already mindful of such packages and does not update them.
+ In some rare situations, FreedomBox itself might fail to update or the update mechanism might fall into a situation that might need manual intervention from a terminal. To perform manual upgrades on the terminal, login into FreedomBox on a terminal (if you have monitor and keyboard connected), via a web terminal (using FreedomBox/Manual/Cockpit) or using a remote secure shell (see Secure Shell section). Then run the following commands:
- This will ask you if it is alright to install/upgrade (or remove) some packages and use (or release) some disk space. Say yes after review. In some cases, during the upgrades process you will be asked questions about modified configuration files, answering with a default Keep current configuration is usually safe.
+Password:
+# dpkg --configure -a
+# apt update
+# apt -f install
+# unattended-upgrade --debug
+# apt install freedombox
+# apt update]]>
+ If apt-get update asks for a confirmation to change Codename or other release information, confirm yes. If during update of freedombox package, if a question about overwriting configuration files is asked, answer to install new configuration files from the latest version of the package. This process will upgrade only packages that don't require configuration file questions (except for freedombox package). After this, let FreedomBox handle the upgrade of remaining packages. Be patient while new releases of FreedomBox are made to handle packages that require manual intervention.
+ If you want to go beyond the recommendation to upgrade all the packages on your FreedomBox and if you are really sure about handling the configuration changes for packages yourself, run the following command:
+
@@ -12673,46 +12693,90 @@ FreedomBox app to configure Tiny Tiny RSS.
Screenshots
-
+
-
+
- About Page
+ Home Page
-
+
-
+
+
+
+ Apps Page
+
+
+
+
+
+
+
+
+
+ System Page
+
+
+
+
+
+
+
+
+
Enabling Tor Hidden Services
-
+
-
-
-
- Setting up Email Client
-
-
-
-
-
-
-
+
Newsfeed from anywhere
+
+
+
+
+
+
+ Email Client
+
+
+
+
+
+
+
+
+
+
+
+ Manual Pages
+
+
+
+
+
+
+
+
+
+ About Page
+
+
+
diff --git a/doc/images/freedombox-screenshot-about.png b/doc/images/freedombox-screenshot-about.png
new file mode 100644
index 0000000000000000000000000000000000000000..6026e9d08f41362dc591688db1a48e4a4f95c806
GIT binary patch
literal 167497
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 t(jjnqk0_M&N`hoRtWwDb)R4|S-
z-qT)d1xFqn;d^WR>V(=)aGfl#qD!~s)ZR~=Kcr&gBcn}dKVa5twz&UQZo6?d66r)>
z^CErtgF$^L?d7U`1XW}bFK+Upbgz8!Tb@Bb-Xra7E3Xp$E9ObkrLEXNwPXR~MC`h1
z`Nl0d{j}m=bw=gPZt-cKFs<-=)$|1?_F3G5r>P-1mnk1esdViR1^J>*KK-=&cI6b_
z>&W8!&DivRl~|0(T)KPccx+mh>!26~r=7g+PY5ETwQ8yWmqtK&=D7{DU0A<4h{!D4ZwXe>E(0^x>(Zd^(ZIO4NaLvmxWU~(D=v-ajP6jn$0Q>{>j&6tqs>iKKy3z
z=-frc>V<3s#*0V2S`o=9I>4xF?Ecym;9#HSErFQe5W47tP*~?YA3M}!d;4yec>S4{
ze#EzzRjOgG?lK$g?;`s3$w}FwKp}I1IqTU#4?QJ~n_v`NDPXwb;MH#KhStu0osd(1
z`-HT3YG)<89Mkqx`BzyZUCj%0Rxf)qS{WK*%_jB?yY4q3;M5bGKXl$0))4)~gKEXZmz@t0RUsjrBkt9rlfkK>dT|NBUD7+6{7vkvxV7@;mW!VQ1;CKe({8{abZ_#s4I#>j9|^&MxD?-Lm(
z+xL9}b}3jTP|)I$;8mzwlM$4E2hhC`lSr(r=XxW*UxwMVyX@PL!=IqJ@R%g2Xozr0JLEO<5r^}Oy5v#`
zY92lV{REY(!>3mGV)^eXjN3Cf`Uv>27TQhS(KIb{(CUF%tiU6O9YSI-WzXUZI`9t#yJC!q
z7i>>;^;M2l#z!#1j7#gT-%$H>Yx3w-j)8|YP6<{#_~eYcp8OxSzB``k_kaI&&M}U8
zWLG$3W<-T#&y2FN_ew(&g{xf{gnJvT
zYzEQfVmUtMN;hVdn$UA3knX<_F&5go^Oa|l2QkbiBsk1mMsH)xKC`h`HzWm&44gL6
zFMZq!+*C}iyC=h^c+DD&Cr@eXtRbu}I|C(+y!uuwco4xv2!)V%v(-#%ND95wc{Oju
zvs(uTpDULdm@YW$XU2_z)qA5_Vma|&y_U$4Lf9E`TSZqSSwmmMSnd_IOtO(>&tdCO
zF*Dnntbai(#Ww;QuZ
zjPmJUUr*?mVIM4R5OLuVW@Qv&H`K2PRC#IbffurlBUQcXQ8%)@{i85{;|52~1zh|c
zHP$|3@@dW70)?Up2bnh{0@+jIKJ|&6$Jefw0AYvdBj4j=pE|z1?jC
z{IHGD$!C2`q%)Lm^C^X(!UxjRKE4JRet=c#1fTP9wu=)eT2GCps*OwR5^?eHmW&6dTS*W}sEMdv#`W8#wyp>Y!O>W^6;51K2ro~yVJ
zeN^UqZmE=pV=T9Wrp#3=z=(Zn(HS*B!u&1wQUY=*b5}VNNaXkLvSV`iH*vLYu$BXI
z@YI&;gY{$uB
zpTo@nqh=#|q1r5N`3b})wb))JhX2CbEyTIoj2EVPG$K1`TQyx(e@V%-ey;xL5-^cH
zq6+*-URB|z>WuqthmqHbofX6w#?Z0CGUPessD(4T!-`Ij&;--!#kuGjOf|-H+G8mB
zI>Pxb)kG@UzJli}DFs~$CN&ci4M$(^vn_E@jG>cu;EP)bk|Z;MCvhe-k{3QP^rIMM
zy}%^vUx=7sG#6?16mt!f8C0pgr9P*2;j7F0pmXkT%&mSV%ldVD@&{T2G1tg8obmUN
z8y9v-6%kha*sVUD@BS_sOnpwPh2Fc&C+Luqzle1jJ0AgEEkAGS@pBZ|VL*vCWG=gO
zeC`bQrqn+!OFCPp>q|OJ`09{sNbBlfWly8qoh0lKQts9E=tx~CIijRDc
zXCDxShNLn~aWR}eQ+eOfWeA(;=My}FY1gu;=&dy9o^eV3>O8d`>hFD~l0KvO0g$DE
z1;UPl=ZobV*Z8c6D<>zhO
zL#WLLxxA-yl&TY7+;%10078&%*_Csy 2Fb
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 | | |