Service object to handle services on a system-level

The Service object now offers handling services on a system level,
and gathering information whether it's enabled or running.
New methods: enable, disable, is_enabled, is_running;

For this it needs the correct (system-level) service name.
All of the methods can be overridden/customized.

This changes all modules to the new Service object and deletes
action scripts that are not required anymore.
This commit is contained in:
fonfon 2016-04-25 10:25:14 +00:00 committed by James Valleroy
parent 9fe49f881f
commit a9528c56d9
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
30 changed files with 243 additions and 629 deletions

View File

@ -1,59 +0,0 @@
#!/usr/bin/python3
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Configuration helper for service discovery.
"""
import argparse
from plinth import action_utils
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser('enable', help='Enable avahi-daemon service')
subparsers.add_parser('disable', help='Disable avahi-daemon service')
return parser.parse_args()
def subcommand_enable(_):
"""Start service."""
action_utils.service_enable('avahi-daemon')
def subcommand_disable(_):
"""Stop service."""
action_utils.service_disable('avahi-daemon')
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == '__main__':
main()

View File

@ -1,60 +0,0 @@
#!/usr/bin/python3
# -*- mode: python -*-
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Configuration helper for date and time
"""
import argparse
from plinth import action_utils
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser('enable', help='Enable NTP service')
subparsers.add_parser('disable', help='Disable NTP service')
return parser.parse_args()
def subcommand_enable(_):
"""Start service."""
action_utils.service_enable('ntp')
def subcommand_disable(_):
"""Stop service."""
action_utils.service_disable('ntp')
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == '__main__':
main()

View File

@ -1,59 +0,0 @@
#!/usr/bin/python3
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Configuration helper for Minetest server.
"""
import argparse
from plinth import action_utils
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser('enable', help='Enable Minetest server')
subparsers.add_parser('disable', help='Disable Minetest server')
return parser.parse_args()
def subcommand_enable(_):
"""Enable and start server."""
action_utils.service_enable('minetest-server')
def subcommand_disable(_):
"""Disable and stop server."""
action_utils.service_disable('minetest-server')
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == '__main__':
main()

View File

@ -1,63 +0,0 @@
#!/usr/bin/python3
# -*- mode: python -*-
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Configuration helper for Mumble server
"""
import argparse
from plinth import action_utils
SERVICE_CONFIG = '/etc/default/mumble-server'
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser('enable', help='Enable Mumble service')
subparsers.add_parser('disable', help='Disable Mumble service')
return parser.parse_args()
def subcommand_enable(_):
"""Start service."""
action_utils.service_enable('mumble-server')
def subcommand_disable(_):
"""Stop service."""
action_utils.service_disable('mumble-server')
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == '__main__':
main()

View File

@ -98,9 +98,6 @@ def parse_arguments():
subparsers.add_parser('is-setup', help='Return whether setup is completed') subparsers.add_parser('is-setup', help='Return whether setup is completed')
subparsers.add_parser('setup', help='Setup OpenVPN server configuration') subparsers.add_parser('setup', help='Setup OpenVPN server configuration')
subparsers.add_parser('enable', help='Enable OpenVPN server')
subparsers.add_parser('disable', help='Disable OpenVPN server')
get_profile = subparsers.add_parser( get_profile = subparsers.add_parser(
'get-profile', help='Return the OpenVPN profile of a user') 'get-profile', help='Return the OpenVPN profile of a user')
get_profile.add_argument('username', help='User to get profile for') get_profile.add_argument('username', help='User to get profile for')
@ -156,16 +153,6 @@ def _create_certificates():
subprocess.check_call(['/usr/share/easy-rsa/build-dh'], **COMMON_ARGS) subprocess.check_call(['/usr/share/easy-rsa/build-dh'], **COMMON_ARGS)
def subcommand_enable(_):
"""Start OpenVPN service."""
action_utils.service_enable('openvpn@freedombox')
def subcommand_disable(_):
"""Stop OpenVPN service."""
action_utils.service_disable('openvpn@freedombox')
def subcommand_get_profile(arguments): def subcommand_get_profile(arguments):
"""Return the profile for a user.""" """Return the profile for a user."""
username = arguments.username username = arguments.username

View File

