v1.8.66: fix 7 Redis bugs — shlex parser, GUI stats, SSL, error handling, dedup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
70
tools/ssh.py
70
tools/ssh.py
@@ -694,14 +694,12 @@ def _check_status_one(server: dict) -> str:
|
||||
return "ONLINE"
|
||||
|
||||
if stype == "redis":
|
||||
import redis as redis_lib
|
||||
r = redis_lib.Redis(host=server["ip"], port=server.get("port", 6379),
|
||||
password=server.get("password", "") or None,
|
||||
db=server.get("db_index", 0), socket_timeout=10,
|
||||
ssl=server.get("ssl", False))
|
||||
r.ping()
|
||||
r.close()
|
||||
return "ONLINE"
|
||||
r = _get_redis_client(server)
|
||||
try:
|
||||
r.ping()
|
||||
return "ONLINE"
|
||||
finally:
|
||||
r.close()
|
||||
|
||||
if stype == "grafana":
|
||||
import requests
|
||||
@@ -991,23 +989,37 @@ def sql_tables(server: dict, database: str = None):
|
||||
|
||||
# ── Redis commands ────────────────────────────────────
|
||||
|
||||
def _get_redis_client(server: dict):
|
||||
"""Create a Redis client from server config. Single source of truth."""
|
||||
import redis as redis_lib
|
||||
return redis_lib.Redis(
|
||||
host=server["ip"],
|
||||
port=server.get("port", 6379),
|
||||
password=server.get("password", "") or None,
|
||||
db=server.get("db_index", 0),
|
||||
decode_responses=True,
|
||||
socket_timeout=10,
|
||||
ssl=server.get("ssl", False),
|
||||
)
|
||||
|
||||
|
||||
def run_redis_cmd(server: dict, command: str):
|
||||
"""Execute a Redis command."""
|
||||
import redis as redis_lib
|
||||
host = server["ip"]
|
||||
port = server.get("port", 6379)
|
||||
password = server.get("password", "") or None
|
||||
db_index = server.get("db_index", 0)
|
||||
ssl_enabled = server.get("ssl", False)
|
||||
|
||||
r = redis_lib.Redis(host=host, port=port, password=password, db=db_index,
|
||||
decode_responses=True, socket_timeout=10, ssl=ssl_enabled)
|
||||
r = _get_redis_client(server)
|
||||
try:
|
||||
parts = command.split()
|
||||
import shlex
|
||||
try:
|
||||
parts = shlex.split(command)
|
||||
except ValueError:
|
||||
parts = command.split()
|
||||
if not parts:
|
||||
print("ERROR: Empty Redis command")
|
||||
sys.exit(1)
|
||||
result = r.execute_command(*parts)
|
||||
try:
|
||||
result = r.execute_command(*parts)
|
||||
except Exception as e:
|
||||
print(f"(error) {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if isinstance(result, list):
|
||||
for i, item in enumerate(result):
|
||||
print(f"{i + 1}) {item}")
|
||||
@@ -1025,15 +1037,7 @@ def run_redis_cmd(server: dict, command: str):
|
||||
|
||||
def redis_info(server: dict):
|
||||
"""Show Redis INFO."""
|
||||
import redis as redis_lib
|
||||
host = server["ip"]
|
||||
port = server.get("port", 6379)
|
||||
password = server.get("password", "") or None
|
||||
db_index = server.get("db_index", 0)
|
||||
ssl_enabled = server.get("ssl", False)
|
||||
|
||||
r = redis_lib.Redis(host=host, port=port, password=password, db=db_index,
|
||||
decode_responses=True, socket_timeout=10, ssl=ssl_enabled)
|
||||
r = _get_redis_client(server)
|
||||
try:
|
||||
info = r.info()
|
||||
# Print key sections
|
||||
@@ -1056,15 +1060,7 @@ def redis_info(server: dict):
|
||||
|
||||
def redis_keys(server: dict, pattern: str):
|
||||
"""SCAN keys matching a pattern."""
|
||||
import redis as redis_lib
|
||||
host = server["ip"]
|
||||
port = server.get("port", 6379)
|
||||
password = server.get("password", "") or None
|
||||
db_index = server.get("db_index", 0)
|
||||
ssl_enabled = server.get("ssl", False)
|
||||
|
||||
r = redis_lib.Redis(host=host, port=port, password=password, db=db_index,
|
||||
decode_responses=True, socket_timeout=10, ssl=ssl_enabled)
|
||||
r = _get_redis_client(server)
|
||||
try:
|
||||
keys = []
|
||||
cursor = 0
|
||||
|
||||
Reference in New Issue
Block a user