feat(tasks): allow management of job intervals and disabling them (#3408)

This commit is contained in:
Meier Lukas
2025-07-03 20:59:26 +02:00
committed by GitHub
parent 95c8aadb0c
commit 9398dd983c
37 changed files with 5224 additions and 195 deletions

View File

@@ -1,7 +1,8 @@
import { observable } from "@trpc/server/observable";
import z from "zod/v4";
import { objectEntries } from "@homarr/common";
import { cronJobNames, cronJobs, jobNameSchema, triggerCronJobAsync } from "@homarr/cron-job-runner";
import { cronExpressionSchema, jobGroupKeys, jobNameSchema } from "@homarr/cron-job-api";
import { cronJobApi } from "@homarr/cron-job-api/client";
import type { TaskStatus } from "@homarr/cron-job-status";
import { createCronJobStatusChannel } from "@homarr/cron-job-status";
import { logger } from "@homarr/log";
@@ -13,19 +14,51 @@ export const cronJobsRouter = createTRPCRouter({
.requiresPermission("admin")
.input(jobNameSchema)
.mutation(async ({ input }) => {
await triggerCronJobAsync(input);
await cronJobApi.trigger.mutate(input);
}),
getJobs: permissionRequiredProcedure.requiresPermission("admin").query(() => {
return objectEntries(cronJobs).map(([name, options]) => ({
name,
preventManualExecution: options.preventManualExecution,
}));
startJob: permissionRequiredProcedure
.requiresPermission("admin")
.input(jobNameSchema)
.mutation(async ({ input }) => {
await cronJobApi.start.mutate(input);
}),
stopJob: permissionRequiredProcedure
.requiresPermission("admin")
.input(jobNameSchema)
.mutation(async ({ input }) => {
await cronJobApi.stop.mutate(input);
}),
updateJobInterval: permissionRequiredProcedure
.requiresPermission("admin")
.input(
z.object({
name: jobNameSchema,
cron: cronExpressionSchema,
}),
)
.mutation(async ({ input }) => {
await cronJobApi.updateInterval.mutate(input);
}),
disableJob: permissionRequiredProcedure
.requiresPermission("admin")
.input(jobNameSchema)
.mutation(async ({ input }) => {
await cronJobApi.disable.mutate(input);
}),
enableJob: permissionRequiredProcedure
.requiresPermission("admin")
.input(jobNameSchema)
.mutation(async ({ input }) => {
await cronJobApi.enable.mutate(input);
}),
getJobs: permissionRequiredProcedure.requiresPermission("admin").query(async () => {
return await cronJobApi.getAll.query();
}),
subscribeToStatusUpdates: permissionRequiredProcedure.requiresPermission("admin").subscription(() => {
return observable<TaskStatus>((emit) => {
const unsubscribes: (() => void)[] = [];
for (const name of cronJobNames) {
for (const name of jobGroupKeys) {
const channel = createCronJobStatusChannel(name);
const unsubscribe = channel.subscribe((data) => {
emit.next(data);