@ -37,8 +37,6 @@ def parse_arguments():
subparsers.add_parser('setup', subparsers.add_parser('setup',
help='Perform Privoxy configuration setup') help='Perform Privoxy configuration setup')
subparsers.add_parser('enable', help='Enable Privoxy service')
subparsers.add_parser('disable', help='Disable Privoxy service')
return parser.parse_args() return parser.parse_args()
@ -63,16 +61,6 @@ def subcommand_setup(_):
action_utils.service_restart('privoxy') action_utils.service_restart('privoxy')
def subcommand_enable(_):
"""Start service."""
action_utils.service_enable('privoxy')
def subcommand_disable(_):
"""Stop service."""
action_utils.service_disable('privoxy')
def main(): def main():
"""Parse arguments and perform all duties.""" """Parse arguments and perform all duties."""
arguments = parse_arguments() arguments = parse_arguments()

View File

@ -1,59 +0,0 @@
#!/usr/bin/python3
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Configuration helper for Quassel core.
"""
import argparse
from plinth import action_utils
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser('enable', help='Enable Quassel core service')
subparsers.add_parser('disable', help='Disable Quassel core service')
return parser.parse_args()
def subcommand_enable(_):
"""Start service."""
action_utils.service_enable('quasselcore')
def subcommand_disable(_):
"""Stop service."""
action_utils.service_disable('quasselcore')
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == '__main__':
main()

View File

@ -33,8 +33,6 @@ def parse_arguments():
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser('setup', help='Configure repro') subparsers.add_parser('setup', help='Configure repro')
subparsers.add_parser('enable', help='Enable repro service')
subparsers.add_parser('disable', help='Disable repro service')
return parser.parse_args() return parser.parse_args()
@ -61,16 +59,6 @@ def subcommand_setup(_):
action_utils.webserver_enable('repro-plinth') action_utils.webserver_enable('repro-plinth')
def subcommand_enable(_):
"""Start service."""
action_utils.service_enable('repro')
def subcommand_disable(_):
"""Stop service."""
action_utils.service_disable('repro')
def main(): def main():
"""Parse arguments and perform all duties.""" """Parse arguments and perform all duties."""
arguments = parse_arguments() arguments = parse_arguments()

View File

@ -1,60 +0,0 @@
#!/usr/bin/python3
# -*- mode: python -*-
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Configuration helper for reStore.
"""
import argparse
from plinth import action_utils
def parse_arguments():
"""Return parsed command line arguments as dictionary."""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
subparsers.add_parser('enable', help='Enable reStore')
subparsers.add_parser('disable', help='Disable reStore')
return parser.parse_args()
def subcommand_enable(_):
"""Enable reStore."""
action_utils.service_enable('node-restore')
def subcommand_disable(_):
"""Disable reStore."""
action_utils.service_disable('node-restore')
def main():
"""Parse arguments and perform all duties."""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == '__main__':
main()

View File

