diff --git a/doc/helper.html b/doc/helper.html index fac8094..eb567fc 100644 --- a/doc/helper.html +++ b/doc/helper.html @@ -68,6 +68,9 @@ Methods __get_regex_acl Gibt formatierten RegEx-String zurueck. +__iter__ +Gibt einzelne ACLs als aus. + __set_acl Uebernimmt neue ACL-Liste fuer die Ausertung der Level. @@ -86,11 +89,17 @@ Static Methods

IpAclManager (Constructor)

-IpAclManager(acl=None, minlevel=0, maxlevel=0) +IpAclManager(minlevel, maxlevel, acl=None)

Init IpAclManager class.

-
acl
+
minlevel
+
+Smallest access level (min. 0) +
maxlevel
+
+Biggest access level (max. 9) +
acl
ACL Liste fuer Berechtigungen als
@@ -108,6 +117,12 @@ IpAclManager.__get_regex_acl

Gibt formatierten RegEx-String zurueck. return RegEx Code als +

+

+IpAclManager.__iter__

+__iter__() +

+Gibt einzelne ACLs als aus.

IpAclManager.__set_acl

diff --git a/doc/xrpcserver.html b/doc/xrpcserver.html index 8ff5aec..2b5fd14 100644 --- a/doc/xrpcserver.html +++ b/doc/xrpcserver.html @@ -125,7 +125,7 @@ Static Methods

SaveXMLRPCServer (Constructor)

-SaveXMLRPCServer(addr, logRequests=True, allow_none=False, use_builtin_types=False, ipacl=IpAclManager()) +SaveXMLRPCServer(addr, logRequests=True, allow_none=False, use_builtin_types=False, ipacl=None)

Init SaveXMLRPCServer class.

