Merge pull request #469 from YunoHost/services_dbus

move service_status to sytemd via dbus
This commit is contained in:
Bram 2018-05-18 04:09:34 +02:00 committed by GitHub
commit bc68bf39e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 69 deletions

View file

@ -61,11 +61,17 @@ do_pre_regen() {
_update_services() {
sudo python2 - << EOF
import yaml
with open('services.yml') as f:
new_services = yaml.load(f)
with open('/etc/yunohost/services.yml') as f:
services = yaml.load(f)
updated = False
for service, conf in new_services.items():
# remove service with empty conf
if conf is None:
@ -73,20 +79,32 @@ for service, conf in new_services.items():
print("removing '{0}' from services".format(service))
del services[service]
updated = True
# add new service
elif not services.get(service, None):
print("adding '{0}' to services".format(service))
services[service] = conf
updated = True
# update service conf
else:
conffiles = services[service].pop('conffiles', {})
# status need to be removed
if "status" not in conf and "status" in services[service]:
print("update '{0}' service status access".format(service))
del services[service]["status"]
updated = True
if services[service] != conf:
print("update '{0}' service".format(service))
services[service].update(conf)
updated = True
if conffiles:
services[service]['conffiles'] = conffiles
if updated:
with open('/etc/yunohost/services.yml-new', 'w') as f:
yaml.safe_dump(services, f, default_flow_style=False)

View file

@ -1,57 +1,42 @@
nginx:
status: service
log: /var/log/nginx
log: /var/log/nginx
avahi-daemon:
status: service
log: /var/log/daemon.log
log: /var/log/daemon.log
dnsmasq:
status: service
log: /var/log/daemon.log
log: /var/log/daemon.log
fail2ban:
status: service
log: /var/log/fail2ban.log
log: /var/log/fail2ban.log
dovecot:
status: service
log: [/var/log/mail.log,/var/log/mail.err]
log: [/var/log/mail.log,/var/log/mail.err]
postfix:
status: service
log: [/var/log/mail.log,/var/log/mail.err]
log: [/var/log/mail.log,/var/log/mail.err]
rmilter:
status: systemctl status rmilter.service
log: /var/log/mail.log
log: /var/log/mail.log
rspamd:
status: systemctl status rspamd.service
log: /var/log/mail.log
log: /var/log/mail.log
redis-server:
status: service
log: /var/log/redis/redis-server.log
log: /var/log/redis/redis-server.log
mysql:
status: service
log: [/var/log/mysql.log,/var/log/mysql.err]
glances:
status: service
log: [/var/log/mysql.log,/var/log/mysql.err]
glances: {}
ssh:
status: service
log: /var/log/auth.log
log: /var/log/auth.log
ssl:
status: null
metronome:
status: metronomectl status
log: [/var/log/metronome/metronome.log,/var/log/metronome/metronome.err]
log: [/var/log/metronome/metronome.log,/var/log/metronome/metronome.err]
slapd:
status: service
log: /var/log/syslog
log: /var/log/syslog
php5-fpm:
status: service
log: /var/log/php5-fpm.log
log: /var/log/php5-fpm.log
yunohost-api:
status: service
log: /var/log/yunohost/yunohost-api.log
log: /var/log/yunohost/yunohost-api.log
yunohost-firewall:
status: service
need_lock: true
nslcd:
status: service
log: /var/log/syslog
nsswitch: {}
log: /var/log/syslog
nsswitch:
status: null
bind9: null
tahoe-lafs: null
memcached: null

2
debian/control vendored
View file

@ -12,7 +12,7 @@ Architecture: all
Depends: ${python:Depends}, ${misc:Depends}
, moulinette (>= 2.7.1), ssowat (>= 2.7.1)
, python-psutil, python-requests, python-dnspython, python-openssl
, python-apt, python-miniupnpc
, python-apt, python-miniupnpc, python-dbus
, glances
, dnsutils, bind9utils, unzip, git, curl, cron, wget
, ca-certificates, netcat-openbsd, iproute

View file

@ -27,12 +27,13 @@ import os
import time
import yaml
import json
import glob
import subprocess
import errno
import shutil
import hashlib
from difflib import unified_diff
from datetime import datetime
from moulinette import m18n
from moulinette.core import MoulinetteError
@ -213,46 +214,54 @@ def service_status(names=[]):
raise MoulinetteError(errno.EINVAL,
m18n.n('service_unknown', service=name))
status = None
if services[name].get('status') == 'service':
status = 'service %s status' % name
elif "status" in services[name]:
status = str(services[name]['status'])
else:
# this "service" isn't a service actually so we skip it
#
# the historical reason is because regenconf has been hacked into the
# service part of YunoHost will in some situation we need to regenconf
# for things that aren't services
# the hack was to add fake services...
# we need to extract regenconf from service at some point, also because
# some app would really like to use it
if "status" in services[name] and services[name]["status"] is None:
continue
runlevel = 5
if 'runlevel' in services[name].keys():
runlevel = int(services[name]['runlevel'])
status = _get_service_information_from_systemd(name)
result[name] = {'status': 'unknown', 'loaded': 'unknown'}
# Retrieve service status
try:
subprocess.check_output(status, stderr=subprocess.STDOUT,
shell=True)
except subprocess.CalledProcessError as e:
if 'usage:' in e.output.lower():
logger.warning(m18n.n('service_status_failed', service=name))
else:
result[name]['status'] = 'inactive'
else:
result[name]['status'] = 'running'
# Retrieve service loading
rc_path = glob.glob("/etc/rc%d.d/S[0-9][0-9]%s" % (runlevel, name))
if len(rc_path) == 1 and os.path.islink(rc_path[0]):
result[name]['loaded'] = 'enabled'
elif os.path.isfile("/etc/init.d/%s" % name):
result[name]['loaded'] = 'disabled'
else:
result[name]['loaded'] = 'not-found'
result[name] = {
'status': str(status.get("SubState", "unknown")),
'loaded': "enabled" if str(status.get("LoadState", "unknown")) == "loaded" else str(status.get("LoadState", "unknown")),
'active': str(status.get("ActiveState", "unknown")),
'active_at': {
"timestamp": str(status.get("ActiveEnterTimestamp", "unknown")),
"human": datetime.fromtimestamp(status.get("ActiveEnterTimestamp") / 1000000).strftime("%F %X"),
},
'description': str(status.get("Description", "")),
'service_file_path': str(status.get("FragmentPath", "unknown")),
}
if len(names) == 1:
return result[names[0]]
return result
def _get_service_information_from_systemd(service):
"this is the equivalent of 'systemctl status $service'"
import dbus
d = dbus.SystemBus()
systemd = d.get_object('org.freedesktop.systemd1','/org/freedesktop/systemd1')
manager = dbus.Interface(systemd, 'org.freedesktop.systemd1.Manager')
service_path = manager.GetUnit(service + ".service")
service_proxy = d.get_object('org.freedesktop.systemd1', service_path)
# unit_proxy = dbus.Interface(service_proxy, 'org.freedesktop.systemd1.Unit',)
properties_interface = dbus.Interface(service_proxy, 'org.freedesktop.DBus.Properties')
return properties_interface.GetAll('org.freedesktop.systemd1.Unit')
def service_log(name, number=50):
"""
Log every log files of a service