machineconfig 1.97__py3-none-any.whl โ 2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/cloud_manager.py +22 -29
- machineconfig/cluster/data_transfer.py +2 -3
- machineconfig/cluster/distribute.py +0 -2
- machineconfig/cluster/file_manager.py +4 -5
- machineconfig/cluster/job_params.py +1 -4
- machineconfig/cluster/loader_runner.py +8 -11
- machineconfig/cluster/remote_machine.py +4 -5
- machineconfig/cluster/script_execution.py +2 -2
- machineconfig/cluster/script_notify_upon_completion.py +0 -1
- machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +4 -6
- machineconfig/cluster/sessions_managers/archive/session_managers.py +0 -1
- machineconfig/cluster/sessions_managers/enhanced_command_runner.py +35 -75
- machineconfig/cluster/sessions_managers/wt_local.py +113 -185
- machineconfig/cluster/sessions_managers/wt_local_manager.py +127 -197
- machineconfig/cluster/sessions_managers/wt_remote.py +60 -67
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +110 -149
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +61 -64
- machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +72 -172
- machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +27 -60
- machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +58 -137
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +46 -74
- machineconfig/cluster/sessions_managers/zellij_local.py +91 -147
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +165 -190
- machineconfig/cluster/sessions_managers/zellij_remote.py +51 -58
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +40 -46
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +19 -17
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +30 -31
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +64 -134
- machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +7 -11
- machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +27 -55
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +14 -13
- machineconfig/cluster/templates/cli_click.py +0 -1
- machineconfig/cluster/templates/cli_gooey.py +0 -2
- machineconfig/cluster/templates/cli_trogon.py +0 -1
- machineconfig/cluster/templates/run_cloud.py +0 -1
- machineconfig/cluster/templates/run_cluster.py +0 -1
- machineconfig/cluster/templates/run_remote.py +0 -1
- machineconfig/cluster/templates/utils.py +27 -11
- machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/linux/msc/cli_agents.sh +16 -0
- machineconfig/jobs/python/check_installations.py +9 -9
- machineconfig/jobs/python/create_bootable_media.py +0 -2
- machineconfig/jobs/python/python_cargo_build_share.py +2 -2
- machineconfig/jobs/python/python_ve_symlink.py +9 -11
- machineconfig/jobs/python/tasks.py +0 -1
- machineconfig/jobs/python/vscode/api.py +5 -5
- machineconfig/jobs/python/vscode/link_ve.py +20 -21
- machineconfig/jobs/python/vscode/select_interpreter.py +28 -29
- machineconfig/jobs/python/vscode/sync_code.py +14 -18
- machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +15 -15
- machineconfig/jobs/python_custom_installers/dev/aider.py +10 -18
- machineconfig/jobs/python_custom_installers/dev/alacritty.py +12 -21
- machineconfig/jobs/python_custom_installers/dev/brave.py +13 -22
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +13 -20
- machineconfig/jobs/python_custom_installers/dev/code.py +17 -24
- machineconfig/jobs/python_custom_installers/dev/cursor.py +10 -21
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +12 -11
- machineconfig/jobs/python_custom_installers/dev/espanso.py +19 -23
- machineconfig/jobs/python_custom_installers/dev/goes.py +9 -16
- machineconfig/jobs/python_custom_installers/dev/lvim.py +13 -21
- machineconfig/jobs/python_custom_installers/dev/nerdfont.py +15 -22
- machineconfig/jobs/python_custom_installers/dev/redis.py +15 -23
- machineconfig/jobs/python_custom_installers/dev/wezterm.py +15 -22
- machineconfig/jobs/python_custom_installers/dev/winget.py +32 -50
- machineconfig/jobs/python_custom_installers/docker.py +15 -24
- machineconfig/jobs/python_custom_installers/gh.py +18 -26
- machineconfig/jobs/python_custom_installers/hx.py +33 -17
- machineconfig/jobs/python_custom_installers/warp-cli.py +15 -23
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_generic_installers/config.json +412 -389
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_windows_installers/dev/config.json +1 -1
- machineconfig/jobs/windows/archive/archive_pygraphviz.ps1 +1 -1
- machineconfig/jobs/windows/msc/cli_agents.bat +0 -0
- machineconfig/jobs/windows/msc/cli_agents.ps1 +0 -0
- machineconfig/jobs/windows/start_terminal.ps1 +1 -1
- machineconfig/logger.py +50 -0
- machineconfig/profile/create.py +50 -36
- machineconfig/profile/create_hardlinks.py +33 -26
- machineconfig/profile/shell.py +87 -60
- machineconfig/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/cloud/init.sh +2 -2
- machineconfig/scripts/linux/checkout_versions +1 -1
- machineconfig/scripts/linux/choose_wezterm_theme +1 -1
- machineconfig/scripts/linux/cloud_copy +1 -1
- machineconfig/scripts/linux/cloud_manager +1 -1
- machineconfig/scripts/linux/cloud_mount +1 -1
- machineconfig/scripts/linux/cloud_repo_sync +1 -1
- machineconfig/scripts/linux/cloud_sync +1 -1
- machineconfig/scripts/linux/croshell +1 -1
- machineconfig/scripts/linux/devops +3 -5
- machineconfig/scripts/linux/fire +2 -1
- machineconfig/scripts/linux/fire_agents +3 -3
- machineconfig/scripts/linux/ftpx +1 -1
- machineconfig/scripts/linux/gh_models +1 -1
- machineconfig/scripts/linux/kill_process +1 -1
- machineconfig/scripts/linux/mcinit +2 -2
- machineconfig/scripts/linux/repos +1 -1
- machineconfig/scripts/linux/scheduler +1 -1
- machineconfig/scripts/linux/start_slidev +1 -1
- machineconfig/scripts/linux/start_terminals +1 -1
- machineconfig/scripts/linux/url2md +1 -1
- machineconfig/scripts/linux/warp-cli.sh +122 -0
- machineconfig/scripts/linux/wifi_conn +1 -1
- machineconfig/scripts/python/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/croshell.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-313.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/__init__.py +0 -0
- machineconfig/scripts/python/ai/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/generate_files.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/mcinit.cpython-313.pyc +0 -0
- machineconfig/scripts/python/ai/chatmodes/Thinking-Beast-Mode.chatmode.md +337 -0
- machineconfig/scripts/python/ai/chatmodes/Ultimate-Transparent-Thinking-Beast-Mode.chatmode.md +644 -0
- machineconfig/scripts/python/ai/chatmodes/deepResearch.chatmode.md +81 -0
- machineconfig/scripts/python/ai/configs/.gemini/settings.json +81 -0
- machineconfig/scripts/python/ai/generate_files.py +84 -0
- machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +45 -0
- machineconfig/scripts/python/ai/mcinit.py +107 -0
- machineconfig/scripts/python/ai/prompts/allLintersAndTypeCheckers.prompt.md +5 -0
- machineconfig/scripts/python/ai/prompts/research-report-skeleton.prompt.md +38 -0
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +52 -0
- machineconfig/scripts/python/archive/tmate_conn.py +5 -5
- machineconfig/scripts/python/archive/tmate_start.py +3 -3
- machineconfig/scripts/python/choose_wezterm_theme.py +2 -2
- machineconfig/scripts/python/cloud_copy.py +20 -19
- machineconfig/scripts/python/cloud_mount.py +10 -8
- machineconfig/scripts/python/cloud_repo_sync.py +15 -15
- machineconfig/scripts/python/cloud_sync.py +1 -1
- machineconfig/scripts/python/croshell.py +18 -16
- machineconfig/scripts/python/devops.py +6 -6
- machineconfig/scripts/python/devops_add_identity.py +9 -7
- machineconfig/scripts/python/devops_add_ssh_key.py +19 -19
- machineconfig/scripts/python/devops_backup_retrieve.py +14 -14
- machineconfig/scripts/python/devops_devapps_install.py +3 -3
- machineconfig/scripts/python/devops_update_repos.py +141 -53
- machineconfig/scripts/python/dotfile.py +3 -3
- machineconfig/scripts/python/fire_agents.py +202 -41
- machineconfig/scripts/python/fire_jobs.py +20 -21
- machineconfig/scripts/python/ftpx.py +4 -3
- machineconfig/scripts/python/gh_models.py +94 -94
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-313.pyc +0 -0
- machineconfig/scripts/python/helpers/cloud_helpers.py +3 -3
- machineconfig/scripts/python/helpers/helpers2.py +3 -3
- machineconfig/scripts/python/helpers/helpers4.py +8 -7
- machineconfig/scripts/python/helpers/helpers5.py +7 -7
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +2 -2
- machineconfig/scripts/python/mount_nfs.py +4 -3
- machineconfig/scripts/python/mount_nw_drive.py +4 -4
- machineconfig/scripts/python/mount_ssh.py +4 -3
- machineconfig/scripts/python/repos.py +9 -9
- machineconfig/scripts/python/scheduler.py +1 -1
- machineconfig/scripts/python/start_slidev.py +9 -8
- machineconfig/scripts/python/start_terminals.py +1 -1
- machineconfig/scripts/python/viewer.py +40 -40
- machineconfig/scripts/python/wifi_conn.py +65 -66
- machineconfig/scripts/python/wsl_windows_transfer.py +2 -2
- machineconfig/scripts/windows/checkout_version.ps1 +1 -3
- machineconfig/scripts/windows/choose_wezterm_theme.ps1 +1 -3
- machineconfig/scripts/windows/cloud_copy.ps1 +2 -6
- machineconfig/scripts/windows/cloud_manager.ps1 +1 -1
- machineconfig/scripts/windows/cloud_repo_sync.ps1 +1 -2
- machineconfig/scripts/windows/cloud_sync.ps1 +2 -2
- machineconfig/scripts/windows/croshell.ps1 +2 -2
- machineconfig/scripts/windows/devops.ps1 +1 -4
- machineconfig/scripts/windows/dotfile.ps1 +1 -3
- machineconfig/scripts/windows/fire.ps1 +1 -1
- machineconfig/scripts/windows/ftpx.ps1 +2 -2
- machineconfig/scripts/windows/gpt.ps1 +1 -1
- machineconfig/scripts/windows/kill_process.ps1 +1 -2
- machineconfig/scripts/windows/mcinit.ps1 +2 -2
- machineconfig/scripts/windows/mount_nfs.ps1 +1 -1
- machineconfig/scripts/windows/mount_ssh.ps1 +1 -1
- machineconfig/scripts/windows/pomodoro.ps1 +1 -1
- machineconfig/scripts/windows/py2exe.ps1 +1 -3
- machineconfig/scripts/windows/repos.ps1 +1 -1
- machineconfig/scripts/windows/scheduler.ps1 +1 -1
- machineconfig/scripts/windows/snapshot.ps1 +2 -2
- machineconfig/scripts/windows/start_slidev.ps1 +1 -1
- machineconfig/scripts/windows/start_terminals.ps1 +1 -1
- machineconfig/scripts/windows/wifi_conn.ps1 +1 -1
- machineconfig/scripts/windows/wsl_windows_transfer.ps1 +1 -3
- machineconfig/settings/lf/linux/lfrc +1 -1
- machineconfig/settings/linters/.ruff.toml +2 -2
- machineconfig/settings/linters/.ruff_cache/.gitignore +2 -0
- machineconfig/settings/linters/.ruff_cache/CACHEDIR.TAG +1 -0
- machineconfig/settings/lvim/windows/archive/config_additional.lua +1 -1
- machineconfig/settings/shells/ipy/profiles/default/startup/playext.py +71 -71
- machineconfig/settings/shells/wt/settings.json +8 -8
- machineconfig/settings/svim/linux/init.toml +1 -1
- machineconfig/settings/svim/windows/init.toml +1 -1
- machineconfig/setup_linux/web_shortcuts/croshell.sh +0 -54
- machineconfig/setup_linux/web_shortcuts/interactive.sh +6 -6
- machineconfig/setup_linux/web_shortcuts/tmp.sh +2 -0
- machineconfig/setup_windows/web_shortcuts/all.ps1 +2 -2
- machineconfig/setup_windows/web_shortcuts/ascii_art.ps1 +1 -1
- machineconfig/setup_windows/web_shortcuts/croshell.ps1 +1 -1
- machineconfig/setup_windows/web_shortcuts/interactive.ps1 +5 -5
- machineconfig/setup_windows/wt_and_pwsh/install_fonts.ps1 +51 -15
- machineconfig/setup_windows/wt_and_pwsh/set_pwsh_theme.py +75 -18
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +52 -42
- machineconfig/utils/ai/browser_user_wrapper.py +5 -5
- machineconfig/utils/ai/generate_file_checklist.py +19 -22
- machineconfig/utils/ai/url2md.py +5 -3
- machineconfig/utils/cloud/onedrive/setup_oauth.py +5 -4
- machineconfig/utils/cloud/onedrive/transaction.py +192 -227
- machineconfig/utils/code.py +71 -43
- machineconfig/utils/installer.py +77 -85
- machineconfig/utils/installer_utils/installer_abc.py +29 -17
- machineconfig/utils/installer_utils/installer_class.py +188 -83
- machineconfig/utils/io_save.py +3 -15
- machineconfig/utils/links.py +22 -11
- machineconfig/utils/notifications.py +197 -0
- machineconfig/utils/options.py +38 -25
- machineconfig/utils/path.py +18 -6
- machineconfig/utils/path_reduced.py +637 -316
- machineconfig/utils/procs.py +69 -63
- machineconfig/utils/scheduling.py +11 -13
- machineconfig/utils/ssh.py +351 -0
- machineconfig/utils/terminal.py +225 -0
- machineconfig/utils/utils.py +13 -12
- machineconfig/utils/utils2.py +43 -10
- machineconfig/utils/utils5.py +242 -46
- machineconfig/utils/ve.py +11 -6
- {machineconfig-1.97.dist-info โ machineconfig-2.1.dist-info}/METADATA +15 -9
- {machineconfig-1.97.dist-info โ machineconfig-2.1.dist-info}/RECORD +232 -235
- machineconfig/cluster/self_ssh.py +0 -57
- machineconfig/jobs/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python/archive/python_tools.txt +0 -12
- machineconfig/jobs/python/vscode/__pycache__/select_interpreter.cpython-311.pyc +0 -0
- machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/jobs/python_generic_installers/update.py +0 -3
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/create.cpython-311.pyc +0 -0
- machineconfig/profile/__pycache__/shell.cpython-311.pyc +0 -0
- machineconfig/scripts/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/linux/activate_ve +0 -87
- machineconfig/scripts/python/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_copy.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_mount.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/cloud_sync.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/croshell.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_backup_retrieve.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_devapps_install.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/devops_update_repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_agents.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/fire_jobs.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/get_zellij_cmd.cpython-311.pyc +0 -0
- machineconfig/scripts/python/__pycache__/repos.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/__pycache__/init.cpython-311.pyc +0 -0
- machineconfig/scripts/python/ai/init.py +0 -56
- machineconfig/scripts/python/ai/rules/python/dev.md +0 -31
- machineconfig/scripts/python/helpers/__pycache__/__init__.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/cloud_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers2.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/helpers4.cpython-311.pyc +0 -0
- machineconfig/scripts/python/helpers/__pycache__/repo_sync_helpers.cpython-311.pyc +0 -0
- machineconfig/scripts/windows/activate_ve.ps1 +0 -54
- {machineconfig-1.97.dist-info โ machineconfig-2.1.dist-info}/WHEEL +0 -0
- {machineconfig-1.97.dist-info โ machineconfig-2.1.dist-info}/top_level.txt +0 -0
|
@@ -10,6 +10,9 @@ from machineconfig.cluster.sessions_managers.wt_remote import WTRemoteLayoutGene
|
|
|
10
10
|
|
|
11
11
|
TMP_SERIALIZATION_DIR = Path.home().joinpath("tmp_results", "session_manager", "wt", "remote_manager")
|
|
12
12
|
|
|
13
|
+
# Module-level logger to be used throughout this module
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
class WTSessionManager:
|
|
15
18
|
def __init__(self, machine2wt_tabs: dict[str, dict[str, tuple[str, str]]], session_name_prefix: str = "WTJobMgr"):
|
|
@@ -34,13 +37,10 @@ class WTSessionManager:
|
|
|
34
37
|
a_cmd = run_command_in_wt_tab(command=ssh_cmd, tab_name=hostname, cwd=None)
|
|
35
38
|
cmds += a_cmd + "\n"
|
|
36
39
|
return cmds
|
|
37
|
-
|
|
40
|
+
|
|
38
41
|
def kill_all_sessions(self) -> None:
|
|
39
42
|
for an_m in self.managers:
|
|
40
|
-
WTRemoteLayoutGenerator.run_remote_command(
|
|
41
|
-
remote_name=an_m.remote_name,
|
|
42
|
-
command="powershell -Command \"Get-Process -Name 'WindowsTerminal' -ErrorAction SilentlyContinue | Stop-Process -Force\""
|
|
43
|
-
)
|
|
43
|
+
WTRemoteLayoutGenerator.run_remote_command(remote_name=an_m.remote_name, command="powershell -Command \"Get-Process -Name 'WindowsTerminal' -ErrorAction SilentlyContinue | Stop-Process -Force\"")
|
|
44
44
|
|
|
45
45
|
def run_monitoring_routine(self, wait_ms: int = 60000) -> None:
|
|
46
46
|
def routine(scheduler: Scheduler):
|
|
@@ -60,12 +60,12 @@ class WTSessionManager:
|
|
|
60
60
|
for i, key in enumerate(keys):
|
|
61
61
|
if i < len(values):
|
|
62
62
|
status_data.append({"tabName": key, "status": values[i]})
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
# Check if all stopped
|
|
65
65
|
running_count = sum(1 for item in status_data if item.get("status", {}).get("running", False))
|
|
66
66
|
if running_count == 0: # they all stopped
|
|
67
67
|
scheduler.max_cycles = scheduler.cycle # stop the scheduler from calling this routine again
|
|
68
|
-
|
|
68
|
+
|
|
69
69
|
# Print status
|
|
70
70
|
for item in status_data:
|
|
71
71
|
print(f"Tab: {item['tabName']}, Status: {item['status']}")
|
|
@@ -74,68 +74,63 @@ class WTSessionManager:
|
|
|
74
74
|
for _idx, an_m in enumerate(self.managers):
|
|
75
75
|
a_status = an_m.check_wt_session_status()
|
|
76
76
|
statuses.append(a_status)
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
# Print statuses
|
|
79
79
|
for i, status in enumerate(statuses):
|
|
80
80
|
print(f"Manager {i}: {status}")
|
|
81
|
-
|
|
81
|
+
|
|
82
|
+
sched = Scheduler(routine=routine, wait_ms=wait_ms, logger=logger)
|
|
82
83
|
sched.run()
|
|
83
84
|
|
|
84
85
|
def save(self, session_id: Optional[str] = None) -> str:
|
|
85
86
|
if session_id is None:
|
|
86
87
|
session_id = str(uuid.uuid4())[:8]
|
|
87
|
-
|
|
88
|
+
|
|
88
89
|
# Create session directory
|
|
89
90
|
session_dir = TMP_SERIALIZATION_DIR / session_id
|
|
90
91
|
session_dir.mkdir(parents=True, exist_ok=True)
|
|
91
|
-
|
|
92
|
+
|
|
92
93
|
# Save the machine2wt_tabs configuration
|
|
93
94
|
config_file = session_dir / "machine2wt_tabs.json"
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
text = json.dumps(self.machine2wt_tabs, indent=2, ensure_ascii=False)
|
|
96
|
+
config_file.write_text(text, encoding="utf-8")
|
|
97
|
+
|
|
97
98
|
# Save session metadata
|
|
98
|
-
metadata = {
|
|
99
|
-
"session_name_prefix": self.session_name_prefix,
|
|
100
|
-
"created_at": str(datetime.now()),
|
|
101
|
-
"num_managers": len(self.managers),
|
|
102
|
-
"machines": list(self.machine2wt_tabs.keys()),
|
|
103
|
-
"manager_type": "WTSessionManager"
|
|
104
|
-
}
|
|
99
|
+
metadata = {"session_name_prefix": self.session_name_prefix, "created_at": str(datetime.now()), "num_managers": len(self.managers), "machines": list(self.machine2wt_tabs.keys()), "manager_type": "WTSessionManager"}
|
|
105
100
|
metadata_file = session_dir / "metadata.json"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
101
|
+
text = json.dumps(metadata, indent=2, ensure_ascii=False)
|
|
102
|
+
metadata_file.write_text(text, encoding="utf-8")
|
|
103
|
+
|
|
109
104
|
# Save each WTRemoteLayoutGenerator
|
|
110
105
|
managers_dir = session_dir / "managers"
|
|
111
106
|
managers_dir.mkdir(exist_ok=True)
|
|
112
|
-
|
|
107
|
+
|
|
113
108
|
for i, manager in enumerate(self.managers):
|
|
114
109
|
manager_file = managers_dir / f"manager_{i}_{manager.remote_name}.json"
|
|
115
110
|
manager.to_json(str(manager_file))
|
|
116
|
-
|
|
117
|
-
|
|
111
|
+
|
|
112
|
+
logger.info(f"โ
Saved WTSessionManager session to: {session_dir}")
|
|
118
113
|
return session_id
|
|
119
114
|
|
|
120
115
|
@classmethod
|
|
121
|
-
def load(cls, session_id: str) ->
|
|
116
|
+
def load(cls, session_id: str) -> "WTSessionManager":
|
|
122
117
|
session_dir = TMP_SERIALIZATION_DIR / session_id
|
|
123
|
-
|
|
118
|
+
|
|
124
119
|
if not session_dir.exists():
|
|
125
|
-
raise FileNotFoundError(f"Session directory not found: {session_dir}")
|
|
120
|
+
raise FileNotFoundError(f"Session directory not found: {session_dir}")
|
|
126
121
|
config_file = session_dir / "machine2wt_tabs.json"
|
|
127
122
|
if not config_file.exists():
|
|
128
|
-
raise FileNotFoundError(f"Configuration file not found: {config_file}")
|
|
129
|
-
with open(config_file,
|
|
123
|
+
raise FileNotFoundError(f"Configuration file not found: {config_file}")
|
|
124
|
+
with open(config_file, "r", encoding="utf-8") as f:
|
|
130
125
|
machine2wt_tabs = json.load(f)
|
|
131
|
-
|
|
126
|
+
|
|
132
127
|
# Load metadata
|
|
133
128
|
metadata_file = session_dir / "metadata.json"
|
|
134
129
|
session_name_prefix = "WTJobMgr" # default fallback
|
|
135
130
|
if metadata_file.exists():
|
|
136
|
-
with open(metadata_file,
|
|
131
|
+
with open(metadata_file, "r", encoding="utf-8") as f:
|
|
137
132
|
metadata = json.load(f)
|
|
138
|
-
session_name_prefix = metadata.get("session_name_prefix", "WTJobMgr")
|
|
133
|
+
session_name_prefix = metadata.get("session_name_prefix", "WTJobMgr")
|
|
139
134
|
# Create new instance (this will create new managers)
|
|
140
135
|
instance = cls(machine2wt_tabs=machine2wt_tabs, session_name_prefix=session_name_prefix)
|
|
141
136
|
# Load saved managers to restore their states
|
|
@@ -144,43 +139,44 @@ class WTSessionManager:
|
|
|
144
139
|
# Clear the auto-created managers and load the saved ones
|
|
145
140
|
instance.managers = []
|
|
146
141
|
# Get all manager files and sort them
|
|
147
|
-
manager_files = sorted(managers_dir.glob("manager_*.json"))
|
|
142
|
+
manager_files = sorted(managers_dir.glob("manager_*.json"))
|
|
148
143
|
for manager_file in manager_files:
|
|
149
144
|
try:
|
|
150
145
|
loaded_manager = WTRemoteLayoutGenerator.from_json(str(manager_file))
|
|
151
146
|
instance.managers.append(loaded_manager)
|
|
152
147
|
except Exception as e:
|
|
153
|
-
|
|
154
|
-
|
|
148
|
+
logger.warning(f"Failed to load manager from {manager_file}: {e}")
|
|
149
|
+
logger.info(f"โ
Loaded WTSessionManager session from: {session_dir}")
|
|
155
150
|
return instance
|
|
156
151
|
|
|
157
152
|
@staticmethod
|
|
158
153
|
def list_saved_sessions() -> list[str]:
|
|
159
154
|
if not TMP_SERIALIZATION_DIR.exists():
|
|
160
155
|
return []
|
|
161
|
-
|
|
156
|
+
|
|
162
157
|
sessions = []
|
|
163
158
|
for item in TMP_SERIALIZATION_DIR.iterdir():
|
|
164
159
|
if item.is_dir() and (item / "metadata.json").exists():
|
|
165
160
|
sessions.append(item.name)
|
|
166
|
-
|
|
161
|
+
|
|
167
162
|
return sorted(sessions)
|
|
168
163
|
|
|
169
164
|
@staticmethod
|
|
170
165
|
def delete_session(session_id: str) -> bool:
|
|
171
166
|
session_dir = TMP_SERIALIZATION_DIR / session_id
|
|
172
|
-
|
|
167
|
+
|
|
173
168
|
if not session_dir.exists():
|
|
174
|
-
|
|
169
|
+
logger.warning(f"Session directory not found: {session_dir}")
|
|
175
170
|
return False
|
|
176
|
-
|
|
171
|
+
|
|
177
172
|
try:
|
|
178
173
|
import shutil
|
|
174
|
+
|
|
179
175
|
shutil.rmtree(session_dir)
|
|
180
|
-
|
|
176
|
+
logger.info(f"โ
Deleted session: {session_id}")
|
|
181
177
|
return True
|
|
182
178
|
except Exception as e:
|
|
183
|
-
|
|
179
|
+
logger.error(f"Failed to delete session {session_id}: {e}")
|
|
184
180
|
return False
|
|
185
181
|
|
|
186
182
|
def start_all_sessions(self) -> dict[str, Any]:
|
|
@@ -190,85 +186,64 @@ class WTSessionManager:
|
|
|
190
186
|
try:
|
|
191
187
|
session_name = manager.session_name
|
|
192
188
|
remote_name = manager.remote_name
|
|
193
|
-
|
|
189
|
+
|
|
194
190
|
# Start the Windows Terminal session on the remote machine
|
|
195
191
|
start_result = manager.start_wt_session()
|
|
196
|
-
|
|
192
|
+
|
|
197
193
|
results[f"{remote_name}:{session_name}"] = start_result
|
|
198
|
-
|
|
194
|
+
|
|
199
195
|
if start_result.get("success"):
|
|
200
|
-
|
|
196
|
+
logger.info(f"โ
Started session '{session_name}' on {remote_name}")
|
|
201
197
|
else:
|
|
202
|
-
|
|
203
|
-
|
|
198
|
+
logger.error(f"โ Failed to start session '{session_name}' on {remote_name}: {start_result.get('error')}")
|
|
199
|
+
|
|
204
200
|
except Exception as e:
|
|
205
|
-
results[f"{manager.remote_name}:{manager.session_name}"] = {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}
|
|
209
|
-
logging.error(f"โ Exception starting session on {manager.remote_name}: {e}")
|
|
210
|
-
|
|
201
|
+
results[f"{manager.remote_name}:{manager.session_name}"] = {"success": False, "error": str(e)}
|
|
202
|
+
logger.error(f"โ Exception starting session on {manager.remote_name}: {e}")
|
|
203
|
+
|
|
211
204
|
return results
|
|
212
205
|
|
|
213
206
|
def check_all_sessions_status(self) -> dict[str, dict[str, Any]]:
|
|
214
207
|
"""Check the status of all remote sessions and their commands."""
|
|
215
208
|
status_report = {}
|
|
216
|
-
|
|
209
|
+
|
|
217
210
|
for manager in self.managers:
|
|
218
211
|
session_key = f"{manager.remote_name}:{manager.session_name}"
|
|
219
|
-
|
|
212
|
+
|
|
220
213
|
try:
|
|
221
214
|
# Get Windows Terminal session status
|
|
222
215
|
wt_status = manager.check_wt_session_status()
|
|
223
|
-
|
|
216
|
+
|
|
224
217
|
# Get commands status for this session
|
|
225
218
|
commands_status = manager.check_all_commands_status()
|
|
226
|
-
|
|
219
|
+
|
|
227
220
|
# Calculate summary for this session
|
|
228
221
|
running_count = sum(1 for status in commands_status.values() if status.get("running", False))
|
|
229
222
|
total_count = len(commands_status)
|
|
230
|
-
|
|
223
|
+
|
|
231
224
|
status_report[session_key] = {
|
|
232
225
|
"remote_name": manager.remote_name,
|
|
233
226
|
"session_name": manager.session_name,
|
|
234
227
|
"wt_status": wt_status,
|
|
235
228
|
"commands_status": commands_status,
|
|
236
|
-
"summary": {
|
|
237
|
-
"total_commands": total_count,
|
|
238
|
-
"running_commands": running_count,
|
|
239
|
-
"stopped_commands": total_count - running_count,
|
|
240
|
-
"session_healthy": wt_status.get("wt_running", False)
|
|
241
|
-
}
|
|
229
|
+
"summary": {"total_commands": total_count, "running_commands": running_count, "stopped_commands": total_count - running_count, "session_healthy": wt_status.get("wt_running", False)},
|
|
242
230
|
}
|
|
243
|
-
|
|
231
|
+
|
|
244
232
|
except Exception as e:
|
|
245
|
-
status_report[session_key] = {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
"error": str(e),
|
|
249
|
-
"summary": {
|
|
250
|
-
"total_commands": 0,
|
|
251
|
-
"running_commands": 0,
|
|
252
|
-
"stopped_commands": 0,
|
|
253
|
-
"session_healthy": False
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
logging.error(f"Error checking status for {session_key}: {e}")
|
|
257
|
-
|
|
233
|
+
status_report[session_key] = {"remote_name": manager.remote_name, "session_name": manager.session_name, "error": str(e), "summary": {"total_commands": 0, "running_commands": 0, "stopped_commands": 0, "session_healthy": False}}
|
|
234
|
+
logger.error(f"Error checking status for {session_key}: {e}")
|
|
235
|
+
|
|
258
236
|
return status_report
|
|
259
237
|
|
|
260
238
|
def get_global_summary(self) -> dict[str, Any]:
|
|
261
239
|
"""Get a global summary across all remote sessions."""
|
|
262
240
|
all_status = self.check_all_sessions_status()
|
|
263
|
-
|
|
241
|
+
|
|
264
242
|
total_sessions = len(all_status)
|
|
265
|
-
healthy_sessions = sum(1 for status in all_status.values()
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
total_running = sum(status["summary"]["running_commands"]
|
|
270
|
-
for status in all_status.values())
|
|
271
|
-
|
|
243
|
+
healthy_sessions = sum(1 for status in all_status.values() if status["summary"]["session_healthy"])
|
|
244
|
+
total_commands = sum(status["summary"]["total_commands"] for status in all_status.values())
|
|
245
|
+
total_running = sum(status["summary"]["running_commands"] for status in all_status.values())
|
|
246
|
+
|
|
272
247
|
return {
|
|
273
248
|
"total_sessions": total_sessions,
|
|
274
249
|
"healthy_sessions": healthy_sessions,
|
|
@@ -278,18 +253,18 @@ class WTSessionManager:
|
|
|
278
253
|
"stopped_commands": total_commands - total_running,
|
|
279
254
|
"all_sessions_healthy": healthy_sessions == total_sessions,
|
|
280
255
|
"all_commands_running": total_running == total_commands,
|
|
281
|
-
"remote_machines": list(set(status["remote_name"] for status in all_status.values()))
|
|
256
|
+
"remote_machines": list(set(status["remote_name"] for status in all_status.values())),
|
|
282
257
|
}
|
|
283
258
|
|
|
284
259
|
def print_status_report(self) -> None:
|
|
285
260
|
"""Print a comprehensive status report for all remote sessions."""
|
|
286
261
|
all_status = self.check_all_sessions_status()
|
|
287
262
|
global_summary = self.get_global_summary()
|
|
288
|
-
|
|
263
|
+
|
|
289
264
|
print("=" * 80)
|
|
290
265
|
print("๐ฅ๏ธ WINDOWS TERMINAL REMOTE MANAGER STATUS REPORT")
|
|
291
266
|
print("=" * 80)
|
|
292
|
-
|
|
267
|
+
|
|
293
268
|
# Global summary
|
|
294
269
|
print("๐ GLOBAL SUMMARY:")
|
|
295
270
|
print(f" Total sessions: {global_summary['total_sessions']}")
|
|
@@ -299,24 +274,24 @@ class WTSessionManager:
|
|
|
299
274
|
print(f" Remote machines: {len(global_summary['remote_machines'])}")
|
|
300
275
|
print(f" All healthy: {'โ
' if global_summary['all_sessions_healthy'] else 'โ'}")
|
|
301
276
|
print()
|
|
302
|
-
|
|
277
|
+
|
|
303
278
|
# Per-session details
|
|
304
279
|
for _, status in all_status.items():
|
|
305
280
|
remote_name = status["remote_name"]
|
|
306
281
|
session_name = status["session_name"]
|
|
307
|
-
|
|
282
|
+
|
|
308
283
|
print(f"๐ฅ๏ธ REMOTE: {remote_name} | SESSION: {session_name}")
|
|
309
284
|
print("-" * 60)
|
|
310
|
-
|
|
285
|
+
|
|
311
286
|
if "error" in status:
|
|
312
287
|
print(f"โ Error: {status['error']}")
|
|
313
288
|
print()
|
|
314
289
|
continue
|
|
315
|
-
|
|
290
|
+
|
|
316
291
|
wt_status = status["wt_status"]
|
|
317
292
|
commands_status = status["commands_status"]
|
|
318
293
|
summary = status["summary"]
|
|
319
|
-
|
|
294
|
+
|
|
320
295
|
# Windows Terminal session health
|
|
321
296
|
if wt_status.get("wt_running", False):
|
|
322
297
|
if wt_status.get("session_exists", False):
|
|
@@ -329,7 +304,7 @@ class WTSessionManager:
|
|
|
329
304
|
print(f"โ ๏ธ Windows Terminal is running but no session windows found on {remote_name}")
|
|
330
305
|
else:
|
|
331
306
|
print(f"โ Windows Terminal issue on {remote_name}: {wt_status.get('error', 'Unknown error')}")
|
|
332
|
-
|
|
307
|
+
|
|
333
308
|
# Commands in this session
|
|
334
309
|
print(f" Commands ({summary['running_commands']}/{summary['total_commands']} running):")
|
|
335
310
|
for tab_name, cmd_status in commands_status.items():
|
|
@@ -338,146 +313,132 @@ class WTSessionManager:
|
|
|
338
313
|
if len(cmd_status.get("command", "")) > 50:
|
|
339
314
|
cmd_text += "..."
|
|
340
315
|
print(f" {status_icon} {tab_name}: {cmd_text}")
|
|
341
|
-
|
|
316
|
+
|
|
342
317
|
if cmd_status.get("processes"):
|
|
343
318
|
for proc in cmd_status["processes"][:2]: # Show first 2 processes
|
|
344
319
|
print(f" โโ PID {proc.get('pid', 'Unknown')}: {proc.get('name', 'Unknown')}")
|
|
345
320
|
print()
|
|
346
|
-
|
|
321
|
+
|
|
347
322
|
print("=" * 80)
|
|
348
323
|
|
|
349
324
|
def get_remote_overview(self) -> dict[str, Any]:
|
|
350
325
|
"""Get overview of all remote machines and their Windows Terminal status."""
|
|
351
326
|
overview = {}
|
|
352
|
-
|
|
327
|
+
|
|
353
328
|
for manager in self.managers:
|
|
354
329
|
try:
|
|
355
330
|
remote_name = manager.remote_name
|
|
356
|
-
|
|
331
|
+
|
|
357
332
|
# Get remote Windows info
|
|
358
333
|
windows_info = manager.get_remote_windows_info()
|
|
359
|
-
|
|
334
|
+
|
|
360
335
|
# Get Windows Terminal processes
|
|
361
336
|
wt_processes = manager.list_wt_processes()
|
|
362
|
-
|
|
337
|
+
|
|
363
338
|
# Get Windows Terminal version
|
|
364
339
|
wt_version = manager.get_wt_version()
|
|
365
|
-
|
|
366
|
-
overview[remote_name] = {
|
|
367
|
-
|
|
368
|
-
"wt_processes": wt_processes,
|
|
369
|
-
"wt_version": wt_version,
|
|
370
|
-
"session_name": manager.session_name,
|
|
371
|
-
"tab_count": len(manager.tab_config)
|
|
372
|
-
}
|
|
373
|
-
|
|
340
|
+
|
|
341
|
+
overview[remote_name] = {"windows_info": windows_info, "wt_processes": wt_processes, "wt_version": wt_version, "session_name": manager.session_name, "tab_count": len(manager.tab_config)}
|
|
342
|
+
|
|
374
343
|
except Exception as e:
|
|
375
|
-
overview[manager.remote_name] = {
|
|
376
|
-
|
|
377
|
-
"session_name": manager.session_name
|
|
378
|
-
}
|
|
379
|
-
|
|
344
|
+
overview[manager.remote_name] = {"error": str(e), "session_name": manager.session_name}
|
|
345
|
+
|
|
380
346
|
return overview
|
|
381
347
|
|
|
382
348
|
def print_remote_overview(self) -> None:
|
|
383
349
|
"""Print overview of all remote machines."""
|
|
384
350
|
overview = self.get_remote_overview()
|
|
385
|
-
|
|
351
|
+
|
|
386
352
|
print("=" * 80)
|
|
387
353
|
print("๐ REMOTE MACHINES OVERVIEW")
|
|
388
354
|
print("=" * 80)
|
|
389
|
-
|
|
355
|
+
|
|
390
356
|
for remote_name, info in overview.items():
|
|
391
357
|
print(f"๐ฅ๏ธ REMOTE: {remote_name}")
|
|
392
358
|
print("-" * 40)
|
|
393
|
-
|
|
359
|
+
|
|
394
360
|
if "error" in info:
|
|
395
361
|
print(f"โ Error: {info['error']}")
|
|
396
362
|
print()
|
|
397
363
|
continue
|
|
398
|
-
|
|
364
|
+
|
|
399
365
|
# Windows Terminal availability
|
|
400
366
|
windows_info = info.get("windows_info", {})
|
|
401
367
|
wt_available = windows_info.get("wt_available", False)
|
|
402
368
|
print(f"Windows Terminal: {'โ
Available' if wt_available else 'โ Not Available'}")
|
|
403
|
-
|
|
369
|
+
|
|
404
370
|
# Version info
|
|
405
371
|
wt_version = info.get("wt_version", {})
|
|
406
372
|
if wt_version.get("success"):
|
|
407
373
|
print(f"Version: {wt_version.get('version', 'Unknown')}")
|
|
408
|
-
|
|
374
|
+
|
|
409
375
|
# Current processes
|
|
410
376
|
wt_processes = info.get("wt_processes", {})
|
|
411
377
|
if wt_processes.get("success"):
|
|
412
378
|
processes_output = wt_processes.get("processes", "")
|
|
413
379
|
if processes_output.strip():
|
|
414
|
-
print(
|
|
380
|
+
print("Active processes: Found")
|
|
415
381
|
else:
|
|
416
|
-
print(
|
|
417
|
-
|
|
382
|
+
print("Active processes: None")
|
|
383
|
+
|
|
418
384
|
# Session info
|
|
419
385
|
session_name = info.get("session_name", "Unknown")
|
|
420
386
|
tab_count = info.get("tab_count", 0)
|
|
421
387
|
print(f"Managed session: {session_name} ({tab_count} tabs)")
|
|
422
|
-
|
|
388
|
+
|
|
423
389
|
print()
|
|
424
|
-
|
|
390
|
+
|
|
425
391
|
print("=" * 80)
|
|
426
392
|
|
|
427
393
|
|
|
428
394
|
if __name__ == "__main__":
|
|
429
395
|
# Example usage
|
|
430
396
|
sample_machines = {
|
|
431
|
-
"server1": {
|
|
432
|
-
|
|
433
|
-
"๐Monitor": ("~", "Get-Process | Sort-Object CPU -Descending | Select-Object -First 10"),
|
|
434
|
-
},
|
|
435
|
-
"server2": {
|
|
436
|
-
"๐คBot2": ("~/code/project", "python bot2.py"),
|
|
437
|
-
"๐Logs": ("C:/logs", "Get-Content app.log -Wait"),
|
|
438
|
-
}
|
|
397
|
+
"server1": {"๐คBot1": ("~/code/project", "python bot1.py"), "๐Monitor": ("~", "Get-Process | Sort-Object CPU -Descending | Select-Object -First 10")},
|
|
398
|
+
"server2": {"๐คBot2": ("~/code/project", "python bot2.py"), "๐Logs": ("C:/logs", "Get-Content app.log -Wait")},
|
|
439
399
|
}
|
|
440
|
-
|
|
400
|
+
|
|
441
401
|
try:
|
|
442
402
|
# Create the remote manager
|
|
443
403
|
manager = WTSessionManager(sample_machines, session_name_prefix="RemoteJobs")
|
|
444
404
|
print(f"โ
Remote manager created with {len(manager.managers)} remote sessions")
|
|
445
|
-
|
|
405
|
+
|
|
446
406
|
# Show SSH commands
|
|
447
407
|
print("\n๐ SSH commands to connect to all machines:")
|
|
448
408
|
ssh_commands = manager.ssh_to_all_machines()
|
|
449
409
|
print(ssh_commands)
|
|
450
|
-
|
|
410
|
+
|
|
451
411
|
# Show current status
|
|
452
412
|
print("\n๐ Current status:")
|
|
453
413
|
manager.print_status_report()
|
|
454
|
-
|
|
414
|
+
|
|
455
415
|
# Show remote overview
|
|
456
416
|
print("\n๐ Remote machines overview:")
|
|
457
417
|
manager.print_remote_overview()
|
|
458
|
-
|
|
418
|
+
|
|
459
419
|
# Demonstrate save/load
|
|
460
420
|
print("\n๐พ Demonstrating save/load...")
|
|
461
421
|
session_id = manager.save()
|
|
462
422
|
print(f"โ
Saved session: {session_id}")
|
|
463
|
-
|
|
423
|
+
|
|
464
424
|
# List saved sessions
|
|
465
425
|
saved_sessions = WTSessionManager.list_saved_sessions()
|
|
466
426
|
print(f"๐ Saved sessions: {saved_sessions}")
|
|
467
|
-
|
|
427
|
+
|
|
468
428
|
# Load and verify
|
|
469
429
|
loaded_manager = WTSessionManager.load(session_id)
|
|
470
430
|
print(f"โ
Loaded session with {len(loaded_manager.managers)} remote sessions")
|
|
471
|
-
|
|
431
|
+
|
|
472
432
|
# Show how to start sessions
|
|
473
433
|
print("\nโถ๏ธ To start all sessions, run:")
|
|
474
434
|
print("manager.start_all_sessions()")
|
|
475
|
-
|
|
435
|
+
|
|
476
436
|
# Show how to start monitoring (commented out to prevent infinite loop in demo)
|
|
477
437
|
print("\nโฐ To start monitoring, run:")
|
|
478
438
|
print("manager.run_monitoring_routine(wait_ms=60000) # 60 seconds")
|
|
479
|
-
|
|
439
|
+
|
|
480
440
|
except Exception as e:
|
|
481
441
|
print(f"โ Error: {e}")
|
|
482
442
|
import traceback
|
|
483
|
-
|
|
443
|
+
|
|
444
|
+
traceback.print_exc()
|