BackendConfigurationError bei DepotSelectionAlgorithmByLatency
Verfasst: 12 Jul 2016, 12:06
Hallo,
wir nutzen die neueste OPSI Version und versuchen in unserem Netzwerk die Depotauswahl dynmaisch zu halten. Dabei sind wir entsprechend des Handbuchs vorgegangen. Nachdem wir in der 70_dynamic_depot.conf unter /etc/opsi/backendManager/extend.d$ ganz unten return self.getDepotSelectionAlgorithmByLatency() einkommentiert und #return self.getDepotSelectionAlgorithmByNetworkAddress() auskommentiert haben. Danach bekommen wir auf der Weboberfläche folgenden Fehler:
Jul 12 11:57:53.178 2016 -- Response 500 Internal Server Error {"result": null, "id": null, "error": {"message": "Backend configuration error: Failed to read extensions from '/etc/opsi/backendManager/extend.d': Error reading file u'/etc/opsi/backendManager/extend.d/70_dynamic_depot.conf': unexpected indent (70_dynamic_depot.conf, line 176)", "class": "BackendConfigurationError"}}
Wenn wir versuchen den Server "service opsiconfd restart" neu zu starten, startet dieser nicht mehr. Setzen wir die Einstellungen in der 70_dynamic_depot.conf zurück funktioniert alles wieden. Auch die Depotauswahl nach NetworkAddress funktioniert einwandfrei.
70_dynamic_depot.conf (original):
# -*- coding: utf-8 -*-
global showDepotInfoFunction
showDepotInfoFunction = \
'''
def showDepotInfo():
logger.info(u"Choosing depot from list of depots:")
logger.info(u" Master depot: %s" % masterDepot)
for alternativeDepot in alternativeDepots:
logger.info(u" Alternative depot: %s" % alternativeDepot)
'''
global getDepotWithLowestLatencyFunction
getDepotWithLowestLatencyFunction = \
'''
def getDepotWithLowestLatency(latency):
"""
Given a dict with depot as key and latency as value it will \
return the depot with the lowest latency.
Will return None if no depot can be determined.
"""
selectedDepot = None
if latency:
minValue = 1000
for (depot, value) in latency.items():
if value < minValue:
minValue = value
selectedDepot = depot
logger.notice(u"Depot with lowest latency: %s (%0.3f ms)" % (selectedDepot, minValue*1000))
return selectedDepot
'''
global getLatencyInformationFunction
getLatencyInformationFunction = \
'''
def getLatencyInformation(depots):
"""
Pings the given depots and returns the latency information in \
a dict with depot as key and the latency as value.
Depots that can't be reached in time will not be included.
"""
from OPSI.Util.Ping import ping
from OPSI.Util.HTTP import urlsplit
latency = {}
for depot in depots:
if not depot.repositoryRemoteUrl:
logger.info(
"Skipping {depot} because repositoryRemoteUrl is "
"missing.".format(depot=depot)
)
continue
try:
(_, host, _, _, _, _) = urlsplit(depot.repositoryRemoteUrl)
# To increase the timeout (in seconds) for the ping you
# can implement it in the following way:
# depotLatency = ping(host, timeout=5)
depotLatency = ping(host)
if depotLatency is None:
logger.info(u"Ping to depot {0} timed out.".format(depot))
else:
logger.info(u"Latency of depot %s: %0.3f ms" % (depot, depotLatency * 1000))
latency[depot] = depotLatency
except Exception as e:
logger.warning(e)
return latency
'''
def getDepotSelectionAlgorithmByMasterDepotAndLatency(self):
return '''\
def selectDepot(clientConfig, masterDepot, alternativeDepots=[]):
{getLatencyInformationFunction}
{getDepotWithLowestLatencyFunction}
{showDepotInfoFunction}
showDepotInfo()
if alternativeDepots:
from collections import defaultdict
# Mapping of depots to its master.
# key: Master depot
# value: All slave depots + master
depotsByMaster = defaultdict(list)
allDepots = [masterDepot] + alternativeDepots
for depot in allDepots:
if depot.masterDepotId:
depotsByMaster[depot.masterDepotId].append(depot)
else:
depotsByMaster[depot.id].append(depot)
depotsWithLatency = getLatencyInformation(depotsByMaster[masterDepot.id])
depotWithLowestLatency = getDepotWithLowestLatency(depotsWithLatency)
if not depotWithLowestLatency:
logger.info('No depot with lowest latency. Falling back to master depot.')
depotWithLowestLatency = masterDepot
return depotWithLowestLatency
return masterDepot
'''.format(
showDepotInfoFunction=showDepotInfoFunction,
getLatencyInformationFunction=getLatencyInformationFunction,
getDepotWithLowestLatencyFunction=getDepotWithLowestLatencyFunction
)
def getDepotSelectionAlgorithmByLatency(self):
return '''\
def selectDepot(clientConfig, masterDepot, alternativeDepots=[]):
{getLatencyInformationFunction}
{getDepotWithLowestLatencyFunction}
{showDepotInfoFunction}
showDepotInfo()
selectedDepot = masterDepot
if alternativeDepots:
depotsWithLatency = getLatencyInformation([masterDepot] + alternativeDepots)
selectedDepot = getDepotWithLowestLatency(depotsWithLatency)
if not selectedDepot:
logger.info('No depot with lowest latency. Falling back to master depot.')
selectedDepot = masterDepot
return selectedDepot
'''.format(
showDepotInfoFunction=showDepotInfoFunction,
getLatencyInformationFunction=getLatencyInformationFunction,
getDepotWithLowestLatencyFunction=getDepotWithLowestLatencyFunction
)
def getDepotSelectionAlgorithmByNetworkAddress(self):
return '''\
def selectDepot(clientConfig, masterDepot, alternativeDepots=[]):
{showDepotInfoFunction}
showDepotInfo()
selectedDepot = masterDepot
if alternativeDepots:
from OPSI.Util import ipAddressInNetwork
depots = [masterDepot]
depots.extend(alternativeDepots)
for depot in depots:
if not depot.networkAddress:
logger.warning(u"Network address of depot '%s' not known" % depot)
continue
if ipAddressInNetwork(clientConfig['ipAddress'], depot.networkAddress):
logger.notice(u"Choosing depot with networkAddress %s for ip %s" % (depot.networkAddress, clientConfig['ipAddress']))
selectedDepot = depot
break
else:
logger.info(u"IP %s does not match networkAddress %s of depot %s" % (clientConfig['ipAddress'], depot.networkAddress, depot))
return selectedDepot
'''.format(
showDepotInfoFunction=showDepotInfoFunction,
)
def getDepotSelectionAlgorithm(self):
""" Returns the selected depot selection algorythm. """
# return self.getDepotSelectionAlgorithmByMasterDepotAndLatency()
# return self.getDepotSelectionAlgorithmByLatency()
return self.getDepotSelectionAlgorithmByNetworkAddress()
def getBytes(self, num):
if (num <= 0):
return ""
len128 = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
bytes = ""
while (len(bytes) < num):
bytes += len128
if (len(bytes) > num):
bytes = bytes[:num]
return bytes
Kann jemand helfen?
Gruß
S. Schiller
wir nutzen die neueste OPSI Version und versuchen in unserem Netzwerk die Depotauswahl dynmaisch zu halten. Dabei sind wir entsprechend des Handbuchs vorgegangen. Nachdem wir in der 70_dynamic_depot.conf unter /etc/opsi/backendManager/extend.d$ ganz unten return self.getDepotSelectionAlgorithmByLatency() einkommentiert und #return self.getDepotSelectionAlgorithmByNetworkAddress() auskommentiert haben. Danach bekommen wir auf der Weboberfläche folgenden Fehler:
Jul 12 11:57:53.178 2016 -- Response 500 Internal Server Error {"result": null, "id": null, "error": {"message": "Backend configuration error: Failed to read extensions from '/etc/opsi/backendManager/extend.d': Error reading file u'/etc/opsi/backendManager/extend.d/70_dynamic_depot.conf': unexpected indent (70_dynamic_depot.conf, line 176)", "class": "BackendConfigurationError"}}
Wenn wir versuchen den Server "service opsiconfd restart" neu zu starten, startet dieser nicht mehr. Setzen wir die Einstellungen in der 70_dynamic_depot.conf zurück funktioniert alles wieden. Auch die Depotauswahl nach NetworkAddress funktioniert einwandfrei.
70_dynamic_depot.conf (original):
# -*- coding: utf-8 -*-
global showDepotInfoFunction
showDepotInfoFunction = \
'''
def showDepotInfo():
logger.info(u"Choosing depot from list of depots:")
logger.info(u" Master depot: %s" % masterDepot)
for alternativeDepot in alternativeDepots:
logger.info(u" Alternative depot: %s" % alternativeDepot)
'''
global getDepotWithLowestLatencyFunction
getDepotWithLowestLatencyFunction = \
'''
def getDepotWithLowestLatency(latency):
"""
Given a dict with depot as key and latency as value it will \
return the depot with the lowest latency.
Will return None if no depot can be determined.
"""
selectedDepot = None
if latency:
minValue = 1000
for (depot, value) in latency.items():
if value < minValue:
minValue = value
selectedDepot = depot
logger.notice(u"Depot with lowest latency: %s (%0.3f ms)" % (selectedDepot, minValue*1000))
return selectedDepot
'''
global getLatencyInformationFunction
getLatencyInformationFunction = \
'''
def getLatencyInformation(depots):
"""
Pings the given depots and returns the latency information in \
a dict with depot as key and the latency as value.
Depots that can't be reached in time will not be included.
"""
from OPSI.Util.Ping import ping
from OPSI.Util.HTTP import urlsplit
latency = {}
for depot in depots:
if not depot.repositoryRemoteUrl:
logger.info(
"Skipping {depot} because repositoryRemoteUrl is "
"missing.".format(depot=depot)
)
continue
try:
(_, host, _, _, _, _) = urlsplit(depot.repositoryRemoteUrl)
# To increase the timeout (in seconds) for the ping you
# can implement it in the following way:
# depotLatency = ping(host, timeout=5)
depotLatency = ping(host)
if depotLatency is None:
logger.info(u"Ping to depot {0} timed out.".format(depot))
else:
logger.info(u"Latency of depot %s: %0.3f ms" % (depot, depotLatency * 1000))
latency[depot] = depotLatency
except Exception as e:
logger.warning(e)
return latency
'''
def getDepotSelectionAlgorithmByMasterDepotAndLatency(self):
return '''\
def selectDepot(clientConfig, masterDepot, alternativeDepots=[]):
{getLatencyInformationFunction}
{getDepotWithLowestLatencyFunction}
{showDepotInfoFunction}
showDepotInfo()
if alternativeDepots:
from collections import defaultdict
# Mapping of depots to its master.
# key: Master depot
# value: All slave depots + master
depotsByMaster = defaultdict(list)
allDepots = [masterDepot] + alternativeDepots
for depot in allDepots:
if depot.masterDepotId:
depotsByMaster[depot.masterDepotId].append(depot)
else:
depotsByMaster[depot.id].append(depot)
depotsWithLatency = getLatencyInformation(depotsByMaster[masterDepot.id])
depotWithLowestLatency = getDepotWithLowestLatency(depotsWithLatency)
if not depotWithLowestLatency:
logger.info('No depot with lowest latency. Falling back to master depot.')
depotWithLowestLatency = masterDepot
return depotWithLowestLatency
return masterDepot
'''.format(
showDepotInfoFunction=showDepotInfoFunction,
getLatencyInformationFunction=getLatencyInformationFunction,
getDepotWithLowestLatencyFunction=getDepotWithLowestLatencyFunction
)
def getDepotSelectionAlgorithmByLatency(self):
return '''\
def selectDepot(clientConfig, masterDepot, alternativeDepots=[]):
{getLatencyInformationFunction}
{getDepotWithLowestLatencyFunction}
{showDepotInfoFunction}
showDepotInfo()
selectedDepot = masterDepot
if alternativeDepots:
depotsWithLatency = getLatencyInformation([masterDepot] + alternativeDepots)
selectedDepot = getDepotWithLowestLatency(depotsWithLatency)
if not selectedDepot:
logger.info('No depot with lowest latency. Falling back to master depot.')
selectedDepot = masterDepot
return selectedDepot
'''.format(
showDepotInfoFunction=showDepotInfoFunction,
getLatencyInformationFunction=getLatencyInformationFunction,
getDepotWithLowestLatencyFunction=getDepotWithLowestLatencyFunction
)
def getDepotSelectionAlgorithmByNetworkAddress(self):
return '''\
def selectDepot(clientConfig, masterDepot, alternativeDepots=[]):
{showDepotInfoFunction}
showDepotInfo()
selectedDepot = masterDepot
if alternativeDepots:
from OPSI.Util import ipAddressInNetwork
depots = [masterDepot]
depots.extend(alternativeDepots)
for depot in depots:
if not depot.networkAddress:
logger.warning(u"Network address of depot '%s' not known" % depot)
continue
if ipAddressInNetwork(clientConfig['ipAddress'], depot.networkAddress):
logger.notice(u"Choosing depot with networkAddress %s for ip %s" % (depot.networkAddress, clientConfig['ipAddress']))
selectedDepot = depot
break
else:
logger.info(u"IP %s does not match networkAddress %s of depot %s" % (clientConfig['ipAddress'], depot.networkAddress, depot))
return selectedDepot
'''.format(
showDepotInfoFunction=showDepotInfoFunction,
)
def getDepotSelectionAlgorithm(self):
""" Returns the selected depot selection algorythm. """
# return self.getDepotSelectionAlgorithmByMasterDepotAndLatency()
# return self.getDepotSelectionAlgorithmByLatency()
return self.getDepotSelectionAlgorithmByNetworkAddress()
def getBytes(self, num):
if (num <= 0):
return ""
len128 = "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
bytes = ""
while (len(bytes) < num):
bytes += len128
if (len(bytes) > num):
bytes = bytes[:num]
return bytes
Kann jemand helfen?
Gruß
S. Schiller