BackendConfigurationError bei DepotSelectionAlgorithmByLatency

Antworten
ZuseLab
Beiträge: 2
Registriert: 12 Jul 2016, 11:31

BackendConfigurationError bei DepotSelectionAlgorithmByLatency

Beitrag von ZuseLab »

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
Benutzeravatar
n.wenselowski
Ex-uib-Team
Beiträge: 3194
Registriert: 04 Apr 2013, 12:15

Re: BackendConfigurationError bei DepotSelectionAlgorithmByLatency

Beitrag von n.wenselowski »

Hi,
ZuseLab hat geschrieben: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"}}
Die Fehlermeldung sagt, dass dort in Zeile 176 die Einrückung nicht stimmt.
Bitte mal überprüfen, dass diese zum Rest passt. Das sieht man leider bei dem von dir gepasteten Block nicht.


Gruß

Niko

Code: Alles auswählen

import OPSI
ZuseLab
Beiträge: 2
Registriert: 12 Jul 2016, 11:31

Re: BackendConfigurationError bei DepotSelectionAlgorithmByLatency

Beitrag von ZuseLab »

Hi,

vielen Dank für den Hinweis, das hat geklappt.
Wie bzw. wann genau wird einer der Slaveserver genommen? Wählt er denjenigen mit der geringsten Latanzzeit nach einem Ping aus oder gibt es einer Latenzgrenze? Wenn also beim Ping eine gewisse Zeit überschritten wählt er einen der Slaveserver?


Dank
VG
Benutzeravatar
n.wenselowski
Ex-uib-Team
Beiträge: 3194
Registriert: 04 Apr 2013, 12:15

Re: BackendConfigurationError bei DepotSelectionAlgorithmByLatency

Beitrag von n.wenselowski »

Hi,

er pingt die relevanten Server und nimmt dann den mit der geringsten Latenz.
Default timeout für den Ping ist 2s.


Gruß

Niko

Code: Alles auswählen

import OPSI
Antworten