*: Drop use of managed_services, rely on Daemon component

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2021-11-16 16:20:45 -08:00 committed by James Valleroy
parent ba4b58de78
commit 781d8fa18b
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
39 changed files with 123 additions and 161 deletions

View File

@ -14,7 +14,7 @@ import sys
from shutil import move
from plinth import action_utils
from plinth.modules import shadowsocks
from plinth.modules.shadowsocks import ShadowsocksApp
SHADOWSOCKS_CONFIG_SYMLINK = '/etc/shadowsocks-libev/freedombox.json'
SHADOWSOCKS_CONFIG_ACTUAL = \
@ -76,8 +76,8 @@ def subcommand_setup(_):
if not wrong_state_dir.is_symlink() and wrong_state_dir.is_dir():
wrong_state_dir.rmdir()
if action_utils.service_is_enabled(shadowsocks.managed_services[0]):
action_utils.service_restart(shadowsocks.managed_services[0])
if action_utils.service_is_enabled(ShadowsocksApp.DAEMON):
action_utils.service_restart(ShadowsocksApp.DAEMON)
def subcommand_get_config(_):
@ -110,8 +110,8 @@ def subcommand_merge_config(_):
# Don't try_restart because initial configuration may not be valid so
# shadowsocks will not be running even when enabled.
if action_utils.service_is_enabled(shadowsocks.managed_services[0]):
action_utils.service_restart(shadowsocks.managed_services[0])
if action_utils.service_is_enabled(ShadowsocksApp.DAEMON):
action_utils.service_restart(ShadowsocksApp.DAEMON)
def main():

View File

@ -9,7 +9,7 @@ from django.utils.translation import gettext_lazy as _
from plinth import actions
from plinth import app as app_module
from plinth import cfg
from plinth.daemon import Daemon
from plinth.daemon import Daemon, RelatedDaemon
from plinth.modules.firewall.components import Firewall
from plinth.modules.letsencrypt.components import LetsEncrypt
from plinth.package import Packages
@ -19,8 +19,6 @@ version = 9
is_essential = True
managed_services = ['apache2', 'uwsgi']
app = None
@ -55,10 +53,13 @@ class ApacheApp(app_module.App):
self.add(freedombox_ports)
letsencrypt = LetsEncrypt('letsencrypt-apache', domains='*',
daemons=[managed_services[0]])
daemons=['apache2'])
self.add(letsencrypt)
daemon = Daemon('daemon-apache', managed_services[0])
daemon = Daemon('daemon-apache', 'apache2')
self.add(daemon)
daemon = RelatedDaemon('related-daemon-apache', 'uwsgi')
self.add(daemon)

View File

