Compare commits

...

5 Commits

Author SHA1 Message Date
Sunil Mohan Adapa
d5062ef5ea
README: Use the Weblate's language chart widget
- This shows status of each language rather than just a single number for all
the languages. This hopefully highlights languages needing more work.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Veiko Aasa <veiko17@disroot.org>
2025-11-03 13:58:50 +02:00
Sunil Mohan Adapa
24d2d92ab5
Run service using systemd even for development
- This means that systemd sandbox will be in effect even during development. We
won't miss out on bugs in sandbox configuration.

- We won't have disable systemd sandbox features just because we can test
properly on development setup. Such as JoinsNamespaceOf=.

- This also leads to significant reduction in hacky code for setting up for
development and functional tests.

- One disadvantage is that first setup is run before user gets a chance to
interact with the started container/VM. However, this is okay since first setup
can be re-run easily by removing the /var/lib/plinth/plinth.sqlite3 file and
also the need for doing this is rare.

Tests:

- Start a fresh container and run functional tests with './container run-tests'
on it. The tests run as expected (succeed or fail).

- While first setup is in progress, running the command 'make
wait-while-first-setup' waits while printing dots. After the first setup is
done, it exists.

- Running the command freedombox-logs shows FreedomBox logs for both the web and
privileged services.

- Changing a source code file in the /freedombox directory (or on the host)
leads to a restart of the Plinth web service.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Veiko Aasa <veiko17@disroot.org>
2025-11-03 13:54:00 +02:00
Sunil Mohan Adapa
e5026282fe
main: Allow setting development mode from environment
- Similar to freedombox-privileged daemon. It makes it easy to turn on
development mode from a systemd service override (without having to override the
entire command line).

Tests:

- With the changes to systemd service file in this patch series, changing source
code file leads to plinth getting restarted.

Reviewed-by: Veiko Aasa <veiko17@disroot.org>
2025-11-03 13:54:00 +02:00
Sunil Mohan Adapa
623604649e
views: Implement an API to retrieve the readiness status in JSON
- This can have may uses such as:

  - Waiting properly on the reboot page until the system has been restarted
  while showing the status.

  - Or, waiting for first setup to complete before running functional tests.

  - Or, monitoring for the health status of FreedomBox in general.

- The page is public as all the information conveyed there is also already
public. Should we introduce any sensitive information there such as
'operations_in_progress', we can provide that information only to
administrators.

Tests:

- Visiting /plinth/status/ shows the status in JSON. Using curl to retrieve the
information is also possible.

- During the first setup 'is_first_setup_running' is 'true'. After it has
completed, it is 'false'.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Veiko Aasa <veiko17@disroot.org>
2025-11-03 13:53:59 +02:00
Coucouf
8a4f03c58a
Translated using Weblate (French)
Currently translated at 100.0% (1879 of 1879 strings)
2025-10-30 04:24:25 +00:00
12 changed files with 97 additions and 81 deletions

View File

@ -16,7 +16,7 @@ RUN apt-get dist-upgrade -y
# Install freedombox package so that plint:plinth user/group are created etc.
RUN apt-get install -y freedombox/trixie-backports
RUN systemctl mask plinth.service
RUN systemctl disable plinth.service
# Don't ask for the secret in first wizard
RUN rm -f /var/lib/plinth/firstboot-wizard-secret

View File

@ -16,8 +16,7 @@
- apt-get update
- apt-get -y install make
- make provision-dev
- sudo -u plinth ./run --develop > plinth.log 2>&1 &
- while ! grep -q "Setup finished" plinth.log; do sleep 1; echo -n .; done
- make wait-while-first-setup
script:
- FREDOMBOX_URL=https://localhost FREEDOMBOX_SSH_PORT=22 FREEDOMBOX_SAMBA_PORT=445 pytest -v --durations=10 --include-functional --splinter-headless --instafail --template=html1/index.html --report=functional-tests.html
artifacts:

View File