diff --git a/eric-revpipyload.api b/eric-revpipyload.api index a6a64d2..3d4c816 100644 --- a/eric-revpipyload.api +++ b/eric-revpipyload.api @@ -1,11 +1,12 @@ helper.IpAclManager.__get_acl?6() helper.IpAclManager.__get_regex_acl?6() +helper.IpAclManager.__iter__?6() helper.IpAclManager.__set_acl?6(value) helper.IpAclManager.acl?7 helper.IpAclManager.get_acllevel?4(ipaddress) helper.IpAclManager.loadacl?4(str_acl) helper.IpAclManager.regex_acl?7 -helper.IpAclManager?1(acl=None, minlevel=0, maxlevel=0) +helper.IpAclManager?1(minlevel, maxlevel, acl=None) helper._setuprt?5(pid, evt_exit) helper._zeroprocimg?5() helper.refullmatch?4(regex, string) @@ -90,4 +91,4 @@ xrpcserver.SaveXMLRPCServer.isAlive?4() xrpcserver.SaveXMLRPCServer.register_function?4(acl_level, function, name=None) xrpcserver.SaveXMLRPCServer.start?4() xrpcserver.SaveXMLRPCServer.stop?4() -xrpcserver.SaveXMLRPCServer?1(addr, logRequests=True, allow_none=False, use_builtin_types=False, ipacl=IpAclManager()) +xrpcserver.SaveXMLRPCServer?1(addr, logRequests=True, allow_none=False, use_builtin_types=False, ipacl=None) diff --git a/revpipyload.e4p b/revpipyload.e4p index e3175a6..930cc3d 100644 --- a/revpipyload.e4p +++ b/revpipyload.e4p @@ -1,7 +1,7 @@ - + en_US @@ -9,7 +9,7 @@ Python3 Console Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten. - 0.6.0 + 0.6.1 Sven Sager akira@narux.de diff --git a/revpipyload/helper.py b/revpipyload/helper.py index 2e9e3bc..e73c960 100644 --- a/revpipyload/helper.py +++ b/revpipyload/helper.py @@ -16,17 +16,28 @@ class IpAclManager(): """Verwaltung fuer IP Adressen und deren ACL Level.""" - def __init__(self, acl=None, minlevel=0, maxlevel=0): + def __init__(self, minlevel, maxlevel, acl=None): """Init IpAclManager class. - @param acl ACL Liste fuer Berechtigungen als """ - if minlevel > maxlevel: - raise ValueError("minlevel is smaller than maxlevel") + + @param minlevel Smallest access level (min. 0) + @param maxlevel Biggest access level (max. 9) + @param acl ACL Liste fuer Berechtigungen als + + """ + if type(minlevel) != int: + raise ValueError("parameter minlevel must be ") + if type(maxlevel) != int: + raise ValueError("parameter maxlevel must be ") if minlevel < 0: raise ValueError("minlevel must be 0 or more") + if maxlevel > 9: + raise ValueError("maxlevel maximum is 9") + if minlevel > maxlevel: + raise ValueError("minlevel is smaller than maxlevel") self.__dict_acl = {} - self.__dict_ips = {} - self.__rawacl = "" + self.__dict_regex = {} + self.__dict_knownips = {} self.__re_ipacl = "(([\\d\\*]{1,3}\\.){3}[\\d\\*]{1,3},[" \ + str(minlevel) + "-" + str(maxlevel) + "] ?)*" @@ -34,10 +45,18 @@ class IpAclManager(): if acl is not None: self.__set_acl(acl) + def __iter__(self): + """Gibt einzelne ACLs als aus.""" + for aclip in sorted(self.__dict_acl): + yield (aclip, self.__dict_acl[aclip]) + def __get_acl(self): """Getter fuer den rohen ACL-String. return ACLs als """ - return self.__rawacl + str_acl = "" + for aclip in sorted(self.__dict_acl): + str_acl += "{},{} ".format(aclip, self.__dict_acl[aclip]) + return str_acl.strip() def __get_regex_acl(self): """Gibt formatierten RegEx-String zurueck. @@ -50,32 +69,34 @@ class IpAclManager(): if type(value) != str: raise ValueError("parameter acl must be ") + value = value.strip() if not refullmatch(self.__re_ipacl, value): raise ValueError("acl format ist not okay - 1.2.3.4,0 5.6.7.8,1") # Klassenwerte übernehmen self.__dict_acl = {} - self.__dict_ips = {} - self.__rawacl = value + self.__dict_regex = {} + self.__dict_knownips = {} # Liste neu füllen mit regex Strings for ip_level in value.split(): ip, level = ip_level.split(",", 1) - ip = ip.replace(".", "\\.").replace("*", "\\d{1,3}") self.__dict_acl[ip] = int(level) + self.__dict_regex[ip] = \ + ip.replace(".", "\\.").replace("*", "\\d{1,3}") def get_acllevel(self, ipaddress): """Prueft IP gegen ACL List und gibt ACL-Wert aus. @param ipaddress zum pruefen @return ACL Wert oder -1 wenn nicht gefunden""" # Bei bereits aufgelösten IPs direkt ACL auswerten - if ipaddress in self.__dict_ips: - return self.__dict_ips[ipaddress] + if ipaddress in self.__dict_knownips: + return self.__dict_knownips[ipaddress] for aclip in sorted(self.__dict_acl, reverse=True): - if refullmatch(aclip, ipaddress): + if refullmatch(self.__dict_regex[aclip], ipaddress): # IP und Level merken - self.__dict_ips[ipaddress] = self.__dict_acl[aclip] + self.__dict_knownips[ipaddress] = self.__dict_acl[aclip] # Level zurückgeben return self.__dict_acl[aclip] @@ -86,10 +107,10 @@ class IpAclManager(): """Laed ACL String und gibt erfolg zurueck. @param str_acl ACL als @return True, wenn erfolgreich uebernommen""" - if refullmatch(self.__re_ipacl, str_acl): - self.__set_acl(str_acl) - return True - return False + if not refullmatch(self.__re_ipacl, str_acl): + return False + self.__set_acl(str_acl) + return True acl = property(__get_acl, __set_acl) regex_acl = property(__get_regex_acl) diff --git a/revpipyload/plcsystem.py b/revpipyload/plcsystem.py index aca9587..61958ee 100644 --- a/revpipyload/plcsystem.py +++ b/revpipyload/plcsystem.py @@ -39,6 +39,7 @@ class RevPiPlc(Thread): self._procplc = None self._pversion = pversion self.autoreload = False + self.autoreloaddelay = 5 * 2 self.exitcode = None self.gid = 65534 self.uid = 65534 @@ -131,44 +132,54 @@ class RevPiPlc(Thread): _setuprt(self._procplc.pid, self._evt_exit) # Überwachung starten + delaycounter = self.autoreloaddelay while not self._evt_exit.is_set(): # Auswerten self.exitcode = self._procplc.poll() if self.exitcode is not None: - if self.exitcode > 0: - # PLC Python Programm abgestürzt - proginit.logger.error( - "plc program crashed - exitcode: {}".format( - self.exitcode + if delaycounter == self.autoreloaddelay: + if self.exitcode > 0: + # PLC Python Programm abgestürzt + proginit.logger.error( + "plc program crashed - exitcode: {}".format( + self.exitcode + ) ) - ) - if self.zeroonerror: - _zeroprocimg() - proginit.logger.warning( - "set piControl0 to ZERO after PLC program error") + if self.zeroonerror: + _zeroprocimg() + proginit.logger.warning( + "set piControl0 to ZERO after " + "PLC program error" + ) - else: - # PLC Python Programm sauber beendet - proginit.logger.info("plc program did a clean exit") - if self.zeroonexit: - _zeroprocimg() - proginit.logger.info( - "set piControl0 to ZERO after PLC program returns " - "clean exitcode") + else: + # PLC Python Programm sauber beendet + proginit.logger.info("plc program did a clean exit") + if self.zeroonexit: + _zeroprocimg() + proginit.logger.info( + "set piControl0 to ZERO after " + "PLC program returns clean exitcode" + ) if not self._evt_exit.is_set() and self.autoreload: - # Prozess neu starten - self._procplc = self._spopen(lst_proc) - if self.exitcode == 0: - proginit.logger.warning( - "restart plc program after clean exit" - ) + if delaycounter > 0: + delaycounter -= 1 else: - proginit.logger.warning( - "restart plc program after crash" - ) + delaycounter = self.autoreloaddelay + + # Prozess neu starten + self._procplc = self._spopen(lst_proc) + if self.exitcode == 0: + proginit.logger.warning( + "restart plc program after clean exit" + ) + else: + proginit.logger.warning( + "restart plc program after crash" + ) else: break diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py index a0c6c30..e665643 100755 --- a/revpipyload/revpipyload.py +++ b/revpipyload/revpipyload.py @@ -49,7 +49,7 @@ from time import asctime from xmlrpc.client import Binary from xrpcserver import SaveXMLRPCServer -pyloadversion = "0.6.0" +pyloadversion = "0.6.1" class RevPiPyLoad(): @@ -305,6 +305,7 @@ class RevPiPyLoad(): self.pythonversion ) th_plc.autoreload = bool(self.autoreload) + th_plc.autoreloaddelay = self.autoreloaddelay th_plc.gid = int(self.plcgid) th_plc.uid = int(self.plcuid) th_plc.rtlevel = int(self.rtlevel) diff --git a/revpipyload/xrpcserver.py b/revpipyload/xrpcserver.py index 2320006..3304bed 100644 --- a/revpipyload/xrpcserver.py +++ b/revpipyload/xrpcserver.py @@ -18,7 +18,7 @@ class SaveXMLRPCServer(SimpleXMLRPCServer): def __init__( self, addr, logRequests=True, allow_none=False, - use_builtin_types=False, ipacl=IpAclManager()): + use_builtin_types=False, ipacl=None): """Init SaveXMLRPCServer class.""" proginit.logger.debug("enter SaveXMLRPCServer.__init__()") @@ -34,7 +34,10 @@ class SaveXMLRPCServer(SimpleXMLRPCServer): ) # Klassenvariablen - self.aclmgr = ipacl + if ipacl is None: + self.aclmgr = IpAclManager(0, 0) + else: + self.aclmgr = ipacl self.funcacls = {} self.requestacl = -1 self.tpe = futures.ThreadPoolExecutor(max_workers=1) diff --git a/setup.py b/setup.py index 07ca3b9..8102a5c 100644 --- a/setup.py +++ b/setup.py @@ -27,11 +27,12 @@ setup( license="LGPLv3", name="revpipyload", - version="0.6.0", + version="0.6.1", scripts=["data/revpipyload"], install_requires=["revpimodio2"], + python_requires=">=3.2", data_files=[ ("/etc/avahi/services", [ diff --git a/stdeb.cfg b/stdeb.cfg index 191693a..b883c01 100644 --- a/stdeb.cfg +++ b/stdeb.cfg @@ -3,4 +3,3 @@ Debian-Version: 1 Depends3: python3-revpimodio2 (>= 2.0.0) Package: revpipyload Suite: stable -X-Python3-Version: >=3.2