machineconfig 2.0__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 +0 -3
- machineconfig/cluster/data_transfer.py +0 -1
- machineconfig/cluster/file_manager.py +0 -1
- machineconfig/cluster/job_params.py +0 -3
- machineconfig/cluster/loader_runner.py +0 -3
- machineconfig/cluster/remote_machine.py +0 -1
- machineconfig/cluster/script_notify_upon_completion.py +0 -1
- machineconfig/cluster/sessions_managers/archive/create_zellij_template.py +3 -5
- machineconfig/cluster/sessions_managers/archive/session_managers.py +0 -1
- machineconfig/cluster/sessions_managers/enhanced_command_runner.py +17 -57
- machineconfig/cluster/sessions_managers/wt_local.py +36 -110
- machineconfig/cluster/sessions_managers/wt_local_manager.py +42 -112
- machineconfig/cluster/sessions_managers/wt_remote.py +23 -30
- machineconfig/cluster/sessions_managers/wt_remote_manager.py +20 -62
- machineconfig/cluster/sessions_managers/wt_utils/layout_generator.py +10 -15
- machineconfig/cluster/sessions_managers/wt_utils/process_monitor.py +27 -127
- machineconfig/cluster/sessions_managers/wt_utils/remote_executor.py +10 -43
- machineconfig/cluster/sessions_managers/wt_utils/session_manager.py +22 -101
- machineconfig/cluster/sessions_managers/wt_utils/status_reporter.py +11 -39
- machineconfig/cluster/sessions_managers/zellij_local.py +49 -102
- machineconfig/cluster/sessions_managers/zellij_local_manager.py +34 -78
- machineconfig/cluster/sessions_managers/zellij_remote.py +17 -24
- machineconfig/cluster/sessions_managers/zellij_remote_manager.py +7 -13
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +4 -2
- machineconfig/cluster/sessions_managers/zellij_utils/layout_generator.py +6 -6
- machineconfig/cluster/sessions_managers/zellij_utils/process_monitor.py +18 -88
- machineconfig/cluster/sessions_managers/zellij_utils/remote_executor.py +2 -6
- machineconfig/cluster/sessions_managers/zellij_utils/session_manager.py +12 -40
- machineconfig/cluster/sessions_managers/zellij_utils/status_reporter.py +3 -2
- 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 +26 -10
- machineconfig/jobs/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/linux/msc/cli_agents.sh +16 -0
- machineconfig/jobs/python/check_installations.py +1 -0
- machineconfig/jobs/python/create_bootable_media.py +0 -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 +13 -14
- machineconfig/jobs/python/vscode/select_interpreter.py +21 -22
- machineconfig/jobs/python/vscode/sync_code.py +9 -13
- machineconfig/jobs/python_custom_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_custom_installers/archive/ngrok.py +13 -13
- machineconfig/jobs/python_custom_installers/dev/aider.py +7 -15
- machineconfig/jobs/python_custom_installers/dev/alacritty.py +9 -18
- machineconfig/jobs/python_custom_installers/dev/brave.py +10 -19
- machineconfig/jobs/python_custom_installers/dev/bypass_paywall.py +8 -15
- machineconfig/jobs/python_custom_installers/dev/code.py +14 -21
- machineconfig/jobs/python_custom_installers/dev/cursor.py +3 -14
- machineconfig/jobs/python_custom_installers/dev/docker_desktop.py +8 -7
- machineconfig/jobs/python_custom_installers/dev/espanso.py +15 -19
- machineconfig/jobs/python_custom_installers/dev/goes.py +5 -12
- machineconfig/jobs/python_custom_installers/dev/lvim.py +9 -17
- machineconfig/jobs/python_custom_installers/dev/nerdfont.py +12 -19
- machineconfig/jobs/python_custom_installers/dev/redis.py +12 -20
- machineconfig/jobs/python_custom_installers/dev/wezterm.py +12 -19
- machineconfig/jobs/python_custom_installers/dev/winget.py +5 -23
- machineconfig/jobs/python_custom_installers/docker.py +12 -21
- machineconfig/jobs/python_custom_installers/gh.py +11 -19
- machineconfig/jobs/python_custom_installers/hx.py +32 -16
- machineconfig/jobs/python_custom_installers/warp-cli.py +12 -20
- machineconfig/jobs/python_generic_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- machineconfig/jobs/python_linux_installers/__pycache__/__init__.cpython-313.pyc +0 -0
- 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/profile/create.py +29 -22
- machineconfig/profile/create_hardlinks.py +26 -19
- machineconfig/profile/shell.py +51 -28
- 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 +4 -6
- machineconfig/scripts/linux/fire +1 -1
- machineconfig/scripts/linux/fire_agents +3 -2
- machineconfig/scripts/linux/ftpx +1 -1
- machineconfig/scripts/linux/gh_models +1 -1
- machineconfig/scripts/linux/kill_process +1 -1
- machineconfig/scripts/linux/mcinit +1 -1
- 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/generate_files.py +84 -0
- machineconfig/scripts/python/ai/instructions/python/dev.instructions.md +2 -2
- machineconfig/scripts/python/ai/mcinit.py +7 -3
- machineconfig/scripts/python/ai/scripts/lint_and_type_check.sh +10 -5
- machineconfig/scripts/python/cloud_copy.py +1 -1
- machineconfig/scripts/python/cloud_mount.py +1 -1
- machineconfig/scripts/python/cloud_repo_sync.py +4 -4
- machineconfig/scripts/python/croshell.py +5 -3
- machineconfig/scripts/python/devops_add_identity.py +1 -1
- machineconfig/scripts/python/devops_add_ssh_key.py +1 -1
- machineconfig/scripts/python/devops_backup_retrieve.py +1 -1
- machineconfig/scripts/python/devops_update_repos.py +140 -52
- machineconfig/scripts/python/dotfile.py +1 -1
- machineconfig/scripts/python/fire_agents.py +28 -9
- machineconfig/scripts/python/fire_jobs.py +3 -4
- machineconfig/scripts/python/ftpx.py +2 -1
- 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/helpers2.py +2 -2
- machineconfig/scripts/python/helpers/helpers4.py +1 -2
- machineconfig/scripts/python/helpers/repo_sync_helpers.py +1 -1
- machineconfig/scripts/python/mount_nfs.py +1 -1
- machineconfig/scripts/python/mount_ssh.py +1 -1
- machineconfig/scripts/python/repos.py +1 -1
- machineconfig/scripts/python/start_slidev.py +1 -1
- machineconfig/scripts/python/wsl_windows_transfer.py +1 -1
- 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 +1 -1
- 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_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/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_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 +66 -12
- machineconfig/setup_windows/wt_and_pwsh/set_wt_settings.py +44 -36
- machineconfig/utils/ai/generate_file_checklist.py +8 -10
- machineconfig/utils/ai/url2md.py +4 -2
- machineconfig/utils/cloud/onedrive/setup_oauth.py +1 -0
- machineconfig/utils/cloud/onedrive/transaction.py +63 -98
- machineconfig/utils/code.py +60 -39
- machineconfig/utils/installer.py +27 -33
- machineconfig/utils/installer_utils/installer_abc.py +8 -7
- machineconfig/utils/installer_utils/installer_class.py +149 -70
- machineconfig/utils/links.py +22 -11
- machineconfig/utils/notifications.py +197 -0
- machineconfig/utils/options.py +29 -23
- machineconfig/utils/path.py +13 -6
- machineconfig/utils/path_reduced.py +485 -216
- machineconfig/utils/procs.py +47 -41
- machineconfig/utils/scheduling.py +0 -1
- machineconfig/utils/ssh.py +157 -76
- machineconfig/utils/terminal.py +82 -37
- machineconfig/utils/utils.py +12 -10
- machineconfig/utils/utils2.py +38 -48
- machineconfig/utils/utils5.py +183 -116
- machineconfig/utils/ve.py +9 -4
- {machineconfig-2.0.dist-info → machineconfig-2.1.dist-info}/METADATA +3 -2
- {machineconfig-2.0.dist-info → machineconfig-2.1.dist-info}/RECORD +200 -217
- 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/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/__pycache__/mcinit.cpython-311.pyc +0 -0
- 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-2.0.dist-info → machineconfig-2.1.dist-info}/WHEEL +0 -0
- {machineconfig-2.0.dist-info → machineconfig-2.1.dist-info}/top_level.txt +0 -0
|
@@ -21,7 +21,6 @@ TMP_LAYOUT_DIR = Path.home().joinpath("tmp_results", "zellij_layouts", "layout_m
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class ZellijRemoteLayoutGenerator:
|
|
24
|
-
|
|
25
24
|
def __init__(self, remote_name: str, session_name_prefix: str):
|
|
26
25
|
self.remote_name = remote_name
|
|
27
26
|
self.session_name = session_name_prefix + "_" + LayoutGenerator.generate_random_suffix()
|
|
@@ -96,14 +95,7 @@ class ZellijRemoteLayoutGenerator:
|
|
|
96
95
|
return executor.run_command(command, timeout)
|
|
97
96
|
|
|
98
97
|
def to_dict(self) -> Dict[str, Any]:
|
|
99
|
-
return {
|
|
100
|
-
"remote_name": self.remote_name,
|
|
101
|
-
"session_name": self.session_name,
|
|
102
|
-
"tab_config": self.tab_config,
|
|
103
|
-
"layout_path": self.layout_path,
|
|
104
|
-
"created_at": datetime.now().isoformat(),
|
|
105
|
-
"class_name": self.__class__.__name__
|
|
106
|
-
}
|
|
98
|
+
return {"remote_name": self.remote_name, "session_name": self.session_name, "tab_config": self.tab_config, "layout_path": self.layout_path, "created_at": datetime.now().isoformat(), "class_name": self.__class__.__name__}
|
|
107
99
|
|
|
108
100
|
def to_json(self, file_path: Optional[Union[str, Path]] = None) -> str:
|
|
109
101
|
# Generate file path if not provided
|
|
@@ -116,8 +108,8 @@ class ZellijRemoteLayoutGenerator:
|
|
|
116
108
|
file_path_obj = Path(file_path)
|
|
117
109
|
|
|
118
110
|
# Ensure .json extension
|
|
119
|
-
if not str(file_path_obj).endswith(
|
|
120
|
-
file_path_obj = file_path_obj.with_suffix(
|
|
111
|
+
if not str(file_path_obj).endswith(".json"):
|
|
112
|
+
file_path_obj = file_path_obj.with_suffix(".json")
|
|
121
113
|
|
|
122
114
|
# Ensure parent directory exists
|
|
123
115
|
file_path_obj.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -132,38 +124,38 @@ class ZellijRemoteLayoutGenerator:
|
|
|
132
124
|
return str(file_path_obj)
|
|
133
125
|
|
|
134
126
|
@classmethod
|
|
135
|
-
def from_json(cls, file_path: Union[str, Path]) ->
|
|
127
|
+
def from_json(cls, file_path: Union[str, Path]) -> "ZellijRemoteLayoutGenerator":
|
|
136
128
|
file_path = Path(file_path)
|
|
137
129
|
|
|
138
130
|
# Ensure .json extension
|
|
139
|
-
if not str(file_path).endswith(
|
|
140
|
-
file_path = file_path.with_suffix(
|
|
131
|
+
if not str(file_path).endswith(".json"):
|
|
132
|
+
file_path = file_path.with_suffix(".json")
|
|
141
133
|
|
|
142
134
|
if not file_path.exists():
|
|
143
135
|
raise FileNotFoundError(f"JSON file not found: {file_path}")
|
|
144
136
|
|
|
145
137
|
# Load JSON data
|
|
146
|
-
with open(file_path,
|
|
138
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
147
139
|
data = json.load(f)
|
|
148
140
|
|
|
149
141
|
# Validate that it's the correct class
|
|
150
|
-
if data.get(
|
|
142
|
+
if data.get("class_name") != cls.__name__:
|
|
151
143
|
logger.warning(f"Class name mismatch: expected {cls.__name__}, got {data.get('class_name')}")
|
|
152
144
|
|
|
153
145
|
# Create new instance
|
|
154
146
|
# Extract session name prefix by removing the suffix
|
|
155
|
-
session_name = data[
|
|
156
|
-
if
|
|
157
|
-
session_name_prefix =
|
|
147
|
+
session_name = data["session_name"]
|
|
148
|
+
if "_" in session_name:
|
|
149
|
+
session_name_prefix = "_".join(session_name.split("_")[:-1])
|
|
158
150
|
else:
|
|
159
151
|
session_name_prefix = session_name
|
|
160
152
|
|
|
161
|
-
instance = cls(remote_name=data[
|
|
153
|
+
instance = cls(remote_name=data["remote_name"], session_name_prefix=session_name_prefix)
|
|
162
154
|
|
|
163
155
|
# Restore state
|
|
164
|
-
instance.session_name = data[
|
|
165
|
-
instance.tab_config = data[
|
|
166
|
-
instance.layout_path = data[
|
|
156
|
+
instance.session_name = data["session_name"]
|
|
157
|
+
instance.tab_config = data["tab_config"]
|
|
158
|
+
instance.layout_path = data["layout_path"]
|
|
167
159
|
|
|
168
160
|
logger.info(f"✅ Loaded ZellijRemoteLayoutGenerator from: {file_path}")
|
|
169
161
|
return instance
|
|
@@ -181,13 +173,14 @@ class ZellijRemoteLayoutGenerator:
|
|
|
181
173
|
json_files = [f.name for f in directory_path.glob("*.json")]
|
|
182
174
|
return sorted(json_files)
|
|
183
175
|
|
|
176
|
+
|
|
184
177
|
if __name__ == "__main__":
|
|
185
178
|
# Example usage
|
|
186
179
|
sample_tabs = {
|
|
187
180
|
"🤖Bot1": ("~/code/bytesense/bithence", "~/scripts/fire -mO go1.py bot1 --kw create_new_bot True"),
|
|
188
181
|
"🤖Bot2": ("~/code/bytesense/bithence", "~/scripts/fire -mO go2.py bot2 --kw create_new_bot True"),
|
|
189
182
|
"📊Monitor": ("~", "htop"),
|
|
190
|
-
"📝Logs": ("/var/log", "tail -f /var/log/app.log")
|
|
183
|
+
"📝Logs": ("/var/log", "tail -f /var/log/app.log"),
|
|
191
184
|
}
|
|
192
185
|
|
|
193
186
|
# Replace 'myserver' with an actual SSH config alias
|
|
@@ -39,10 +39,7 @@ class ZellijSessionManager:
|
|
|
39
39
|
|
|
40
40
|
def kill_all_sessions(self) -> None:
|
|
41
41
|
for an_m in self.managers:
|
|
42
|
-
ZellijRemoteLayoutGenerator.run_remote_command(
|
|
43
|
-
remote_name=an_m.remote_name,
|
|
44
|
-
command="zellij kill-all-sessions --yes"
|
|
45
|
-
)
|
|
42
|
+
ZellijRemoteLayoutGenerator.run_remote_command(remote_name=an_m.remote_name, command="zellij kill-all-sessions --yes")
|
|
46
43
|
|
|
47
44
|
def start_zellij_sessions(self) -> None:
|
|
48
45
|
for an_m in self.managers:
|
|
@@ -84,6 +81,7 @@ class ZellijSessionManager:
|
|
|
84
81
|
# Print statuses
|
|
85
82
|
for i, status in enumerate(statuses):
|
|
86
83
|
print(f"Manager {i}: {status}")
|
|
84
|
+
|
|
87
85
|
sched = Scheduler(routine=routine, wait_ms=60_000, logger=logger)
|
|
88
86
|
sched.run()
|
|
89
87
|
|
|
@@ -101,12 +99,7 @@ class ZellijSessionManager:
|
|
|
101
99
|
config_file.write_text(text, encoding="utf-8")
|
|
102
100
|
|
|
103
101
|
# Save session metadata
|
|
104
|
-
metadata = {
|
|
105
|
-
"session_name_prefix": self.session_name_prefix,
|
|
106
|
-
"created_at": str(datetime.now()),
|
|
107
|
-
"num_managers": len(self.managers),
|
|
108
|
-
"machines": list(self.machine2zellij_tabs.keys())
|
|
109
|
-
}
|
|
102
|
+
metadata = {"session_name_prefix": self.session_name_prefix, "created_at": str(datetime.now()), "num_managers": len(self.managers), "machines": list(self.machine2zellij_tabs.keys())}
|
|
110
103
|
metadata_file = session_dir / "metadata.json"
|
|
111
104
|
text = json.dumps(metadata, indent=2, ensure_ascii=False)
|
|
112
105
|
metadata_file.write_text(text, encoding="utf-8")
|
|
@@ -122,7 +115,7 @@ class ZellijSessionManager:
|
|
|
122
115
|
return session_id
|
|
123
116
|
|
|
124
117
|
@classmethod
|
|
125
|
-
def load(cls, session_id: str) ->
|
|
118
|
+
def load(cls, session_id: str) -> "ZellijSessionManager":
|
|
126
119
|
session_dir = TMP_SERIALIAZATION_DIR / session_id
|
|
127
120
|
|
|
128
121
|
if not session_dir.exists():
|
|
@@ -130,14 +123,14 @@ class ZellijSessionManager:
|
|
|
130
123
|
config_file = session_dir / "machine2zellij_tabs.json"
|
|
131
124
|
if not config_file.exists():
|
|
132
125
|
raise FileNotFoundError(f"Configuration file not found: {config_file}")
|
|
133
|
-
with open(config_file,
|
|
126
|
+
with open(config_file, "r", encoding="utf-8") as f:
|
|
134
127
|
machine2zellij_tabs = json.load(f)
|
|
135
128
|
|
|
136
129
|
# Load metadata
|
|
137
130
|
metadata_file = session_dir / "metadata.json"
|
|
138
131
|
session_name_prefix = "JobMgr" # default fallback
|
|
139
132
|
if metadata_file.exists():
|
|
140
|
-
with open(metadata_file,
|
|
133
|
+
with open(metadata_file, "r", encoding="utf-8") as f:
|
|
141
134
|
metadata = json.load(f)
|
|
142
135
|
session_name_prefix = metadata.get("session_name_prefix", "JobMgr")
|
|
143
136
|
# Create new instance (this will create new managers)
|
|
@@ -180,6 +173,7 @@ class ZellijSessionManager:
|
|
|
180
173
|
|
|
181
174
|
try:
|
|
182
175
|
import shutil
|
|
176
|
+
|
|
183
177
|
shutil.rmtree(session_dir)
|
|
184
178
|
logger.info(f"✅ Deleted session: {session_id}")
|
|
185
179
|
return True
|
|
@@ -5,6 +5,7 @@ Example usage of the modularized Zellij remote layout generator.
|
|
|
5
5
|
|
|
6
6
|
from machineconfig.cluster.sessions_managers.zellij_remote import ZellijRemoteLayoutGenerator
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
def example_usage():
|
|
9
10
|
"""Demonstrate the refactored modular usage."""
|
|
10
11
|
|
|
@@ -13,7 +14,7 @@ def example_usage():
|
|
|
13
14
|
"🤖Bot1": ("~/code/bytesense/bithence", "~/scripts/fire -mO go1.py bot1 --kw create_new_bot True"),
|
|
14
15
|
"🤖Bot2": ("~/code/bytesense/bithence", "~/scripts/fire -mO go2.py bot2 --kw create_new_bot True"),
|
|
15
16
|
"📊Monitor": ("~", "htop"),
|
|
16
|
-
"📝Logs": ("/var/log", "tail -f /var/log/app.log")
|
|
17
|
+
"📝Logs": ("/var/log", "tail -f /var/log/app.log"),
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
# Replace 'myserver' with an actual SSH config alias
|
|
@@ -37,7 +38,7 @@ def example_usage():
|
|
|
37
38
|
generator.print_status_report()
|
|
38
39
|
|
|
39
40
|
# The individual components can also be used directly:
|
|
40
|
-
print(
|
|
41
|
+
print("\n🔧 Direct component usage examples:")
|
|
41
42
|
|
|
42
43
|
# Use remote executor directly
|
|
43
44
|
print(f"Remote executor: {generator.remote_executor.remote_name}")
|
|
@@ -60,5 +61,6 @@ def example_usage():
|
|
|
60
61
|
except Exception as e:
|
|
61
62
|
print(f"❌ Error: {e}")
|
|
62
63
|
|
|
64
|
+
|
|
63
65
|
if __name__ == "__main__":
|
|
64
66
|
example_usage()
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Zellij layout generation utilities for creating KDL layout files.
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
import shlex
|
|
6
7
|
import random
|
|
7
8
|
import string
|
|
@@ -31,7 +32,7 @@ class LayoutGenerator:
|
|
|
31
32
|
@staticmethod
|
|
32
33
|
def generate_random_suffix(length: int = 8) -> str:
|
|
33
34
|
"""Generate a random string suffix for unique layout file names."""
|
|
34
|
-
return
|
|
35
|
+
return "".join(random.choices(string.ascii_lowercase + string.digits, k=length))
|
|
35
36
|
|
|
36
37
|
@staticmethod
|
|
37
38
|
def parse_command(command: str) -> Tuple[str, List[str]]:
|
|
@@ -53,7 +54,7 @@ class LayoutGenerator:
|
|
|
53
54
|
return ""
|
|
54
55
|
formatted_args = []
|
|
55
56
|
for arg in args:
|
|
56
|
-
if
|
|
57
|
+
if " " in arg or '"' in arg or "'" in arg:
|
|
57
58
|
escaped_arg = arg.replace('"', '\\"')
|
|
58
59
|
formatted_args.append(f'"{escaped_arg}"')
|
|
59
60
|
else:
|
|
@@ -71,8 +72,8 @@ class LayoutGenerator:
|
|
|
71
72
|
tab_section = f' tab name="{escaped_tab_name}" cwd="{tab_cwd}" {{\n'
|
|
72
73
|
tab_section += f' pane command="{cmd}" {{\n'
|
|
73
74
|
if args_str:
|
|
74
|
-
tab_section += f
|
|
75
|
-
tab_section +=
|
|
75
|
+
tab_section += f" args {args_str}\n"
|
|
76
|
+
tab_section += " }\n }\n"
|
|
76
77
|
return tab_section
|
|
77
78
|
|
|
78
79
|
@staticmethod
|
|
@@ -99,8 +100,7 @@ class LayoutGenerator:
|
|
|
99
100
|
|
|
100
101
|
return layout_content
|
|
101
102
|
|
|
102
|
-
def create_layout_file(self, tab_config: Dict[str, Tuple[str, str]],
|
|
103
|
-
output_dir: Path, session_name: str) -> str:
|
|
103
|
+
def create_layout_file(self, tab_config: Dict[str, Tuple[str, str]], output_dir: Path, session_name: str) -> str:
|
|
104
104
|
"""Create a layout file and return its absolute path."""
|
|
105
105
|
self.validate_tab_config(tab_config)
|
|
106
106
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Process monitoring and status checking utilities for remote commands.
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
import json
|
|
6
7
|
import shlex
|
|
7
8
|
import logging
|
|
@@ -17,18 +18,10 @@ class ProcessMonitor:
|
|
|
17
18
|
def __init__(self, remote_executor: RemoteExecutor):
|
|
18
19
|
self.remote_executor = remote_executor
|
|
19
20
|
|
|
20
|
-
def check_command_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]],
|
|
21
|
-
use_verification: bool = True) -> Dict[str, Any]:
|
|
21
|
+
def check_command_status(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]], use_verification: bool = True) -> Dict[str, Any]:
|
|
22
22
|
"""Check command status with optional process verification."""
|
|
23
23
|
if tab_name not in tab_config:
|
|
24
|
-
return {
|
|
25
|
-
"status": "unknown",
|
|
26
|
-
"error": f"Tab '{tab_name}' not found in tracked configuration",
|
|
27
|
-
"running": False,
|
|
28
|
-
"pid": None,
|
|
29
|
-
"command": None,
|
|
30
|
-
"remote": self.remote_executor.remote_name
|
|
31
|
-
}
|
|
24
|
+
return {"status": "unknown", "error": f"Tab '{tab_name}' not found in tracked configuration", "running": False, "pid": None, "command": None, "remote": self.remote_executor.remote_name}
|
|
32
25
|
|
|
33
26
|
# Use the verified method by default for more accurate results
|
|
34
27
|
if use_verification:
|
|
@@ -42,7 +35,7 @@ class ProcessMonitor:
|
|
|
42
35
|
|
|
43
36
|
try:
|
|
44
37
|
check_script = self._create_process_check_script(command)
|
|
45
|
-
remote_cmd = f"$HOME/
|
|
38
|
+
remote_cmd = f"$HOME/code/machineconfig/.venv/bin/python -c {shlex.quote(check_script)}"
|
|
46
39
|
result = self.remote_executor.run_command(remote_cmd, timeout=15)
|
|
47
40
|
|
|
48
41
|
if result.returncode == 0:
|
|
@@ -50,53 +43,18 @@ class ProcessMonitor:
|
|
|
50
43
|
matching_processes = json.loads(result.stdout.strip())
|
|
51
44
|
|
|
52
45
|
if matching_processes:
|
|
53
|
-
return {
|
|
54
|
-
"status": "running",
|
|
55
|
-
"running": True,
|
|
56
|
-
"processes": matching_processes,
|
|
57
|
-
"command": command,
|
|
58
|
-
"tab_name": tab_name,
|
|
59
|
-
"remote": self.remote_executor.remote_name
|
|
60
|
-
}
|
|
46
|
+
return {"status": "running", "running": True, "processes": matching_processes, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
|
|
61
47
|
else:
|
|
62
|
-
return {
|
|
63
|
-
"status": "not_running",
|
|
64
|
-
"running": False,
|
|
65
|
-
"processes": [],
|
|
66
|
-
"command": command,
|
|
67
|
-
"tab_name": tab_name,
|
|
68
|
-
"remote": self.remote_executor.remote_name
|
|
69
|
-
}
|
|
48
|
+
return {"status": "not_running", "running": False, "processes": [], "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
|
|
70
49
|
except json.JSONDecodeError as e:
|
|
71
50
|
logger.error(f"Failed to parse remote process check output: {e}")
|
|
72
|
-
return {
|
|
73
|
-
"status": "error",
|
|
74
|
-
"error": f"Failed to parse remote output: {e}",
|
|
75
|
-
"running": False,
|
|
76
|
-
"command": command,
|
|
77
|
-
"tab_name": tab_name,
|
|
78
|
-
"remote": self.remote_executor.remote_name
|
|
79
|
-
}
|
|
51
|
+
return {"status": "error", "error": f"Failed to parse remote output: {e}", "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
|
|
80
52
|
else:
|
|
81
|
-
return {
|
|
82
|
-
"status": "error",
|
|
83
|
-
"error": f"Remote command failed: {result.stderr}",
|
|
84
|
-
"running": False,
|
|
85
|
-
"command": command,
|
|
86
|
-
"tab_name": tab_name,
|
|
87
|
-
"remote": self.remote_executor.remote_name
|
|
88
|
-
}
|
|
53
|
+
return {"status": "error", "error": f"Remote command failed: {result.stderr}", "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
|
|
89
54
|
|
|
90
55
|
except Exception as e:
|
|
91
56
|
logger.error(f"Error checking command status for tab '{tab_name}': {e}")
|
|
92
|
-
return {
|
|
93
|
-
"status": "error",
|
|
94
|
-
"error": str(e),
|
|
95
|
-
"running": False,
|
|
96
|
-
"command": command,
|
|
97
|
-
"tab_name": tab_name,
|
|
98
|
-
"remote": self.remote_executor.remote_name
|
|
99
|
-
}
|
|
57
|
+
return {"status": "error", "error": str(e), "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
|
|
100
58
|
|
|
101
59
|
def _create_process_check_script(self, command: str) -> str:
|
|
102
60
|
"""Create Python script for checking processes on remote machine."""
|
|
@@ -151,13 +109,7 @@ if __name__ == "__main__":
|
|
|
151
109
|
def force_fresh_process_check(self, tab_name: str, tab_config: Dict[str, Tuple[str, str]]) -> Dict[str, Any]:
|
|
152
110
|
"""Force a fresh process check with additional validation."""
|
|
153
111
|
if tab_name not in tab_config:
|
|
154
|
-
return {
|
|
155
|
-
"status": "unknown",
|
|
156
|
-
"error": f"Tab '{tab_name}' not found in tracked configuration",
|
|
157
|
-
"running": False,
|
|
158
|
-
"command": None,
|
|
159
|
-
"remote": self.remote_executor.remote_name
|
|
160
|
-
}
|
|
112
|
+
return {"status": "unknown", "error": f"Tab '{tab_name}' not found in tracked configuration", "running": False, "command": None, "remote": self.remote_executor.remote_name}
|
|
161
113
|
|
|
162
114
|
_, command = tab_config[tab_name]
|
|
163
115
|
|
|
@@ -167,7 +119,7 @@ if __name__ == "__main__":
|
|
|
167
119
|
check_timestamp = timestamp_result.stdout.strip() if timestamp_result.returncode == 0 else "unknown"
|
|
168
120
|
|
|
169
121
|
check_script = self._create_fresh_check_script(command)
|
|
170
|
-
remote_cmd = f"$HOME/
|
|
122
|
+
remote_cmd = f"$HOME/code/machineconfig/.venv/bin/python -c {shlex.quote(check_script)}"
|
|
171
123
|
result = self.remote_executor.run_command(remote_cmd, timeout=15)
|
|
172
124
|
|
|
173
125
|
if result.returncode == 0:
|
|
@@ -183,45 +135,23 @@ if __name__ == "__main__":
|
|
|
183
135
|
"tab_name": tab_name,
|
|
184
136
|
"remote": self.remote_executor.remote_name,
|
|
185
137
|
"check_timestamp": check_timestamp,
|
|
186
|
-
"method": "force_fresh_check"
|
|
138
|
+
"method": "force_fresh_check",
|
|
187
139
|
}
|
|
188
140
|
except json.JSONDecodeError as e:
|
|
189
141
|
logger.error(f"Failed to parse fresh check output: {e}")
|
|
190
|
-
return {
|
|
191
|
-
"status": "error",
|
|
192
|
-
"error": f"Failed to parse output: {e}",
|
|
193
|
-
"running": False,
|
|
194
|
-
"command": command,
|
|
195
|
-
"tab_name": tab_name,
|
|
196
|
-
"remote": self.remote_executor.remote_name,
|
|
197
|
-
"raw_output": result.stdout
|
|
198
|
-
}
|
|
142
|
+
return {"status": "error", "error": f"Failed to parse output: {e}", "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name, "raw_output": result.stdout}
|
|
199
143
|
else:
|
|
200
|
-
return {
|
|
201
|
-
"status": "error",
|
|
202
|
-
"error": f"Remote command failed: {result.stderr}",
|
|
203
|
-
"running": False,
|
|
204
|
-
"command": command,
|
|
205
|
-
"tab_name": tab_name,
|
|
206
|
-
"remote": self.remote_executor.remote_name
|
|
207
|
-
}
|
|
144
|
+
return {"status": "error", "error": f"Remote command failed: {result.stderr}", "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
|
|
208
145
|
|
|
209
146
|
except Exception as e:
|
|
210
147
|
logger.error(f"Error in fresh process check for tab '{tab_name}': {e}")
|
|
211
|
-
return {
|
|
212
|
-
"status": "error",
|
|
213
|
-
"error": str(e),
|
|
214
|
-
"running": False,
|
|
215
|
-
"command": command,
|
|
216
|
-
"tab_name": tab_name,
|
|
217
|
-
"remote": self.remote_executor.remote_name
|
|
218
|
-
}
|
|
148
|
+
return {"status": "error", "error": str(e), "running": False, "command": command, "tab_name": tab_name, "remote": self.remote_executor.remote_name}
|
|
219
149
|
|
|
220
150
|
def _create_fresh_check_script(self, command: str) -> str:
|
|
221
151
|
"""Create enhanced process checking script with freshness validation."""
|
|
222
152
|
escaped_command = command.replace("'", "\\'").replace('"', '\\"')
|
|
223
153
|
|
|
224
|
-
return f
|
|
154
|
+
return f"""
|
|
225
155
|
import psutil
|
|
226
156
|
import json
|
|
227
157
|
import os
|
|
@@ -286,7 +216,7 @@ def force_fresh_check():
|
|
|
286
216
|
if __name__ == "__main__":
|
|
287
217
|
result = force_fresh_check()
|
|
288
218
|
print(json.dumps(result))
|
|
289
|
-
|
|
219
|
+
"""
|
|
290
220
|
|
|
291
221
|
def verify_process_alive(self, pid: int) -> bool:
|
|
292
222
|
"""Verify if a process with given PID is actually alive."""
|
|
@@ -295,7 +225,7 @@ if __name__ == "__main__":
|
|
|
295
225
|
result = self.remote_executor.run_command(verify_cmd, timeout=5)
|
|
296
226
|
|
|
297
227
|
if result.returncode == 0:
|
|
298
|
-
return result.stdout.strip() ==
|
|
228
|
+
return result.stdout.strip() == "alive"
|
|
299
229
|
return False
|
|
300
230
|
except Exception:
|
|
301
231
|
return False
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Remote command execution utilities for SSH operations.
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
import subprocess
|
|
6
7
|
import logging
|
|
7
8
|
from typing import Dict, Any
|
|
@@ -19,12 +20,7 @@ class RemoteExecutor:
|
|
|
19
20
|
"""Execute a command on the remote machine via SSH."""
|
|
20
21
|
ssh_cmd = ["ssh", self.remote_name, command]
|
|
21
22
|
try:
|
|
22
|
-
result = subprocess.run(
|
|
23
|
-
ssh_cmd,
|
|
24
|
-
capture_output=True,
|
|
25
|
-
text=True,
|
|
26
|
-
timeout=timeout
|
|
27
|
-
)
|
|
23
|
+
result = subprocess.run(ssh_cmd, capture_output=True, text=True, timeout=timeout)
|
|
28
24
|
return result
|
|
29
25
|
except subprocess.TimeoutExpired:
|
|
30
26
|
logger.error(f"SSH command timed out after {timeout}s: {command}")
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Zellij session management utilities for remote operations.
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
import logging
|
|
6
7
|
from typing import Dict, Any, Optional
|
|
7
8
|
from pathlib import Path
|
|
@@ -43,34 +44,18 @@ class SessionManager:
|
|
|
43
44
|
def check_zellij_session_status(self) -> Dict[str, Any]:
|
|
44
45
|
"""Check if the Zellij session exists and is running."""
|
|
45
46
|
try:
|
|
46
|
-
result = self.remote_executor.run_command(
|
|
47
|
+
result = self.remote_executor.run_command("zellij list-sessions", timeout=10)
|
|
47
48
|
|
|
48
49
|
if result.returncode == 0:
|
|
49
|
-
sessions = result.stdout.strip().split(
|
|
50
|
+
sessions = result.stdout.strip().split("\n") if result.stdout.strip() else []
|
|
50
51
|
session_running = any(self.session_name in session for session in sessions)
|
|
51
52
|
|
|
52
|
-
return {
|
|
53
|
-
"zellij_running": True,
|
|
54
|
-
"session_exists": session_running,
|
|
55
|
-
"session_name": self.session_name,
|
|
56
|
-
"all_sessions": sessions,
|
|
57
|
-
"remote": self.remote_executor.remote_name
|
|
58
|
-
}
|
|
53
|
+
return {"zellij_running": True, "session_exists": session_running, "session_name": self.session_name, "all_sessions": sessions, "remote": self.remote_executor.remote_name}
|
|
59
54
|
else:
|
|
60
|
-
return {
|
|
61
|
-
"zellij_running": False,
|
|
62
|
-
"error": result.stderr,
|
|
63
|
-
"session_name": self.session_name,
|
|
64
|
-
"remote": self.remote_executor.remote_name
|
|
65
|
-
}
|
|
55
|
+
return {"zellij_running": False, "error": result.stderr, "session_name": self.session_name, "remote": self.remote_executor.remote_name}
|
|
66
56
|
|
|
67
57
|
except Exception as e:
|
|
68
|
-
return {
|
|
69
|
-
"zellij_running": False,
|
|
70
|
-
"error": str(e),
|
|
71
|
-
"session_name": self.session_name,
|
|
72
|
-
"remote": self.remote_executor.remote_name
|
|
73
|
-
}
|
|
58
|
+
return {"zellij_running": False, "error": str(e), "session_name": self.session_name, "remote": self.remote_executor.remote_name}
|
|
74
59
|
|
|
75
60
|
def start_zellij_session(self, layout_file_path: Optional[str] = None) -> Dict[str, Any]:
|
|
76
61
|
"""Start a Zellij session on the remote machine with the generated layout."""
|
|
@@ -82,7 +67,9 @@ class SessionManager:
|
|
|
82
67
|
raise ValueError("No layout file path provided.")
|
|
83
68
|
|
|
84
69
|
# Enhanced Rich logging for session start
|
|
85
|
-
console.print(
|
|
70
|
+
console.print(
|
|
71
|
+
f"[bold cyan]🚀 Starting Zellij session[/bold cyan] [yellow]'{self.session_name}'[/yellow] [dim]on remote[/dim] [bold yellow]'{self.remote_executor.remote_name}'[/bold yellow] [dim]with layout:[/dim] [blue]{remote_layout_file}[/blue]"
|
|
72
|
+
)
|
|
86
73
|
|
|
87
74
|
# Start Zellij session with layout
|
|
88
75
|
start_cmd = f"zellij --layout {remote_layout_file} a -b {self.session_name}"
|
|
@@ -91,28 +78,13 @@ class SessionManager:
|
|
|
91
78
|
|
|
92
79
|
if result.returncode == 0:
|
|
93
80
|
console.print(f"[bold green]✅ Zellij session[/bold green] [yellow]'{self.session_name}'[/yellow] [green]started successfully on[/green] [bold yellow]{self.remote_executor.remote_name}[/bold yellow]")
|
|
94
|
-
return {
|
|
95
|
-
"success": True,
|
|
96
|
-
"session_name": self.session_name,
|
|
97
|
-
"remote": self.remote_executor.remote_name,
|
|
98
|
-
"message": "Session started successfully"
|
|
99
|
-
}
|
|
81
|
+
return {"success": True, "session_name": self.session_name, "remote": self.remote_executor.remote_name, "message": "Session started successfully"}
|
|
100
82
|
else:
|
|
101
|
-
return {
|
|
102
|
-
"success": False,
|
|
103
|
-
"error": result.stderr,
|
|
104
|
-
"session_name": self.session_name,
|
|
105
|
-
"remote": self.remote_executor.remote_name
|
|
106
|
-
}
|
|
83
|
+
return {"success": False, "error": result.stderr, "session_name": self.session_name, "remote": self.remote_executor.remote_name}
|
|
107
84
|
|
|
108
85
|
except Exception as e:
|
|
109
86
|
logger.error(f"Failed to start Zellij session on {self.remote_executor.remote_name}: {e}")
|
|
110
|
-
return {
|
|
111
|
-
"success": False,
|
|
112
|
-
"error": str(e),
|
|
113
|
-
"session_name": self.session_name,
|
|
114
|
-
"remote": self.remote_executor.remote_name
|
|
115
|
-
}
|
|
87
|
+
return {"success": False, "error": str(e), "session_name": self.session_name, "remote": self.remote_executor.remote_name}
|
|
116
88
|
|
|
117
89
|
def attach_to_session(self) -> None:
|
|
118
90
|
"""Attach to the Zellij session on the remote machine via SSH."""
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"""
|
|
3
3
|
Status reporting utilities for Zellij remote layouts.
|
|
4
4
|
"""
|
|
5
|
+
|
|
5
6
|
import logging
|
|
6
7
|
from typing import Dict, Any, Tuple
|
|
7
8
|
from .process_monitor import ProcessMonitor
|
|
@@ -33,8 +34,8 @@ class StatusReporter:
|
|
|
33
34
|
"running_commands": running_count,
|
|
34
35
|
"stopped_commands": total_count - running_count,
|
|
35
36
|
"session_healthy": zellij_status.get("session_exists", False),
|
|
36
|
-
"remote": self.session_manager.remote_executor.remote_name
|
|
37
|
-
}
|
|
37
|
+
"remote": self.session_manager.remote_executor.remote_name,
|
|
38
|
+
},
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
def print_status_report(self, tab_config: Dict[str, Tuple[str, str]]) -> None:
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
# """Gooey
|
|
3
2
|
# """
|
|
4
3
|
|
|
@@ -12,7 +11,6 @@
|
|
|
12
11
|
# # from typing import Any, Optional
|
|
13
12
|
|
|
14
13
|
|
|
15
|
-
|
|
16
14
|
# @Gooey(program_name="Cluster Launcher", program_description='Cofigure remote cluster and launch jobs.') # type: ignore
|
|
17
15
|
# def main() -> RemoteMachineConfig:
|
|
18
16
|
# # parser = GooeyParser(description='Example of Gooey\'s basic functionality')
|