updated start proto to return exception strings, updated grpc start session to exist early when a failure is found, updated coretk ui to not switch ui to running when start fails and display error dialog
This commit is contained in:
parent
5639aeab75
commit
6d68034177
8 changed files with 70 additions and 36 deletions
|
@ -124,7 +124,10 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
session.add_hook(hook.state, hook.file, None, hook.data)
|
||||
|
||||
# create nodes
|
||||
grpcutils.create_nodes(session, request.nodes)
|
||||
_, exceptions = grpcutils.create_nodes(session, request.nodes)
|
||||
if exceptions:
|
||||
exceptions = [str(x) for x in exceptions]
|
||||
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
|
||||
|
||||
# emane configs
|
||||
config = session.emane.get_configs()
|
||||
|
@ -156,14 +159,28 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
)
|
||||
|
||||
# create links
|
||||
grpcutils.create_links(session, request.links)
|
||||
_, exceptions = grpcutils.create_links(session, request.links)
|
||||
if exceptions:
|
||||
exceptions = [str(x) for x in exceptions]
|
||||
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
|
||||
|
||||
# asymmetric links
|
||||
grpcutils.edit_links(session, request.asymmetric_links)
|
||||
_, exceptions = grpcutils.edit_links(session, request.asymmetric_links)
|
||||
if exceptions:
|
||||
exceptions = [str(x) for x in exceptions]
|
||||
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
|
||||
|
||||
# set to instantiation and start
|
||||
session.set_state(EventTypes.INSTANTIATION_STATE)
|
||||
session.instantiate()
|
||||
|
||||
# boot services
|
||||
boot_exceptions = session.instantiate()
|
||||
if boot_exceptions:
|
||||
exceptions = []
|
||||
for boot_exception in boot_exceptions:
|
||||
for service_exception in boot_exception.args:
|
||||
exceptions.append(str(service_exception))
|
||||
return core_pb2.StartSessionResponse(result=False, exceptions=exceptions)
|
||||
|
||||
return core_pb2.StartSessionResponse(result=True)
|
||||
|
||||
|
|
|
@ -635,7 +635,6 @@ class Session:
|
|||
:return: created node
|
||||
:raises core.CoreError: when an invalid node type is given
|
||||
"""
|
||||
|
||||
# validate node type, get class, or throw error
|
||||
if _cls is None:
|
||||
node_class = self.get_node_class(_type)
|
||||
|
@ -1450,17 +1449,19 @@ class Session:
|
|||
return
|
||||
|
||||
# boot node services and then start mobility
|
||||
self.boot_nodes()
|
||||
self.mobility.startup()
|
||||
exceptions = self.boot_nodes()
|
||||
if not exceptions:
|
||||
self.mobility.startup()
|
||||
|
||||
# notify listeners that instantiation is complete
|
||||
event = EventData(event_type=EventTypes.INSTANTIATION_COMPLETE.value)
|
||||
self.broadcast_event(event)
|
||||
# notify listeners that instantiation is complete
|
||||
event = EventData(event_type=EventTypes.INSTANTIATION_COMPLETE.value)
|
||||
self.broadcast_event(event)
|
||||
|
||||
# assume either all nodes have booted already, or there are some
|
||||
# nodes on slave servers that will be booted and those servers will
|
||||
# send a node status response message
|
||||
self.check_runtime()
|
||||
# assume either all nodes have booted already, or there are some
|
||||
# nodes on slave servers that will be booted and those servers will
|
||||
# send a node status response message
|
||||
self.check_runtime()
|
||||
return exceptions
|
||||
|
||||
def get_node_count(self):
|
||||
"""
|
||||
|
@ -1577,6 +1578,9 @@ class Session:
|
|||
Invoke the boot() procedure for all nodes and send back node
|
||||
messages to the GUI for node messages that had the status
|
||||
request flag.
|
||||
|
||||
:return: service boot exceptions
|
||||
:rtype: list[core.services.coreservices.ServiceBootError]
|
||||
"""
|
||||
with self._nodes_lock:
|
||||
funcs = []
|
||||
|
@ -1589,9 +1593,9 @@ class Session:
|
|||
results, exceptions = utils.threadpool(funcs)
|
||||
total = time.monotonic() - start
|
||||
logging.debug("boot run time: %s", total)
|
||||
if exceptions:
|
||||
raise CoreError(exceptions)
|
||||
self.update_control_interface_hosts()
|
||||
if not exceptions:
|
||||
self.update_control_interface_hosts()
|
||||
return exceptions
|
||||
|
||||
def get_control_net_prefixes(self):
|
||||
"""
|
||||
|
|
|
@ -6,6 +6,7 @@ import logging
|
|||
import os
|
||||
import time
|
||||
from pathlib import Path
|
||||
from tkinter import messagebox
|
||||
|
||||
import grpc
|
||||
|
||||
|
@ -476,21 +477,31 @@ class CoreClient:
|
|||
file_configs,
|
||||
asymmetric_links,
|
||||
)
|
||||
self.set_metadata()
|
||||
process_time = time.perf_counter() - start
|
||||
logging.debug(
|
||||
"start session(%s), result: %s", self.session_id, response.result
|
||||
)
|
||||
self.app.statusbar.start_session_callback(process_time)
|
||||
process_time = time.perf_counter() - start
|
||||
|
||||
# display mobility players
|
||||
for node_id, config in self.mobility_configs.items():
|
||||
canvas_node = self.canvas_nodes[node_id]
|
||||
mobility_player = MobilityPlayer(
|
||||
self.app, self.app, canvas_node, config
|
||||
)
|
||||
mobility_player.show()
|
||||
self.mobility_players[node_id] = mobility_player
|
||||
# stop progress bar and update status
|
||||
self.app.statusbar.progress_bar.stop()
|
||||
message = f"Start ran for {process_time:.3f} seconds"
|
||||
self.app.statusbar.set_status(message)
|
||||
|
||||
if response.result:
|
||||
self.set_metadata()
|
||||
self.app.toolbar.set_runtime()
|
||||
|
||||
# display mobility players
|
||||
for node_id, config in self.mobility_configs.items():
|
||||
canvas_node = self.canvas_nodes[node_id]
|
||||
mobility_player = MobilityPlayer(
|
||||
self.app, self.app, canvas_node, config
|
||||
)
|
||||
mobility_player.show()
|
||||
self.mobility_players[node_id] = mobility_player
|
||||
else:
|
||||
message = "\n".join(response.exceptions)
|
||||
messagebox.showerror("Start Error", message)
|
||||
except grpc.RpcError as e:
|
||||
show_grpc_error(e)
|
||||
|
||||
|
|
|
@ -68,10 +68,9 @@ class StatusBar(ttk.Frame):
|
|||
dialog = AlertsDialog(self.app, self.app)
|
||||
dialog.show()
|
||||
|
||||
def start_session_callback(self, process_time):
|
||||
self.progress_bar.stop()
|
||||
self.statusvar.set(f"Session started in {process_time:.3f} seconds")
|
||||
def set_status(self, message):
|
||||
self.statusvar.set(message)
|
||||
|
||||
def stop_session_callback(self, cleanup_time):
|
||||
self.progress_bar.stop()
|
||||
self.statusvar.set(f"Stopped session in {cleanup_time:.3f} seconds")
|
||||
self.statusvar.set(f"Stopped in {cleanup_time:.3f} seconds")
|
||||
|
|
|
@ -236,11 +236,12 @@ class Toolbar(ttk.Frame):
|
|||
:return: nothing
|
||||
"""
|
||||
self.app.canvas.hide_context()
|
||||
self.app.statusbar.core_alarms.clear()
|
||||
self.app.statusbar.progress_bar.start(5)
|
||||
self.app.canvas.mode = GraphMode.SELECT
|
||||
thread = threading.Thread(target=self.app.core.start_session)
|
||||
thread.start()
|
||||
|
||||
def set_runtime(self):
|
||||
self.runtime_frame.tkraise()
|
||||
self.click_runtime_selection()
|
||||
|
||||
|
|
|
@ -458,7 +458,7 @@ class CoreServices:
|
|||
"""
|
||||
Start all services on a node.
|
||||
|
||||
:param core.netns.vnode.LxcNode node: node to start services on
|
||||
:param core.nodes.base.CoreNode node: node to start services on
|
||||
:return: nothing
|
||||
"""
|
||||
boot_paths = ServiceDependencies(node.services).boot_paths()
|
||||
|
@ -468,7 +468,7 @@ class CoreServices:
|
|||
funcs.append((self._start_boot_paths, args, {}))
|
||||
result, exceptions = utils.threadpool(funcs)
|
||||
if exceptions:
|
||||
raise ServiceBootError(exceptions)
|
||||
raise ServiceBootError(*exceptions)
|
||||
|
||||
def _start_boot_paths(self, node, boot_path):
|
||||
"""
|
||||
|
|
|
@ -8,7 +8,7 @@ from core import constants, utils
|
|||
from core.errors import CoreCommandError
|
||||
from core.nodes import ipaddress
|
||||
from core.nodes.ipaddress import Ipv4Prefix, Ipv6Prefix
|
||||
from core.services.coreservices import CoreService
|
||||
from core.services.coreservices import CoreService, ServiceMode
|
||||
|
||||
|
||||
class UtilService(CoreService):
|
||||
|
@ -173,6 +173,7 @@ class SshService(UtilService):
|
|||
startup = ("sh startsshd.sh",)
|
||||
shutdown = ("killall sshd",)
|
||||
validate = ()
|
||||
validation_mode = ServiceMode.BLOCKING
|
||||
|
||||
@classmethod
|
||||
def generate_config(cls, node, filename):
|
||||
|
|
|
@ -155,6 +155,7 @@ message StartSessionRequest {
|
|||
|
||||
message StartSessionResponse {
|
||||
bool result = 1;
|
||||
repeated string exceptions = 2;
|
||||
}
|
||||
|
||||
message StopSessionRequest {
|
||||
|
|
Loading…
Reference in a new issue