feat: allow stopping an ongoing backup

This commit is contained in:
Nicolas Meienberger
2025-11-08 23:26:53 +01:00
parent 3abf8ab12d
commit 5f620b4c45
11 changed files with 258 additions and 97 deletions

View File

@@ -36,6 +36,7 @@ import {
updateBackupSchedule,
getBackupScheduleForVolume,
runBackupNow,
stopBackup,
getSystemInfo,
downloadResticPassword,
} from "../sdk.gen";
@@ -94,9 +95,10 @@ import type {
GetBackupScheduleForVolumeData,
RunBackupNowData,
RunBackupNowResponse,
StopBackupData,
StopBackupResponse,
GetSystemInfoData,
DownloadResticPasswordData,
DownloadResticPasswordError,
DownloadResticPasswordResponse,
} from "../types.gen";
import { client as _heyApiClient } from "../client.gen";
@@ -1108,6 +1110,45 @@ export const runBackupNowMutation = (
return mutationOptions;
};
export const stopBackupQueryKey = (options: Options<StopBackupData>) => createQueryKey("stopBackup", options);
/**
* Stop a backup that is currently in progress
*/
export const stopBackupOptions = (options: Options<StopBackupData>) => {
return queryOptions({
queryFn: async ({ queryKey, signal }) => {
const { data } = await stopBackup({
...options,
...queryKey[0],
signal,
throwOnError: true,
});
return data;
},
queryKey: stopBackupQueryKey(options),
});
};
/**
* Stop a backup that is currently in progress
*/
export const stopBackupMutation = (
options?: Partial<Options<StopBackupData>>,
): UseMutationOptions<StopBackupResponse, DefaultError, Options<StopBackupData>> => {
const mutationOptions: UseMutationOptions<StopBackupResponse, DefaultError, Options<StopBackupData>> = {
mutationFn: async (localOptions) => {
const { data } = await stopBackup({
...options,
...localOptions,
throwOnError: true,
});
return data;
},
};
return mutationOptions;
};
export const getSystemInfoQueryKey = (options?: Options<GetSystemInfoData>) => createQueryKey("getSystemInfo", options);
/**
@@ -1154,14 +1195,10 @@ export const downloadResticPasswordOptions = (options?: Options<DownloadResticPa
*/
export const downloadResticPasswordMutation = (
options?: Partial<Options<DownloadResticPasswordData>>,
): UseMutationOptions<
DownloadResticPasswordResponse,
DownloadResticPasswordError,
Options<DownloadResticPasswordData>
> => {
): UseMutationOptions<DownloadResticPasswordResponse, DefaultError, Options<DownloadResticPasswordData>> => {
const mutationOptions: UseMutationOptions<
DownloadResticPasswordResponse,
DownloadResticPasswordError,
DefaultError,
Options<DownloadResticPasswordData>
> = {
mutationFn: async (localOptions) => {

View File

@@ -74,11 +74,13 @@ import type {
GetBackupScheduleForVolumeResponses,
RunBackupNowData,
RunBackupNowResponses,
StopBackupData,
StopBackupResponses,
StopBackupErrors,
GetSystemInfoData,
GetSystemInfoResponses,
DownloadResticPasswordData,
DownloadResticPasswordResponses,
DownloadResticPasswordErrors,
} from "./types.gen";
import { client as _heyApiClient } from "./client.gen";
@@ -533,6 +535,16 @@ export const runBackupNow = <ThrowOnError extends boolean = false>(
});
};
/**
* Stop a backup that is currently in progress
*/
export const stopBackup = <ThrowOnError extends boolean = false>(options: Options<StopBackupData, ThrowOnError>) => {
return (options.client ?? _heyApiClient).post<StopBackupResponses, StopBackupErrors, ThrowOnError>({
url: "/api/v1/backups/{scheduleId}/stop",
...options,
});
};
/**
* Get system information including available capabilities
*/
@@ -551,11 +563,7 @@ export const getSystemInfo = <ThrowOnError extends boolean = false>(
export const downloadResticPassword = <ThrowOnError extends boolean = false>(
options?: Options<DownloadResticPasswordData, ThrowOnError>,
) => {
return (options?.client ?? _heyApiClient).post<
DownloadResticPasswordResponses,
DownloadResticPasswordErrors,
ThrowOnError
>({
return (options?.client ?? _heyApiClient).post<DownloadResticPasswordResponses, unknown, ThrowOnError>({
url: "/api/v1/system/restic-password",
...options,
headers: {

View File

@@ -1480,6 +1480,33 @@ export type RunBackupNowResponses = {
export type RunBackupNowResponse = RunBackupNowResponses[keyof RunBackupNowResponses];
export type StopBackupData = {
body?: never;
path: {
scheduleId: string;
};
query?: never;
url: "/api/v1/backups/{scheduleId}/stop";
};
export type StopBackupErrors = {
/**
* No backup is currently running for this schedule
*/
409: unknown;
};
export type StopBackupResponses = {
/**
* Backup stopped successfully
*/
200: {
success: boolean;
};
};
export type StopBackupResponse = StopBackupResponses[keyof StopBackupResponses];
export type GetSystemInfoData = {
body?: never;
path?: never;
@@ -1509,17 +1536,6 @@ export type DownloadResticPasswordData = {
url: "/api/v1/system/restic-password";
};
export type DownloadResticPasswordErrors = {
/**
* Authentication required or incorrect password
*/
401: {
message?: string;
};
};
export type DownloadResticPasswordError = DownloadResticPasswordErrors[keyof DownloadResticPasswordErrors];
export type DownloadResticPasswordResponses = {
/**
* Restic password file content