renamed config service dependency finder method to startup_paths, added pydocs to config service related methods

This commit is contained in:
Blake Harnden 2020-01-27 11:44:00 -08:00
parent 09aa882017
commit 45fb32c834
3 changed files with 88 additions and 16 deletions

View file

@ -101,6 +101,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
:param context: :param context:
:return: session object that satisfies, if session not found then raise an :return: session object that satisfies, if session not found then raise an
exception exception
:raises Exception: raises grpc exception when session does not exist
""" """
session = self.coreemu.sessions.get(session_id) session = self.coreemu.sessions.get(session_id)
if not session: if not session:
@ -117,6 +118,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
:param node_id: node id :param node_id: node id
:param context: :param context:
:return: node object that satisfies. If node not found then raise an exception. :return: node object that satisfies. If node not found then raise an exception.
:raises Exception: raises grpc exception when node does not exist
""" """
try: try:
return session.get_node(node_id) return session.get_node(node_id)
@ -126,6 +128,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def validate_service( def validate_service(
self, name: str, context: ServicerContext self, name: str, context: ServicerContext
) -> Type[ConfigService]: ) -> Type[ConfigService]:
"""
Validates a configuration service is a valid known service.
:param name: name of service to validate
:param context: grpc context
:return: class for service to validate
:raises Exception: raises grpc exception when service does not exist
"""
service = self.coreemu.service_manager.services.get(name) service = self.coreemu.service_manager.services.get(name)
if not service: if not service:
context.abort(grpc.StatusCode.NOT_FOUND, f"unknown service {name}") context.abort(grpc.StatusCode.NOT_FOUND, f"unknown service {name}")
@ -138,7 +148,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
Start a session. Start a session.
:param request: start session request :param request: start session request
:param context: grcp context :param context: grpc context
:return: start session response :return: start session response
""" """
logging.debug("start session: %s", request) logging.debug("start session: %s", request)
@ -235,7 +245,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
Stop a running session. Stop a running session.
:param request: stop session request :param request: stop session request
:param context: grcp context :param context: grpc context
:return: stop session response :return: stop session response
""" """
logging.debug("stop session: %s", request) logging.debug("stop session: %s", request)
@ -1475,6 +1485,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetConfigServices( def GetConfigServices(
self, request: GetConfigServicesRequest, context: ServicerContext self, request: GetConfigServicesRequest, context: ServicerContext
) -> GetConfigServicesResponse: ) -> GetConfigServicesResponse:
"""
Gets all currently known configuration services.
:param request: get config services request
:param context: grpc context
:return: get config services response
"""
services = [] services = []
for service in self.coreemu.service_manager.services.values(): for service in self.coreemu.service_manager.services.values():
service_proto = ConfigService( service_proto = ConfigService(
@ -1497,6 +1514,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetNodeConfigService( def GetNodeConfigService(
self, request: GetNodeConfigServiceRequest, context: ServicerContext self, request: GetNodeConfigServiceRequest, context: ServicerContext
) -> GetNodeConfigServiceResponse: ) -> GetNodeConfigServiceResponse:
"""
Gets configuration, for a given configuration service, for a given node.
:param request: get node config service request
:param context: grpc context
:return: get node config service response
"""
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context)
self.validate_service(request.name, context) self.validate_service(request.name, context)
@ -1511,6 +1535,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetConfigServiceDefaults( def GetConfigServiceDefaults(
self, request: GetConfigServiceDefaultsRequest, context: ServicerContext self, request: GetConfigServiceDefaultsRequest, context: ServicerContext
) -> GetConfigServiceDefaultsResponse: ) -> GetConfigServiceDefaultsResponse:
"""
Get default values for a given configuration service.
:param request: get config service defaults request
:param context: grpc context
:return: get config service defaults response
"""
service_class = self.validate_service(request.name, context) service_class = self.validate_service(request.name, context)
service = service_class(None) service = service_class(None)
templates = service.get_templates() templates = service.get_templates()
@ -1536,6 +1567,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetNodeConfigServiceConfigs( def GetNodeConfigServiceConfigs(
self, request: GetNodeConfigServiceConfigsRequest, context: ServicerContext self, request: GetNodeConfigServiceConfigsRequest, context: ServicerContext
) -> GetNodeConfigServiceConfigsResponse: ) -> GetNodeConfigServiceConfigsResponse:
"""
Get current custom templates and config for configuration services for a given
node.
:param request: get node config service configs request
:param context: grpc context
:return: get node config service configs response
"""
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
configs = [] configs = []
for node in session.nodes.values(): for node in session.nodes.values():
@ -1557,6 +1596,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def GetNodeConfigServices( def GetNodeConfigServices(
self, request: GetNodeConfigServicesRequest, context: ServicerContext self, request: GetNodeConfigServicesRequest, context: ServicerContext
) -> GetNodeConfigServicesResponse: ) -> GetNodeConfigServicesResponse:
"""
Get configuration services for a given node.
:param request: get node config services request
:param context: grpc context
:return: get node config services response
"""
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context)
services = node.config_services.keys() services = node.config_services.keys()
@ -1565,6 +1611,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
def SetNodeConfigService( def SetNodeConfigService(
self, request: SetNodeConfigServiceRequest, context: ServicerContext self, request: SetNodeConfigServiceRequest, context: ServicerContext
) -> SetNodeConfigServiceResponse: ) -> SetNodeConfigServiceResponse:
"""
Set custom config, for a given configuration service, for a given node.
:param request: set node config service request
:param context: grpc context
:return: set node config service response
"""
session = self.get_session(request.session_id, context) session = self.get_session(request.session_id, context)
node = self.get_node(session, request.node_id, context) node = self.get_node(session, request.node_id, context)
self.validate_service(request.name, context) self.validate_service(request.name, context)

