/usr/lib/python3/dist-packages/provisioningserver/rackdservices/service_monitor_service.py is in python3-maas-provisioningserver 2.4.0~beta2-6865-gec43e47e6-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | # Copyright 2015-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Service to periodically check that all the other services that MAAS depends
on stays running."""
__all__ = [
"ServiceMonitorService"
]
from datetime import timedelta
from provisioningserver.config import is_dev_environment
from provisioningserver.logger import (
get_maas_logger,
LegacyLogger,
)
from provisioningserver.rpc.exceptions import NoConnectionsAvailable
from provisioningserver.rpc.region import UpdateServices
from provisioningserver.service_monitor import service_monitor
from provisioningserver.utils.twisted import (
pause,
retries,
)
from twisted.application.internet import TimerService
from twisted.internet.defer import inlineCallbacks
maaslog = get_maas_logger("service_monitor_service")
log = LegacyLogger()
class ServiceMonitorService(TimerService, object):
"""Service to monitor external services that the cluster requires."""
# Services that we don't perform any checks on at the moment and we
# always considered working as since they run in the same process as rackd.
# "rackd" should not show in this list as the region controller handles
# updating the status of "rackd". This is because its status all depends
# on the connections across the multiple regions.
ALWAYS_RUNNING_SERVICES = [
{
"name": "http",
"status": "running",
"status_info": "",
},
{
"name": "tftp",
"status": "running",
"status_info": "",
},
]
check_interval = timedelta(seconds=30).total_seconds()
def __init__(self, client_service, clock):
# Call self.monitorServices() every self.check_interval.
super(ServiceMonitorService, self).__init__(
self.check_interval, self.monitorServices)
self.client_service = client_service
self.clock = clock
def monitorServices(self):
"""Monitors all of the external services and makes sure they
stay running.
"""
if is_dev_environment():
log.msg(
"Skipping check of services; they're not running under "
"the supervision of systemd.")
else:
d = self._getConnection()
d.addCallback(self._ensureServices)
d.addCallback(self._updateRegion)
d.addErrback(
log.err, "Failed to monitor services and update region.")
return d
@inlineCallbacks
def _getConnection(self):
"""Get a connection to the region."""
client = None
for elapsed, remaining, wait in retries(30, 10, self.clock):
try:
client = yield self.client_service.getClientNow()
break
except NoConnectionsAvailable:
yield pause(wait, self.clock)
else:
maaslog.error(
"Can't update service statuses, no RPC "
"connection to region.")
return client
@inlineCallbacks
def _ensureServices(self, client):
if client:
services = yield service_monitor.ensureServices()
return (client, services)
return None, None
@inlineCallbacks
def _updateRegion(self, result):
"""Update region about services status."""
client, services = result
if client:
services = yield self._buildServices(services)
yield client(
UpdateServices,
system_id=client.localIdent,
services=services)
@inlineCallbacks
def _buildServices(self, services):
"""Build the list of services to be sent over RPC."""
msg_services = list(self.ALWAYS_RUNNING_SERVICES)
for name, state in services.items():
service = service_monitor.getServiceByName(name)
status, status_info = yield state.getStatusInfo(service)
msg_services.append({
"name": name,
"status": status,
"status_info": status_info,
})
return msg_services
|