Skip to content

Commit 61fe696

Browse files
authored
feat: basic array controls (#1291)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Expanded API operations for array management, including new mutations for state changes and disk handling. - Introduced new enumeration and input types for managing array states in the GraphQL schema. - Added a new resolver for handling array mutations in the GraphQL API. - **Chores** - Upgraded configuration version to 4.4.1 and refined connectivity status reporting. - **Refactor** - Streamlined request processing with improved error handling to provide clearer feedback on connectivity issues. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent b4c8efa commit 61fe696

File tree

14 files changed

+645
-78
lines changed

14 files changed

+645
-78
lines changed

api/dev/Unraid.net/myservers.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[api]
2-
version="4.1.3"
2+
version="4.4.1"
33
extraOrigins="https://google.com,https://test.com"
44
[local]
55
sandbox="yes"

api/dev/states/myservers.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[api]
2-
version="4.1.3"
2+
version="4.4.1"
33
extraOrigins="https://google.com,https://test.com"
44
[local]
55
sandbox="yes"
@@ -20,5 +20,5 @@ dynamicRemoteAccessType="DISABLED"
2020
ssoSubIds=""
2121
allowedOrigins="/var/run/unraid-notifications.sock, /var/run/unraid-php.sock, /var/run/unraid-cli.sock, http://localhost:8080, https://localhost:4443, https://tower.local:4443, https://192.168.1.150:4443, https://tower:4443, https://192-168-1-150.thisisfourtyrandomcharacters012345678900.myunraid.net:4443, https://85-121-123-122.thisisfourtyrandomcharacters012345678900.myunraid.net:8443, https://10-252-0-1.hash.myunraid.net:4443, https://10-252-1-1.hash.myunraid.net:4443, https://10-253-3-1.hash.myunraid.net:4443, https://10-253-4-1.hash.myunraid.net:4443, https://10-253-5-1.hash.myunraid.net:4443, https://10-100-0-1.hash.myunraid.net:4443, https://10-100-0-2.hash.myunraid.net:4443, https://10-123-1-2.hash.myunraid.net:4443, https://221-123-121-112.hash.myunraid.net:4443, https://google.com, https://test.com, https://connect.myunraid.net, https://connect-staging.myunraid.net, https://dev-my.myunraid.net:4000, https://studio.apollographql.com"
2222
[connectionStatus]
23-
minigraph="PRE_INIT"
23+
minigraph="ERROR_RETRYING"
2424
upnpStatus=""

api/src/core/modules/array/get-array-data.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { GraphQLError } from 'graphql';
22
import { sum } from 'lodash-es';
33

44
import type { ArrayCapacity, ArrayType } from '@app/graphql/generated/api/types.js';
5-
import { getServerIdentifier } from '@app/core/utils/server-identifier.js';
65
import { ArrayDiskType } from '@app/graphql/generated/api/types.js';
76
import { store } from '@app/store/index.js';
87
import { FileLoadStatus } from '@app/store/types.js';

api/src/core/utils/clients/emcmd.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { got } from 'got';
22

3+
import { AppError } from '@app/core/errors/app-error.js';
34
import { logger } from '@app/core/log.js';
45
import { type LooseObject } from '@app/core/types/index.js';
5-
import { catchHandlers } from '@app/core/utils/misc/catch-handlers.js';
66
import { DRY_RUN } from '@app/environment.js';
77
import { getters } from '@app/store/index.js';
88

@@ -27,10 +27,15 @@ export const emcmd = async (commands: LooseObject) => {
2727
// Ensure we only log on dry-run
2828
return;
2929
}
30-
// Untested, this code is unused right now so going to assume it's probably not working well anyway, swapped
31-
// to got to remove this request-promise dependency
3230
return got
33-
.get(url, { searchParams: { ...commands, csrf_token: csrfToken } })
34-
.catch(catchHandlers.emhttpd);
35-
// return request.get(url, options).catch(catchHandlers.emhttpd);
31+
.get(url, {
32+
enableUnixSockets: true,
33+
searchParams: { ...commands, csrf_token: csrfToken },
34+
})
35+
.catch((error: NodeJS.ErrnoException) => {
36+
if (error.code === 'ENOENT') {
37+
throw new AppError('emhttpd socket unavailable.');
38+
}
39+
throw error;
40+
});
3641
};

api/src/graphql/generated/api/operations.ts

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import * as Types from '@app/graphql/generated/api/types.js';
33

