Jobs html view changes.
This commit is contained in:
@@ -4,6 +4,7 @@ from typing import List, Optional, Union, Tuple, Dict, Any
|
|||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import logging
|
import logging
|
||||||
|
import base64
|
||||||
from traceback import format_exc
|
from traceback import format_exc
|
||||||
|
|
||||||
from packetserver.http.dependencies import get_current_http_user
|
from packetserver.http.dependencies import get_current_http_user
|
||||||
@@ -11,6 +12,7 @@ from packetserver.http.auth import HttpUser
|
|||||||
from packetserver.http.database import DbDependency
|
from packetserver.http.database import DbDependency
|
||||||
from packetserver.server.jobs import Job, JobStatus
|
from packetserver.server.jobs import Job, JobStatus
|
||||||
from packetserver.http.server import templates
|
from packetserver.http.server import templates
|
||||||
|
from packetserver.runner import RunnerFile
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1", tags=["jobs"])
|
router = APIRouter(prefix="/api/v1", tags=["jobs"])
|
||||||
dashboard_router = APIRouter(tags=["jobs"])
|
dashboard_router = APIRouter(tags=["jobs"])
|
||||||
@@ -30,12 +32,12 @@ class JobDetail(JobSummary):
|
|||||||
errors: str # base64-encoded
|
errors: str # base64-encoded
|
||||||
artifacts: List[Tuple[str, str]] # list of (filename, base64_data)
|
artifacts: List[Tuple[str, str]] # list of (filename, base64_data)
|
||||||
|
|
||||||
|
from typing import Dict
|
||||||
|
|
||||||
class JobCreate(BaseModel):
|
class JobCreate(BaseModel):
|
||||||
cmd: Union[str, List[str]]
|
cmd: Union[str, List[str]]
|
||||||
description: Optional[str] = None
|
|
||||||
env: Optional[Dict[str, str]] = None
|
env: Optional[Dict[str, str]] = None
|
||||||
workdir: Optional[str] = None
|
files: Optional[Dict[str, str]] = None
|
||||||
artifact_paths: Optional[List[str]] = None
|
|
||||||
|
|
||||||
@router.get("/jobs", response_model=List[JobSummary])
|
@router.get("/jobs", response_model=List[JobSummary])
|
||||||
async def list_user_jobs(
|
async def list_user_jobs(
|
||||||
@@ -157,25 +159,32 @@ async def create_job(
|
|||||||
username = current_user.username.upper().strip()
|
username = current_user.username.upper().strip()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with db.transaction() as conn:
|
# Process files: convert base64 dict to list of RunnerFile
|
||||||
root = conn.root()
|
runner_files = []
|
||||||
|
if payload.files:
|
||||||
|
for filename, b64_data in payload.files.items():
|
||||||
|
try:
|
||||||
|
data_bytes = base64.b64decode(b64_data)
|
||||||
|
runner_files.append(RunnerFile(filename, data=data_bytes))
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(status_code=400, detail=f"Invalid base64 for file {filename}")
|
||||||
|
|
||||||
# Queue the job using existing method
|
# Create the Job instance
|
||||||
new_job = Job.queue(
|
new_job = Job(
|
||||||
cmd=payload.cmd,
|
cmd=payload.cmd,
|
||||||
owner=username,
|
owner=username,
|
||||||
description=payload.description or "",
|
|
||||||
env=payload.env or {},
|
env=payload.env or {},
|
||||||
workdir=payload.workdir or "",
|
files=runner_files
|
||||||
artifact_paths=payload.artifact_paths or [],
|
|
||||||
db=root # or root, depending on your queue() signature
|
|
||||||
)
|
)
|
||||||
|
|
||||||
logging.info(f"User {username} queued job {new_job.id}: {payload.cmd}")
|
with db.transaction() as conn:
|
||||||
|
root = conn.root()
|
||||||
|
new_jid = new_job.queue(root)
|
||||||
|
|
||||||
|
logging.info(f"User {username} queued job {new_jid}: {payload.cmd} with {len(runner_files)} files")
|
||||||
|
|
||||||
# Return summary (reuse the same format as list)
|
|
||||||
return JobSummary(
|
return JobSummary(
|
||||||
id=new_job.id,
|
id=new_jid,
|
||||||
cmd=new_job.cmd,
|
cmd=new_job.cmd,
|
||||||
owner=new_job.owner,
|
owner=new_job.owner,
|
||||||
created_at=new_job.created_at,
|
created_at=new_job.created_at,
|
||||||
@@ -185,6 +194,10 @@ async def create_job(
|
|||||||
return_code=new_job.return_code
|
return_code=new_job.return_code
|
||||||
)
|
)
|
||||||
|
|
||||||
|
except ValueError as ve:
|
||||||
|
raise HTTPException(status_code=400, detail=str(ve))
|
||||||
|
except HTTPException:
|
||||||
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Job creation failed for {username}: {e}\n{format_exc()}")
|
logging.error(f"Job creation failed for {username}: {e}\n{format_exc()}")
|
||||||
raise HTTPException(status_code=500, detail="Failed to queue job")
|
raise HTTPException(status_code=500, detail="Failed to queue job")
|
||||||
@@ -202,6 +202,7 @@ class Job(persistent.Persistent):
|
|||||||
"return_code": self.return_code,
|
"return_code": self.return_code,
|
||||||
"artifacts": [],
|
"artifacts": [],
|
||||||
"status": self.status.name,
|
"status": self.status.name,
|
||||||
|
"env": self.env,
|
||||||
"id": self.id
|
"id": self.id
|
||||||
}
|
}
|
||||||
if include_data:
|
if include_data:
|
||||||
|
|||||||
Reference in New Issue
Block a user