206 lines
7.6 KiB
PHP
206 lines
7.6 KiB
PHP
<?php
|
|
|
|
namespace routes;
|
|
|
|
use classes\authentication;
|
|
use classes\cron_scheduler;
|
|
use classes\cron_worker;
|
|
use classes\release_manager;
|
|
use objects\logs_o;
|
|
use Throwable;
|
|
use traits\route_t;
|
|
|
|
class cronRoute
|
|
{
|
|
use route_t;
|
|
|
|
public function run(): void
|
|
{
|
|
$this->get('/superuser/cron', function () {
|
|
global $response;
|
|
|
|
$this->requireClassicSuperuserPermission('superuser_cron_view');
|
|
$response->success((new cron_scheduler())->listTasks());
|
|
}, [
|
|
'superuser_cron_view' => 'View cron task schedule, run status, estimates, and history',
|
|
]);
|
|
|
|
$this->get('/superuser/cron/runs', function () {
|
|
global $response;
|
|
|
|
$this->requireClassicSuperuserPermission('superuser_cron_view');
|
|
$task_id = $this->getParameter('task_id');
|
|
$limit = (int)($this->getParameter('limit') ?? 50);
|
|
$response->success([
|
|
'runs' => (new cron_scheduler())->listRuns(is_string($task_id) ? $task_id : null, $limit),
|
|
]);
|
|
}, [
|
|
'superuser_cron_view' => 'View cron task schedule, run status, estimates, and history',
|
|
]);
|
|
|
|
$this->get('/superuser/cron/workers', function () {
|
|
global $response;
|
|
|
|
$this->requireClassicSuperuserPermission('superuser_cron_view');
|
|
$parameters = $this->getParametersAsArray();
|
|
$workers = (new cron_worker())->listWorkers();
|
|
try {
|
|
$workers['deployment'] = (new release_manager())->cronWorkerStatus($parameters);
|
|
} catch (Throwable $throwable) {
|
|
$workers['deployment'] = [
|
|
'ok' => false,
|
|
'error' => $throwable->getMessage(),
|
|
];
|
|
}
|
|
$response->success($workers);
|
|
}, [
|
|
'superuser_cron_view' => 'View cron worker deployment and heartbeat state',
|
|
]);
|
|
|
|
$this->post('/superuser/cron/workers/deploy', function () {
|
|
global $response;
|
|
|
|
$this->requireClassicSuperuserPermission('superuser_cron_manage');
|
|
$this->requirePermission('superuser_coolify_manage');
|
|
try {
|
|
$result = (new release_manager())->deployCronWorker(
|
|
$this->getParametersAsArray(),
|
|
$this->actorUserId()
|
|
);
|
|
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_WORKER_DEPLOY', 'Deployed cron worker');
|
|
$response->success($result);
|
|
} catch (Throwable $throwable) {
|
|
$response->error(['message' => $throwable->getMessage()], 409);
|
|
}
|
|
}, [
|
|
'superuser_cron_manage' => 'Deploy and configure cron workers',
|
|
'superuser_coolify_manage' => 'Deploy Coolify-managed infrastructure resources',
|
|
]);
|
|
|
|
$this->post('/superuser/cron/run', function () {
|
|
global $response;
|
|
|
|
$this->requireClassicSuperuserPermission('SUPERUSER_RUN_CRON');
|
|
$parameters = $this->getParametersAsArray();
|
|
$task_id = trim((string)($parameters['task_id'] ?? ''));
|
|
if ($task_id === '') {
|
|
$response->error('Missing cron task id.', 400);
|
|
}
|
|
|
|
try {
|
|
$run = (new cron_scheduler())->queueTaskRun(
|
|
$task_id,
|
|
$this->actorUserId(),
|
|
$this->toBool($parameters['force'] ?? false, false)
|
|
);
|
|
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_JOB_QUEUED', 'Queued cron task: ' . $task_id);
|
|
$response->success($run, 202);
|
|
} catch (Throwable $throwable) {
|
|
$response->error(['message' => $throwable->getMessage()], 409);
|
|
}
|
|
}, [
|
|
'SUPERUSER_RUN_CRON' => 'Run cron jobs',
|
|
]);
|
|
|
|
$this->patch('/superuser/cron/config', function () {
|
|
global $response;
|
|
|
|
$this->requireClassicSuperuserPermission('superuser_cron_manage');
|
|
$parameters = $this->getParametersAsArray();
|
|
$task_id = trim((string)($parameters['task_id'] ?? ''));
|
|
if ($task_id === '') {
|
|
$response->error('Missing cron task id.', 400);
|
|
}
|
|
|
|
try {
|
|
$config = [];
|
|
if (array_key_exists('enabled', $parameters)) {
|
|
$config['enabled'] = $this->toBool($parameters['enabled'], true);
|
|
}
|
|
if (array_key_exists('schedule', $parameters)) {
|
|
$config['schedule'] = $parameters['schedule'];
|
|
}
|
|
$result = (new cron_scheduler())->updateTaskConfig($task_id, $config);
|
|
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_TASK_CONFIG_UPDATED', 'Updated cron task: ' . $task_id);
|
|
$response->success($result);
|
|
} catch (Throwable $throwable) {
|
|
$response->error(['message' => $throwable->getMessage()], 409);
|
|
}
|
|
}, [
|
|
'superuser_cron_manage' => 'Configure cron task schedules and enabled state',
|
|
]);
|
|
|
|
$this->post('/superuser/cron', function () {
|
|
global $response;
|
|
|
|
$this->requireClassicSuperuserPermission('SUPERUSER_RUN_CRON');
|
|
$parameters = $this->getParametersAsArray();
|
|
$scheduler = new cron_scheduler();
|
|
|
|
try {
|
|
if (isset($parameters['job']) && trim((string)$parameters['job']) !== '') {
|
|
$job = trim((string)$parameters['job']);
|
|
$run = $scheduler->runTask($job, 'manual', $this->actorUserId(), true);
|
|
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_JOB_RUN', 'Ran cron job: ' . $job);
|
|
$response->success([
|
|
'message' => 'Cron job ran successfully',
|
|
'run' => $run,
|
|
]);
|
|
}
|
|
|
|
$result = $scheduler->runDue('manual');
|
|
(new logs_o())->add('cron', 'global', 1, $this->actorUserId() ?? 0, 'CRON_RUN', 'Ran due cron jobs');
|
|
$response->success([
|
|
'message' => 'Due cron jobs ran successfully',
|
|
'data' => $result,
|
|
]);
|
|
} catch (Throwable $throwable) {
|
|
$response->error(['message' => $throwable->getMessage()], 409);
|
|
}
|
|
},
|
|
[
|
|
'SUPERUSER_RUN_CRON' => 'Run cron jobs'
|
|
]
|
|
);
|
|
}
|
|
|
|
private function requireClassicSuperuserPermission(string $permission): bool
|
|
{
|
|
global $response;
|
|
|
|
if ((new authentication())->get_subuser() !== false) {
|
|
$response->error('Subuser sessions cannot manage cron tasks.', 403);
|
|
}
|
|
|
|
return $this->requirePermission($permission);
|
|
}
|
|
|
|
private function actorUserId(): ?int
|
|
{
|
|
try {
|
|
$user = (new authentication())->get_user();
|
|
return $user !== false && isset($user->id) ? (int)$user->id : null;
|
|
} catch (Throwable) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private function toBool(mixed $value, bool $default): bool
|
|
{
|
|
if (is_bool($value)) {
|
|
return $value;
|
|
}
|
|
if ($value === null) {
|
|
return $default;
|
|
}
|
|
$normalized = strtolower(trim((string)$value));
|
|
if (in_array($normalized, ['1', 'true', 'yes', 'on'], true)) {
|
|
return true;
|
|
}
|
|
if (in_array($normalized, ['0', 'false', 'no', 'off'], true)) {
|
|
return false;
|
|
}
|
|
return $default;
|
|
}
|
|
}
|