@ -27,8 +27,6 @@ is_essential = True
depends = ['names']
managed_services = ['avahi-daemon']
_description = [
format_lazy(
_('Service discovery allows other devices on the network to '
@ -74,7 +72,7 @@ class AvahiApp(app_module.App):
is_external=False)
self.add(firewall)
daemon = Daemon('daemon-avahi', managed_services[0])
daemon = Daemon('daemon-avahi', 'avahi-daemon')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-avahi',

View File

@ -23,8 +23,6 @@ from . import manifest
version = 2
managed_services = ['named']
_description = [
_('BIND enables you to publish your Domain Name System (DNS) information '
'on the Internet, and to resolve DNS queries for your user devices on '
@ -93,10 +91,8 @@ class BindApp(app_module.App):
self.add(firewall)
daemon = Daemon(
'daemon-bind', managed_services[0], listen_ports=[(53, 'tcp6'),
(53, 'udp6'),
(53, 'tcp4'),
(53, 'udp4')])
'daemon-bind', 'named', listen_ports=[(53, 'tcp6'), (53, 'udp6'),
(53, 'tcp4'), (53, 'udp4')])
self.add(daemon)
backup_restore = BackupRestore('backup-restore-bind',

View File

@ -23,8 +23,6 @@ from . import manifest
version = 1
managed_services = ['calibre-server-freedombox']
_description = [
format_lazy(
_('calibre server provides online access to your e-book collection. '
@ -50,6 +48,8 @@ class CalibreApp(app_module.App):
app_id = 'calibre'
DAEMON = 'calibre-server-freedombox'
def __init__(self):
"""Create components for the app."""
super().__init__()
@ -88,7 +88,7 @@ class CalibreApp(app_module.App):
urls=['https://{host}/calibre'])
self.add(webserver)
daemon = Daemon('daemon-calibre', managed_services[0],
daemon = Daemon('daemon-calibre', self.DAEMON,
listen_ports=[(8844, 'tcp4')])
self.add(daemon)
@ -123,10 +123,10 @@ def list_libraries():
def create_library(name):
"""Create an empty library."""
actions.superuser_run('calibre', ['create-library', name])
actions.superuser_run('service', ['try-restart', managed_services[0]])
actions.superuser_run('service', ['try-restart', CalibreApp.DAEMON])
def delete_library(name):
"""Delete a library and its contents."""
actions.superuser_run('calibre', ['delete-library', name])
actions.superuser_run('service', ['try-restart', managed_services[0]])
actions.superuser_run('service', ['try-restart', CalibreApp.DAEMON])

View File

@ -24,8 +24,6 @@ version = 1
is_essential = True
managed_services = ['cockpit.socket']
_description = [
format_lazy(
_('Cockpit is a server manager that makes it easy to administer '
@ -56,6 +54,8 @@ class CockpitApp(app_module.App):
app_id = 'cockpit'
DAEMON = 'cockpit.socket'
def __init__(self):
"""Create components for the app."""
super().__init__()
@ -92,7 +92,7 @@ class CockpitApp(app_module.App):
urls=['https://{host}/_cockpit/'])
self.add(webserver)
daemon = Daemon('daemon-cockpit', managed_services[0])
daemon = Daemon('daemon-cockpit', self.DAEMON)
self.add(daemon)
backup_restore = BackupRestore('backup-restore-cockpit',
@ -123,7 +123,7 @@ def on_domain_added(sender, domain_type, name, description='', services=None,
if name not in utils.get_domains():
actions.superuser_run('cockpit', ['add-domain', name])
actions.superuser_run('service',
['try-restart', managed_services[0]])
['try-restart', CockpitApp.DAEMON])
def on_domain_removed(sender, domain_type, name, **kwargs):
@ -133,4 +133,4 @@ def on_domain_removed(sender, domain_type, name, **kwargs):
if name in utils.get_domains():
actions.superuser_run('cockpit', ['remove-domain', name])
actions.superuser_run('service',
['try-restart', managed_services[0]])
['try-restart', CockpitApp.DAEMON])

View File

@ -12,6 +12,7 @@ from django.utils.translation import gettext_lazy as _
from plinth import actions
from plinth import app as app_module
from plinth import frontpage, menu
from plinth.daemon import RelatedDaemon
from plinth.modules.apache import (get_users_with_website, user_of_uws_url,
uws_url_of_user)
from plinth.modules.names.components import DomainType
@ -22,8 +23,6 @@ version = 3
is_essential = True
managed_services = ['systemd-journald', 'rsyslog']
_description = [
_('Here you can set some general configuration options '
'like hostname, domain name, webserver home page etc.')
@ -66,6 +65,12 @@ class ConfigApp(app_module.App):
packages = Packages('packages-config', ['zram-tools'])
self.add(packages)
daemon1 = RelatedDaemon('related-daemon-config1', 'systemd-journald')
self.add(daemon1)
daemon2 = RelatedDaemon('related-daemon-config2', 'rsyslog')
self.add(daemon2)
domain_type = DomainType('domain-type-static', _('Domain Name'),
'config:index', can_have_certificate=True)
self.add(domain_type)

View File

@ -27,8 +27,6 @@ from . import manifest
version = 1
managed_services = ['coturn']
managed_paths = [pathlib.Path('/etc/coturn/')]
_description = [
@ -76,8 +74,8 @@ class CoturnApp(app_module.App):
self.add(firewall)
letsencrypt = LetsEncrypt(
'letsencrypt-coturn', domains=get_domains,
daemons=managed_services, should_copy_certificates=True,
'letsencrypt-coturn', domains=get_domains, daemons=['coturn'],
should_copy_certificates=True,
private_key_path='/etc/coturn/certs/pkey.pem',
certificate_path='/etc/coturn/certs/cert.pem',
user_owner='turnserver', group_owner='turnserver',
@ -85,13 +83,22 @@ class CoturnApp(app_module.App):
self.add(letsencrypt)
daemon = Daemon(
'daemon-coturn', managed_services[0],
listen_ports=[(3478, 'udp4'), (3478, 'udp6'), (3478, 'tcp4'),
(3478, 'tcp6'), (3479, 'udp4'), (3479, 'udp6'),
(3479, 'tcp4'), (3479, 'tcp6'), (5349, 'udp4'),
(5349, 'udp6'), (5349, 'tcp4'), (5349, 'tcp6'),
(5350, 'udp4'), (5350, 'udp6'), (5350, 'tcp4'),
(5350, 'tcp6')])
'daemon-coturn', 'coturn', listen_ports=[(3478, 'udp4'),
(3478, 'udp6'),
(3478, 'tcp4'),
(3478, 'tcp6'),
(3479, 'udp4'),
(3479, 'udp6'),
(3479, 'tcp4'),
(3479, 'tcp6'),
(5349, 'udp4'),
(5349, 'udp6'),
(5349, 'tcp4'),
(5349, 'tcp6'),
(5350, 'udp4'),
(5350, 'udp6'),
(5350, 'tcp4'),
(5350, 'tcp6')])
self.add(daemon)
users_and_groups = UsersAndGroups('users-and-groups-coturn',

View File

@ -18,8 +18,6 @@ version = 2
is_essential = True
managed_services = ['systemd-timesyncd']
_description = [
_('Network time server is a program that maintains the system time '
'in synchronization with servers on the Internet.')
@ -76,7 +74,7 @@ class DateTimeApp(app_module.App):
self.add(menu_item)
if self._is_time_managed():
daemon = Daemon('daemon-datetime', managed_services[0])
daemon = Daemon('daemon-datetime', 'systemd-timesyncd')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-datetime',

View File

@ -20,8 +20,6 @@ from . import manifest
version = 6
managed_services = ['deluged', 'deluge-web']
_description = [
_('Deluge is a BitTorrent client that features a Web UI.'),
_('The default password is \'deluge\', but you should log in and '
@ -79,11 +77,11 @@ class DelugeApp(app_module.App):
urls=['https://{host}/deluge'])
self.add(webserver)
daemon = Daemon('daemon-deluged', managed_services[0],
daemon = Daemon('daemon-deluged', 'deluged',
listen_ports=[(58846, 'tcp4')])
self.add(daemon)
daemon_web = Daemon('daemon-deluge-web', managed_services[1],
daemon_web = Daemon('daemon-deluge-web', 'deluge-web',
listen_ports=[(8112, 'tcp4')])
self.add(daemon_web)

View File

@ -38,8 +38,6 @@ def get_configured_domain_name():
version = 1
managed_services = ['diaspora']
_description = [
_('diaspora* is a decentralized social network where you can store '
'and control your own data.'),
@ -92,7 +90,7 @@ class DiasporaApp(app_module.App):
webserver = Webserver('webserver-diaspora', 'diaspora-plinth')
self.add(webserver)
daemon = Daemon('daemon-diaspora', managed_services[0])
daemon = Daemon('daemon-diaspora', 'diaspora')
self.add(daemon)
def diagnose(self):

View File

@ -30,8 +30,6 @@ from . import manifest
version = 4
managed_services = ['ejabberd']
managed_paths = [pathlib.Path('/etc/ejabberd/')]
_description = [
@ -110,9 +108,12 @@ class EjabberdApp(app_module.App):
self.add(letsencrypt)
daemon = Daemon(
'daemon-ejabberd', managed_services[0],
listen_ports=[(5222, 'tcp4'), (5222, 'tcp6'), (5269, 'tcp4'),
(5269, 'tcp6'), (5443, 'tcp4'), (5443, 'tcp6')])
'daemon-ejabberd', 'ejabberd', listen_ports=[(5222, 'tcp4'),
(5222, 'tcp6'),
(5269, 'tcp4'),
(5269, 'tcp6'),
(5443, 'tcp4'),
(5443, 'tcp6')])
self.add(daemon)
users_and_groups = UsersAndGroups('users-and-groups-ejabberd',

View File

@ -35,8 +35,6 @@ port_info = {
'dovecot': ('imaps', 993, 'pop3s', 995),
}
managed_services = ['postfix', 'dovecot', 'rspamd']
_description = [
_('<a href="/plinth/apps/roundcube/">Roundcube app</a> provides web '
'interface for users to access email.'),
@ -105,7 +103,7 @@ class EmailServerApp(plinth.app.App):
self.add(menu_item)
def _add_daemons(self):
for srvname in managed_services:
for srvname in ['postfix', 'dovecot', 'rspamd']:
# Construct `listen_ports` parameter for the daemon
mixed = port_info.get(srvname, ())
port_numbers = [v for v in mixed if isinstance(v, int)]
@ -168,8 +166,9 @@ def setup(helper, old_version=None):
helper.call('post', audit.rcube.repair)
# Reload
for srvname in managed_services:
actions.superuser_run('service', ['reload', srvname])
actions.superuser_run('service', ['reload', 'postfix'])
actions.superuser_run('service', ['reload', 'dovecot'])
actions.superuser_run('service', ['reload', 'rspamd'])
# Expose to public internet
helper.call('post', app.enable)

View File

@ -25,8 +25,6 @@ version = 2
is_essential = True
managed_services = ['firewalld']
_description = [
format_lazy(
_('Firewall is a security system that controls the incoming and '
@ -75,7 +73,7 @@ class FirewallApp(app_module.App):
packages = Packages('packages-firewall', ['firewalld', 'nftables'])
self.add(packages)
daemon = Daemon('daemon-firewall', managed_services[0])
daemon = Daemon('daemon-firewall', 'firewalld')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-firewall',

View File

@ -20,10 +20,6 @@ from . import manifest
version = 1
service_name = 'i2p'
managed_services = [service_name]
_description = [
_('The Invisible Internet Project is an anonymous network layer intended '
'to protect communication from censorship and surveillance. I2P '
@ -92,8 +88,7 @@ class I2PApp(app_module.App):
urls=['https://{host}/i2p/'])
self.add(webserver)
daemon = Daemon('daemon-i2p', managed_services[0],
listen_ports=[(7657, 'tcp6')])
daemon = Daemon('daemon-i2p', 'i2p', listen_ports=[(7657, 'tcp6')])
self.add(daemon)
users_and_groups = UsersAndGroups('users-and-groups-i2p',

View File

@ -19,8 +19,6 @@ from . import manifest
version = 3
managed_services = ['infinoted']
_description = [
_('infinoted is a server for Gobby, a collaborative text editor.'),
format_lazy(
@ -70,7 +68,7 @@ class InfinotedApp(app_module.App):
ports=['infinoted-plinth'], is_external=True)
self.add(firewall)
daemon = Daemon('daemon-infinoted', managed_services[0],
daemon = Daemon('daemon-infinoted', 'infinoted',
listen_ports=[(6523, 'tcp4'), (6523, 'tcp6')])
self.add(daemon)

View File

@ -28,8 +28,6 @@ from . import manifest
version = 7
managed_services = ['matrix-synapse']
managed_paths = [pathlib.Path('/etc/matrix-synapse/')]
_description = [
@ -107,14 +105,14 @@ class MatrixSynapseApp(app_module.App):
letsencrypt = LetsEncrypt(
'letsencrypt-matrixsynapse', domains=get_domains,
daemons=[managed_services[0]], should_copy_certificates=True,
daemons=['matrix-synapse'], should_copy_certificates=True,
private_key_path='/etc/matrix-synapse/homeserver.tls.key',
certificate_path='/etc/matrix-synapse/homeserver.tls.crt',
user_owner='matrix-synapse', group_owner='nogroup',
managing_app='matrixsynapse')
self.add(letsencrypt)
daemon = Daemon('daemon-matrixsynapse', managed_services[0],
daemon = Daemon('daemon-matrixsynapse', 'matrix-synapse',
listen_ports=[(8008, 'tcp4'), (8448, 'tcp4')])
self.add(daemon)

View File

@ -21,8 +21,6 @@ from . import manifest
version = 10
managed_services = ['mediawiki-jobrunner']
_description = [
_('MediaWiki is the wiki engine that powers Wikipedia and other WikiMedia '
'projects. A wiki engine is a program for creating a collaboratively '
@ -89,7 +87,7 @@ class MediaWikiApp(app_module.App):
'mediawiki-freedombox')
self.add(webserver)
daemon = Daemon('daemon-mediawiki', managed_services[0])
daemon = Daemon('daemon-mediawiki', 'mediawiki-jobrunner')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-mediawiki',

View File

@ -20,8 +20,6 @@ from . import manifest
version = 2
managed_services = ['minetest-server']
_mods = [
'minetest-mod-character-creator', 'minetest-mod-craftguide',
'minetest-mod-infinite-chest', 'minetest-mod-lucky-block',
@ -85,7 +83,7 @@ class MinetestApp(app_module.App):
ports=['minetest-plinth'], is_external=True)
self.add(firewall)
daemon = Daemon('daemon-minetest', managed_services[0],
daemon = Daemon('daemon-minetest', 'minetest-server',
listen_ports=[(30000, 'udp4')])
self.add(daemon)

View File

@ -18,8 +18,6 @@ from . import manifest
version = 2
managed_services = ['minidlna']
_description = [
_('MiniDLNA is a simple media server software, with the aim of being '
'fully compliant with DLNA/UPnP-AV clients. '
@ -81,7 +79,7 @@ class MiniDLNAApp(app_module.App):
urls=['http://localhost:8200/'])
self.add(webserver)
daemon = Daemon('daemon-minidlna', managed_services[0])
daemon = Daemon('daemon-minidlna', 'minidlna')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-minidlna',

View File

@ -21,8 +21,6 @@ from . import manifest
version = 2
managed_services = ['mldonkey-server']
_description = [
_('MLDonkey is a peer-to-peer file sharing application used to exchange '
'large files. It can participate in multiple peer-to-peer networks '
@ -46,6 +44,8 @@ class MLDonkeyApp(app_module.App):
app_id = 'mldonkey'
DAEMON = 'mldonkey-server'
def __init__(self):
"""Create components for the app."""
super().__init__()
@ -83,7 +83,7 @@ class MLDonkeyApp(app_module.App):
urls=['https://{host}/mldonkey/'])
self.add(webserver)
daemon = Daemon('daemon-mldonkey', managed_services[0],
daemon = Daemon('daemon-mldonkey', self.DAEMON,
listen_ports=[(4080, 'tcp4')])
self.add(daemon)
@ -104,4 +104,4 @@ def setup(helper, old_version=None):
if not old_version:
helper.call('post', app.enable)
add_user_to_share_group(_SYSTEM_USER, managed_services[0])
add_user_to_share_group(_SYSTEM_USER, MLDonkeyApp.DAEMON)

View File

@ -24,8 +24,6 @@ from . import manifest
version = 2
managed_services = ['mumble-server']
managed_paths = [pathlib.Path('/var/lib/mumble-server')]
_description = [
@ -76,7 +74,7 @@ class MumbleApp(app_module.App):
letsencrypt = LetsEncrypt(
'letsencrypt-mumble', domains=get_domains,
daemons=managed_services, should_copy_certificates=True,
daemons=['mumble-server'], should_copy_certificates=True,
private_key_path='/var/lib/mumble-server/privkey.pem',
certificate_path='/var/lib/mumble-server/fullchain.pem',
user_owner='mumble-server', group_owner='mumble-server',
@ -84,9 +82,10 @@ class MumbleApp(app_module.App):
self.add(letsencrypt)
daemon = Daemon(
'daemon-mumble', managed_services[0],
listen_ports=[(64738, 'tcp4'), (64738, 'tcp6'), (64738, 'udp4'),
(64738, 'udp6')])
'daemon-mumble', 'mumble-server', listen_ports=[(64738, 'tcp4'),
(64738, 'tcp6'),
(64738, 'udp4'),
(64738, 'udp6')])
self.add(daemon)
users_and_groups = UsersAndGroups('users-and-groups-mumble',

View File

@ -22,8 +22,6 @@ from . import manifest
version = 4
managed_services = ['openvpn-server@freedombox']
_description = [
format_lazy(
_('Virtual Private Network (VPN) is a technique for securely '
@ -87,7 +85,7 @@ class OpenVPNApp(app_module.App):
is_external=True)
self.add(firewall)
daemon = Daemon('daemon-openvpn', managed_services[0],
daemon = Daemon('daemon-openvpn', 'openvpn-server@freedombox',
listen_ports=[(1194, 'udp4'), (1194, 'udp6')])
self.add(daemon)

View File

@ -20,8 +20,6 @@ version = 2
depends = ['names']
managed_services = ['pagekite']
_description = [
format_lazy(
_('PageKite is a system for exposing {box_name} services when '
@ -56,6 +54,8 @@ class PagekiteApp(app_module.App):
app_id = 'pagekite'
DAEMON = 'pagekite'
def __init__(self):
"""Create components for the app."""
super().__init__()
@ -80,7 +80,7 @@ class PagekiteApp(app_module.App):
'pagekite:index', can_have_certificate=True)
self.add(domain_type)
daemon = Daemon('daemon-pagekite', managed_services[0])
daemon = Daemon('daemon-pagekite', self.DAEMON)
self.add(daemon)
backup_restore = BackupRestore('backup-restore-pagekite',
@ -112,4 +112,4 @@ def setup(helper, old_version=None):
helper.call('post', app.enable)
if old_version == 1:
actions.superuser_run('service', ['try-restart', managed_services[0]])
actions.superuser_run('service', ['try-restart', PagekiteApp.DAEMON])

View File

@ -17,10 +17,6 @@ version = 1
name = _('Performance')
managed_services = [
'pmcd.service', 'pmie.service', 'pmlogger.service', 'pmproxy.service'
]
_description = [
_('Performance app allows you to collect, store and view information '
'about utilization of the hardware. This can give you basic insights '
@ -62,19 +58,19 @@ class PerformanceApp(app_module.App):
**manifest.backup)
self.add(backup_restore)
daemon_0 = Daemon('daemon-performance-0', managed_services[0],
daemon_0 = Daemon('daemon-performance-0', 'pmcd.service',
listen_ports=None)
self.add(daemon_0)
daemon_1 = Daemon('daemon-performance-1', managed_services[1],
daemon_1 = Daemon('daemon-performance-1', 'pmie.service',
listen_ports=None)
self.add(daemon_1)
daemon_2 = Daemon('daemon-performance-2', managed_services[2],
daemon_2 = Daemon('daemon-performance-2', 'pmlogger.service',
listen_ports=None)
self.add(daemon_2)
daemon_3 = Daemon('daemon-performance-3', managed_services[3],
daemon_3 = Daemon('daemon-performance-3', 'pmproxy.service',
listen_ports=None)
self.add(daemon_3)

View File

@ -23,8 +23,6 @@ version = 1
is_essential = False
managed_services = ['privoxy']
_description = [
_('Privoxy is a non-caching web proxy with advanced filtering '
'capabilities for enhancing privacy, modifying web page data and '
@ -78,7 +76,7 @@ class PrivoxyApp(app_module.App):
is_external=False)
self.add(firewall)
daemon = Daemon('daemon-privoxy', managed_services[0],
daemon = Daemon('daemon-privoxy', 'privoxy',
listen_ports=[(8118, 'tcp4'), (8118, 'tcp6')])
self.add(daemon)

View File

@ -24,8 +24,6 @@ from . import manifest
version = 1
managed_services = ['quasselcore']
managed_paths = [pathlib.Path('/var/lib/quassel/')]
_description = [
@ -85,14 +83,14 @@ class QuasselApp(app_module.App):
letsencrypt = LetsEncrypt(
'letsencrypt-quassel', domains=get_domains,
daemons=managed_services, should_copy_certificates=True,
daemons=['quasselcore'], should_copy_certificates=True,
private_key_path='/var/lib/quassel/quasselCert.pem',
certificate_path='/var/lib/quassel/quasselCert.pem',
user_owner='quasselcore', group_owner='quassel',
managing_app='quassel')
self.add(letsencrypt)
daemon = Daemon('daemon-quassel', managed_services[0],
daemon = Daemon('daemon-quassel', 'quasselcore',
listen_ports=[(4242, 'tcp4'), (4242, 'tcp6')])
self.add(daemon)

View File

@ -25,8 +25,6 @@ from . import manifest
version = 2
managed_services = ['smbd', 'nmbd']
_description = [
_('Samba allows to share files and folders between FreedomBox and '
'other computers in your local network.'),
@ -85,13 +83,12 @@ class SambaApp(app_module.App):
self.add(firewall)
daemon = Daemon(
'daemon-samba', managed_services[0], listen_ports=[(139, 'tcp4'),
(139, 'tcp6'),
(445, 'tcp4'),
(445, 'tcp6')])
'daemon-samba', 'smbd', listen_ports=[(139, 'tcp4'), (139, 'tcp6'),
(445, 'tcp4'),
(445, 'tcp6')])
self.add(daemon)
daemon_nmbd = Daemon('daemon-samba-nmbd', managed_services[1],
daemon_nmbd = Daemon('daemon-samba-nmbd', 'nmbd',
listen_ports=[(137, 'udp4'), (138, 'udp4')])
self.add(daemon_nmbd)

View File

@ -12,7 +12,7 @@ from django.utils.translation import gettext_lazy as _
from plinth import actions
from plinth import app as app_module
from plinth import menu, module_loader
from plinth.daemon import Daemon
from plinth.daemon import Daemon, RelatedDaemon
from plinth.modules.backups.components import BackupRestore
from plinth.package import Packages
@ -22,8 +22,6 @@ version = 7
is_essential = True
managed_services = ['fail2ban']
ACCESS_CONF_FILE = '/etc/security/access.d/50freedombox.conf'
ACCESS_CONF_FILE_OLD = '/etc/security/access.conf'
ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx plinth (admin) (sudo):ALL'
@ -54,6 +52,9 @@ class SecurityApp(app_module.App):
packages = Packages('packages-security', ['fail2ban', 'debsecan'])
self.add(packages)
daemon = RelatedDaemon('related-daemon-fail2ban', 'fail2ban')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-security',
**manifest.backup)
self.add(backup_restore)

View File

@ -19,8 +19,6 @@ from . import manifest
version = 3
managed_services = ['shadowsocks-libev-local@freedombox']
_description = [
_('Shadowsocks is a lightweight and secure SOCKS5 proxy, designed to '
'protect your Internet traffic. It can be used to bypass Internet '
@ -43,6 +41,8 @@ class ShadowsocksApp(app_module.App):
app_id = 'shadowsocks'
DAEMON = 'shadowsocks-libev-local@freedombox'
def __init__(self):
"""Create components for the app."""
super().__init__()
@ -76,7 +76,7 @@ class ShadowsocksApp(app_module.App):
is_external=False)
self.add(firewall)
daemon = Daemon('daemon-shadowsocks', managed_services[0],
daemon = Daemon('daemon-shadowsocks', self.DAEMON,
listen_ports=[(1080, 'tcp4'), (1080, 'tcp6')])
self.add(daemon)

View File

@ -23,8 +23,6 @@ version = 1
is_essential = True
managed_services = ['ssh']
_description = [
_('A Secure Shell server uses the secure shell protocol to accept '
'connections from remote computers. An authorized remote computer '
@ -61,7 +59,7 @@ class SSHApp(app_module.App):
is_external=True)
self.add(firewall)
daemon = Daemon('daemon-ssh', managed_services[0])
daemon = Daemon('daemon-ssh', 'ssh')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-ssh', **manifest.backup)

View File

@ -21,8 +21,6 @@ from . import manifest
version = 5
managed_services = ['syncthing@syncthing']
_description = [
_('Syncthing is an application to synchronize files across multiple '
'devices, e.g. your desktop computer and mobile phone. Creation, '
@ -49,6 +47,8 @@ class SyncthingApp(app_module.App):
app_id = 'syncthing'
DAEMON = 'syncthing@syncthing'
def __init__(self):
"""Create components for the app."""
super().__init__()
@ -94,7 +94,7 @@ class SyncthingApp(app_module.App):
urls=['https://{host}/syncthing/'])
self.add(webserver)
daemon = Daemon('daemon-syncthing', managed_services[0])
daemon = Daemon('daemon-syncthing', self.DAEMON)
self.add(daemon)
users_and_groups = UsersAndGroups('users-and-groups-syncthing',
@ -110,7 +110,7 @@ def setup(helper, old_version=None):
"""Install and configure the module."""
app.setup(old_version)
helper.call('post', actions.superuser_run, 'syncthing', ['setup'])
add_user_to_share_group(SYSTEM_USER, managed_services[0])
add_user_to_share_group(SYSTEM_USER, SyncthingApp.DAEMON)
if not old_version:
helper.call('post', app.enable)

View File

@ -24,8 +24,6 @@ from .errors import TahoeConfigurationError
version = 1
managed_services = ['tahoe-lafs']
_description = [
_('Tahoe-LAFS is a decentralized secure file storage system. '
'It uses provider independent security to store files over a '
@ -88,7 +86,7 @@ class TahoeApp(app_module.App):
webserver = Webserver('webserver-tahoe', 'tahoe-plinth')
self.add(webserver)
daemon = Daemon('daemon-tahoe', managed_services[0])
daemon = Daemon('daemon-tahoe', 'tahoe-lafs')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-tahoe',

View File

@ -26,8 +26,6 @@ version = 5
depends = ['names']
managed_services = ['tor@plinth']
_description = [
_('Tor is an anonymous communication system. You can learn more '
'about it from the <a href="https://www.torproject.org/">Tor '
@ -81,7 +79,7 @@ class TorApp(app_module.App):
self.add(firewall)
daemon = Daemon(
'daemon-tor', managed_services[0], strict_check=True,
'daemon-tor', 'tor@plinth', strict_check=True,
listen_ports=[(9050, 'tcp4'), (9050, 'tcp6'), (9040, 'tcp4'),
(9040, 'tcp6'), (9053, 'udp4'), (9053, 'udp6')])
self.add(daemon)

View File

@ -22,8 +22,6 @@ from . import manifest
version = 4
managed_services = ['transmission-daemon']
_description = [
_('Transmission is a BitTorrent client with a web interface.'),
_('BitTorrent is a peer-to-peer file sharing protocol. '
@ -41,6 +39,8 @@ class TransmissionApp(app_module.App):
app_id = 'transmission'
DAEMON = 'transmission-daemon'
def __init__(self):
"""Create components for the app."""
super().__init__()
@ -83,7 +83,7 @@ class TransmissionApp(app_module.App):
self.add(webserver)
daemon = Daemon(
'daemon-transmission', managed_services[0], listen_ports=[
'daemon-transmission', self.DAEMON, listen_ports=[
(9091, 'tcp4'),
(51413, 'tcp4'),
(51413, 'tcp6'),
@ -115,5 +115,5 @@ def setup(helper, old_version=None):
helper.call('post', actions.superuser_run, 'transmission',
['merge-configuration'],
input=json.dumps(new_configuration).encode())
add_user_to_share_group(SYSTEM_USER, managed_services[0])
add_user_to_share_group(SYSTEM_USER, TransmissionApp.DAEMON)
helper.call('post', app.enable)

View File

@ -21,8 +21,6 @@ from . import manifest
version = 3
managed_services = ['tt-rss']
_description = [
_('Tiny Tiny RSS is a news feed (RSS/Atom) reader and aggregator, '
'designed to allow reading news from any location, while feeling as '
@ -85,7 +83,7 @@ class TTRSSApp(app_module.App):
urls=['https://{host}/tt-rss'])
self.add(webserver)
daemon = Daemon('daemon-ttrss', managed_services[0])
daemon = Daemon('daemon-ttrss', 'tt-rss')
self.add(daemon)
users_and_groups = UsersAndGroups('users-and-groups-ttrss',

View File

@ -16,6 +16,7 @@ import plinth
from plinth import actions
from plinth import app as app_module
from plinth import cfg, glib, kvstore, menu
from plinth.daemon import RelatedDaemon
from plinth.modules.backups.components import BackupRestore
from plinth.package import Packages
@ -25,8 +26,6 @@ version = 9
is_essential = True
managed_services = ['freedombox-dist-upgrade']
first_boot_steps = [
{
'id': 'backports_wizard',
@ -87,6 +86,10 @@ class UpgradesApp(app_module.App):
['unattended-upgrades', 'needrestart'])
self.add(packages)
daemon = RelatedDaemon('related-daemon-upgrades',
'freedombox-dist-upgrade')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-upgrades',
**manifest.backup)
self.add(backup_restore)

View File

@ -21,8 +21,6 @@ version = 3
is_essential = True
managed_services = ['slapd']
first_boot_steps = [
{
'id': 'users_firstboot',
@ -73,8 +71,8 @@ class UsersApp(app_module.App):
])
self.add(packages)
daemon = Daemon('daemon-users', managed_services[0],
listen_ports=[(389, 'tcp4'), (389, 'tcp6')])
daemon = Daemon('daemon-users', 'slapd', listen_ports=[(389, 'tcp4'),
(389, 'tcp6')])
self.add(daemon)
# Add the admin group

View File

@ -21,8 +21,6 @@ PUBLIC_ACCESS_FILE = '/etc/wordpress/is_public'
version = 1
managed_services = ['wordpress-freedombox.timer']
_description = [
_('WordPress is a popular way to create and manage websites and blogs. '
'Content can be managed using a visual interface. Layout and '
@ -102,7 +100,7 @@ class WordPressApp(app_module.App):
urls=['https://{host}/wordpress/'])
self.add(webserver)
daemon = Daemon('daemon-wordpress', managed_services[0])
daemon = Daemon('daemon-wordpress', 'wordpress-freedombox.timer')
self.add(daemon)
backup_restore = WordPressBackupRestore('backup-restore-wordpress',