View file

@ -18,7 +18,7 @@ class ConfigServiceDependencies:
""" """
# helpers to check validity # helpers to check validity
self.dependents = {} self.dependents = {}
self.booted = set() self.started = set()
self.node_services = {} self.node_services = {}
for service in services.values(): for service in services.values():
self.node_services[service.name] = service self.node_services[service.name] = service
@ -31,18 +31,18 @@ class ConfigServiceDependencies:
self.visited = set() self.visited = set()
self.visiting = set() self.visiting = set()
def boot_paths(self) -> List[List["ConfigService"]]: def startup_paths(self) -> List[List["ConfigService"]]:
""" """
Find services sets based on dependencies. Find startup path sets based on service dependencies.
:return: lists of lists of services that can be started in parallel :return: lists of lists of services that can be started in parallel
""" """
paths = [] paths = []
for name in self.node_services: for name in self.node_services:
service = self.node_services[name] service = self.node_services[name]
if service.name in self.booted: if service.name in self.started:
logging.debug( logging.debug(
"skipping service that will already be booted: %s", service.name "skipping service that will already be started: %s", service.name
) )
continue continue
@ -50,10 +50,10 @@ class ConfigServiceDependencies:
if path: if path:
paths.append(path) paths.append(path)
if self.booted != set(self.node_services): if self.started != set(self.node_services):
raise ValueError( raise ValueError(
"failure to boot all services: %s != %s" "failure to start all services: %s != %s"
% (self.booted, self.node_services.keys()) % (self.started, self.node_services.keys())
) )
return paths return paths
@ -109,8 +109,8 @@ class ConfigServiceDependencies:
self._visit(service) self._visit(service)
# add service when bottom is found # add service when bottom is found
logging.debug("adding service to boot path: %s", current_service.name) logging.debug("adding service to startup path: %s", current_service.name)
self.booted.add(current_service.name) self.started.add(current_service.name)
self.path.append(current_service) self.path.append(current_service)
self.visiting.remove(current_service.name) self.visiting.remove(current_service.name)

View file

@ -285,22 +285,41 @@ class CoreNodeBase(NodeBase):
self.nodedir = None self.nodedir = None
self.tmpnodedir = False self.tmpnodedir = False
def add_config_service(self, service_class: "ConfigServiceType"): def add_config_service(self, service_class: "ConfigServiceType") -> None:
"""
Adds a configuration service to the node.
:param service_class: configuration service class to assign to node
:return: nothing
"""
name = service_class.name name = service_class.name
if name in self.config_services: if name in self.config_services:
raise CoreError(f"node({self.name}) already has service({name})") raise CoreError(f"node({self.name}) already has service({name})")
self.config_services[name] = service_class(self) self.config_services[name] = service_class(self)
def set_service_config(self, name: str, data: Dict[str, str]) -> None: def set_service_config(self, name: str, data: Dict[str, str]) -> None:
"""
Sets configuration service custom config data.
:param name: name of configuration service
:param data: custom config data to set
:return: nothing
"""
service = self.config_services.get(name) service = self.config_services.get(name)
if service is None: if service is None:
raise CoreError(f"node({self.name}) does not have service({name})") raise CoreError(f"node({self.name}) does not have service({name})")
service.set_config(data) service.set_config(data)
def start_config_services(self) -> None: def start_config_services(self) -> None:
boot_paths = ConfigServiceDependencies(self.config_services).boot_paths() """
for boot_path in boot_paths: Determins startup paths and starts configuration services, based on their
for service in boot_path: dependency chains.
:return: nothing
"""
startup_paths = ConfigServiceDependencies(self.config_services).startup_paths()
for startup_path in startup_paths:
for service in startup_path:
service.start() service.start()
def makenodedir(self) -> None: def makenodedir(self) -> None: