mirror of
https://github.com/unraid/api.git
synced 2026-01-01 06:01:18 -06:00
fix: rm short-circuit in rc.unraid-api if plugin config dir is absent (#1515)
This short-circuit causes any/all `rc.unraid-api` invocations to immediately fail on fresh 7.2 images (because `/boot/config/dynamix.my.servers` doesn't exist). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Refactor** * Removed initial checks and setup for a plugin directory and default environment file in the startup script. * Simplified environment switching with streamlined commands and improved error handling. * Removed deprecated environment path references and updated related tests. * **Documentation** * Added descriptive comments clarifying build and environment settings. * **Tests** * Updated test cases by removing assertions related to deprecated environment paths. * **Maintenance** * Updated timestamp fixtures for consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -17,7 +17,6 @@ exports[`Returns paths 1`] = `
|
|||||||
"myservers-base",
|
"myservers-base",
|
||||||
"myservers-config",
|
"myservers-config",
|
||||||
"myservers-config-states",
|
"myservers-config-states",
|
||||||
"myservers-env",
|
|
||||||
"myservers-keepalive",
|
"myservers-keepalive",
|
||||||
"keyfile-base",
|
"keyfile-base",
|
||||||
"machine-id",
|
"machine-id",
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ test('Returns paths', async () => {
|
|||||||
'myservers-base': '/boot/config/plugins/dynamix.my.servers/',
|
'myservers-base': '/boot/config/plugins/dynamix.my.servers/',
|
||||||
'myservers-config': expect.stringContaining('api/dev/Unraid.net/myservers.cfg'),
|
'myservers-config': expect.stringContaining('api/dev/Unraid.net/myservers.cfg'),
|
||||||
'myservers-config-states': expect.stringContaining('api/dev/states/myservers.cfg'),
|
'myservers-config-states': expect.stringContaining('api/dev/states/myservers.cfg'),
|
||||||
'myservers-env': '/boot/config/plugins/dynamix.my.servers/env',
|
|
||||||
'myservers-keepalive': './dev/Unraid.net/fb_keepalive',
|
'myservers-keepalive': './dev/Unraid.net/fb_keepalive',
|
||||||
'keyfile-base': expect.stringContaining('api/dev/Unraid.net'),
|
'keyfile-base': expect.stringContaining('api/dev/Unraid.net'),
|
||||||
'machine-id': expect.stringContaining('api/dev/data/machine-id'),
|
'machine-id': expect.stringContaining('api/dev/data/machine-id'),
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export const getPackageJsonDependencies = (): string[] | undefined => {
|
|||||||
|
|
||||||
export const API_VERSION = process.env.npm_package_version ?? getPackageJson().version;
|
export const API_VERSION = process.env.npm_package_version ?? getPackageJson().version;
|
||||||
|
|
||||||
|
/** Controls how the app is built/run (i.e. in terms of optimization) */
|
||||||
export const NODE_ENV =
|
export const NODE_ENV =
|
||||||
(process.env.NODE_ENV as 'development' | 'test' | 'staging' | 'production') ?? 'production';
|
(process.env.NODE_ENV as 'development' | 'test' | 'staging' | 'production') ?? 'production';
|
||||||
export const environment = {
|
export const environment = {
|
||||||
@@ -76,6 +77,7 @@ export const CHOKIDAR_USEPOLLING = process.env.CHOKIDAR_USEPOLLING === 'true';
|
|||||||
export const IS_DOCKER = process.env.IS_DOCKER === 'true';
|
export const IS_DOCKER = process.env.IS_DOCKER === 'true';
|
||||||
export const DEBUG = process.env.DEBUG === 'true';
|
export const DEBUG = process.env.DEBUG === 'true';
|
||||||
export const INTROSPECTION = process.env.INTROSPECTION === 'true';
|
export const INTROSPECTION = process.env.INTROSPECTION === 'true';
|
||||||
|
/** Determines the app-level & business logic environment (i.e. what data & infrastructure is used) */
|
||||||
export const ENVIRONMENT = process.env.ENVIRONMENT
|
export const ENVIRONMENT = process.env.ENVIRONMENT
|
||||||
? (process.env.ENVIRONMENT as 'production' | 'staging' | 'development')
|
? (process.env.ENVIRONMENT as 'production' | 'staging' | 'development')
|
||||||
: 'production';
|
: 'production';
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ const initialState = {
|
|||||||
resolvePath(process.env.PATHS_STATES ?? ('/usr/local/emhttp/state/' as const)),
|
resolvePath(process.env.PATHS_STATES ?? ('/usr/local/emhttp/state/' as const)),
|
||||||
'myservers.cfg' as const
|
'myservers.cfg' as const
|
||||||
),
|
),
|
||||||
'myservers-env': '/boot/config/plugins/dynamix.my.servers/env' as const,
|
|
||||||
'myservers-keepalive':
|
'myservers-keepalive':
|
||||||
process.env.PATHS_MY_SERVERS_FB ??
|
process.env.PATHS_MY_SERVERS_FB ??
|
||||||
('/boot/config/plugins/dynamix.my.servers/fb_keepalive' as const),
|
('/boot/config/plugins/dynamix.my.servers/fb_keepalive' as const),
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { copyFile, readFile, writeFile } from 'fs/promises';
|
import { copyFile } from 'fs/promises';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
|
||||||
import { Command, CommandRunner, Option } from 'nest-commander';
|
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||||
|
|
||||||
import { cliLogger } from '@app/core/log.js';
|
import { fileExistsSync } from '@app/core/utils/files/file-exists.js';
|
||||||
|
import { ENVIRONMENT } from '@app/environment.js';
|
||||||
import { getters } from '@app/store/index.js';
|
import { getters } from '@app/store/index.js';
|
||||||
import { LogService } from '@app/unraid-api/cli/log.service.js';
|
import { LogService } from '@app/unraid-api/cli/log.service.js';
|
||||||
import { StartCommand } from '@app/unraid-api/cli/start.command.js';
|
import { RestartCommand } from '@app/unraid-api/cli/restart.command.js';
|
||||||
import { StopCommand } from '@app/unraid-api/cli/stop.command.js';
|
|
||||||
|
|
||||||
interface SwitchEnvOptions {
|
interface SwitchEnvOptions {
|
||||||
environment?: 'staging' | 'production';
|
environment?: 'staging' | 'production';
|
||||||
@@ -31,60 +31,43 @@ export class SwitchEnvCommand extends CommandRunner {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly logger: LogService,
|
private readonly logger: LogService,
|
||||||
private readonly stopCommand: StopCommand,
|
private readonly restartCommand: RestartCommand
|
||||||
private readonly startCommand: StartCommand
|
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getEnvironmentFromFile(path: string): Promise<'production' | 'staging'> {
|
|
||||||
const envFile = await readFile(path, 'utf-8').catch(() => '');
|
|
||||||
this.logger.debug(`Checking ${path} for current ENV, found ${envFile}`);
|
|
||||||
|
|
||||||
// Match the env file env="production" which would be [0] = env="production", [1] = env and [2] = production
|
|
||||||
const matchArray = /([a-zA-Z]+)=["]*([a-zA-Z]+)["]*/.exec(envFile);
|
|
||||||
// Get item from index 2 of the regex match or return production
|
|
||||||
const [, , currentEnvInFile] = matchArray && matchArray.length === 3 ? matchArray : [];
|
|
||||||
return this.parseStringToEnv(currentEnvInFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
private switchToOtherEnv(environment: 'production' | 'staging'): 'production' | 'staging' {
|
|
||||||
if (environment === 'production') {
|
|
||||||
return 'staging';
|
|
||||||
}
|
|
||||||
return 'production';
|
|
||||||
}
|
|
||||||
|
|
||||||
async run(_, options: SwitchEnvOptions): Promise<void> {
|
async run(_, options: SwitchEnvOptions): Promise<void> {
|
||||||
const paths = getters.paths();
|
const paths = getters.paths();
|
||||||
const basePath = paths['unraid-api-base'];
|
const basePath = paths['unraid-api-base'];
|
||||||
const envFlashFilePath = paths['myservers-env'];
|
const currentEnvPath = join(basePath, '.env');
|
||||||
|
|
||||||
this.logger.warn('Stopping the Unraid API');
|
// Determine target environment
|
||||||
try {
|
const currentEnv = ENVIRONMENT;
|
||||||
await this.stopCommand.run([], { delete: false });
|
const targetEnv = options.environment ?? 'production';
|
||||||
} catch (err) {
|
|
||||||
this.logger.warn('Failed to stop the Unraid API (maybe already stopped?)');
|
this.logger.info(`Switching environment from ${currentEnv} to ${targetEnv}`);
|
||||||
|
|
||||||
|
// Check if target environment file exists
|
||||||
|
const sourceEnvPath = join(basePath, `.env.${targetEnv}`);
|
||||||
|
if (!fileExistsSync(sourceEnvPath)) {
|
||||||
|
this.logger.error(
|
||||||
|
`Environment file ${sourceEnvPath} does not exist. Cannot switch to ${targetEnv} environment.`
|
||||||
|
);
|
||||||
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newEnv =
|
// Copy the target environment file to .env
|
||||||
options.environment ??
|
this.logger.debug(`Copying ${sourceEnvPath} to ${currentEnvPath}`);
|
||||||
this.switchToOtherEnv(await this.getEnvironmentFromFile(envFlashFilePath));
|
try {
|
||||||
this.logger.info(`Setting environment to ${newEnv}`);
|
await copyFile(sourceEnvPath, currentEnvPath);
|
||||||
|
this.logger.info(`Successfully switched to ${targetEnv} environment`);
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`Failed to copy environment file: ${error}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Write new env to flash
|
// Restart the API to pick up the new environment
|
||||||
const newEnvLine = `env="${newEnv}"`;
|
this.logger.info('Restarting Unraid API to apply environment changes...');
|
||||||
this.logger.debug('Writing %s to %s', newEnvLine, envFlashFilePath);
|
await this.restartCommand.run();
|
||||||
await writeFile(envFlashFilePath, newEnvLine);
|
|
||||||
|
|
||||||
// Copy the new env over to live location before restarting
|
|
||||||
const source = join(basePath, `.env.${newEnv}`);
|
|
||||||
const destination = join(basePath, '.env');
|
|
||||||
|
|
||||||
cliLogger.debug('Copying %s to %s', source, destination);
|
|
||||||
await copyFile(source, destination);
|
|
||||||
|
|
||||||
cliLogger.info('Now using %s', newEnv);
|
|
||||||
await this.startCommand.run([], {});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1751630630443
|
1752524464371
|
||||||
@@ -1 +1 @@
|
|||||||
1751630630198
|
1752524464066
|
||||||
@@ -1 +1 @@
|
|||||||
1751630630343
|
1752524464213
|
||||||
@@ -1 +1 @@
|
|||||||
1751630630571
|
1752524464631
|
||||||
@@ -1 +1 @@
|
|||||||
1751630630810
|
1752524464761
|
||||||
@@ -4,9 +4,6 @@
|
|||||||
# shellcheck source=/dev/null
|
# shellcheck source=/dev/null
|
||||||
source /etc/profile
|
source /etc/profile
|
||||||
|
|
||||||
flash="/boot/config/plugins/dynamix.my.servers"
|
|
||||||
[[ ! -d "${flash}" ]] && echo "Please reinstall the Unraid Connect plugin" && exit 1
|
|
||||||
[[ ! -f "${flash}/env" ]] && echo 'env=production' >"${flash}/env"
|
|
||||||
unraid_binary_path="/usr/local/bin/unraid-api"
|
unraid_binary_path="/usr/local/bin/unraid-api"
|
||||||
api_base_dir="/usr/local/unraid-api"
|
api_base_dir="/usr/local/unraid-api"
|
||||||
scripts_dir="/usr/local/share/dynamix.unraid.net/scripts"
|
scripts_dir="/usr/local/share/dynamix.unraid.net/scripts"
|
||||||
|
|||||||
Reference in New Issue
Block a user