1
# Copyright 2016 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Services monitored on regiond."""
9
from datetime import timedelta
11
from maasserver.models.regioncontrollerprocess import RegionControllerProcess
12
from maasserver.models.service import Service
13
from maasserver.utils.orm import transactional
14
from maasserver.utils.threads import deferToDatabase
15
from provisioningserver.config import is_dev_environment
16
from provisioningserver.logger import get_maas_logger
17
from provisioningserver.utils.service_monitor import (
21
from twisted.application.internet import TimerService
22
from twisted.internet import reactor
23
from twisted.internet.defer import inlineCallbacks
24
from twisted.python import log
27
maaslog = get_maas_logger("service_monitor_service")
30
class BIND9Service(AlwaysOnService):
31
"""Monitored bind9 service."""
34
service_name = "bind9"
37
class ProxyService(AlwaysOnService):
38
"""Monitored proxy service."""
41
service_name = "maas-proxy"
44
# Global service monitor for regiond.
45
service_monitor = ServiceMonitor(
51
class ServiceMonitorService(TimerService, object):
52
"""Service to monitor external services that the region requires."""
54
check_interval = timedelta(minutes=1).total_seconds()
56
def __init__(self, advertisingService, clock=reactor):
57
# Call self.monitorServices() every self.check_interval.
58
super(ServiceMonitorService, self).__init__(
59
self.check_interval, self.monitorServices)
61
self.advertisingService = advertisingService
63
def monitorServices(self):
64
"""Monitors all of the external services and makes sure they
67
if is_dev_environment():
69
"Skipping check of services; they're not running under "
70
"the supervision of systemd.")
72
d = service_monitor.ensureServices()
73
d.addCallback(self._updateDatabase)
75
log.err, "Failed to monitor services and update database.")
79
def _updateDatabase(self, services):
80
"""Update database about services status."""
81
processId = yield self.advertisingService.processId.get()
82
services = yield self._buildServices(services)
83
yield deferToDatabase(self._saveIntoDatabase, processId, services)
86
def _saveIntoDatabase(self, processId, services):
87
"""Save the `services` in the the database for process by `processId`.
89
process = RegionControllerProcess.objects.get(id=processId)
90
for service in services:
91
Service.objects.update_service_for(
92
process.region, service["name"],
93
service["status"], service["status_info"])
96
def _buildServices(self, services):
97
"""Build the list of services so they can be updated into the database.
100
for name, state in services.items():
101
service = service_monitor.getServiceByName(name)
102
status, status_info = yield state.get_status_and_status_info_for(
104
msg_services.append({
107
"status_info": status_info,