@ -21,8 +21,6 @@ Plinth module for service discovery.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions
from plinth import action_utils
from plinth import cfg from plinth import cfg
from plinth import service as service_module from plinth import service as service_module
from plinth.utils import format_lazy from plinth.utils import format_lazy
@ -35,6 +33,8 @@ is_essential = True
depends = ['system'] depends = ['system']
managed_services = ['avahi-daemon']
title = _('Service Discovery') title = _('Service Discovery')
description = [ description = [
@ -58,7 +58,7 @@ def init():
global service # pylint: disable=W0603 global service # pylint: disable=W0603
service = service_module.Service( service = service_module.Service(
'avahi', title, ['mdns'], is_external=False, enabled=is_enabled()) managed_services[0], title, ports=['mdns'], is_external=False)
def setup(helper, old_version=False): def setup(helper, old_version=False):
@ -68,22 +68,13 @@ def setup(helper, old_version=False):
def get_status(): def get_status():
"""Get the current settings from server.""" """Get the current settings from server."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled():
"""Return whether the module is enabled."""
return action_utils.service_is_enabled('avahi-daemon')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('avahi-daemon')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' if should_enable:
actions.superuser_run('avahi', [sub_command]) service.enable()
service.notify_enabled(None, should_enable) else:
service.disable()

View File

@ -22,7 +22,6 @@ Plinth module to configure system date and time
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import subprocess import subprocess
from plinth import action_utils
from plinth import cfg from plinth import cfg
from plinth import service as service_module from plinth import service as service_module
@ -33,6 +32,8 @@ is_essential = True
depends = ['system'] depends = ['system']
managed_services = ['ntp']
title = _('Date & Time') title = _('Date & Time')
description = [ description = [
@ -50,7 +51,7 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'ntp', title, is_external=False, enabled=is_enabled()) managed_services[0], title, is_external=False)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -61,27 +62,25 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current settings from server.""" """Get the current settings from server."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running(), 'is_running': service.is_running(),
'time_zone': get_current_time_zone()} 'time_zone': get_current_time_zone()}
def enable(should_enable):
"""Enable/disable the module."""
if should_enable:
service.enable()
else:
service.disable()
def get_current_time_zone(): def get_current_time_zone():
"""Get current time zone.""" """Get current time zone."""
time_zone = open('/etc/timezone').read().rstrip() time_zone = open('/etc/timezone').read().rstrip()
return time_zone or 'none' return time_zone or 'none'
def is_enabled():
"""Return whether the module is enabled."""
return action_utils.service_is_enabled('ntp')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('ntp')
def diagnose(): def diagnose():
"""Run diagnostics and return the results.""" """Run diagnostics and return the results."""
results = [] results = []

View File

@ -40,10 +40,11 @@ class ConfigurationView(views.ConfigurationView):
modified = False modified = False
if old_status['enabled'] != new_status['enabled']: if old_status['enabled'] != new_status['enabled']:
sub_command = 'enable' if new_status['enabled'] else 'disable' if new_status['enabled']:
datetime.service.enable()
else:
datetime.service.disable()
modified = True modified = True
actions.superuser_run('datetime', [sub_command])
datetime.service.notify_enabled(None, new_status['enabled'])
messages.success(self.request, _('Configuration updated')) messages.success(self.request, _('Configuration updated'))
if old_status['time_zone'] != new_status['time_zone'] and \ if old_status['time_zone'] != new_status['time_zone'] and \

View File

@ -20,6 +20,7 @@ Plinth module to configure a Deluge web client.
""" """
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from functools import partial
from plinth import actions from plinth import actions
from plinth import action_utils from plinth import action_utils
@ -44,6 +45,8 @@ description = [
service = None service = None
managed_services = ['deluge-web']
def init(): def init():
"""Initialize the Deluge module.""" """Initialize the Deluge module."""
@ -52,8 +55,8 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'deluge', title, ['http', 'https'], is_external=True, managed_services[0], title, ports=['http', 'https'], is_external=True,
enabled=is_enabled()) is_enabled=is_enabled, enable=_enable, disable=_disable)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -65,8 +68,8 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current settings.""" """Get the current settings."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled(): def is_enabled():
@ -75,11 +78,6 @@ def is_enabled():
action_utils.service_is_enabled('deluge-web')) action_utils.service_is_enabled('deluge-web'))
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('deluge-web')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' sub_command = 'enable' if should_enable else 'disable'
@ -97,3 +95,7 @@ def diagnose():
'https://{host}/deluge', extra_options=['--no-check-certificate'])) 'https://{host}/deluge', extra_options=['--no-check-certificate']))
return results return results
_enable = partial(enable, True)
_disable = partial(enable, False)

View File

@ -20,6 +20,7 @@ Plinth module to configure ikiwiki
""" """
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from functools import partial
from plinth import actions from plinth import actions
from plinth import action_utils from plinth import action_utils
@ -48,8 +49,8 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'ikiwiki', title, ['http', 'https'], is_external=True, 'ikiwiki', title, ports=['http', 'https'], is_external=True,
enabled=is_enabled()) is_enabled=is_enabled, enable=_enable, disable=_disable)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -90,3 +91,7 @@ def diagnose():
'https://{host}/ikiwiki', extra_options=['--no-check-certificate'])) 'https://{host}/ikiwiki', extra_options=['--no-check-certificate']))
return results return results
_enable = partial(enable, True)
_disable = partial(enable, False)

View File

@ -21,7 +21,6 @@ Plinth module for minetest.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions
from plinth import action_utils from plinth import action_utils
from plinth import cfg from plinth import cfg
from plinth import service as service_module from plinth import service as service_module
@ -45,6 +44,8 @@ description = [
service = None service = None
managed_services = ['minetest-server']
def init(): def init():
"""Initialize the module.""" """Initialize the module."""
@ -53,36 +54,27 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'minetest-plinth', title, is_external=True, enabled=is_enabled()) managed_services[0], title, is_external=True)
def setup(helper, old_version=None): def setup(helper, old_version=None):
"""Install and configure the module.""" """Install and configure the module."""
helper.install(['minetest-server']) helper.install(managed_services)
helper.call('post', service.notify_enabled, None, True) helper.call('post', service.notify_enabled, None, True)
def get_status(): def get_status():
"""Get the current service status.""" """Get the current service status."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled():
"""Return whether the service is enabled."""
return action_utils.service_is_enabled('minetest-server')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('minetest-server')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' if should_enable:
actions.superuser_run('minetest', [sub_command]) service.enable()
service.notify_enabled(None, should_enable) else:
service.disable()
def diagnose(): def diagnose():

View File

@ -21,7 +21,6 @@ Plinth module to configure Mumble server
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions
from plinth import action_utils from plinth import action_utils
from plinth import cfg from plinth import cfg
from plinth import service as service_module from plinth import service as service_module
@ -44,6 +43,8 @@ description = [
service = None service = None
managed_services = ['mumble-server']
def init(): def init():
"""Intialize the Mumble module.""" """Intialize the Mumble module."""
@ -52,7 +53,7 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'mumble-plinth', title, is_external=True, enabled=is_enabled()) managed_services[0], title, is_external=True)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -63,25 +64,16 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current settings from server.""" """Get the current settings from server."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled():
"""Return whether the module is enabled."""
return action_utils.service_is_enabled('mumble-server')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('mumble-server')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' if should_enable:
actions.superuser_run('mumble', [sub_command]) service.enable()
service.notify_enabled(None, should_enable) else:
service.disable()
def diagnose(): def diagnose():

View File

@ -47,6 +47,8 @@ description = [
service = None service = None
managed_services = ['openvpn@freedombox']
def init(): def init():
"""Intialize the OpenVPN module.""" """Intialize the OpenVPN module."""
@ -55,7 +57,7 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'openvpn', title, ['openvpn'], is_external=True, enabled=is_enabled()) managed_services[0], title, ports=['openvpn'], is_external=True)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -63,16 +65,6 @@ def setup(helper, old_version=None):
helper.install(['openvpn', 'easy-rsa']) helper.install(['openvpn', 'easy-rsa'])
def is_enabled():
"""Return whether the module is enabled."""
return action_utils.service_is_enabled('openvpn@freedombox')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('openvpn@freedombox')
def is_setup(): def is_setup():
"""Return whether the service is running.""" """Return whether the service is running."""
return actions.superuser_run('openvpn', ['is-setup']).strip() == 'true' return actions.superuser_run('openvpn', ['is-setup']).strip() == 'true'

