/usr/lib/python3/dist-packages/provisioningserver/pserv_services/node_power_monitor_service.py is in python3-maas-provisioningserver 2.0.0~beta3+bzr4941-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 | # Copyright 2014-2016 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Service to periodically query the power state on this cluster's nodes."""
__all__ = [
"NodePowerMonitorService"
]
from datetime import timedelta
from provisioningserver.logger.log import get_maas_logger
from provisioningserver.power.query import query_all_nodes
from provisioningserver.rpc import getRegionClient
from provisioningserver.rpc.exceptions import (
NoConnectionsAvailable,
NoSuchCluster,
)
from provisioningserver.rpc.region import ListNodePowerParameters
from twisted.application.internet import TimerService
from twisted.internet.defer import inlineCallbacks
from twisted.python import log
maaslog = get_maas_logger("power_monitor_service")
class NodePowerMonitorService(TimerService, object):
"""Service to monitor the power status of all nodes in this cluster."""
check_interval = timedelta(seconds=15).total_seconds()
max_nodes_at_once = 5
def __init__(self, clock=None):
# Call self.query_nodes() every self.check_interval.
super(NodePowerMonitorService, self).__init__(
self.check_interval, self.try_query_nodes)
self.clock = clock
def try_query_nodes(self):
"""Attempt to query nodes' power states.
Log errors on failure, but do not propagate them up; that will
stop the timed loop from running.
"""
try:
client = getRegionClient()
except NoConnectionsAvailable:
maaslog.debug(
"Cannot monitor nodes' power status; "
"region not available.")
else:
d = self.query_nodes(client)
d.addErrback(self.query_nodes_failed, client.localIdent)
return d
@inlineCallbacks
def query_nodes(self, client):
# Get the nodes' power parameters from the region. Keep getting more
# power parameters until the region returns an empty list.
while True:
response = yield client(
ListNodePowerParameters, uuid=client.localIdent)
power_parameters = response['nodes']
if len(power_parameters) > 0:
yield query_all_nodes(
power_parameters, max_concurrency=self.max_nodes_at_once,
clock=self.clock)
else:
break
def query_nodes_failed(self, failure, localIdent):
if failure.check(NoSuchCluster):
maaslog.error(
"Rack controller '%s' is not recognised.", localIdent)
else:
# Log the error in full to the Twisted log.
log.err(failure, "Querying node power states.")
# Log something concise to the MAAS log.
maaslog.error(
"Failed to query nodes' power status: %s",
failure.getErrorMessage())
|