dayhoff-tools 1.9.12__py3-none-any.whl → 1.9.13__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.
- dayhoff_tools/cli/engine/engine_core.py +54 -5
- dayhoff_tools/cli/engine/engine_maintenance.py +56 -10
- {dayhoff_tools-1.9.12.dist-info → dayhoff_tools-1.9.13.dist-info}/METADATA +1 -1
- {dayhoff_tools-1.9.12.dist-info → dayhoff_tools-1.9.13.dist-info}/RECORD +6 -6
- {dayhoff_tools-1.9.12.dist-info → dayhoff_tools-1.9.13.dist-info}/WHEEL +0 -0
- {dayhoff_tools-1.9.12.dist-info → dayhoff_tools-1.9.13.dist-info}/entry_points.txt +0 -0
@@ -217,8 +217,12 @@ def list_engines(
|
|
217
217
|
|
218
218
|
def engine_status(
|
219
219
|
name_or_id: str = typer.Argument(help="Engine name or instance ID"),
|
220
|
-
detailed: bool = typer.Option(
|
221
|
-
|
220
|
+
detailed: bool = typer.Option(
|
221
|
+
False, "--detailed", "-d", help="Show detailed status (slower)"
|
222
|
+
),
|
223
|
+
show_log: bool = typer.Option(
|
224
|
+
False, "--show-log", help="Show bootstrap log (requires --detailed)"
|
225
|
+
),
|
222
226
|
):
|
223
227
|
"""Show engine status and information."""
|
224
228
|
check_aws_sso()
|
@@ -477,6 +481,47 @@ def engine_status(
|
|
477
481
|
except Exception:
|
478
482
|
pass
|
479
483
|
|
484
|
+
# Slack notifications status (detailed view only)
|
485
|
+
try:
|
486
|
+
ssm = boto3.client("ssm", region_name="us-east-1")
|
487
|
+
resp = ssm.send_command(
|
488
|
+
InstanceIds=[engine["instance_id"]],
|
489
|
+
DocumentName="AWS-RunShellScript",
|
490
|
+
Parameters={
|
491
|
+
"commands": ["grep '^SLACK_NOTIFY_' /etc/engine.env || true"],
|
492
|
+
"executionTimeout": ["10"],
|
493
|
+
},
|
494
|
+
)
|
495
|
+
cid = resp["Command"]["CommandId"]
|
496
|
+
time.sleep(1)
|
497
|
+
inv = ssm.get_command_invocation(
|
498
|
+
CommandId=cid, InstanceId=engine["instance_id"]
|
499
|
+
)
|
500
|
+
if inv["Status"] == "Success":
|
501
|
+
settings_raw = inv["StandardOutputContent"].strip()
|
502
|
+
settings = {}
|
503
|
+
for line in settings_raw.splitlines():
|
504
|
+
if "=" in line:
|
505
|
+
key, value = line.split("=", 1)
|
506
|
+
settings[key.strip()] = value.strip().lower()
|
507
|
+
|
508
|
+
status_lines.append("")
|
509
|
+
status_lines.append("[bold]Slack Notifications:[/bold]")
|
510
|
+
|
511
|
+
def _setting_line(label: str, key: str) -> str:
|
512
|
+
val = settings.get(key, "false") # Default to false if not set
|
513
|
+
status = "[green]on[/green]" if val == "true" else "[dim]off[/dim]"
|
514
|
+
return f" - {label:15} {status}"
|
515
|
+
|
516
|
+
status_lines.append(_setting_line("Idle Start", "SLACK_NOTIFY_IDLE_START"))
|
517
|
+
status_lines.append(
|
518
|
+
_setting_line("IDE Disconnect", "SLACK_NOTIFY_IDE_DISCONNECT")
|
519
|
+
)
|
520
|
+
status_lines.append(_setting_line("Warnings", "SLACK_NOTIFY_WARNINGS"))
|
521
|
+
status_lines.append(_setting_line("Shutdown", "SLACK_NOTIFY_SHUTDOWN"))
|
522
|
+
except Exception:
|
523
|
+
pass
|
524
|
+
|
480
525
|
# Activity Sensors (show all with YES/no)
|
481
526
|
if idle_detector.get("available"):
|
482
527
|
status_lines.append("")
|
@@ -564,10 +609,14 @@ def _format_idle_status_display(
|
|
564
609
|
):
|
565
610
|
remaining = max(0, int(thresh_v) - int(idle_seconds_v))
|
566
611
|
remaining_mins = remaining // 60
|
567
|
-
|
568
|
-
|
612
|
+
remaining_secs = remaining % 60
|
613
|
+
|
614
|
+
if remaining < 60:
|
615
|
+
time_left_str = f"[red]{remaining}s[/red] left"
|
569
616
|
else:
|
570
|
-
|
617
|
+
time_left_str = f"[red]{remaining_mins}m {remaining_secs}s[/red] left"
|
618
|
+
|
619
|
+
return f"[yellow]Idle {int(idle_seconds_v)//60}m/{int(thresh_v)//60}m: {time_left_str}[/yellow]"
|
571
620
|
elif isinstance(thresh_v, (int, float)):
|
572
621
|
return f"[yellow]Idle ?/{int(thresh_v)//60}m[/yellow]"
|
573
622
|
else:
|
@@ -11,12 +11,7 @@ from botocore.exceptions import ClientError
|
|
11
11
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
12
12
|
from rich.prompt import Confirm
|
13
13
|
|
14
|
-
from .shared import
|
15
|
-
check_aws_sso,
|
16
|
-
console,
|
17
|
-
make_api_request,
|
18
|
-
resolve_engine,
|
19
|
-
)
|
14
|
+
from .shared import check_aws_sso, console, make_api_request, resolve_engine
|
20
15
|
|
21
16
|
|
22
17
|
def coffee(
|
@@ -123,9 +118,11 @@ def idle_timeout_cmd(
|
|
123
118
|
set: Optional[str] = typer.Option(
|
124
119
|
None, "--set", "-s", help="New timeout (e.g., 2h30m, 45m)"
|
125
120
|
),
|
126
|
-
|
121
|
+
slack: Optional[str] = typer.Option(
|
122
|
+
None, "--slack", help="Set Slack notifications: none, default, all"
|
123
|
+
),
|
127
124
|
):
|
128
|
-
"""Show or set
|
125
|
+
"""Show or set engine idle-detector settings."""
|
129
126
|
check_aws_sso()
|
130
127
|
|
131
128
|
# Resolve engine
|
@@ -139,7 +136,56 @@ def idle_timeout_cmd(
|
|
139
136
|
|
140
137
|
ssm = boto3.client("ssm", region_name="us-east-1")
|
141
138
|
|
142
|
-
|
139
|
+
# Handle slack notifications change
|
140
|
+
if slack:
|
141
|
+
slack = slack.lower()
|
142
|
+
if slack not in ["none", "default", "all"]:
|
143
|
+
console.print("[red]❌ Invalid slack option. Use: none, default, all[/red]")
|
144
|
+
raise typer.Exit(1)
|
145
|
+
|
146
|
+
console.print(f"Setting Slack notifications to [bold]{slack}[/bold]...")
|
147
|
+
|
148
|
+
if slack == "none":
|
149
|
+
settings = {
|
150
|
+
"SLACK_NOTIFY_WARNINGS": "false",
|
151
|
+
"SLACK_NOTIFY_IDLE_START": "false",
|
152
|
+
"SLACK_NOTIFY_IDE_DISCONNECT": "false",
|
153
|
+
"SLACK_NOTIFY_SHUTDOWN": "false",
|
154
|
+
}
|
155
|
+
elif slack == "default":
|
156
|
+
settings = {
|
157
|
+
"SLACK_NOTIFY_WARNINGS": "true",
|
158
|
+
"SLACK_NOTIFY_IDLE_START": "false",
|
159
|
+
"SLACK_NOTIFY_IDE_DISCONNECT": "false",
|
160
|
+
"SLACK_NOTIFY_SHUTDOWN": "true",
|
161
|
+
}
|
162
|
+
else: # all
|
163
|
+
settings = {
|
164
|
+
"SLACK_NOTIFY_WARNINGS": "true",
|
165
|
+
"SLACK_NOTIFY_IDLE_START": "true",
|
166
|
+
"SLACK_NOTIFY_IDE_DISCONNECT": "true",
|
167
|
+
"SLACK_NOTIFY_SHUTDOWN": "true",
|
168
|
+
}
|
169
|
+
|
170
|
+
commands = []
|
171
|
+
for key, value in settings.items():
|
172
|
+
# Use a robust sed command that adds the line if it doesn't exist
|
173
|
+
commands.append(
|
174
|
+
f"grep -q '^{key}=' /etc/engine.env && sudo sed -i 's|^{key}=.*|{key}={value}|' /etc/engine.env || echo '{key}={value}' | sudo tee -a /etc/engine.env > /dev/null"
|
175
|
+
)
|
176
|
+
|
177
|
+
commands.append("sudo systemctl restart engine-idle-detector.service")
|
178
|
+
|
179
|
+
resp = ssm.send_command(
|
180
|
+
InstanceIds=[engine["instance_id"]],
|
181
|
+
DocumentName="AWS-RunShellScript",
|
182
|
+
Parameters={"commands": commands, "executionTimeout": ["60"]},
|
183
|
+
)
|
184
|
+
cid = resp["Command"]["CommandId"]
|
185
|
+
time.sleep(2) # Give it a moment to process
|
186
|
+
console.print(f"[green]✓ Slack notifications updated to '{slack}'[/green]")
|
187
|
+
|
188
|
+
if set is None and not slack:
|
143
189
|
# Show current timeout setting
|
144
190
|
resp = ssm.send_command(
|
145
191
|
InstanceIds=[engine["instance_id"]],
|
@@ -164,7 +210,7 @@ def idle_timeout_cmd(
|
|
164
210
|
console.print("[red]❌ Could not retrieve idle timeout[/red]")
|
165
211
|
return
|
166
212
|
|
167
|
-
# ----- set new value -----
|
213
|
+
# ----- set new value for timeout -----
|
168
214
|
m = re.match(r"^(?:(\d+)h)?(?:(\d+)m)?$", set)
|
169
215
|
if not m:
|
170
216
|
console.print("[red]❌ Invalid duration format. Use e.g. 2h, 45m, 1h30m[/red]")
|
@@ -4,9 +4,9 @@ dayhoff_tools/chemistry/utils.py,sha256=jt-7JgF-GeeVC421acX-bobKbLU_X94KNOW24p_P
|
|
4
4
|
dayhoff_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
5
|
dayhoff_tools/cli/cloud_commands.py,sha256=33qcWLmq-FwEXMdL3F0OHm-5Stlh2r65CldyEZgQ1no,40904
|
6
6
|
dayhoff_tools/cli/engine/__init__.py,sha256=CGJ2blhWIIEsVb8HoLibZjSlMFRTSYZOO4zDQTtY3SY,9300
|
7
|
-
dayhoff_tools/cli/engine/engine_core.py,sha256=
|
7
|
+
dayhoff_tools/cli/engine/engine_core.py,sha256=ItfqW3ZWoHEWLOgtWPYT-SO1idxk5RBBCIe8w9xxf3w,26959
|
8
8
|
dayhoff_tools/cli/engine/engine_lifecycle.py,sha256=_Dk-EZs_qbm8APdOuGOuxhlbK6RgkkoLk2nrwKoo1-A,4519
|
9
|
-
dayhoff_tools/cli/engine/engine_maintenance.py,sha256=
|
9
|
+
dayhoff_tools/cli/engine/engine_maintenance.py,sha256=xZgEgpjwTDI2RpoN7P6E7MEGiIA8RJpb0MkCT9u2R14,15889
|
10
10
|
dayhoff_tools/cli/engine/engine_management.py,sha256=s_H3FtMlKsdfzR8pwV-j2W2QX-Fypkqj2kPC0aTqC1A,19072
|
11
11
|
dayhoff_tools/cli/engine/shared.py,sha256=Ecx6I1jtzmxQDn3BezKpgpQ4SJeZf4SZjUCLg-67p80,16844
|
12
12
|
dayhoff_tools/cli/engine/studio_commands.py,sha256=VwTQujz32-uMcYusDRE73SdzRpgvIkv7ZAF4zRv6AzA,30266
|
@@ -33,7 +33,7 @@ dayhoff_tools/intake/uniprot.py,sha256=BZYJQF63OtPcBBnQ7_P9gulxzJtqyorgyuDiPeOJq
|
|
33
33
|
dayhoff_tools/logs.py,sha256=DKdeP0k0kliRcilwvX0mUB2eipO5BdWUeHwh-VnsICs,838
|
34
34
|
dayhoff_tools/sqlite.py,sha256=jV55ikF8VpTfeQqqlHSbY8OgfyfHj8zgHNpZjBLos_E,18672
|
35
35
|
dayhoff_tools/warehouse.py,sha256=UETBtZD3r7WgvURqfGbyHlT7cxoiVq8isjzMuerKw8I,24475
|
36
|
-
dayhoff_tools-1.9.
|
37
|
-
dayhoff_tools-1.9.
|
38
|
-
dayhoff_tools-1.9.
|
39
|
-
dayhoff_tools-1.9.
|
36
|
+
dayhoff_tools-1.9.13.dist-info/METADATA,sha256=Sf1ILU9mg5Cvs7NepbxAB0NJSuKM_gMqrKopTykTqDM,2915
|
37
|
+
dayhoff_tools-1.9.13.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
38
|
+
dayhoff_tools-1.9.13.dist-info/entry_points.txt,sha256=iAf4jteNqW3cJm6CO6czLxjW3vxYKsyGLZ8WGmxamSc,49
|
39
|
+
dayhoff_tools-1.9.13.dist-info/RECORD,,
|
File without changes
|
File without changes
|