From ff9c48f14e4d5e794bb471af21b39397ea41eba8 Mon Sep 17 00:00:00 2001 From: Willem Leuverink Date: Sun, 17 Nov 2024 16:04:25 +0100 Subject: [PATCH] Fix / Forward native ENV variables to child process (#129) * remove commented env merge * fix typo * forward native env variables to child process * Build plugin * Update resources/js/electron-plugin/src/server/api/childProcess.ts Co-authored-by: Simon Hamp * Build plugin * add php endpoint with native env variables * extract defaultPhpIniSettings function * mix in php ini settings * boyscouting - cleanup startQueueWorker * Build plugin * Code style * merge defaults with user configured ini settings * Build plugin * tidy * Build plugin --------- Co-authored-by: Simon Hamp --- .../dist/server/api/childProcess.js | 18 ++++++++-- .../js/electron-plugin/dist/server/php.js | 28 ++++++--------- .../src/server/api/childProcess.ts | 36 +++++++++++++++++-- .../js/electron-plugin/src/server/php.ts | 29 +++++++-------- 4 files changed, 73 insertions(+), 38 deletions(-) diff --git a/resources/js/electron-plugin/dist/server/api/childProcess.js b/resources/js/electron-plugin/dist/server/api/childProcess.js index 9f2228c5..a922e785 100644 --- a/resources/js/electron-plugin/dist/server/api/childProcess.js +++ b/resources/js/electron-plugin/dist/server/api/childProcess.js @@ -12,6 +12,7 @@ import { utilityProcess } from 'electron'; import state from '../state'; import { notifyLaravel } from "../utils"; import { join } from 'path'; +import { getDefaultEnvironmentVariables, getDefaultPhpIniSettings } from "../php"; const router = express.Router(); const killSync = require('kill-sync'); function startProcess(settings) { @@ -21,8 +22,8 @@ function startProcess(settings) { } const proc = utilityProcess.fork(join(__dirname, '../../electron-plugin/dist/server/childProcess.js'), cmd, { cwd, - serviceName: alias, stdio: 'pipe', + serviceName: alias, env: Object.assign(Object.assign({}, process.env), env) }); proc.stdout.on('data', (data) => { @@ -68,7 +69,7 @@ function startProcess(settings) { const settings = Object.assign({}, getSettings(alias)); delete state.processes[alias]; if (settings.persistent) { - console.log('Process [' + alias + '] wathchdog restarting...'); + console.log('Process [' + alias + '] watchdog restarting...'); startProcess(settings); } }); @@ -78,6 +79,15 @@ function startProcess(settings) { settings }; } +function startPhpProcess(settings) { + const defaultEnv = getDefaultEnvironmentVariables(state.randomSecret, state.electronApiPort); + const iniSettings = Object.assign(Object.assign({}, getDefaultPhpIniSettings()), state.phpIni); + const iniArgs = Object.keys(iniSettings).map(key => { + return ['-d', `${key}=${iniSettings[key]}`]; + }).flat(); + settings = Object.assign(Object.assign({}, settings), { cmd: [state.php, ...iniArgs, ...settings.cmd], env: Object.assign(Object.assign({}, settings.env), defaultEnv) }); + return startProcess(settings); +} function stopProcess(alias) { const proc = getProcess(alias); if (proc === undefined) { @@ -105,6 +115,10 @@ router.post('/start', (req, res) => { const proc = startProcess(req.body); res.json(proc); }); +router.post('/start-php', (req, res) => { + const proc = startPhpProcess(req.body); + res.json(proc); +}); router.post('/stop', (req, res) => { const { alias } = req.body; stopProcess(alias); diff --git a/resources/js/electron-plugin/dist/server/php.js b/resources/js/electron-plugin/dist/server/php.js index 9bb14972..d11d2298 100644 --- a/resources/js/electron-plugin/dist/server/php.js +++ b/resources/js/electron-plugin/dist/server/php.js @@ -58,12 +58,7 @@ function retrieveNativePHPConfig() { }); } function callPhp(args, options, phpIniSettings = {}) { - let defaultIniSettings = { - 'memory_limit': '512M', - 'curl.cainfo': state.caCert, - 'openssl.cafile': state.caCert - }; - let iniSettings = Object.assign(defaultIniSettings, phpIniSettings); + let iniSettings = Object.assign(getDefaultPhpIniSettings(), phpIniSettings); Object.keys(iniSettings).forEach(key => { args.unshift('-d', `${key}=${iniSettings[key]}`); }); @@ -101,15 +96,7 @@ function ensureAppFoldersAreAvailable() { } } function startQueueWorker(secret, apiPort, phpIniSettings = {}) { - const env = { - APP_ENV: process.env.NODE_ENV === 'development' ? 'local' : 'production', - APP_DEBUG: process.env.NODE_ENV === 'development' ? 'true' : 'false', - NATIVEPHP_STORAGE_PATH: storagePath, - NATIVEPHP_DATABASE_PATH: databaseFile, - NATIVEPHP_API_URL: `http://localhost:${apiPort}/api/`, - NATIVEPHP_RUNNING: true, - NATIVEPHP_SECRET: secret - }; + const env = getDefaultEnvironmentVariables(secret, apiPort); const phpOptions = { cwd: appPath, env @@ -139,7 +126,7 @@ function getDefaultEnvironmentVariables(secret, apiPort) { NATIVEPHP_STORAGE_PATH: storagePath, NATIVEPHP_DATABASE_PATH: databaseFile, NATIVEPHP_API_URL: `http://localhost:${apiPort}/api/`, - NATIVEPHP_RUNNING: true, + NATIVEPHP_RUNNING: 'true', NATIVEPHP_SECRET: secret, NATIVEPHP_USER_HOME_PATH: getPath('home'), NATIVEPHP_APP_DATA_PATH: getPath('appData'), @@ -153,6 +140,13 @@ function getDefaultEnvironmentVariables(secret, apiPort) { NATIVEPHP_RECENT_PATH: getPath('recent'), }; } +function getDefaultPhpIniSettings() { + return { + 'memory_limit': '512M', + 'curl.cainfo': state.caCert, + 'openssl.cafile': state.caCert + }; +} function serveApp(secret, apiPort, phpIniSettings) { return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { const appPath = getAppPath(); @@ -220,4 +214,4 @@ function serveApp(secret, apiPort, phpIniSettings) { }); })); } -export { startQueueWorker, startScheduler, serveApp, getAppPath, retrieveNativePHPConfig, retrievePhpIniSettings }; +export { startQueueWorker, startScheduler, serveApp, getAppPath, retrieveNativePHPConfig, retrievePhpIniSettings, getDefaultEnvironmentVariables, getDefaultPhpIniSettings }; diff --git a/resources/js/electron-plugin/src/server/api/childProcess.ts b/resources/js/electron-plugin/src/server/api/childProcess.ts index 0edf064a..c2f869a2 100644 --- a/resources/js/electron-plugin/src/server/api/childProcess.ts +++ b/resources/js/electron-plugin/src/server/api/childProcess.ts @@ -3,6 +3,8 @@ import { utilityProcess } from 'electron'; import state from '../state'; import { notifyLaravel } from "../utils"; import { join } from 'path'; +import { getDefaultEnvironmentVariables, getDefaultPhpIniSettings } from "../php"; + const router = express.Router(); const killSync = require('kill-sync'); @@ -19,8 +21,8 @@ function startProcess(settings) { cmd, { cwd, - serviceName: alias, stdio: 'pipe', + serviceName: alias, env: { ...process.env, ...env, @@ -81,7 +83,7 @@ function startProcess(settings) { delete state.processes[alias]; if (settings.persistent) { - console.log('Process [' + alias + '] wathchdog restarting...'); + console.log('Process [' + alias + '] watchdog restarting...'); startProcess(settings); } }); @@ -93,6 +95,30 @@ function startProcess(settings) { }; } +function startPhpProcess(settings) { + const defaultEnv = getDefaultEnvironmentVariables( + state.randomSecret, + state.electronApiPort + ); + + // Construct command args from ini settings + const iniSettings = { ...getDefaultPhpIniSettings(), ...state.phpIni }; + const iniArgs = Object.keys(iniSettings).map(key => { + return ['-d', `${key}=${iniSettings[key]}`]; + }).flat(); + + + settings = { + ...settings, + // Prepend cmd with php executable path & ini settings + cmd: [ state.php, ...iniArgs, ...settings.cmd ], + // Mix in the internal NativePHP env + env: { ...settings.env, ...defaultEnv } + }; + + return startProcess(settings); +} + function stopProcess(alias) { const proc = getProcess(alias); @@ -129,6 +155,12 @@ router.post('/start', (req, res) => { res.json(proc); }); +router.post('/start-php', (req, res) => { + const proc = startPhpProcess(req.body); + + res.json(proc); +}); + router.post('/stop', (req, res) => { const {alias} = req.body; diff --git a/resources/js/electron-plugin/src/server/php.ts b/resources/js/electron-plugin/src/server/php.ts index c7f7c90f..da8ba909 100644 --- a/resources/js/electron-plugin/src/server/php.ts +++ b/resources/js/electron-plugin/src/server/php.ts @@ -53,13 +53,8 @@ async function retrieveNativePHPConfig() { } function callPhp(args, options, phpIniSettings = {}) { - let defaultIniSettings = { - 'memory_limit': '512M', - 'curl.cainfo': state.caCert, - 'openssl.cafile': state.caCert - } - let iniSettings = Object.assign(defaultIniSettings, phpIniSettings); + let iniSettings = Object.assign(getDefaultPhpIniSettings(), phpIniSettings); Object.keys(iniSettings).forEach(key => { args.unshift('-d', `${key}=${iniSettings[key]}`); @@ -120,15 +115,7 @@ function ensureAppFoldersAreAvailable() { } function startQueueWorker(secret, apiPort, phpIniSettings = {}) { - const env = { - APP_ENV: process.env.NODE_ENV === 'development' ? 'local' : 'production', - APP_DEBUG: process.env.NODE_ENV === 'development' ? 'true' : 'false', - NATIVEPHP_STORAGE_PATH: storagePath, - NATIVEPHP_DATABASE_PATH: databaseFile, - NATIVEPHP_API_URL: `http://localhost:${apiPort}/api/`, - NATIVEPHP_RUNNING: true, - NATIVEPHP_SECRET: secret - }; + const env = getDefaultEnvironmentVariables(secret, apiPort); const phpOptions = { cwd: appPath, @@ -165,7 +152,7 @@ function getDefaultEnvironmentVariables(secret, apiPort) { NATIVEPHP_STORAGE_PATH: storagePath, NATIVEPHP_DATABASE_PATH: databaseFile, NATIVEPHP_API_URL: `http://localhost:${apiPort}/api/`, - NATIVEPHP_RUNNING: true, + NATIVEPHP_RUNNING: 'true', NATIVEPHP_SECRET: secret, NATIVEPHP_USER_HOME_PATH: getPath('home'), NATIVEPHP_APP_DATA_PATH: getPath('appData'), @@ -180,6 +167,14 @@ function getDefaultEnvironmentVariables(secret, apiPort) { }; } +function getDefaultPhpIniSettings() { + return { + 'memory_limit': '512M', + 'curl.cainfo': state.caCert, + 'openssl.cafile': state.caCert + } +} + function serveApp(secret, apiPort, phpIniSettings): Promise { return new Promise(async (resolve, reject) => { const appPath = getAppPath(); @@ -267,4 +262,4 @@ function serveApp(secret, apiPort, phpIniSettings): Promise { }) } -export {startQueueWorker, startScheduler, serveApp, getAppPath, retrieveNativePHPConfig, retrievePhpIniSettings} +export {startQueueWorker, startScheduler, serveApp, getAppPath, retrieveNativePHPConfig, retrievePhpIniSettings, getDefaultEnvironmentVariables, getDefaultPhpIniSettings}