Initial YakPanel commit
This commit is contained in:
113
YakPanel-server/backend/app/api/crontab.py
Normal file
113
YakPanel-server/backend/app/api/crontab.py
Normal file
@@ -0,0 +1,113 @@
|
||||
"""YakPanel - Crontab API"""
|
||||
import tempfile
|
||||
import os
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
from pydantic import BaseModel
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.core.utils import exec_shell_sync
|
||||
from app.api.auth import get_current_user
|
||||
from app.models.user import User
|
||||
from app.models.crontab import Crontab
|
||||
|
||||
router = APIRouter(prefix="/crontab", tags=["crontab"])
|
||||
|
||||
|
||||
class CreateCrontabRequest(BaseModel):
|
||||
name: str = ""
|
||||
type: str = "shell"
|
||||
schedule: str
|
||||
execstr: str
|
||||
|
||||
|
||||
@router.get("/list")
|
||||
async def crontab_list(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""List cron jobs"""
|
||||
result = await db.execute(select(Crontab).order_by(Crontab.id))
|
||||
rows = result.scalars().all()
|
||||
return [{"id": r.id, "name": r.name, "type": r.type, "schedule": r.schedule, "execstr": r.execstr} for r in rows]
|
||||
|
||||
|
||||
@router.post("/create")
|
||||
async def crontab_create(
|
||||
body: CreateCrontabRequest,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Create cron job"""
|
||||
cron = Crontab(name=body.name, type=body.type, schedule=body.schedule, execstr=body.execstr)
|
||||
db.add(cron)
|
||||
await db.commit()
|
||||
return {"status": True, "msg": "Cron job created", "id": cron.id}
|
||||
|
||||
|
||||
@router.post("/apply")
|
||||
async def crontab_apply(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Sync panel cron jobs to system crontab (root)"""
|
||||
result = await db.execute(select(Crontab).order_by(Crontab.id))
|
||||
rows = result.scalars().all()
|
||||
lines = [
|
||||
"# YakPanel managed crontab - do not edit manually",
|
||||
"",
|
||||
]
|
||||
for r in rows:
|
||||
if r.name:
|
||||
lines.append(f"# {r.name}")
|
||||
lines.append(f"{r.schedule} {r.execstr}")
|
||||
lines.append("")
|
||||
content = "\n".join(lines).strip() + "\n"
|
||||
fd, path = tempfile.mkstemp(suffix=".crontab", prefix="cit_")
|
||||
try:
|
||||
os.write(fd, content.encode("utf-8"))
|
||||
os.close(fd)
|
||||
out, err = exec_shell_sync(f"crontab {path}", timeout=10)
|
||||
if err and "error" in err.lower():
|
||||
raise HTTPException(status_code=500, detail=err.strip() or out.strip())
|
||||
finally:
|
||||
if os.path.exists(path):
|
||||
os.unlink(path)
|
||||
return {"status": True, "msg": "Crontab applied", "count": len(rows)}
|
||||
|
||||
|
||||
@router.put("/{cron_id}")
|
||||
async def crontab_update(
|
||||
cron_id: int,
|
||||
body: CreateCrontabRequest,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Update cron job"""
|
||||
result = await db.execute(select(Crontab).where(Crontab.id == cron_id))
|
||||
cron = result.scalar_one_or_none()
|
||||
if not cron:
|
||||
raise HTTPException(status_code=404, detail="Cron job not found")
|
||||
cron.name = body.name
|
||||
cron.type = body.type
|
||||
cron.schedule = body.schedule
|
||||
cron.execstr = body.execstr
|
||||
await db.commit()
|
||||
return {"status": True, "msg": "Cron job updated"}
|
||||
|
||||
|
||||
@router.delete("/{cron_id}")
|
||||
async def crontab_delete(
|
||||
cron_id: int,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
):
|
||||
"""Delete cron job"""
|
||||
result = await db.execute(select(Crontab).where(Crontab.id == cron_id))
|
||||
cron = result.scalar_one_or_none()
|
||||
if not cron:
|
||||
raise HTTPException(status_code=404, detail="Cron job not found")
|
||||
await db.delete(cron)
|
||||
await db.commit()
|
||||
return {"status": True, "msg": "Cron job deleted"}
|
||||
Reference in New Issue
Block a user