fix(deploy): resolve cron pool initialization issues
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:
sinohqb 2026-08-12 13:40:18 +08:00
parent 4e9145db46
commit fed52f3920
4 changed files with 37 additions and 21 deletions

View File

@ -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",
) )

View File

@ -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 ./

View File

@ -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

View File

@ -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 池监控' },
], ],
}, },
{ {