mirror of
https://github.com/unraid/api.git
synced 2025-12-30 04:59:51 -06:00
fix(connect): disable api plugin if unraid plugin is absent (#1773)
Mitigates an edge case where the connect api plugin does not uninstall itself when Unraid version < 7.2.0, resulting in retention of undesired connect functionality on stock unraid after upgrading to 7.2.0+. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * App now detects Connect plugin availability at startup and falls back gracefully with a no-op mode and a logged warning if the plugin is absent. * Added an environment option to skip the plugin availability check when needed. * Export behavior adjusted so the application uses the appropriate module based on plugin presence. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -32,3 +32,4 @@ CHOKIDAR_USEPOLLING=true
|
||||
LOG_TRANSPORT=console
|
||||
LOG_LEVEL=trace
|
||||
ENABLE_NEXT_DOCKER_RELEASE=true
|
||||
SKIP_CONNECT_PLUGIN_CHECK=true
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Inject, Logger, Module } from '@nestjs/common';
|
||||
import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { existsSync } from 'node:fs';
|
||||
|
||||
import { execa } from 'execa';
|
||||
|
||||
import { ConnectConfigPersister } from './config/config.persistence.js';
|
||||
import { configFeature } from './config/connect.config.js';
|
||||
@@ -8,6 +11,10 @@ import { ConnectModule } from './unraid-connect/connect.module.js';
|
||||
|
||||
export const adapter = 'nestjs';
|
||||
|
||||
/**
|
||||
* When the plugin is installed we expose the full Nest module graph.
|
||||
* Configuration and proxy submodules only bootstrap in this branch.
|
||||
*/
|
||||
@Module({
|
||||
imports: [ConfigModule.forFeature(configFeature), ConnectModule, MothershipModule],
|
||||
providers: [ConnectConfigPersister],
|
||||
@@ -23,4 +30,64 @@ class ConnectPluginModule {
|
||||
}
|
||||
}
|
||||
|
||||
export const ApiModule = ConnectPluginModule;
|
||||
/**
|
||||
* Fallback module keeps the export shape intact but only warns operators.
|
||||
* This makes `ApiModule` safe to import even when the plugin is absent.
|
||||
*/
|
||||
@Module({})
|
||||
export class DisabledConnectPluginModule {
|
||||
logger = new Logger(DisabledConnectPluginModule.name);
|
||||
async onModuleInit() {
|
||||
const removalCommand = 'unraid-api plugins remove -b unraid-api-plugin-connect';
|
||||
|
||||
this.logger.warn(
|
||||
'Connect plugin is not installed, but is listed as an API plugin. Attempting `%s` automatically.',
|
||||
removalCommand
|
||||
);
|
||||
|
||||
try {
|
||||
const { stdout, stderr } = await execa('unraid-api', [
|
||||
'plugins',
|
||||
'remove',
|
||||
'-b',
|
||||
'unraid-api-plugin-connect',
|
||||
]);
|
||||
|
||||
if (stdout?.trim()) {
|
||||
this.logger.debug(stdout.trim());
|
||||
}
|
||||
|
||||
if (stderr?.trim()) {
|
||||
this.logger.debug(stderr.trim());
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
'Successfully completed `%s` to prune the stale connect plugin entry.',
|
||||
removalCommand
|
||||
);
|
||||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error
|
||||
? error.message
|
||||
: 'Unknown error while removing stale connect plugin entry.';
|
||||
this.logger.error('Failed to run `%s`: %s', removalCommand, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Local filesystem and env checks stay synchronous so we can branch at module load.
|
||||
*/
|
||||
const isConnectPluginInstalled = () => {
|
||||
if (process.env.SKIP_CONNECT_PLUGIN_CHECK === 'true') {
|
||||
return true;
|
||||
}
|
||||
return existsSync('/boot/config/plugins/dynamix.unraid.net.plg');
|
||||
};
|
||||
|
||||
/**
|
||||
* Downstream code always imports `ApiModule`. We swap the implementation based on availability,
|
||||
* avoiding dynamic module plumbing while keeping the DI graph predictable.
|
||||
* Set `SKIP_CONNECT_PLUGIN_CHECK=true` in development to force the connected path.
|
||||
*/
|
||||
export const ApiModule = isConnectPluginInstalled() ? ConnectPluginModule : DisabledConnectPluginModule;
|
||||
|
||||
Reference in New Issue
Block a user