diff --git a/api/src/__test__/store/modules/__snapshots__/paths.test.ts.snap b/api/src/__test__/store/modules/__snapshots__/paths.test.ts.snap index e34dd1e54f..2bd80788c0 100644 --- a/api/src/__test__/store/modules/__snapshots__/paths.test.ts.snap +++ b/api/src/__test__/store/modules/__snapshots__/paths.test.ts.snap @@ -17,7 +17,6 @@ exports[`Returns paths 1`] = ` "myservers-base", "myservers-config", "myservers-config-states", - "myservers-env", "myservers-keepalive", "keyfile-base", "machine-id", diff --git a/api/src/__test__/store/modules/paths.test.ts b/api/src/__test__/store/modules/paths.test.ts index 78b7b788c5..0fae0dabcd 100644 --- a/api/src/__test__/store/modules/paths.test.ts +++ b/api/src/__test__/store/modules/paths.test.ts @@ -24,7 +24,6 @@ test('Returns paths', async () => { 'myservers-base': '/boot/config/plugins/dynamix.my.servers/', 'myservers-config': expect.stringContaining('api/dev/Unraid.net/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', 'keyfile-base': expect.stringContaining('api/dev/Unraid.net'), 'machine-id': expect.stringContaining('api/dev/data/machine-id'), diff --git a/api/src/environment.ts b/api/src/environment.ts index f418bd8a61..13bdc8495a 100644 --- a/api/src/environment.ts +++ b/api/src/environment.ts @@ -67,6 +67,7 @@ export const getPackageJsonDependencies = (): string[] | undefined => { 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 = (process.env.NODE_ENV as 'development' | 'test' | 'staging' | 'production') ?? 'production'; 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 DEBUG = process.env.DEBUG === '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 ? (process.env.ENVIRONMENT as 'production' | 'staging' | 'development') : 'production'; diff --git a/api/src/store/modules/paths.ts b/api/src/store/modules/paths.ts index 3a70d38e7e..e42e4d83a8 100644 --- a/api/src/store/modules/paths.ts +++ b/api/src/store/modules/paths.ts @@ -49,7 +49,6 @@ const initialState = { resolvePath(process.env.PATHS_STATES ?? ('/usr/local/emhttp/state/' as const)), 'myservers.cfg' as const ), - 'myservers-env': '/boot/config/plugins/dynamix.my.servers/env' as const, 'myservers-keepalive': process.env.PATHS_MY_SERVERS_FB ?? ('/boot/config/plugins/dynamix.my.servers/fb_keepalive' as const), diff --git a/api/src/unraid-api/cli/switch-env.command.ts b/api/src/unraid-api/cli/switch-env.command.ts index 7c4a7b0ea2..18c53b51c0 100644 --- a/api/src/unraid-api/cli/switch-env.command.ts +++ b/api/src/unraid-api/cli/switch-env.command.ts @@ -1,13 +1,13 @@ -import { copyFile, readFile, writeFile } from 'fs/promises'; +import { copyFile } from 'fs/promises'; import { join } from 'path'; 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 { LogService } from '@app/unraid-api/cli/log.service.js'; -import { StartCommand } from '@app/unraid-api/cli/start.command.js'; -import { StopCommand } from '@app/unraid-api/cli/stop.command.js'; +import { RestartCommand } from '@app/unraid-api/cli/restart.command.js'; interface SwitchEnvOptions { environment?: 'staging' | 'production'; @@ -31,60 +31,43 @@ export class SwitchEnvCommand extends CommandRunner { constructor( private readonly logger: LogService, - private readonly stopCommand: StopCommand, - private readonly startCommand: StartCommand + private readonly restartCommand: RestartCommand ) { 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 { const paths = getters.paths(); const basePath = paths['unraid-api-base']; - const envFlashFilePath = paths['myservers-env']; + const currentEnvPath = join(basePath, '.env'); - this.logger.warn('Stopping the Unraid API'); - try { - await this.stopCommand.run([], { delete: false }); - } catch (err) { - this.logger.warn('Failed to stop the Unraid API (maybe already stopped?)'); - } - - const newEnv = - options.environment ?? - this.switchToOtherEnv(await this.getEnvironmentFromFile(envFlashFilePath)); - this.logger.info(`Setting environment to ${newEnv}`); + // Determine target environment + const currentEnv = ENVIRONMENT; + const targetEnv = options.environment ?? 'production'; - // Write new env to flash - const newEnvLine = `env="${newEnv}"`; - this.logger.debug('Writing %s to %s', newEnvLine, envFlashFilePath); - await writeFile(envFlashFilePath, newEnvLine); + this.logger.info(`Switching environment from ${currentEnv} to ${targetEnv}`); - // Copy the new env over to live location before restarting - const source = join(basePath, `.env.${newEnv}`); - const destination = join(basePath, '.env'); + // 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); + } - cliLogger.debug('Copying %s to %s', source, destination); - await copyFile(source, destination); + // Copy the target environment file to .env + this.logger.debug(`Copying ${sourceEnvPath} to ${currentEnvPath}`); + try { + 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); + } - cliLogger.info('Now using %s', newEnv); - await this.startCommand.run([], {}); + // Restart the API to pick up the new environment + this.logger.info('Restarting Unraid API to apply environment changes...'); + await this.restartCommand.run(); } } diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/.login.php.last-download-time b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/.login.php.last-download-time index 83193e3506..57c42a2ef2 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/.login.php.last-download-time +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/.login.php.last-download-time @@ -1 +1 @@ -1751630630443 \ No newline at end of file +1752524464371 \ No newline at end of file diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/DefaultPageLayout.php.last-download-time b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/DefaultPageLayout.php.last-download-time index 125d1dfd84..c25e06d501 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/DefaultPageLayout.php.last-download-time +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/DefaultPageLayout.php.last-download-time @@ -1 +1 @@ -1751630630198 \ No newline at end of file +1752524464066 \ No newline at end of file diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/Notifications.page.last-download-time b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/Notifications.page.last-download-time index c7db09181c..478d8e7f73 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/Notifications.page.last-download-time +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/Notifications.page.last-download-time @@ -1 +1 @@ -1751630630343 \ No newline at end of file +1752524464213 \ No newline at end of file diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/auth-request.php.last-download-time b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/auth-request.php.last-download-time index c2f1dd9f49..e8c55463f0 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/auth-request.php.last-download-time +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/auth-request.php.last-download-time @@ -1 +1 @@ -1751630630571 \ No newline at end of file +1752524464631 \ No newline at end of file diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/rc.nginx.last-download-time b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/rc.nginx.last-download-time index 0e90294497..d3a765f5b3 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/rc.nginx.last-download-time +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/__fixtures__/downloaded/rc.nginx.last-download-time @@ -1 +1 @@ -1751630630810 \ No newline at end of file +1752524464761 \ No newline at end of file diff --git a/plugin/source/dynamix.unraid.net/etc/rc.d/rc.unraid-api b/plugin/source/dynamix.unraid.net/etc/rc.d/rc.unraid-api index 885d5dcbc8..d2685ba4fc 100755 --- a/plugin/source/dynamix.unraid.net/etc/rc.d/rc.unraid-api +++ b/plugin/source/dynamix.unraid.net/etc/rc.d/rc.unraid-api @@ -4,9 +4,6 @@ # shellcheck source=/dev/null 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" api_base_dir="/usr/local/unraid-api" scripts_dir="/usr/local/share/dynamix.unraid.net/scripts"