View File

@ -99,8 +99,8 @@ def get_status():
"""Get the current settings from OpenVPN server.""" """Get the current settings from OpenVPN server."""
status = {'is_setup': openvpn.is_setup(), status = {'is_setup': openvpn.is_setup(),
'setup_running': False, 'setup_running': False,
'enabled': openvpn.is_enabled(), 'enabled': openvpn.service.is_enabled(),
'is_running': openvpn.is_running()} 'is_running': openvpn.service.is_running()}
status['setup_running'] = bool(setup_process) status['setup_running'] = bool(setup_process)
@ -132,9 +132,10 @@ def _apply_changes(request, old_status, new_status):
modified = False modified = False
if old_status['enabled'] != new_status['enabled']: if old_status['enabled'] != new_status['enabled']:
sub_command = 'enable' if new_status['enabled'] else 'disable' if new_status['enabled']:
actions.superuser_run('openvpn', [sub_command]) openvpn.service.enable()
openvpn.service.notify_enabled(None, new_status['enabled']) else:
openvpn.service.disable()
modified = True modified = True
if modified: if modified:

View File

@ -20,6 +20,7 @@ Plinth module to configure ownCloud
""" """
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from functools import partial
from plinth import actions from plinth import actions
from plinth import action_utils from plinth import action_utils
@ -57,8 +58,8 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'owncloud', title, ['http', 'https'], is_external=True, 'owncloud', title, ports=['http', 'https'], is_external=True,
enabled=is_enabled()) is_enabled=is_enabled, enable=_enable, disable=_disable)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -98,3 +99,7 @@ def diagnose():
'https://{host}/owncloud', extra_options=['--no-check-certificate'])) 'https://{host}/owncloud', extra_options=['--no-check-certificate']))
return results return results
_enable = partial(enable, True)
_disable = partial(enable, False)