44
import { z } from 'zod'
5-
import { AccessUrl, AccessUrlInput, AddPermissionInput, AddRoleForApiKeyInput, AddRoleForUserInput, AllowedOriginInput, ApiKey, ApiKeyResponse, ApiKeyWithSecret, ApiSettingsInput, ArrayType, ArrayCapacity, ArrayDisk, ArrayDiskFsColor, ArrayDiskStatus, ArrayDiskType, ArrayPendingState, ArrayState, Baseboard, Capacity, Case, Cloud, CloudResponse, Config, ConfigErrorState, Connect, ConnectSettings, ConnectSettingsValues, ConnectSignInInput, ConnectUserInfoInput, ContainerHostConfig, ContainerMount, ContainerPort, ContainerPortType, ContainerState, CreateApiKeyInput, Devices, Disk, DiskFsType, DiskInterfaceType, DiskPartition, DiskSmartStatus, Display, Docker, DockerContainer, DockerNetwork, DynamicRemoteAccessStatus, DynamicRemoteAccessType, EnableDynamicRemoteAccessInput, Flash, Gpu, Importance, Info, InfoApps, InfoCpu, InfoMemory, KeyFile, LogFile, LogFileContent, Me, MemoryFormFactor, MemoryLayout, MemoryType, MinigraphStatus, MinigraphqlResponse, Mount, Network, Node, Notification, NotificationCounts, NotificationData, NotificationFilter, NotificationOverview, NotificationType, Notifications, NotificationslistArgs, Os, Owner, ParityCheck, Partition, Pci, Permission, ProfileModel, Registration, RegistrationState, RelayResponse, RemoteAccess, RemoveRoleFromApiKeyInput, Resource, Role, Server, ServerStatus, Service, SetupRemoteAccessInput, Share, System, Temperature, Theme, URL_TYPE, UnassignedDevice, Uptime, Usb, User, UserAccount, Vars, Versions, VmDomain, VmState, Vms, WAN_ACCESS_TYPE, WAN_FORWARD_TYPE, Welcome, addUserInput, arrayDiskInput, deleteUserInput, mdState, registrationType, usersInput } from '@app/graphql/generated/api/types.js'
5+
import { AccessUrl, AccessUrlInput, AddPermissionInput, AddRoleForApiKeyInput, AddRoleForUserInput, AllowedOriginInput, ApiKey, ApiKeyResponse, ApiKeyWithSecret, ApiSettingsInput, ArrayType, ArrayCapacity, ArrayDisk, ArrayDiskFsColor, ArrayDiskInput, ArrayDiskStatus, ArrayDiskType, ArrayMutations, ArrayMutationsaddDiskToArrayArgs, ArrayMutationsclearArrayDiskStatisticsArgs, ArrayMutationsmountArrayDiskArgs, ArrayMutationsremoveDiskFromArrayArgs, ArrayMutationssetStateArgs, ArrayMutationsunmountArrayDiskArgs, ArrayPendingState, ArrayState, ArrayStateInput, ArrayStateInputState, Baseboard, Capacity, Case, Cloud, CloudResponse, Config, ConfigErrorState, Connect, ConnectSettings, ConnectSettingsValues, ConnectSignInInput, ConnectUserInfoInput, ContainerHostConfig, ContainerMount, ContainerPort, ContainerPortType, ContainerState, CreateApiKeyInput, Devices, Disk, DiskFsType, DiskInterfaceType, DiskPartition, DiskSmartStatus, Display, Docker, DockerContainer, DockerNetwork, DynamicRemoteAccessStatus, DynamicRemoteAccessType, EnableDynamicRemoteAccessInput, Flash, Gpu, Importance, Info, InfoApps, InfoCpu, InfoMemory, KeyFile, LogFile, LogFileContent, Me, MemoryFormFactor, MemoryLayout, MemoryType, MinigraphStatus, MinigraphqlResponse, Mount, Network, Node, Notification, NotificationCounts, NotificationData, NotificationFilter, NotificationOverview, NotificationType, Notifications, NotificationslistArgs, Os, Owner, ParityCheck, Partition, Pci, Permission, ProfileModel, Registration, RegistrationState, RelayResponse, RemoteAccess, RemoveRoleFromApiKeyInput, Resource, Role, Server, ServerStatus, Service, SetupRemoteAccessInput, Share, System, Temperature, Theme, URL_TYPE, UnassignedDevice, Uptime, Usb, User, UserAccount, Vars, Versions, VmDomain, VmState, Vms, WAN_ACCESS_TYPE, WAN_FORWARD_TYPE, Welcome, addUserInput, deleteUserInput, mdState, registrationType, usersInput } from '@app/graphql/generated/api/types.js'
66
import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
77

