1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/vue-query';
import { computed } from 'vue';
import type { ComputedRef } from 'vue';
import api from '@/store/api';
import { useRedfishRoot } from '@/api/composables/useRedfishRoot';
import { shouldRetry } from '@/api/composables/useAllSubResources';
import type { Manager } from '@/api/types/redfish';
export const rebootBmcQueryKey = ['redfish', 'bmcManager'] as const;
export interface UseRebootBmcReturn {
lastBmcRebootTime: ComputedRef<Date | null>;
rebootBmc: () => Promise<void>;
isBusy: ComputedRef<boolean>;
isError: ComputedRef<boolean>;
isLoading: ComputedRef<boolean>;
isRebootEnabled: ComputedRef<boolean>;
}
export function useRebootBmc(): UseRebootBmcReturn {
const queryClient = useQueryClient();
const { data: serviceRoot, isLoading: rootLoading } = useRedfishRoot();
const managerProvidingServiceUri = computed<string | null>(
() => serviceRoot.value?.ManagerProvidingService?.['@odata.id'] ?? null,
);
const managersCollectionUri = computed<string | null>(
() => serviceRoot.value?.Managers?.['@odata.id'] ?? null,
);
const bmcQuery = useQuery<Manager | null, unknown>({
queryKey: computed(() => [
...rebootBmcQueryKey,
managerProvidingServiceUri.value ?? managersCollectionUri.value,
]),
queryFn: async ({ signal }) => {
let managerUri = managerProvidingServiceUri.value;
if (!managerUri) {
const collectionUri = managersCollectionUri.value;
if (!collectionUri) return null;
const { data: collection } = await api.get<{
Members?: { '@odata.id': string }[];
}>(collectionUri, { signal });
managerUri = collection.Members?.[0]?.['@odata.id'] ?? null;
}
if (!managerUri) return null;
const { data } = await api.get<Manager>(managerUri, { signal });
return data;
},
enabled: computed(
() => !!managerProvidingServiceUri.value || !!managersCollectionUri.value,
),
staleTime: Infinity,
gcTime: Infinity,
refetchOnMount: true,
refetchOnWindowFocus: false,
refetchOnReconnect: true,
retry: shouldRetry,
retryDelay: (attemptIndex: number) => Math.min(1000 * 2 ** attemptIndex, 30000),
});
const mutation = useMutation<void, unknown, void, unknown>({
mutationFn: async () => {
const manager = bmcQuery.data.value;
if (!manager) throw new Error('Manager resource not available');
const resetTarget =
manager.Actions?.['#Manager.Reset']?.target ??
`${manager['@odata.id']}/Actions/Manager.Reset`;
await api.post(resetTarget, { ResetType: 'GracefulRestart' });
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: rebootBmcQueryKey });
},
});
const lastBmcRebootTime = computed<Date | null>(() => {
const lastReset = bmcQuery.data.value?.LastResetTime;
return lastReset ? new Date(lastReset) : null;
});
const isBusy = computed<boolean>(() => mutation.isPending.value);
const isError = computed<boolean>(() => bmcQuery.isError.value);
const isLoading = computed<boolean>(
() => rootLoading.value || bmcQuery.isLoading.value,
);
const isRebootEnabled = computed<boolean>(
() => !isBusy.value && !isError.value && !!bmcQuery.data.value,
);
async function rebootBmc(): Promise<void> {
await mutation.mutateAsync();
}
return {
lastBmcRebootTime,
rebootBmc,
isBusy,
isError,
isLoading,
isRebootEnabled,
};
}
|