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