@ -143,12 +143,12 @@ directory:
guest$ cd /freedombox
```
Run the development version of FreedomBox Service in the container using the
following command. This command continuously deploys your code changes into the
container providing a quick feedback cycle during development.
FreedomBox Service runs as plinth.service in the container. This service
restarts when it detects a change to the source code file. This provides a quick
feedback cycle during development. To watch service logs run:
```bash
guest$ freedombox-develop
guest$ sudo freedombox-logs
```
If you have changed any system configuration files during your development,
@ -156,7 +156,8 @@ you will need to run the following to install those files properly on to the
system and their changes to reflect properly.
```bash
guest$ sudo make build install
guest$ sudo make build install ;
guest$ sudo systemctl restart plinth.service
```
Note: This development container has automatic upgrades disabled by default.
@ -373,13 +374,12 @@ After logging into the virtual machine (VM), the source code is available in
vm$ cd /freedombox
```
Run the development version of FreedomBox Service (Plinth) from your source
directory in the virtual machine using the following command. This command
continuously deploys your code changes into the virtual machine providing a
quick feedback cycle during development.
FreedomBox Service runs as plinth.service in the virtual machine. This service
restarts when it detects a change to the source code file. This provides a quick
feedback cycle during development. To watch service logs run:
```bash
vm$ freedombox-develop
vm$ sudo freedombox-logs
```
If you have changed any system configuration files during your development,

View File

@ -161,6 +161,16 @@ Environment=PYTHONPATH=/freedombox/
endef
export DEVELOP_SERVICE_CONF
define DEVELOP_LOGS_SCRIPT
#!/usr/bin/bash
set -e
set -x
journalctl --follow --unit=plinth.service --unit=freedombox-privileged.service
endef
export DEVELOP_LOGS_SCRIPT
# Run basic setup for a developer environment (VM or container)
provision-dev:
# Install newer build dependencies if any
@ -170,9 +180,15 @@ provision-dev:
# Install latest code over .deb
$(MAKE) build install
# Configure privileged daemon for development setup
# Configure privileged and web daemon for development setup
mkdir -p /etc/systemd/system/freedombox-privileged.service.d/
echo "$$DEVELOP_SERVICE_CONF" > /etc/systemd/system/freedombox-privileged.service.d/develop.conf
mkdir -p /etc/systemd/system/plinth.service.d/
echo "$$DEVELOP_SERVICE_CONF" > /etc/systemd/system/plinth.service.d/develop.conf
# Create a command to easily watch service logs
echo "$$DEVELOP_LOGS_SCRIPT" > /usr/bin/freedombox-logs
chmod 755 /usr/bin/freedombox-logs
# Reload newer systemd units, ignore failure
-systemctl daemon-reload
@ -183,6 +199,10 @@ provision-dev:
-test -d /run/systemd/system && \
systemctl enable --now freedombox-privileged.socket
# Enable and restart plinth service if it is running
-systemctl enable plinth.service
-systemctl restart plinth.service
# Stop any ongoing upgrade, ignore failure
-killall -9 unattended-upgr
@ -207,6 +227,12 @@ provision-dev:
DEBIAN_FRONTEND=noninteractive apt-get install --yes ncurses-term \
sshpass bash-completion
wait-while-first-setup:
while [ x$$(curl -k https://localhost/plinth/status/ 2> /dev/null | \
json_pp 2> /dev/null | grep 'is_first_setup_running' | \
tr -d '[:space:]' | cut -d':' -f2 ) != 'xfalse' ] ; do \
sleep 1; echo -n .; done
.PHONY: \
build \
check \
@ -219,4 +245,5 @@ provision-dev:
configure \
install \
provision \
update-translations
update-translations \
wait-while-first-setup

View File

