-
Couldn't load subscription status.
- Fork 11
chore: begin moving paths to nest #1329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| import { Injectable } from '@nestjs/common'; | ||
| import { join, resolve as resolvePath } from 'path'; | ||
|
|
||
| @Injectable() | ||
| export class PathsConfig { | ||
| private static instance: PathsConfig; | ||
|
|
||
| readonly core = import.meta.dirname; | ||
| readonly unraidApiBase = '/usr/local/unraid-api/'; | ||
| readonly unraidData = resolvePath( | ||
| process.env.PATHS_UNRAID_DATA ?? '/boot/config/plugins/dynamix.my.servers/data/' | ||
| ); | ||
| readonly dockerAutostart = '/var/lib/docker/unraid-autostart'; | ||
| readonly dockerSocket = '/var/run/docker.sock'; | ||
| readonly parityChecks = '/boot/config/parity-checks.log'; | ||
| readonly htpasswd = '/etc/nginx/htpasswd'; | ||
| readonly emhttpdSocket = '/var/run/emhttpd.socket'; | ||
| readonly states = resolvePath(process.env.PATHS_STATES ?? '/usr/local/emhttp/state/'); | ||
| readonly dynamixBase = resolvePath( | ||
| process.env.PATHS_DYNAMIX_BASE ?? '/boot/config/plugins/dynamix/' | ||
| ); | ||
|
|
||
| /** | ||
| * Plugins have a default config and, optionally, a user-customized config. | ||
| * You have to merge them to resolve a the correct config. | ||
| * | ||
| * i.e. the plugin author can update or change defaults without breaking user configs | ||
| * | ||
| * Thus, we've described this plugin's config paths as a list. The order matters! | ||
| * Config data in earlier paths will be overwritten by configs from later paths. | ||
| * | ||
| * See [the original PHP implementation.](https://github.com/unraid/webgui/blob/95c6913c62e64314b985e08222feb3543113b2ec/emhttp/plugins/dynamix/include/Wrappers.php#L42) | ||
| * | ||
| * Here, the first path in the list is the default config. | ||
| * The second is the user-customized config. | ||
| */ | ||
| readonly dynamixConfig = [ | ||
| resolvePath( | ||
| process.env.PATHS_DYNAMIX_CONFIG_DEFAULT ?? | ||
|
Check failure on line 39 in api/src/config/paths.config.ts
|
||
| '/usr/local/emhttp/plugins/dynamix/default.cfg' | ||
| ), | ||
| resolvePath( | ||
|
Check failure on line 42 in api/src/config/paths.config.ts
|
||
| process.env.PATHS_DYNAMIX_CONFIG ?? '/boot/config/plugins/dynamix/dynamix.cfg' | ||
| ), | ||
| ]; | ||
|
|
||
| readonly myserversBase = '/boot/config/plugins/dynamix.my.servers/'; | ||
| readonly myserversConfig = resolvePath( | ||
| process.env.PATHS_MY_SERVERS_CONFIG ?? | ||
|
Check failure on line 49 in api/src/config/paths.config.ts
|
||
| '/boot/config/plugins/dynamix.my.servers/myservers.cfg' | ||
| ); | ||
| readonly myserversConfigStates = join( | ||
| resolvePath(process.env.PATHS_STATES ?? '/usr/local/emhttp/state/'), | ||
| 'myservers.cfg' | ||
| ); | ||
| readonly myserversEnv = '/boot/config/plugins/dynamix.my.servers/env'; | ||
| readonly myserversKeepalive = | ||
| process.env.PATHS_MY_SERVERS_FB ?? | ||
|
Check failure on line 58 in api/src/config/paths.config.ts
|
||
| '/boot/config/plugins/dynamix.my.servers/fb_keepalive'; | ||
| readonly keyfileBase = resolvePath(process.env.PATHS_KEYFILE_BASE ?? '/boot/config'); | ||
| readonly machineId = resolvePath(process.env.PATHS_MACHINE_ID ?? '/var/lib/dbus/machine-id'); | ||
| readonly logBase = resolvePath('/var/log/unraid-api/'); | ||
| readonly unraidLogBase = resolvePath('/var/log/'); | ||
| readonly varRun = '/var/run'; | ||
| readonly authSessions = process.env.PATHS_AUTH_SESSIONS ?? '/var/lib/php'; | ||
| readonly authKeys = resolvePath( | ||
| process.env.PATHS_AUTH_KEY ?? '/boot/config/plugins/dynamix.my.servers/keys' | ||
| ); | ||
|
|
||
| // Singleton access | ||
| static getInstance(): PathsConfig { | ||
| if (!PathsConfig.instance) { | ||
| PathsConfig.instance = new PathsConfig(); | ||
| } | ||
| return PathsConfig.instance; | ||
| } | ||
| } | ||
|
Check failure on line 77 in api/src/config/paths.config.ts
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import { Global, Module } from '@nestjs/common'; | ||
| import { PathsConfig } from './paths.config.js'; | ||
|
Check failure on line 2 in api/src/config/paths.module.ts
|
||
|
|
||
| @Global() | ||
| @Module({ | ||
| providers: [PathsConfig], | ||
| exports: [PathsConfig], | ||
| }) | ||
| export class PathsModule {} | ||
|
Check failure on line 9 in api/src/config/paths.module.ts
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| export enum StateFileKey { | ||
| DISPLAY = 'display', | ||
| DISKS = 'disks', | ||
| DOCKER = 'docker', | ||
| EMHTTP = 'emhttp', | ||
| IDENT = 'ident', | ||
| SHARES = 'shares', | ||
| SLOTS = 'slots', | ||
| USERS = 'users', | ||
| DEVICES = 'devices', | ||
| NETWORK = 'network', | ||
| NFS = 'nfs', | ||
| NGINX = 'nginx', | ||
| SMB = 'smb', | ||
| VAR = 'var', | ||
| SEC = 'sec', | ||
| NOTIFICATION = 'notification', | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,16 @@ | ||
| import Docker from 'dockerode'; | ||
| import { PathsConfig } from '../../../config/paths.config.js'; | ||
|
|
||
| const socketPath = '/var/run/docker.sock'; | ||
| const client = new Docker({ | ||
| socketPath, | ||
| }); | ||
| const createDockerClient = () => { | ||
| const paths = PathsConfig.getInstance(); | ||
| const socketPath = paths.dockerSocket; | ||
| return new Docker({ | ||
| socketPath, | ||
| }); | ||
| }; | ||
|
|
||
| /** | ||
| * Docker client | ||
| */ | ||
| export const docker = client; | ||
| export const docker = createDockerClient(); | ||
| export { createDockerClient }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { PathsConfig } from '../../../config/paths.config.js'; | ||
|
|
||
| export const createEmhttpdClient = () => { | ||
| const paths = PathsConfig.getInstance(); | ||
| const socketPath = paths.emhttpdSocket; | ||
| // Rest of implementation | ||
| }; | ||
|
Comment on lines
+3
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Complete the implementation The function contains a placeholder comment but lacks actual implementation. Please complete the implementation of this client function. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { PathsConfig } from '../../../config/paths.config.js'; | ||
|
|
||
| export const createSshClient = () => { | ||
| const paths = PathsConfig.getInstance(); | ||
| const keyPath = paths.keyfileBase; | ||
| // Rest of implementation | ||
| }; | ||
|
Comment on lines
+3
to
+7
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Complete the implementation The function contains a placeholder comment but lacks actual implementation. Please complete the implementation of this SSH client function. |
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,6 @@ | ||||||||||||||||||||||||||||||||||||
| import { AppError } from '@app/core/errors/app-error.js'; | ||||||||||||||||||||||||||||||||||||
| import { getters } from '@app/store/index.js'; | ||||||||||||||||||||||||||||||||||||
| import { PathsConfig } from '../../../config/paths.config.js'; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| interface DockerError extends NodeJS.ErrnoException { | ||||||||||||||||||||||||||||||||||||
| address: string; | ||||||||||||||||||||||||||||||||||||
|
|
@@ -10,7 +11,8 @@ interface DockerError extends NodeJS.ErrnoException { | |||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||
| export const catchHandlers = { | ||||||||||||||||||||||||||||||||||||
| docker(error: DockerError) { | ||||||||||||||||||||||||||||||||||||
| const socketPath = getters.paths()['docker-socket']; | ||||||||||||||||||||||||||||||||||||
| const paths = PathsConfig.getInstance(); | ||||||||||||||||||||||||||||||||||||
| const socketPath = paths.dockerSocket; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| // Throw custom error for docker socket missing | ||||||||||||||||||||||||||||||||||||
| if (error.code === 'ENOENT' && error.address === socketPath) { | ||||||||||||||||||||||||||||||||||||
|
|
@@ -27,3 +29,9 @@ export const catchHandlers = { | |||||||||||||||||||||||||||||||||||
| throw error; | ||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| export const handleDockerError = (error: Error) => { | ||||||||||||||||||||||||||||||||||||
| const paths = PathsConfig.getInstance(); | ||||||||||||||||||||||||||||||||||||
| const socketPath = paths.dockerSocket; | ||||||||||||||||||||||||||||||||||||
| // Rest of implementation | ||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+33
to
+37
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incomplete implementation for handleDockerError. The function appears to be a stub with "Rest of implementation" as a comment. This should be completed before merging. export const handleDockerError = (error: Error) => {
const paths = PathsConfig.getInstance();
const socketPath = paths.dockerSocket;
- // Rest of implementation
+ // Apply similar logic as in catchHandlers.docker
+ if (error instanceof Error && 'code' in error && 'address' in error) {
+ const dockerError = error as unknown as DockerError;
+ if (dockerError.code === 'ENOENT' && dockerError.address === socketPath) {
+ throw new AppError('Docker socket unavailable.');
+ }
+ }
+ throw error;
};📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| import { promises as fs } from 'fs'; | ||
| import { parse } from 'ini'; | ||
|
|
||
| export const parseStateFile = async (path: string) => { | ||
| const content = await fs.readFile(path, 'utf8'); | ||
| return parse(content); | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Complete the implementation of createEmcmdClient
The function appears to be incomplete with just a comment indicating "Rest of implementation". Complete the function implementation or consider removing it if it's not needed yet.
🏁 Script executed:
Length of output: 214
Action Required: Implement or remove
createEmcmdClientcreateEmcmdClient, suggesting it might not be used elsewhere.