View File

@ -53,6 +53,8 @@ description = [
service = None service = None
managed_services = ['privoxy']
def init(): def init():
"""Intialize the module.""" """Intialize the module."""
@ -61,7 +63,7 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'privoxy', title, is_external=False, enabled=is_enabled()) managed_services[0], title, is_external=False)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -73,25 +75,16 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current settings from server.""" """Get the current settings from server."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled():
"""Return whether the module is enabled."""
return action_utils.service_is_enabled('privoxy')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('privoxy')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' if should_enable:
actions.superuser_run('privoxy', [sub_command]) service.enable()
service.notify_enabled(None, should_enable) else:
service.disable()
def diagnose(): def diagnose():

View File

@ -21,7 +21,6 @@ Plinth module for Quassel.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions
from plinth import action_utils from plinth import action_utils
from plinth import cfg from plinth import cfg
from plinth import service as service_module from plinth import service as service_module
@ -31,8 +30,6 @@ version = 1
depends = ['apps'] depends = ['apps']
managed_services = ['quasselcore']
title = _('IRC Client (Quassel)') title = _('IRC Client (Quassel)')
description = [ description = [
@ -54,6 +51,8 @@ description = [
service = None service = None
managed_services = ['quasselcore']
def init(): def init():
"""Initialize the quassel module.""" """Initialize the quassel module."""
@ -62,7 +61,7 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'quassel-plinth', title, is_external=True, enabled=is_enabled()) managed_services[0], title, description=description, is_external=True)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -73,25 +72,16 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current service status.""" """Get the current service status."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled():
"""Return whether the service is enabled."""
return action_utils.service_is_enabled('quasselcore')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('quasselcore')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' if should_enable:
actions.superuser_run('quassel', [sub_command]) service.enable()
service.notify_enabled(None, should_enable) else:
service.disable()
def diagnose(): def diagnose():

View File

@ -19,6 +19,8 @@
Plinth module for radicale. Plinth module for radicale.
""" """
from functools import partial
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions from plinth import actions
@ -46,6 +48,8 @@ description = [
service = None service = None
managed_services = ['radicale']
def init(): def init():
"""Initialize the radicale module.""" """Initialize the radicale module."""
@ -54,8 +58,8 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'radicale', title, ['http', 'https'], is_external=True, managed_services[0], title, ports=['http', 'https'], is_external=True,
enabled=is_enabled()) enable=_enable, disable=_disable)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -67,18 +71,8 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current service status.""" """Get the current service status."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled():
"""Return whether the service is enabled."""
return action_utils.service_is_enabled('radicale')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('radicale')
def enable(should_enable): def enable(should_enable):
@ -98,3 +92,7 @@ def diagnose():
'https://{host}/radicale', extra_options=['--no-check-certificate'])) 'https://{host}/radicale', extra_options=['--no-check-certificate']))
return results return results
_enable = partial(enable, True)
_disable = partial(enable, False)

View File

@ -55,6 +55,8 @@ description = [
service = None service = None
managed_services = ['repro']
def init(): def init():
"""Initialize the repro module.""" """Initialize the repro module."""
@ -63,8 +65,8 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'repro', title, ['sip-plinth', 'sip-tls-plinth'], is_external=True, managed_services[0], title, ports=['sip-plinth', 'sip-tls-plinth'],
enabled=is_enabled()) is_external=True)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -76,25 +78,16 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current service status.""" """Get the current service status."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled():
"""Return whether the service is enabled."""
return action_utils.service_is_enabled('repro')
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('repro')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' if should_enable:
actions.superuser_run('repro', [sub_command]) service.enable()
service.notify_enabled(None, should_enable) else:
service.disable()
def diagnose(): def diagnose():

View File

