Initial import: monitoring, power-management, maintenance, web scripts
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Wrapper: power on pve2 (DL380p Gen8) via iLO4 Redfish API.
|
||||
Fire-and-forget — sends power-on, does NOT wait for boot.
|
||||
Used by cron job server-start (no_agent mode, 120s timeout)."""
|
||||
import os, sys, json, subprocess
|
||||
|
||||
ENV_FILE = os.path.expanduser("~/.hermes/.env")
|
||||
|
||||
def get_env(key):
|
||||
try:
|
||||
with open(ENV_FILE) as f:
|
||||
for line in f:
|
||||
if line.startswith(key + "="):
|
||||
return line.strip().split("=", 1)[1]
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
return None
|
||||
|
||||
def ilo_token():
|
||||
url = get_env("ILO4_URL")
|
||||
user = get_env("ILO4_USER")
|
||||
pwd = get_env("ILO4_PASSWORD")
|
||||
payload = '{"UserName":"%s","Password":"%s"}' % (user, pwd)
|
||||
cmd = ["curl", "-s", "-k", "--max-time", "10",
|
||||
"-D", "/dev/stderr", "-X", "POST",
|
||||
"-H", "Content-Type: application/json",
|
||||
"-d", payload,
|
||||
url + "/redfish/v1/SessionService/Sessions/"]
|
||||
r = subprocess.run(cmd, capture_output=True, timeout=15)
|
||||
stderr = r.stderr.decode("utf-8", errors="replace")
|
||||
for line in stderr.split("\n"):
|
||||
if "X-Auth-Token" in line:
|
||||
return line.split(":")[1].strip()
|
||||
return None
|
||||
|
||||
url = get_env("ILO4_URL")
|
||||
token = ilo_token()
|
||||
if not token:
|
||||
print("FAIL: iLO auth failed")
|
||||
sys.exit(1)
|
||||
|
||||
hdr = "X-Auth-Token: " + token
|
||||
r = subprocess.run([
|
||||
"curl", "-s", "-k", "--max-time", "15",
|
||||
"-X", "POST",
|
||||
"-H", hdr,
|
||||
"-H", "Content-Type: application/json",
|
||||
"-d", '{"ResetType":"On"}',
|
||||
url + "/redfish/v1/Systems/1/Actions/ComputerSystem.Reset/"
|
||||
], capture_output=True, timeout=20)
|
||||
|
||||
# Check curl exit code
|
||||
if r.returncode != 0:
|
||||
print(f"FAIL: curl returned {r.returncode}")
|
||||
sys.exit(1)
|
||||
|
||||
# Parse iLO response - check for actual error messages
|
||||
# iLO wraps success in "ExtendedError" type with "Success" MessageID
|
||||
stdout = r.stdout.decode("utf-8", errors="replace")
|
||||
if stdout.strip():
|
||||
try:
|
||||
resp = json.loads(stdout)
|
||||
msgs = resp.get("Messages", []) or (resp.get("error", {}) or {}).get("@Message.ExtendedInfo", [])
|
||||
for m in msgs:
|
||||
mid = m.get("MessageID", "")
|
||||
if mid and "Success" not in mid and "OK" not in mid:
|
||||
print(f"FAIL: iLO error: {mid}")
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
|
||||
print("Power-on command sent via iLO")
|
||||
sys.exit(0)
|
||||
Reference in New Issue
Block a user