2424from nebula .addons .env import check_environment
2525from nebula .config .config import Config
2626from nebula .config .mender import Mender
27+ from nebula .controller .database import scenario_set_all_status_to_finished , scenario_set_status_to_finished
2728from nebula .controller .scenarios import Scenario , ScenarioManagement
28- from nebula .utils import DockerUtils , SocketUtils
29+ from nebula .utils import DockerUtils , FileUtils , SocketUtils
2930
3031
3132# Setup controller logger
@@ -271,9 +272,36 @@ async def run_scenario(
271272 return scenarioManagement .scenario_name
272273
273274
275+ @app .post ("/scenarios/stop" )
276+ async def stop_scenario (
277+ scenario_name : str = Body (..., embed = True ),
278+ username : str = Body (..., embed = True ),
279+ all : bool = Body (False , embed = True )
280+ ):
281+ from nebula .controller .scenarios import ScenarioManagement
282+
283+ ScenarioManagement .stop_participants (scenario_name )
284+ DockerUtils .remove_containers_by_prefix (f"{ os .environ .get ('NEBULA_CONTROLLER_NAME' )} _{ username } -participant" )
285+ DockerUtils .remove_docker_network (
286+ f"{ (os .environ .get ('NEBULA_CONTROLLER_NAME' ))} _{ str (username ).lower ()} -nebula-net-scenario"
287+ )
288+ ScenarioManagement .stop_blockchain ()
289+ try :
290+ if all :
291+ scenario_set_all_status_to_finished ()
292+ else :
293+ scenario_set_status_to_finished (scenario_name )
294+ except Exception as e :
295+ logging .error (f"Error setting scenario { scenario_name } to finished: { e } " )
296+ raise HTTPException (status_code = 500 , detail = "Internal server error" )
297+
298+ # Generate statistics for the scenario
299+ # path = FileUtils.check_path(os.environ.get("NEBULA_LOGS_DIR"), scenario_name)
300+ # ScenarioManagement.generate_statistics(path)
301+
274302@app .post ("/scenarios/remove" )
275303async def remove_scenario (
276- scenario_name : str = Body (..., embed = True )
304+ scenario_name : str = Body (..., embed = True ),
277305):
278306 """
279307 Removes a scenario from the database by its name.
@@ -288,6 +316,7 @@ async def remove_scenario(
288316
289317 try :
290318 remove_scenario_by_name (scenario_name )
319+ ScenarioManagement .remove_files_by_scenario (scenario_name )
291320 except Exception as e :
292321 logging .error (f"Error removing scenario { scenario_name } : { e } " )
293322 raise HTTPException (status_code = 500 , detail = "Internal server error" )
@@ -427,8 +456,27 @@ async def get_running_scenario(get_all: bool = False):
427456 raise HTTPException (status_code = 500 , detail = "Internal server error" )
428457
429458
430- @app .get ("/scenarios/check" )
431- async def check_scenario (role : str , scenario_name : str ):
459+ @app .get ("/scenarios/check/{role}/{scenario_name}" )
460+ async def check_scenario (
461+ role : Annotated [
462+ str ,
463+ Path (
464+ regex = "^[a-zA-Z0-9_-]+$" ,
465+ min_length = 1 ,
466+ max_length = 50 ,
467+ description = "Valid role"
468+ )
469+ ],
470+ scenario_name : Annotated [
471+ str ,
472+ Path (
473+ regex = "^[a-zA-Z0-9_-]+$" ,
474+ min_length = 1 ,
475+ max_length = 50 ,
476+ description = "Valid scenario name"
477+ )
478+ ]
479+ ):
432480 """
433481 Checks if a scenario is allowed for a specific role.
434482
0 commit comments