88
type Properties<T> = Required<{
@@ -25,6 +25,8 @@ export const ArrayPendingStateSchema = z.nativeEnum(ArrayPendingState);
2525

2626
export const ArrayStateSchema = z.nativeEnum(ArrayState);
2727

28+
export const ArrayStateInputStateSchema = z.nativeEnum(ArrayStateInputState);
29+
2830
export const ConfigErrorStateSchema = z.nativeEnum(ConfigErrorState);
2931

3032
export const ContainerPortTypeSchema = z.nativeEnum(ContainerPortType);
@@ -213,6 +215,67 @@ export function ArrayDiskSchema(): z.ZodObject<Properties<ArrayDisk>> {
213215
})
214216
}
215217

218+
export function ArrayDiskInputSchema(): z.ZodObject<Properties<ArrayDiskInput>> {
219+
return z.object({
220+
id: z.string(),
221+
slot: z.number().nullish()
222+
})
223+
}
224+
225+
export function ArrayMutationsSchema(): z.ZodObject<Properties<ArrayMutations>> {
226+
return z.object({
227+
__typename: z.literal('ArrayMutations').optional(),
228+
addDiskToArray: ArrayTypeSchema().nullish(),
229+
clearArrayDiskStatistics: z.record(z.string(), z.any()).nullish(),
230+
mountArrayDisk: DiskSchema().nullish(),
231+
removeDiskFromArray: ArrayTypeSchema().nullish(),
232+
setState: ArrayTypeSchema().nullish(),
233+
unmountArrayDisk: DiskSchema().nullish()
234+
})
235+
}
236+
237+
export function ArrayMutationsaddDiskToArrayArgsSchema(): z.ZodObject<Properties<ArrayMutationsaddDiskToArrayArgs>> {
238+
return z.object({
239+
input: z.lazy(() => ArrayDiskInputSchema().nullish())
240+
})
241+
}
242+
243+
export function ArrayMutationsclearArrayDiskStatisticsArgsSchema(): z.ZodObject<Properties<ArrayMutationsclearArrayDiskStatisticsArgs>> {
244+
return z.object({
245+
id: z.string()
246+
})
247+
}
248+
249+
export function ArrayMutationsmountArrayDiskArgsSchema(): z.ZodObject<Properties<ArrayMutationsmountArrayDiskArgs>> {
250+
return z.object({
251+
id: z.string()
252+
})
253+
}
254+
255+
export function ArrayMutationsremoveDiskFromArrayArgsSchema(): z.ZodObject<Properties<ArrayMutationsremoveDiskFromArrayArgs>> {
256+
return z.object({
257+
input: z.lazy(() => ArrayDiskInputSchema().nullish())
258+
})
259+
}
260+
261+
export function ArrayMutationssetStateArgsSchema(): z.ZodObject<Properties<ArrayMutationssetStateArgs>> {
262+
return z.object({
263+
input: z.lazy(() => ArrayStateInputSchema().nullish())
264+
})
265+
}
266+
267+
export function ArrayMutationsunmountArrayDiskArgsSchema(): z.ZodObject<Properties<ArrayMutationsunmountArrayDiskArgs>> {
268+
return z.object({
269+
id: z.string()
270+
})
271+
}
272+
273+
export function ArrayStateInputSchema(): z.ZodObject<Properties<ArrayStateInput>> {
274+
return z.object({
275+
desiredState: z.lazy(() => ArrayStateInputStateSchema)
276+
})
277+
}
278+
216279
export function BaseboardSchema(): z.ZodObject<Properties<Baseboard>> {
217280
return z.object({
218281
__typename: z.literal('Baseboard').optional(),
@@ -1303,13 +1366,6 @@ export function addUserInputSchema(): z.ZodObject<Properties<addUserInput>> {
13031366
})
13041367
}
13051368

1306-
export function arrayDiskInputSchema(): z.ZodObject<Properties<arrayDiskInput>> {
1307-
return z.object({
1308-
id: z.string(),
1309-
slot: z.number().nullish()
1310-
})
1311-
}
1312-
13131369
export function deleteUserInputSchema(): z.ZodObject<Properties<deleteUserInput>> {
13141370
return z.object({
13151371
name: z.string()

0 commit comments

Comments
 (0)