diff --git a/Dockerfile b/Dockerfile index 35e4665b2..c2393c3f1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -108,8 +108,8 @@ FROM build as development COPY --chown=etherpad:etherpad ./src/package.json .npmrc ./src/pnpm-lock.yaml ./src/ COPY --chown=etherpad:etherpad --from=adminBuild /opt/etherpad-lite/admin/dist ./src/templates/admin -RUN bin/installDeps.sh && { [ -z "${ETHERPAD_PLUGINS}" ] || \ - pnpm install --workspace-root ${ETHERPAD_PLUGINS}; } +RUN src/bin/installDeps.sh %% \ + { [ -z "${ETHERPAD_PLUGINS}" ] || pnpm run install-plugins --prefix ./src ${ETHERPAD_PLUGINS}; } FROM build as production @@ -119,9 +119,9 @@ ENV ETHERPAD_PRODUCTION=true COPY --chown=etherpad:etherpad ./src ./src COPY --chown=etherpad:etherpad --from=adminBuild /opt/etherpad-lite/admin/dist ./src/templates/admin -RUN bin/installDeps.sh && { [ -z "${ETHERPAD_PLUGINS}" ] || \ - pnpm install --workspace-root ${ETHERPAD_PLUGINS}; } && \ - rm -rf ~/.npm +RUN src/bin/installDeps.sh && rm -rf ~/.npm && \ + { [ -z "${ETHERPAD_PLUGINS}" ] || pnpm run install-plugins ./src ${ETHERPAD_PLUGINS}; } + # Copy the configuration file. COPY --chown=etherpad:etherpad ${SETTINGS} "${EP_DIR}"/settings.json diff --git a/src/bin/installPlugins.js b/src/bin/installPlugins.js new file mode 100644 index 000000000..6c3e6393b --- /dev/null +++ b/src/bin/installPlugins.js @@ -0,0 +1,37 @@ +#!/usr/bin/env node + +'use strict'; + +const {promises: fs} = require('fs'); +const pluginsModule = require('../static/js/pluginfw/plugins'); +const installer = require('../static/js/pluginfw/installer'); + +if (process.argv.length === 2) { + console.error('Expected at least one argument!'); + process.exit(1); +} + +const plugins = process.argv.slice(2) + +const persistInstalledPlugins = async () => { + const installedPlugins = {plugins: []}; + for (const pkg of Object.values(await pluginsModule.getPackages())) { + installedPlugins.plugins.push({ + name: pkg.name, + version: pkg.version, + }); + } + installedPlugins.plugins = [...new Set(installedPlugins.plugins)]; + await fs.writeFile(installer.installedPluginsPath, JSON.stringify(installedPlugins)); +}; + +async function run() { + for (const plugin of plugins) { + await installer.manager.install(plugin); + } +} + +(async () => { + await run(); + await persistInstalledPlugins(); +})() \ No newline at end of file diff --git a/src/package.json b/src/package.json index 9e955d21a..9f9bba12e 100644 --- a/src/package.json +++ b/src/package.json @@ -117,6 +117,7 @@ "test-container": "mocha --import=tsx --timeout 5000 tests/container/specs/api", "dev": "node --import tsx node/server.ts", "prod": "node --import tsx node/server.ts", + "install-plugins": "node --import tsx bin/installPlugins.js", "ts-check": "tsc --noEmit", "ts-check:watch": "tsc --noEmit --watch", "test-ui": "npx playwright test tests/frontend-new/specs", diff --git a/src/static/js/pluginfw/installer.js b/src/static/js/pluginfw/installer.js index ed7b328e3..22da6b233 100644 --- a/src/static/js/pluginfw/installer.js +++ b/src/static/js/pluginfw/installer.js @@ -14,7 +14,7 @@ const logger = log4js.getLogger('plugins'); exports.manager = new PluginManager(); -const installedPluginsPath = path.join(settings.root, 'var/installed_plugins.json'); +exports.installedPluginsPath = path.join(settings.root, 'var/installed_plugins.json'); const onAllTasksFinished = async () => { await plugins.update(); @@ -67,12 +67,12 @@ exports.checkForMigration = async () => { logger.info('check installed plugins for migration'); try { - await fs.access(installedPluginsPath, fs.constants.F_OK); + await fs.access(exports.installedPluginsPath, fs.constants.F_OK); } catch (err) { await migratePluginsFromNodeModules(); } - const fileContent = await fs.readFile(installedPluginsPath); + const fileContent = await fs.readFile(exports.installedPluginsPath); const installedPlugins = JSON.parse(fileContent.toString()); for (const plugin of installedPlugins.plugins) { @@ -91,7 +91,7 @@ const persistInstalledPlugins = async () => { }); } installedPlugins.plugins = [...new Set(installedPlugins.plugins)]; - await fs.writeFile(installedPluginsPath, JSON.stringify(installedPlugins)); + await fs.writeFile(exports.installedPluginsPath, JSON.stringify(installedPlugins)); }; exports.uninstall = async (pluginName, cb = null) => {