diff --git a/abst/__version__.py b/abst/__version__.py index d6cccdc..7dd177c 100644 --- a/abst/__version__.py +++ b/abst/__version__.py @@ -10,7 +10,7 @@ "CLI Command making OCI Bastion and kubernetes usage simple and fast" ) -__version__ = "2.3.57" +__version__ = "2.3.58" __author__ = "Jiri Otoupal" __author_email__ = "jiri-otoupal@ips-database.eu" __license__ = "MIT" @@ -28,6 +28,5 @@ __version_name__ = "SSHed Penguin" __change_log__ = """ -* 'abst ssh' will show screen with available instances for ssh from all abst processes\n -* moved old ssh to pod from 'abst ssh' to 'abst pod ssh' +* Deleting sessions now happens in parallel \n """ diff --git a/abst/bastion_support/bastion_scheduler.py b/abst/bastion_support/bastion_scheduler.py index 96233ac..46e45a2 100644 --- a/abst/bastion_support/bastion_scheduler.py +++ b/abst/bastion_support/bastion_scheduler.py @@ -1,3 +1,4 @@ +from concurrent.futures import ThreadPoolExecutor from pathlib import Path from threading import Thread from time import sleep @@ -99,7 +100,7 @@ def __display_loop(cls): while True: clear() cls.__display(console) - sleep(1.5) + sleep(1) @classmethod def _run_indefinitely(cls, func, force: bool = False): @@ -164,21 +165,34 @@ def local_port_in_stack(cls, context_name: str): return True, context_name return False, None + @classmethod + def kill_session(cls, sess, index, total): + try: + rich.print(f"[red]Killing[/red] {sess.bid}") + Bastion.current_status = "deleting" + sess.kill() + Bastion.delete_bastion_session(sess.bid, sess.region) + except Exception: + pass + @classmethod def kill_all(cls, a=None, b=None, c=None): # This should be only executed in running state cls.stopped = True blist_copy = list(cls.session_list) - for i, sess in enumerate(blist_copy): - try: - rich.print(f"[red]Killing[/red] {sess.bid}") - Bastion.current_status = "deleting" - sess.kill() - Bastion.delete_bastion_session(sess.bid, sess.region) - except Exception: - pass - finally: - print(f"Deleting {i + 1}/{len(blist_copy)}") + total_sessions = len(blist_copy) + deleted = 0 + + with ThreadPoolExecutor() as executor: + futures = [executor.submit(cls.kill_session, sess, i + 1, total_sessions) + for i, sess in enumerate(blist_copy)] + + # Optionally, wait for all futures to complete if you need synchronization + for future in futures: + future.result() # This will re-raise any exceptions caught during the session killings + deleted += 1 + print(f"Deleting {deleted}/{total_sessions}") + exit(0) @classmethod diff --git a/abst/bastion_support/oci_bastion.py b/abst/bastion_support/oci_bastion.py index c3781d3..860409e 100644 --- a/abst/bastion_support/oci_bastion.py +++ b/abst/bastion_support/oci_bastion.py @@ -116,7 +116,7 @@ def delete_bastion_session(cls, sess_id, region=None): oci.bastion.BastionClient(config).delete_session(sess_id) return except ServiceError: - sleep(1) + sleep(0.1) except Exception as ex: logging.info(f"Exception while trying to delete session {ex}") diff --git a/abst/cli_commands/create_cli/commands.py b/abst/cli_commands/create_cli/commands.py index 7701966..1274073 100644 --- a/abst/cli_commands/create_cli/commands.py +++ b/abst/cli_commands/create_cli/commands.py @@ -47,7 +47,7 @@ def forward(shell, debug, context_name): bastion = Bastion(used_name, region=Bastion.load_json(creds).get("region", None)) link_bastion_signals(bastion) bastion.create_forward_loop(shell=shell) - sleep(1) + sleep(0.1) except FileNotFoundError: rich.print("[red]No such context found[/red]") except KeyboardInterrupt: @@ -84,7 +84,7 @@ def managed(shell, debug, context_name): link_bastion_signals(bastion) bastion.create_managed_loop(shell=shell) - sleep(1) + sleep(0.1) except FileNotFoundError: rich.print("[red]No such context found[/red]") except KeyboardInterrupt: