#!/usr/bin/env python# -*- coding: utf-8 -*-## @Author: Mingyeong YANG (mingyeong@khu.ac.kr), Florian Briegel (briegel@mpia.de)# @Date: 2021-03-22# @Filename: lvmnps/actor/actor.py# @License: BSD 3-clause (http://www.opensource.org/licenses/BSD-3-Clause)from__future__importannotationsimportasyncioimportpathlibfromosimportPathLikefromtypingimportTYPE_CHECKINGfromcluimportCommandfromlvmopstools.actorimportCheckError,ErrorData,LVMActor,create_error_codesfromsdsstools.configurationimportConfigurationfromlvmnpsimport__version__fromlvmnpsimportlogasnps_logfromlvmnps.actor.commandsimportlvmnps_command_parserfromlvmnps.exceptionsimportVerificationErrorfromlvmnps.nps.coreimportNPSClientfromlvmnps.nps.implementationsimportVALID_NPS_TYPESifTYPE_CHECKING:fromsdsstools.loggerimportSDSSLogger__all__=["NPSActor"]AnyPath=str|PathLike[str]CHECK_INTERVAL:float=5NPSErrorCodes=create_error_codes({"VERIFICATION_FAILED":ErrorData(1,critical=True,description="NPS verification failed.",)},name="NPSErrorCodes",)defget_nps_from_config(config:Configuration)->NPSClient:"""Returns an `.NPSClient` instance from the configuration parameters."""if"nps"notinconfig:raiseValueError("nps section does not exist in the configuration.")nps_type=config["nps.type"]ifnps_typeisNone:raiseValueError("nps.type not defined.")ifnps_typenotinVALID_NPS_TYPES:raiseValueError(f"Invalid NPS {nps_type}. Valid types are {VALID_NPS_TYPES}.")init_parameters=config.get("nps.init_parameters",{})ifnps_type=="dli":fromlvmnps.nps.implementations.dliimportDLIClientreturnDLIClient(**init_parameters)elifnps_type=="netio":fromlvmnps.nps.implementations.netioimportNetIOClientreturnNetIOClient(**init_parameters)else:# pragma: no cover - This should unreachable.raiseValueError(f"Invalid NPS {nps_type}. Valid types are {VALID_NPS_TYPES}.")
[docs]classNPSActor(LVMActor):"""LVM network power switches base actor."""parser=lvmnps_command_parserdef__init__(self,*args,schema:AnyPath|None=None,log:SDSSLogger|None=None,**kwargs,):cwd=pathlib.Path(__file__).parentschema=schemaorcwd/"schema.json"log=logornps_logkwargs["version"]=__version__super().__init__(*args,log=log,schema=schema,**kwargs)ifnotisinstance(self.config,Configuration):self.config=Configuration(self.config)self.nps=get_nps_from_config(self.config)self.restart_after=300self.restart_mode="exit"
[docs]asyncdefstart(self,**kwargs):# pragma: no cover"""Starts the actor."""try:awaitself.nps.setup()exceptExceptionaserr:self.log.error(f"Failed to setup NPS: {err}")self.log.error("Waiting 10 seconds and restarting ...")awaitasyncio.sleep(10)awaitself.restart()returnawaitsuper().start(**kwargs)
[docs]asyncdefstop(self):"Stops the actor."awaitself.nps.stop()returnawaitsuper().stop()
asyncdef_check_internal(self):"""Checks the NPS status."""try:result=awaitself.nps.verify()ifresultisFalse:raiseVerificationError("NPS verification failed.")exceptExceptionaserr:raiseCheckError(str(err),error_code=NPSErrorCodes.VERIFICATION_FAILED)self.check_interval=CHECK_INTERVALreturnTrueasyncdef_troubleshoot_internal(self,error_code,exception:Exception|None=None,):"""Handles internal troubleshooting."""iferror_code.value==NPSErrorCodes.VERIFICATION_FAILED:awaitself.restart(mode="exit")