@ -62,7 +62,7 @@ See the [HACKING.md](https://salsa.debian.org/freedombox-team/freedombox/blob/ma
# Localization
[![Translation status](https://hosted.weblate.org/widgets/freedombox/-/287x66-white.png)](https://hosted.weblate.org/engage/freedombox/?utm_source=widget)
[![Translation status](https://hosted.weblate.org/widget/freedombox/horizontal-auto.svg)](https://hosted.weblate.org/engage/freedombox/)
# License

10
Vagrantfile vendored
View File

@ -24,17 +24,13 @@ Vagrant.configure(2) do |config|
config.vm.provision "shell", inline: <<-SHELL
cd /freedombox/
make provision-dev
echo 'alias freedombox-develop="cd /freedombox; sudo -u plinth /freedombox/run --develop"' >> /home/vagrant/.bashrc
SHELL
config.vm.provision "tests", run: "never", type: "shell", path: "plinth/tests/functional/install.sh"
config.vm.post_up_message = "FreedomBox virtual machine is ready
for development. You can run the development version of Plinth using
the following command.
for development. Plinth will be available at https://localhost:4430/plinth
(with an invalid SSL certificate). To watch logs:
$ vagrant ssh
$ freedombox-develop
Plinth will be available at https://localhost:4430/plinth (with
an invalid SSL certificate).
$ sudo freedombox-logs
"
config.trigger.after [:up, :resume, :reload] do |trigger|

View File

@ -196,9 +196,6 @@ cd /freedombox/
sudo apt-get -y install make
sudo make provision-dev
echo 'alias freedombox-develop="cd /freedombox; sudo -u plinth /freedombox/run --develop"' \
>> /home/fbx/.bashrc
# Make some pytest related files and directories writable to the fbx user
sudo touch geckodriver.log
sudo chmod a+rw geckodriver.log
@ -241,25 +238,7 @@ fi
# Run the plinth server if functional tests are requested
if [[ "{pytest_command}" =~ "--include-functional" ]]
then
is_plinth_running=0
ps -ax -o cmd | grep -q "^sudo -u plinth /freedombox/run" && \
is_plinth_running=1
ps -ax -o cmd | grep -q "^/usr/bin/python3 /usr/bin/plinth" && \
is_plinth_running=1
if [[ $is_plinth_running -eq 1 ]]
then
echo "> In machine: Plinth is already running"
else
echo -n "> In machine: Starting plinth ... "
sudo -u plinth /freedombox/run --develop > plinth.log 2>&1 &
while ! grep -q "Setup finished" plinth.log
do
sleep 1
echo -n .
done
echo
fi
make -C /freedombox wait-while-first-setup
if [[ "{pytest_command}" != *"--splinter-headless"* ]]
then
@ -1074,7 +1053,7 @@ Folder overlay : (host, read-only){project_folder}
SSH easily : {script} ssh {options}
Run tests : {script} run-tests {options} [ --pytest-args ... ]
Run FreedomBox inside : freedombox-develop
Watch FreedomBox logs : sudo freedombox-logs
Web access : https://{ip_address}/
Ports access : Any port on {ip_address}

View File

@ -3,6 +3,7 @@
import argparse
import logging
import os
import sys
import threading
@ -121,7 +122,8 @@ def main():
arguments = parse_arguments()
cfg.read()
if arguments.develop:
if arguments.develop or os.getenv('FREEDOMBOX_DEVELOP', '') == '1':
cfg.develop = True
# Use the config in the current working directory
cfg.read_file(cfg.get_develop_config_path())

View File

@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: FreedomBox UI\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-10-07 00:04+0000\n"
"PO-Revision-Date: 2025-10-27 16:02+0000\n"
"PO-Revision-Date: 2025-10-30 04:24+0000\n"
"Last-Translator: Coucouf <coucouf@coucouf.fr>\n"
"Language-Team: French <https://hosted.weblate.org/projects/freedombox/"
"freedombox/fr/>\n"
@ -4784,13 +4784,14 @@ msgid ""
"gaming systems (such as PS3 and Xbox 360) or applications such as totem and "
"Kodi."
msgstr ""
"MiniDLNA est un serveur de médias simple ayant pour but dêtre entièrement "
"compatible avec les clients DLNA et UPnP-AV. Le démon MiniDLNA est capable "
"de servir des fichiers de médias (musique, photos et vidéos) à des clients "
"sur un réseau. DLNA/UPnP est un protocole sans configuration et est "
"compatible avec tout appareil ayant la certification DLNA comme les lecteurs "
"portables, les smartphones, les télévisions et les systèmes de jeu (comme la "
"PS3 ou la Xbox 360) ainsi que les applications telles que Totem ou Kodi."
"MiniDLNA est un serveur de médias simplifié qui vise une compatibilité "
"complète avec les clients DLNA et UPnP-AV. Le démon MiniDLNA est capable de "
"servir des fichiers de médias (musique, photos et vidéos) à des clients "
"réseau. DLNA/UPnP est un protocole sans configuration et est compatible avec "
"tout appareil ayant la certification DLNA comme les lecteurs portables, les "
"smartphones, les télévisions et les consoles de jeu "
"(comme la PS3 ou la Xbox 360) ainsi que les applications telles que Totem ou "
"Kodi."
#: plinth/modules/minidlna/__init__.py:45
msgid "MiniDLNA"
@ -10078,8 +10079,8 @@ msgid ""
"route all outgoing traffic from {box_name} through the VPN."
msgstr ""
"Il peut être utilisé pour se connecter à un fournisseur de réseau privé "
"virtuel VPN proposant un service WireGuard, pour router tout le trafic "
"sortant de la {box_name} à travers ce VPN."
"virtuel VPN proposant un service WireGuard et router tout le trafic sortant "
"de la {box_name} à travers ce VPN."
#: plinth/modules/wireguard/__init__.py:26
#, python-brace-format
@ -10088,10 +10089,10 @@ msgid ""
"travelling. While connected to a public Wi-Fi network, all traffic can be "
"securely relayed through {box_name}."
msgstr ""
"Une autre utilisation possible est de connecter un appareil mobile à votre "
"{box_name} pendant un déplacement. Même si celui-ci est connecté à un réseau "
"Wi-Fi public, tout votre trafic sera alors relayé via votre {box_name} de "
"manière sécurisée."
"Une autre usage possible est de connecter un appareil mobile à votre "
"{box_name} pendant un déplacement. Même si votre appareil est connecté à un "
"réseau Wi-Fi public, tout votre trafic sera alors relayé via votre {box_name}"
" de manière sécurisée."
#: plinth/modules/wireguard/forms.py:32
msgid "Invalid key."
@ -10109,12 +10110,12 @@ msgid ""
"Public key of the peer. Example: "
"MConEJFIg6+DFHg2J1nn9SNLOSE9KR0ysdPgmPjibEs= ."
msgstr ""
"Clé publique du serveur. Exemple : "
"MConEJFIg6+DFHg2J1nn9SNLOSE9KR0ysdPgmPjibEs= ."
"Clé publique du pair. Exemple : MConEJFIg6+DFHg2J1nn9SNLOSE9KR0ysdPgmPjibEs= "
"."
#: plinth/modules/wireguard/forms.py:70
msgid "Endpoint of the server"
msgstr "Point dentrée du serveur"
msgstr "Point de terminaison du serveur"
#: plinth/modules/wireguard/forms.py:71
msgid ""
@ -10133,12 +10134,12 @@ msgid ""
"Provided by the server operator, a long string of characters. Example: "
"MConEJFIg6+DFHg2J1nn9SNLOSE9KR0ysdPgmPjibEs= ."
msgstr ""
"Fourni par le gestionnaire du serveur, il sagit dune longue chaîne de "
"caractères. Par exemple : MConEJFIg6+DFHg2J1nn9SNLOSE9KR0ysdPgmPjibEs= ."
"Il sagit dune longue chaîne de caractères fournie par lopérateur du "
"serveur. Par exemple : MConEJFIg6+DFHg2J1nn9SNLOSE9KR0ysdPgmPjibEs= ."
#: plinth/modules/wireguard/forms.py:82
msgid "Client IP address provided by server"
msgstr "Adresse IP client fournie par le serveur"
msgstr "Adresse IP du client fournie par le serveur"
#: plinth/modules/wireguard/forms.py:83
msgid ""
@ -10147,8 +10148,8 @@ msgid ""
"192.168.0.10."
msgstr ""
"Adresse IP attribuée à cette machine sur le réseau privé virtuel VPN une "
"fois connecté au serveur distant. Cette valeur est généralement fournie par "
"le gestionnaire du serveur. Par exemple : 192.18.0.10."
"fois connectée au serveur distant. Cette valeur est généralement fournie par "
"lopérateur du serveur. Par exemple : 192.18.0.10."
#: plinth/modules/wireguard/forms.py:89
msgid "Private key of this machine"
@ -10163,9 +10164,9 @@ msgid ""
msgstr ""
"Paramètre optionnel. De nouvelles clés privée/publique seront générées si ce "
"champ est laissé vide. La clé publique pourra ensuite être communiquée au "
"serveur. Il sagit de la méthode recommandée, même si certains gestionnaires "
"de serveur insistent pour fournir eux même cette clé. Exemple : "
"MConEJFIg6+DFHg2J1nn9SNLOSE9KR0ysdPgmPjibEs= ."
"serveur. Il sagit de la méthode recommandée, même si certains opérateurs de "
"serveur insistent pour fournir eux même cette clé. Exemple : MConEJFIg6+"
"DFHg2J1nn9SNLOSE9KR0ysdPgmPjibEs= ."
#: plinth/modules/wireguard/forms.py:98
msgid "Pre-shared key"
@ -10189,8 +10190,8 @@ msgstr "Utiliser cette connexion pour y envoyer tout le trafic sortant"
#: plinth/modules/wireguard/forms.py:107
msgid "Typically checked for a VPN service through which all traffic is sent."
msgstr ""
"À activer en général pour un service de réseau privé virtuel VPN à travers "
"lequel tout le trafic est envoyé."
"À activer lorsque le service de réseau privé virtuel VPN doit être utilisé "
"pour envoyer tout le trafic."
#: plinth/modules/wireguard/manifest.py:45
msgid "VPN client"
@ -10211,7 +10212,7 @@ msgstr "IP autorisées"
#: plinth/modules/wireguard/templates/wireguard.html:19
#: plinth/modules/wireguard/templates/wireguard.html:78
msgid "Last Connected Time"
msgstr "Date de dernière connexion"
msgstr "Dernière connexion"
#: plinth/modules/wireguard/templates/wireguard.html:38
#, python-format
@ -10245,7 +10246,7 @@ msgstr "En tant que client"
#: plinth/modules/wireguard/templates/wireguard.html:69
#, python-format
msgid "Servers that %(box_name)s will connect to:"
msgstr "Serveurs auxquels la %(box_name)s va se connecter :"
msgstr "Serveurs auxquels la %(box_name)s se connecte :"
#: plinth/modules/wireguard/templates/wireguard.html:76
#: plinth/modules/wireguard/templates/wireguard_delete_server.html:20
@ -10300,7 +10301,7 @@ msgstr "Clé publique du client :"
#: plinth/modules/wireguard/templates/wireguard_show_client.html:25
msgid "IP address to use for client:"
msgstr "Adresse IP à utiliser pour le client :"
msgstr "Adresse IP à utiliser par le client :"
#: plinth/modules/wireguard/templates/wireguard_show_client.html:29
#: plinth/modules/wireguard/templates/wireguard_show_server.html:32
@ -10309,7 +10310,7 @@ msgstr "Clé pré-partagée :"
#: plinth/modules/wireguard/templates/wireguard_show_client.html:33
msgid "Server endpoints:"
msgstr "Serveurs distants :"
msgstr "Points de terminaisons du serveur :"
#: plinth/modules/wireguard/templates/wireguard_show_client.html:41
#: plinth/modules/wireguard/templates/wireguard_show_server.html:28
@ -10329,7 +10330,7 @@ msgstr "Données reçues :"
#: plinth/modules/wireguard/templates/wireguard_show_client.html:61
#: plinth/modules/wireguard/templates/wireguard_show_server.html:60
msgid "Latest handshake:"
msgstr "Dernier « handshake » :"
msgstr "Dernier établissement dune liaison (« handshake ») :"
#: plinth/modules/wireguard/templates/wireguard_show_server.html:14
#, python-format

View File

@ -30,9 +30,10 @@ class FirstBootMiddleware(MiddlewareMixin):
if user_requests_login:
return
# Don't interfere with help pages
# Don't interfere with help or status pages
user_requests_help = request.path.startswith(reverse('help:index'))
if user_requests_help:
user_requests_status = request.path.startswith(reverse('status'))
if user_requests_help or user_requests_status:
return
# Don't interfere with first setup progress page. When first setup is

View File

@ -18,6 +18,7 @@ system_urlpatterns = [
urlpatterns = [
re_path(r'^$', views.index, name='index'),
re_path(r'^status/$', views.status, name='status'),
re_path(r'^language-selection/$',
public(views.LanguageSelectionView.as_view()),
name='language-selection'),

View File

@ -178,6 +178,16 @@ def index(request):
})
@public
def status(request):
"""Return the status of service in JSON format."""
status = {
'is_available': True,
'is_first_setup_running': setup.is_first_setup_running
}
return JsonResponse(status)
def _pick_menu_items(menu_items, selected_tags):
"""Return a sorted list of menu items filtered by tags."""