fix(deploy): resolve cron pool initialization issues
Some checks failed
CI / test (push) Failing after 32s
Some checks failed
CI / test (push) Failing after 32s
- Add Cron Pool Monitor entry to sidebar menu - Install Docker CE CLI from Aliyun mirror for container exec - Mount Docker socket for managing openclaw-eval container - Fix OpenClaw CLI commands (cron add/rm/list instead of automations) - Add gateway token auth for CLI access
This commit is contained in:
parent
4e9145db46
commit
fed52f3920
@ -26,16 +26,19 @@ class OpenClawCron:
|
|||||||
class OpenClawClient:
|
class OpenClawClient:
|
||||||
"""Client for OpenClaw CLI commands."""
|
"""Client for OpenClaw CLI commands."""
|
||||||
|
|
||||||
def __init__(self, openclaw_bin: str = "openclaw"):
|
def __init__(self, openclaw_bin: str = "docker", container_name: str = "openclaw-eval", gateway_token: str = "agenteval-openclaw-token-2026"):
|
||||||
self.openclaw_bin = openclaw_bin
|
self.openclaw_bin = openclaw_bin
|
||||||
|
self.container_name = container_name
|
||||||
|
self.gateway_token = gateway_token
|
||||||
|
|
||||||
async def _run_command(self, *args: str) -> tuple[int, str, str]:
|
async def _run_command(self, *args: str) -> tuple[int, str, str]:
|
||||||
"""Run an OpenClaw CLI command.
|
"""Run an OpenClaw CLI command via docker exec.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(returncode, stdout, stderr)
|
(returncode, stdout, stderr)
|
||||||
"""
|
"""
|
||||||
cmd = [self.openclaw_bin] + list(args)
|
# token 需要放在子命令後面
|
||||||
|
cmd = [self.openclaw_bin, "exec", self.container_name, "openclaw"] + list(args) + [f"--token={self.gateway_token}"]
|
||||||
_logger.debug(f"Running OpenClaw command: {' '.join(cmd)}")
|
_logger.debug(f"Running OpenClaw command: {' '.join(cmd)}")
|
||||||
|
|
||||||
process = await asyncio.create_subprocess_exec(
|
process = await asyncio.create_subprocess_exec(
|
||||||
@ -64,8 +67,8 @@ class OpenClawClient:
|
|||||||
Args:
|
Args:
|
||||||
name: Cron job name
|
name: Cron job name
|
||||||
schedule: Cron schedule expression (e.g., "* * * * *")
|
schedule: Cron schedule expression (e.g., "* * * * *")
|
||||||
skill: Skill to execute
|
skill: Skill to execute (sent as message to trigger skill)
|
||||||
state: Initial state (JSON)
|
state: Initial state (JSON, stored in description)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Cron job ID
|
Cron job ID
|
||||||
@ -74,29 +77,32 @@ class OpenClawClient:
|
|||||||
RuntimeError: If creation fails
|
RuntimeError: If creation fails
|
||||||
"""
|
"""
|
||||||
args = [
|
args = [
|
||||||
"automations",
|
"cron",
|
||||||
"create",
|
"add",
|
||||||
schedule,
|
"--cron", schedule,
|
||||||
f"--name={name}",
|
f"--name={name}",
|
||||||
f"--skill={skill}",
|
f"--message={skill}",
|
||||||
|
"--json",
|
||||||
]
|
]
|
||||||
|
|
||||||
if state:
|
if state:
|
||||||
args.append(f"--state={json.dumps(state)}")
|
# Store state in description since there's no --state option
|
||||||
|
args.append(f"--description=state:{json.dumps(state)}")
|
||||||
|
|
||||||
returncode, stdout, stderr = await self._run_command(*args)
|
returncode, stdout, stderr = await self._run_command(*args)
|
||||||
|
|
||||||
if returncode != 0:
|
if returncode != 0:
|
||||||
raise RuntimeError(f"Failed to create cron: {stderr}")
|
raise RuntimeError(f"Failed to create cron: {stderr}")
|
||||||
|
|
||||||
# Parse cron ID from output
|
# Parse cron ID from JSON output
|
||||||
# Expected output format: "Created automation <id>"
|
try:
|
||||||
lines = stdout.strip().split("\n")
|
data = json.loads(stdout)
|
||||||
for line in lines:
|
cron_id = data.get("id")
|
||||||
if "Created automation" in line:
|
if cron_id:
|
||||||
cron_id = line.split()[-1]
|
|
||||||
_logger.info(f"Created OpenClaw cron {cron_id}: {name}")
|
_logger.info(f"Created OpenClaw cron {cron_id}: {name}")
|
||||||
return cron_id
|
return cron_id
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
pass
|
||||||
|
|
||||||
raise RuntimeError(f"Failed to parse cron ID from output: {stdout}")
|
raise RuntimeError(f"Failed to parse cron ID from output: {stdout}")
|
||||||
|
|
||||||
@ -110,8 +116,8 @@ class OpenClawClient:
|
|||||||
RuntimeError: If deletion fails
|
RuntimeError: If deletion fails
|
||||||
"""
|
"""
|
||||||
returncode, stdout, stderr = await self._run_command(
|
returncode, stdout, stderr = await self._run_command(
|
||||||
"automations",
|
"cron",
|
||||||
"remove",
|
"rm",
|
||||||
cron_id,
|
cron_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -130,7 +136,7 @@ class OpenClawClient:
|
|||||||
RuntimeError: If listing fails
|
RuntimeError: If listing fails
|
||||||
"""
|
"""
|
||||||
returncode, stdout, stderr = await self._run_command(
|
returncode, stdout, stderr = await self._run_command(
|
||||||
"automations",
|
"cron",
|
||||||
"list",
|
"list",
|
||||||
"--json",
|
"--json",
|
||||||
)
|
)
|
||||||
|
|||||||
@ -24,9 +24,15 @@ RUN sed -i \
|
|||||||
-e 's|security.debian.org|mirrors.aliyun.com/debian-security|g' \
|
-e 's|security.debian.org|mirrors.aliyun.com/debian-security|g' \
|
||||||
/etc/apt/sources.list 2>/dev/null || true
|
/etc/apt/sources.list 2>/dev/null || true
|
||||||
|
|
||||||
# Install any system build dependencies that may be needed for Python wheels.
|
# Install Docker CLI from Aliyun mirror (for China network) and build dependencies.
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& apt-get install -y --no-install-recommends gcc \
|
&& apt-get install -y --no-install-recommends gcc ca-certificates curl gnupg \
|
||||||
|
&& install -m 0755 -d /etc/apt/keyrings \
|
||||||
|
&& curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
|
||||||
|
&& chmod a+r /etc/apt/keyrings/docker.gpg \
|
||||||
|
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" > /etc/apt/sources.list.d/docker.list \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends docker-ce-cli \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY pyproject.toml README.md alembic.ini ./
|
COPY pyproject.toml README.md alembic.ini ./
|
||||||
|
|||||||
@ -20,6 +20,8 @@ services:
|
|||||||
- ../../backend:/app/backend:ro
|
- ../../backend:/app/backend:ro
|
||||||
# Mount .env so Pydantic Settings can load deployment-specific config.
|
# Mount .env so Pydantic Settings can load deployment-specific config.
|
||||||
- ../../.env:/app/.env:ro
|
- ../../.env:/app/.env:ro
|
||||||
|
# Mount Docker socket for managing openclaw-eval container (cron pool).
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
openclaw-eval:
|
openclaw-eval:
|
||||||
@ -31,4 +33,5 @@ services:
|
|||||||
- ../../data/openclaw:/home/node/.openclaw
|
- ../../data/openclaw:/home/node/.openclaw
|
||||||
environment:
|
environment:
|
||||||
- AGENTEVAL_API_URL=http://agenteval:8000
|
- AGENTEVAL_API_URL=http://agenteval:8000
|
||||||
|
- OPENCLAW_GATEWAY_TOKEN=agenteval-openclaw-token-2026
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@ -99,6 +99,7 @@ const menuItems: MenuProps['items'] = [
|
|||||||
label: '智能评估',
|
label: '智能评估',
|
||||||
children: [
|
children: [
|
||||||
{ key: '/intelligent-evals', icon: <BulbOutlined />, label: '评估列表' },
|
{ key: '/intelligent-evals', icon: <BulbOutlined />, label: '评估列表' },
|
||||||
|
{ key: '/cron-pool', icon: <DashboardOutlined />, label: 'Cron 池监控' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user