@ -21,8 +21,7 @@ Plinth module to configure reStore.
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions from plinth import cfg
from plinth import action_utils, cfg
from plinth import service as service_module from plinth import service as service_module
from plinth.utils import format_lazy from plinth.utils import format_lazy
@ -48,6 +47,8 @@ description = [
service = None service = None
managed_services = ['node-restore']
def init(): def init():
"""Initialize the reStore module.""" """Initialize the reStore module."""
@ -56,8 +57,8 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'node-restore', title, ['http', 'https'], is_external=False, managed_services[0], title, ports=['http', 'https'], is_external=False,
enabled=is_enabled()) description=description)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -67,16 +68,12 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current settings.""" """Get the current settings."""
return {'enabled': is_enabled()} return {'enabled': service.is_enabled()}
def is_enabled():
"""Return whether the module is enabled."""
return action_utils.service_is_enabled('node-restore')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' if should_enable:
actions.superuser_run('restore', [sub_command]) service.enable()
service.notify_enabled(None, should_enable) else:
service.disable()

View File

@ -19,6 +19,8 @@
Plinth module to configure Shaarli. Plinth module to configure Shaarli.
""" """
from functools import partial
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import actions from plinth import actions
@ -52,8 +54,8 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'shaarli', title, ['http', 'https'], is_external=True, 'shaarli', title, ports=['http', 'https'], is_external=True,
enabled=is_enabled()) is_enabled=is_enabled, enable=_enable, disable=_disable)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -64,7 +66,7 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current settings.""" """Get the current settings."""
return {'enabled': is_enabled()} return {'enabled': service.is_enabled()}
def is_enabled(): def is_enabled():
@ -77,3 +79,7 @@ def enable(should_enable):
sub_command = 'enable' if should_enable else 'disable' sub_command = 'enable' if should_enable else 'disable'
actions.superuser_run('shaarli', [sub_command]) actions.superuser_run('shaarli', [sub_command])
service.notify_enabled(None, should_enable) service.notify_enabled(None, should_enable)
_enable = partial(enable, True)
_disable = partial(enable, False)

View File

@ -64,13 +64,13 @@ def init():
global socks_service global socks_service
socks_service = service_module.Service( socks_service = service_module.Service(
'tor-socks', _('Tor Anonymity Network'), 'tor-socks', _('Tor Anonymity Network'),
is_external=False, enabled=is_enabled()) is_external=False, is_enabled=is_enabled, is_running=is_running)
global bridge_service global bridge_service
bridge_service = service_module.Service( bridge_service = service_module.Service(
'tor-bridge', _('Tor Bridge Relay'), 'tor-bridge', _('Tor Bridge Relay'),
ports=['tor-orport', 'tor-obfs3', 'tor-obfs4'], ports=['tor-orport', 'tor-obfs3', 'tor-obfs4'],
is_external=True, enabled=is_enabled()) is_external=True, is_enabled=is_enabled, is_running=is_running)
# Register hidden service name with Name Services module. # Register hidden service name with Name Services module.
hs_info = get_hs() hs_info = get_hs()

View File

@ -20,6 +20,7 @@ Plinth module to configure Transmission server
""" """
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from functools import partial
import json import json
import socket import socket
@ -33,8 +34,6 @@ version = 1
depends = ['apps'] depends = ['apps']
managed_services = ['transmission-daemon']
title = _('BitTorrent (Transmission)') title = _('BitTorrent (Transmission)')
description = [ description = [
@ -45,6 +44,8 @@ description = [
service = None service = None
managed_services = ['transmission-daemon']
TRANSMISSION_CONFIG = '/etc/transmission-daemon/settings.json' TRANSMISSION_CONFIG = '/etc/transmission-daemon/settings.json'
@ -55,8 +56,9 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'transmission', title, ['http', 'https'], is_external=True, managed_services[0], title, ports=['http', 'https'], is_external=True,
enabled=is_enabled()) is_enabled=is_enabled, enable=_enable, disable=_disable,
description=description)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -79,7 +81,7 @@ def get_status():
status = {key.translate(str.maketrans({'-': '_'})): value status = {key.translate(str.maketrans({'-': '_'})): value
for key, value in status.items()} for key, value in status.items()}
status['enabled'] = is_enabled() status['enabled'] = is_enabled()
status['is_running'] = is_running() status['is_running'] = service.is_running()
status['hostname'] = socket.gethostname() status['hostname'] = socket.gethostname()
return status return status
@ -91,11 +93,6 @@ def is_enabled():
action_utils.webserver_is_enabled('transmission-plinth')) action_utils.webserver_is_enabled('transmission-plinth'))
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('transmission-daemon')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' sub_command = 'enable' if should_enable else 'disable'
@ -114,3 +111,7 @@ def diagnose():
extra_options=['--no-check-certificate'])) extra_options=['--no-check-certificate']))
return results return results
_enable = partial(enable, True)
_disable = partial(enable, False)

