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

View File

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

View File

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

View File

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

View File

@ -23,8 +23,6 @@ from . import manifest
version = 1 version = 1
managed_services = ['calibre-server-freedombox']
_description = [ _description = [
format_lazy( format_lazy(
_('calibre server provides online access to your e-book collection. ' _('calibre server provides online access to your e-book collection. '
@ -50,6 +48,8 @@ class CalibreApp(app_module.App):
app_id = 'calibre' app_id = 'calibre'
DAEMON = 'calibre-server-freedombox'
def __init__(self): def __init__(self):
"""Create components for the app.""" """Create components for the app."""
super().__init__() super().__init__()
@ -88,7 +88,7 @@ class CalibreApp(app_module.App):
urls=['https://{host}/calibre']) urls=['https://{host}/calibre'])
self.add(webserver) self.add(webserver)
daemon = Daemon('daemon-calibre', managed_services[0], daemon = Daemon('daemon-calibre', self.DAEMON,
listen_ports=[(8844, 'tcp4')]) listen_ports=[(8844, 'tcp4')])
self.add(daemon) self.add(daemon)
@ -123,10 +123,10 @@ def list_libraries():
def create_library(name): def create_library(name):
"""Create an empty library.""" """Create an empty library."""
actions.superuser_run('calibre', ['create-library', name]) 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): def delete_library(name):
"""Delete a library and its contents.""" """Delete a library and its contents."""
actions.superuser_run('calibre', ['delete-library', name]) 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 is_essential = True
managed_services = ['cockpit.socket']
_description = [ _description = [
format_lazy( format_lazy(
_('Cockpit is a server manager that makes it easy to administer ' _('Cockpit is a server manager that makes it easy to administer '
@ -56,6 +54,8 @@ class CockpitApp(app_module.App):
app_id = 'cockpit' app_id = 'cockpit'
DAEMON = 'cockpit.socket'
def __init__(self): def __init__(self):
"""Create components for the app.""" """Create components for the app."""
super().__init__() super().__init__()
@ -92,7 +92,7 @@ class CockpitApp(app_module.App):
urls=['https://{host}/_cockpit/']) urls=['https://{host}/_cockpit/'])
self.add(webserver) self.add(webserver)
daemon = Daemon('daemon-cockpit', managed_services[0]) daemon = Daemon('daemon-cockpit', self.DAEMON)
self.add(daemon) self.add(daemon)
backup_restore = BackupRestore('backup-restore-cockpit', 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(): if name not in utils.get_domains():
actions.superuser_run('cockpit', ['add-domain', name]) actions.superuser_run('cockpit', ['add-domain', name])
actions.superuser_run('service', actions.superuser_run('service',
['try-restart', managed_services[0]]) ['try-restart', CockpitApp.DAEMON])
def on_domain_removed(sender, domain_type, name, **kwargs): 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(): if name in utils.get_domains():
actions.superuser_run('cockpit', ['remove-domain', name]) actions.superuser_run('cockpit', ['remove-domain', name])
actions.superuser_run('service', 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 actions
from plinth import app as app_module from plinth import app as app_module
from plinth import frontpage, menu from plinth import frontpage, menu
from plinth.daemon import RelatedDaemon
from plinth.modules.apache import (get_users_with_website, user_of_uws_url, from plinth.modules.apache import (get_users_with_website, user_of_uws_url,
uws_url_of_user) uws_url_of_user)
from plinth.modules.names.components import DomainType from plinth.modules.names.components import DomainType
@ -22,8 +23,6 @@ version = 3
is_essential = True is_essential = True
managed_services = ['systemd-journald', 'rsyslog']
_description = [ _description = [
_('Here you can set some general configuration options ' _('Here you can set some general configuration options '
'like hostname, domain name, webserver home page etc.') 'like hostname, domain name, webserver home page etc.')
@ -66,6 +65,12 @@ class ConfigApp(app_module.App):
packages = Packages('packages-config', ['zram-tools']) packages = Packages('packages-config', ['zram-tools'])
self.add(packages) 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'), domain_type = DomainType('domain-type-static', _('Domain Name'),
'config:index', can_have_certificate=True) 'config:index', can_have_certificate=True)
self.add(domain_type) self.add(domain_type)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,8 +25,6 @@ version = 2
is_essential = True is_essential = True
managed_services = ['firewalld']
_description = [ _description = [
format_lazy( format_lazy(
_('Firewall is a security system that controls the incoming and ' _('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']) packages = Packages('packages-firewall', ['firewalld', 'nftables'])
self.add(packages) self.add(packages)
daemon = Daemon('daemon-firewall', managed_services[0]) daemon = Daemon('daemon-firewall', 'firewalld')
self.add(daemon) self.add(daemon)
backup_restore = BackupRestore('backup-restore-firewall', backup_restore = BackupRestore('backup-restore-firewall',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -21,8 +21,6 @@ from . import manifest
version = 2 version = 2
managed_services = ['mldonkey-server']
_description = [ _description = [
_('MLDonkey is a peer-to-peer file sharing application used to exchange ' _('MLDonkey is a peer-to-peer file sharing application used to exchange '
'large files. It can participate in multiple peer-to-peer networks ' 'large files. It can participate in multiple peer-to-peer networks '
@ -46,6 +44,8 @@ class MLDonkeyApp(app_module.App):
app_id = 'mldonkey' app_id = 'mldonkey'
DAEMON = 'mldonkey-server'
def __init__(self): def __init__(self):
"""Create components for the app.""" """Create components for the app."""
super().__init__() super().__init__()
@ -83,7 +83,7 @@ class MLDonkeyApp(app_module.App):
urls=['https://{host}/mldonkey/']) urls=['https://{host}/mldonkey/'])
self.add(webserver) self.add(webserver)
daemon = Daemon('daemon-mldonkey', managed_services[0], daemon = Daemon('daemon-mldonkey', self.DAEMON,
listen_ports=[(4080, 'tcp4')]) listen_ports=[(4080, 'tcp4')])
self.add(daemon) self.add(daemon)
@ -104,4 +104,4 @@ def setup(helper, old_version=None):
if not old_version: if not old_version:
helper.call('post', app.enable) 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 version = 2
managed_services = ['mumble-server']
managed_paths = [pathlib.Path('/var/lib/mumble-server')] managed_paths = [pathlib.Path('/var/lib/mumble-server')]
_description = [ _description = [
@ -76,7 +74,7 @@ class MumbleApp(app_module.App):
letsencrypt = LetsEncrypt( letsencrypt = LetsEncrypt(
'letsencrypt-mumble', domains=get_domains, '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', private_key_path='/var/lib/mumble-server/privkey.pem',
certificate_path='/var/lib/mumble-server/fullchain.pem', certificate_path='/var/lib/mumble-server/fullchain.pem',
user_owner='mumble-server', group_owner='mumble-server', user_owner='mumble-server', group_owner='mumble-server',
@ -84,9 +82,10 @@ class MumbleApp(app_module.App):
self.add(letsencrypt) self.add(letsencrypt)
daemon = Daemon( daemon = Daemon(
'daemon-mumble', managed_services[0], 'daemon-mumble', 'mumble-server', listen_ports=[(64738, 'tcp4'),
listen_ports=[(64738, 'tcp4'), (64738, 'tcp6'), (64738, 'udp4'), (64738, 'tcp6'),
(64738, 'udp6')]) (64738, 'udp4'),
(64738, 'udp6')])
self.add(daemon) self.add(daemon)
users_and_groups = UsersAndGroups('users-and-groups-mumble', users_and_groups = UsersAndGroups('users-and-groups-mumble',

View File

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

View File

@ -20,8 +20,6 @@ version = 2
depends = ['names'] depends = ['names']
managed_services = ['pagekite']
_description = [ _description = [
format_lazy( format_lazy(
_('PageKite is a system for exposing {box_name} services when ' _('PageKite is a system for exposing {box_name} services when '
@ -56,6 +54,8 @@ class PagekiteApp(app_module.App):
app_id = 'pagekite' app_id = 'pagekite'
DAEMON = 'pagekite'
def __init__(self): def __init__(self):
"""Create components for the app.""" """Create components for the app."""
super().__init__() super().__init__()
@ -80,7 +80,7 @@ class PagekiteApp(app_module.App):
'pagekite:index', can_have_certificate=True) 'pagekite:index', can_have_certificate=True)
self.add(domain_type) self.add(domain_type)
daemon = Daemon('daemon-pagekite', managed_services[0]) daemon = Daemon('daemon-pagekite', self.DAEMON)
self.add(daemon) self.add(daemon)
backup_restore = BackupRestore('backup-restore-pagekite', backup_restore = BackupRestore('backup-restore-pagekite',
@ -112,4 +112,4 @@ def setup(helper, old_version=None):
helper.call('post', app.enable) helper.call('post', app.enable)
if old_version == 1: 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') name = _('Performance')
managed_services = [
'pmcd.service', 'pmie.service', 'pmlogger.service', 'pmproxy.service'
]
_description = [ _description = [
_('Performance app allows you to collect, store and view information ' _('Performance app allows you to collect, store and view information '
'about utilization of the hardware. This can give you basic insights ' 'about utilization of the hardware. This can give you basic insights '
@ -62,19 +58,19 @@ class PerformanceApp(app_module.App):
**manifest.backup) **manifest.backup)
self.add(backup_restore) self.add(backup_restore)
daemon_0 = Daemon('daemon-performance-0', managed_services[0], daemon_0 = Daemon('daemon-performance-0', 'pmcd.service',
listen_ports=None) listen_ports=None)
self.add(daemon_0) self.add(daemon_0)
daemon_1 = Daemon('daemon-performance-1', managed_services[1], daemon_1 = Daemon('daemon-performance-1', 'pmie.service',
listen_ports=None) listen_ports=None)
self.add(daemon_1) self.add(daemon_1)
daemon_2 = Daemon('daemon-performance-2', managed_services[2], daemon_2 = Daemon('daemon-performance-2', 'pmlogger.service',
listen_ports=None) listen_ports=None)
self.add(daemon_2) self.add(daemon_2)
daemon_3 = Daemon('daemon-performance-3', managed_services[3], daemon_3 = Daemon('daemon-performance-3', 'pmproxy.service',
listen_ports=None) listen_ports=None)
self.add(daemon_3) self.add(daemon_3)

View File

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

View File

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

View File

@ -25,8 +25,6 @@ from . import manifest
version = 2 version = 2
managed_services = ['smbd', 'nmbd']
_description = [ _description = [
_('Samba allows to share files and folders between FreedomBox and ' _('Samba allows to share files and folders between FreedomBox and '
'other computers in your local network.'), 'other computers in your local network.'),
@ -85,13 +83,12 @@ class SambaApp(app_module.App):
self.add(firewall) self.add(firewall)
daemon = Daemon( daemon = Daemon(
'daemon-samba', managed_services[0], listen_ports=[(139, 'tcp4'), 'daemon-samba', 'smbd', listen_ports=[(139, 'tcp4'), (139, 'tcp6'),
(139, 'tcp6'), (445, 'tcp4'),
(445, 'tcp4'), (445, 'tcp6')])
(445, 'tcp6')])
self.add(daemon) 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')]) listen_ports=[(137, 'udp4'), (138, 'udp4')])
self.add(daemon_nmbd) 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 actions
from plinth import app as app_module from plinth import app as app_module
from plinth import menu, module_loader 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.modules.backups.components import BackupRestore
from plinth.package import Packages from plinth.package import Packages
@ -22,8 +22,6 @@ version = 7
is_essential = True is_essential = True
managed_services = ['fail2ban']
ACCESS_CONF_FILE = '/etc/security/access.d/50freedombox.conf' ACCESS_CONF_FILE = '/etc/security/access.d/50freedombox.conf'
ACCESS_CONF_FILE_OLD = '/etc/security/access.conf' ACCESS_CONF_FILE_OLD = '/etc/security/access.conf'
ACCESS_CONF_SNIPPET = '-:ALL EXCEPT root fbx plinth (admin) (sudo):ALL' 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']) packages = Packages('packages-security', ['fail2ban', 'debsecan'])
self.add(packages) self.add(packages)
daemon = RelatedDaemon('related-daemon-fail2ban', 'fail2ban')
self.add(daemon)
backup_restore = BackupRestore('backup-restore-security', backup_restore = BackupRestore('backup-restore-security',
**manifest.backup) **manifest.backup)
self.add(backup_restore) self.add(backup_restore)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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