View File

@ -20,6 +20,7 @@ Plinth module to configure Tiny Tiny RSS.
""" """
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from functools import partial
from plinth import actions from plinth import actions
from plinth import action_utils from plinth import action_utils
@ -44,6 +45,8 @@ description = [
service = None service = None
managed_services = ['tt-rss']
def init(): def init():
"""Intialize the module.""" """Intialize the module."""
@ -52,8 +55,8 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'tt-rss', title, ['http', 'https'], is_external=True, managed_services[0], title, ports=['http', 'https'], is_external=True,
enabled=is_enabled()) is_enabled=is_enabled, enable=_enable, disable=_disable)
def setup(helper, old_version=None): def setup(helper, old_version=None):
@ -67,7 +70,7 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current settings.""" """Get the current settings."""
return {'enabled': is_enabled(), return {'enabled': is_enabled(),
'is_running': is_running()} 'is_running': service.is_running()}
def is_enabled(): def is_enabled():
@ -76,11 +79,6 @@ def is_enabled():
action_utils.webserver_is_enabled('tt-rss-plinth')) action_utils.webserver_is_enabled('tt-rss-plinth'))
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('tt-rss')
def enable(should_enable): def enable(should_enable):
"""Enable/disable the module.""" """Enable/disable the module."""
sub_command = 'enable' if should_enable else 'disable' sub_command = 'enable' if should_enable else 'disable'
@ -96,3 +94,7 @@ def diagnose():
'https://{host}/tt-rss', extra_options=['--no-check-certificate'])) 'https://{host}/tt-rss', extra_options=['--no-check-certificate']))
return results return results
_enable = partial(enable, True)
_disable = partial(enable, False)

View File

@ -20,6 +20,7 @@ Plinth module to configure XMPP server
""" """
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from functools import partial
import logging import logging
import socket import socket
@ -51,6 +52,8 @@ service = None
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
managed_services = ['ejabberd']
def init(): def init():
"""Initialize the XMPP module""" """Initialize the XMPP module"""
@ -59,8 +62,9 @@ def init():
global service global service
service = service_module.Service( service = service_module.Service(
'xmpp', title, ['xmpp-client', 'xmpp-server', 'xmpp-bosh'], 'ejabberd', title, ports=['xmpp-client', 'xmpp-server', 'xmpp-bosh'],
is_external=True, enabled=is_enabled()) is_external=True, is_enabled=is_enabled, enable=_enable,
disable=_disable)
pre_hostname_change.connect(on_pre_hostname_change) pre_hostname_change.connect(on_pre_hostname_change)
post_hostname_change.connect(on_post_hostname_change) post_hostname_change.connect(on_post_hostname_change)
@ -81,8 +85,8 @@ def setup(helper, old_version=None):
def get_status(): def get_status():
"""Get the current settings.""" """Get the current settings."""
return {'enabled': is_enabled(), return {'enabled': service.is_enabled(),
'is_running': is_running(), 'is_running': service.is_running(),
'domainname': get_domainname()} 'domainname': get_domainname()}
@ -92,11 +96,6 @@ def is_enabled():
action_utils.webserver_is_enabled('jwchat-plinth')) action_utils.webserver_is_enabled('jwchat-plinth'))
def is_running():
"""Return whether the service is running."""
return action_utils.service_is_running('ejabberd')
def get_domainname(): def get_domainname():
"""Return the domainname""" """Return the domainname"""
fqdn = socket.getfqdn() fqdn = socket.getfqdn()
@ -164,3 +163,7 @@ def diagnose():
results.extend(action_utils.diagnose_url_on_all('http://{host}/jwchat')) results.extend(action_utils.diagnose_url_on_all('http://{host}/jwchat'))
return results return results
_enable = partial(enable, True)
_disable = partial(enable, False)

View File

@ -20,9 +20,10 @@ Framework for working with servers and their services.
""" """
import collections import collections
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from plinth import cfg from plinth import action_utils, actions, cfg
from plinth.signals import service_enabled from plinth.signals import service_enabled
from plinth.utils import format_lazy from plinth.utils import format_lazy
@ -34,48 +35,95 @@ class Service(object):
Representation of an application service provided by the machine Representation of an application service provided by the machine
containing information such as current status and ports required containing information such as current status and ports required
for operation. for operation.
- service_id: unique service name. If possible this should be the name of
the service on operating system level (as in /etc/init.d/).
- name: service name as to be displayed in the GUI
- description (optional): list of paragraphs that describe the service
- is_enabled (optional): Boolean, or a Function returning Boolean
- enable (optional): Function
- disable (optional): Function
- is_running (optional): Boolean, or a Function returning Boolean
""" """
def __init__(self, service_id, name, ports=None, is_external=False, def __init__(self, service_id, name, ports=None, description=None,
enabled=True): is_external=False, is_enabled=None, enable=None, disable=None,
if not ports: is_running=None):
if ports is None:
ports = [service_id] ports = [service_id]
if is_enabled is None:
is_enabled = self._default_is_enabled
self.service_id = service_id self.service_id = service_id
self.name = name self.name = name
self.description = description
self.ports = ports self.ports = ports
self.is_external = is_external self.is_external = is_external
self._enabled = enabled self._is_enabled = is_enabled
self._enable = enable
self._disable = disable
self._is_running = is_running
# Maintain a complete list of services # Maintain a complete list of services
assert(service_id not in services)
services[service_id] = self services[service_id] = self
def enable(self):
if self._enable is None:
actions.superuser_run('service', ['enable', self.service_id])
else:
self._call_or_return(self._enable)
self.notify_enabled(None, True)
def disable(self):
if self._disable is None:
actions.superuser_run('service', ['disable', self.service_id])
else:
self._call_or_return(self._disable)
self.notify_enabled(None, False)
def is_enabled(self): def is_enabled(self):
"""Return whether the service is enabled.""" """Return whether the service is enabled."""
# TODO: we could cache the service state if we only use this service
# interface to change service status.
return self._call_or_return(self._is_enabled)
if isinstance(self._enabled, collections.Callable): def is_running(self):
return self._enabled() if self._is_running is None:
return action_utils.service_is_running(self.service_id)
return self._enabled else:
return self._call_or_return(self._is_running)
def notify_enabled(self, sender, enabled): def notify_enabled(self, sender, enabled):
"""Notify observers about change in state of service.""" """Notify observers about change in state of service."""
if not isinstance(self._enabled, collections.Callable):
self._enabled = enabled
service_enabled.send_robust(sender=sender, service_id=self.service_id, service_enabled.send_robust(sender=sender, service_id=self.service_id,
enabled=enabled) enabled=enabled)
def _call_or_return(self, obj):
"""Calls obj if it's callable, returns it if it's Boolean."""
if isinstance(obj, collections.Callable):
return obj()
elif type(obj) is bool:
return obj
else:
message = 'obj is expected to be callable or a boolean.'
raise ValueError(message)
def _default_is_enabled(self):
"""Returns is_enabled relying on a correct service_id"""
return action_utils.service_is_enabled(self.service_id)
def init(): def init():
"""Register some misc. services that don't fit elsewhere.""" """Register some misc. services that don't fit elsewhere."""
Service('http', _('Web Server'), ['http'], is_external=True, enabled=True) Service('http', _('Web Server'), ports=['http'], is_external=True,
Service('https', _('Web Server over Secure Socket Layer'), ['https'], is_enabled=True)
is_external=True, enabled=True) Service('https', _('Web Server over Secure Socket Layer'), ports=['https'],
Service('ssh', _('Secure Shell (SSH) Server'), ['ssh'], is_external=True, is_external=True, is_enabled=True)
enabled=True) Service('ssh', _('Secure Shell (SSH) Server'), ports=['ssh'],
Service('plinth', is_external=True, is_enabled=True)
format_lazy(_('{box_name} Web Interface (Plinth)'), Service('plinth', format_lazy(_('{box_name} Web Interface (Plinth)'),
box_name=_(cfg.box_name)), box_name=_(cfg.box_name)),
['https'], is_external=True, enabled=True) ports=['https'], is_external=True, is_enabled=True)