Erreur 502 etherpad_mypads suite à mise à jour

Mon serveur YunoHost

Matériel: Raspberry Pi à la maison
Version de YunoHost: 11.1.22
J’ai accès à mon serveur : En SSH | Par la webadmin
Êtes-vous dans un contexte particulier ou avez-vous effectué des modificiations particulières sur votre instance ? : oui
Installation d’une clic box

Si votre requête est liée à une application, précisez son nom et sa version: etherpad_mypads 1.9.1~ynh1

Description du problème

Bonjour,
après une mise à jour sur mon raspberry Pi 4 des applications, etherpad_mypads ne semble plus fonctionner, j’arrive sur une page avec une erreur 502

voici des logs d’erreurs, ça semble lié à npm

[2023-07-13 19:46:33.437] [ERROR] server - Error: Command exited with code 1: npm ls --long --json --depth=0 --no-production
    at exports (/var/www/etherpad_mypads/src/node/utils/run_cmd.js:119:25)
    at Object.exports.getPackages (/var/www/etherpad_mypads/src/static/js/pluginfw/plugins.js:115:48)
    at Object.exports.update (/var/www/etherpad_mypads/src/static/js/pluginfw/plugins.js:86:34)
    at Object.exports.start (/var/www/etherpad_mypads/src/node/server.js:143:19)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
[2023-07-13 19:46:33.437] [INFO] server - Exiting...
[2023-07-13 19:46:33.438] [INFO] server - Waiting for Node.js to exit...
[2023-07-13 19:46:38.438] [ERROR] server - Something that should have been cleaned up during the shutdown hook (such as a timer, worker thread, or open connection) is preventing Node.js from exiting
[2023-07-13 19:46:38.439] [ERROR] server - Enable `dumpOnUncleanExit` setting to get a dump of objects preventing a clean exit
[2023-07-13 19:46:38.441] [ERROR] server - Forcing an unclean exit...
[2023-07-13 19:46:39.066] [INFO] settings - All relative paths will be interpreted relative to the identified Etherpad base dir: /var/www/etherpad_mypads
[2023-07-13 19:46:39.113] [INFO] settings - settings loaded from: /var/www/etherpad_mypads/settings.json
[2023-07-13 19:46:39.116] [INFO] settings - credentials loaded from: /var/www/etherpad_mypads/credentials.json
[2023-07-13 19:46:39.118] [INFO] settings - Using skin "colibris" in dir: /var/www/etherpad_mypads/src/static/skins/colibris
[2023-07-13 19:46:39.119] [INFO] settings - Session key loaded from: /var/www/etherpad_mypads/SESSIONKEY.txt
[2023-07-13 19:46:39.120] [INFO] settings - Random string used for versioning assets: 671728e7
[2023-07-13 19:46:39.847] [INFO] server - Starting Etherpad...
[2023-07-13 19:46:40.130] [INFO] plugins - Running npm to get a list of installed plugins...
[2023-07-13 19:46:40.443] [INFO] plugins - npm --version: 6.14.16
[2023-07-13 19:46:53.885] [ERROR] runCmd|npm - npm ERR! peer dep missing: eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8, required by eslint-plugin-import@2.27.5
[2023-07-13 19:46:53.962] [ERROR] server - Error occurred while starting Etherpad
[2023-07-13 19:46:53.965] [ERROR] server - Metrics at time of fatal error:
{
  "httpStartTime": 0,
  "memoryUsage": 64282624,
  "memoryUsageHeap": 13937048,
  "ueberdb_lockAwaits": 0,
  "ueberdb_lockAcquires": 0,
  "ueberdb_lockReleases": 0,
  "ueberdb_reads": 0,
  "ueberdb_readsFailed": 0,
  "ueberdb_readsFinished": 0,
  "ueberdb_readsFromCache": 0,
  "ueberdb_readsFromDb": 0,
  "ueberdb_readsFromDbFailed": 0,
  "ueberdb_readsFromDbFinished": 0,
  "ueberdb_writes": 0,
  "ueberdb_writesFailed": 0,
  "ueberdb_writesFinished": 0,
  "ueberdb_writesObsoleted": 0,
  "ueberdb_writesToDb": 0,
  "ueberdb_writesToDbFailed": 0,
  "ueberdb_writesToDbFinished": 0,
  "ueberdb_writesToDbRetried": 0
}
[2023-07-13 19:46:53.965] [ERROR] server - Error: Command exited with code 1: npm ls --long --json --depth=0 --no-production
    at exports (/var/www/etherpad_mypads/src/node/utils/run_cmd.js:119:25)
    at Object.exports.getPackages (/var/www/etherpad_mypads/src/static/js/pluginfw/plugins.js:115:48)
    at Object.exports.update (/var/www/etherpad_mypads/src/static/js/pluginfw/plugins.js:86:34)
    at Object.exports.start (/var/www/etherpad_mypads/src/node/server.js:143:19)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
[2023-07-13 19:46:53.965] [INFO] server - Exiting...
[2023-07-13 19:46:53.966] [INFO] server - Waiting for Node.js to exit...
[2023-07-13 19:46:58.966] [ERROR] server - Something that should have been cleaned up during the shutdown hook (such as a timer, worker thread, or open connection) is preventing Node.js from exiting
[2023-07-13 19:46:58.967] [ERROR] server - Enable `dumpOnUncleanExit` setting to get a dump of objects preventing a clean exit
[2023-07-13 19:46:58.967] [ERROR] server - Forcing an unclean exit...
[2023-07-13 19:46:59.567] [INFO] settings - All relative paths will be interpreted relative to the identified Etherpad base dir: /var/www/etherpad_mypads
[2023-07-13 19:46:59.613] [INFO] settings - settings loaded from: /var/www/etherpad_mypads/settings.json
[2023-07-13 19:46:59.616] [INFO] settings - credentials loaded from: /var/www/etherpad_mypads/credentials.json
[2023-07-13 19:46:59.619] [INFO] settings - Using skin "colibris" in dir: /var/www/etherpad_mypads/src/static/skins/colibris
[2023-07-13 19:46:59.619] [INFO] settings - Session key loaded from: /var/www/etherpad_mypads/SESSIONKEY.txt
[2023-07-13 19:46:59.620] [INFO] settings - Random string used for versioning assets: cc345ed4
[2023-07-13 19:47:00.341] [INFO] server - Starting Etherpad...
[2023-07-13 19:47:00.622] [INFO] plugins - Running npm to get a list of installed plugins...
[2023-07-13 19:47:00.947] [INFO] plugins - npm --version: 6.14.16

I’m also seeing this error after an update.

Running yunohost 11.1.22 (stable) and etherpads 1.9.1~ynh1 on a digital ocean droplet

Some of the logs from /var/log/etherpad_mypads/etherpad.log

    at Object.exports.start (/var/www/etherpad_mypads/src/node/server.js:143:19)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
e[32m[2023-07-13 19:17:12.081] [INFO] server - e[39mExiting...
e[32m[2023-07-13 19:17:12.081] [INFO] server - e[39mWaiting for Node.js to exit...
e[31m[2023-07-13 19:17:17.081] [ERROR] server - e[39mSomething that should have been cleaned up during the shutdown hook (such as a timer, worker thread, or open connection) is preventing Node.js from exiting
e[31m[2023-07-13 19:17:17.081] [ERROR] server - e[39mEnable `dumpOnUncleanExit` setting to get a dump of objects preventing a clean exit
e[31m[2023-07-13 19:17:17.082] [ERROR] server - e[39mForcing an unclean exit...
e[32m[2023-07-13 19:17:17.387] [INFO] settings - e[39mAll relative paths will be interpreted relative to the identified Etherpad base dir: /var/www/etherpad_mypads
e[32m[2023-07-13 19:17:17.421] [INFO] settings - e[39msettings loaded from: /var/www/etherpad_mypads/settings.json
e[32m[2023-07-13 19:17:17.423] [INFO] settings - e[39mcredentials loaded from: /var/www/etherpad_mypads/credentials.json
e[32m[2023-07-13 19:17:17.424] [INFO] settings - e[39mUsing skin "colibris" in dir: /var/www/etherpad_mypads/src/static/skins/colibris
e[32m[2023-07-13 19:17:17.425] [INFO] settings - e[39mSession key loaded from: /var/www/etherpad_mypads/SESSIONKEY.txt
e[32m[2023-07-13 19:17:17.425] [INFO] settings - e[39mRandom string used for versioning assets: 41ab5a4f
e[32m[2023-07-13 19:17:17.787] [INFO] server - e[39mStarting Etherpad...
e[32m[2023-07-13 19:17:18.069] [INFO] plugins - e[39mRunning npm to get a list of installed plugins...
e[32m[2023-07-13 19:17:18.292] [INFO] plugins - e[39mnpm --version: 6.14.16
e[31m[2023-07-13 19:17:25.812] [ERROR] runCmd|npm - e[39mnpm ERR! peer dep missing: eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8, required by eslint-plugin-import@2.27.5
e[31m[2023-07-13 19:17:25.850] [ERROR] server - e[39mError occurred while starting Etherpad
e[31m[2023-07-13 19:17:25.852] [ERROR] server - e[39mMetrics at time of fatal error:
{
  "httpStartTime": 0,
  "memoryUsage": 67522560,
  "memoryUsageHeap": 14230896,
  "ueberdb_lockAwaits": 0,
  "ueberdb_lockAcquires": 0,
  "ueberdb_lockReleases": 0,
  "ueberdb_reads": 0,
  "ueberdb_readsFailed": 0,
  "ueberdb_readsFinished": 0,
  "ueberdb_readsFromCache": 0,
  "ueberdb_readsFromDb": 0,
  "ueberdb_readsFromDbFailed": 0,
  "ueberdb_readsFromDbFinished": 0,
  "ueberdb_writes": 0,
  "ueberdb_writesFailed": 0,
  "ueberdb_writesFinished": 0,
  "ueberdb_writesObsoleted": 0,
  "ueberdb_writesToDb": 0,
  "ueberdb_writesToDbFailed": 0,
  "ueberdb_writesToDbFinished": 0,
  "ueberdb_writesToDbRetried": 0
}
e[31m[2023-07-13 19:17:25.852] [ERROR] server - e[39mError: Command exited with code 1: npm ls --long --json --depth=0 --no-production
    at exports (/var/www/etherpad_mypads/src/node/utils/run_cmd.js:119:25)
    at Object.exports.getPackages (/var/www/etherpad_mypads/src/static/js/pluginfw/plugins.js:115:48)
    at Object.exports.update (/var/www/etherpad_mypads/src/static/js/pluginfw/plugins.js:86:34)
    at Object.exports.start (/var/www/etherpad_mypads/src/node/server.js:143:19)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
e[32m[2023-07-13 19:17:25.852] [INFO] server - e[39mExiting...
e[32m[2023-07-13 19:17:25.852] [INFO] server - e[39mWaiting for Node.js to exit...

For now I have remove the app and restore the old version.
Also I have another server on a dedicated vps where I had do the upgrade before without this issue…

I also was not able to find a solution and restored to the old pre-upgrade version.

Can you tell me if the server is also an arm processor ?

my server is a digital ocean droplet, amd64 running debian.

we have a problem with this file

cat -n /var/www/etherpad_mypads/src/static/js/pluginfw/plugins.js
     1	'use strict';
     2	
     3	const fs = require('fs').promises;
     4	const hooks = require('./hooks');
     5	const log4js = require('log4js');
     6	const path = require('path');
     7	const runCmd = require('../../../node/utils/run_cmd');
     8	const tsort = require('./tsort');
     9	const pluginUtils = require('./shared');
    10	const defs = require('./plugin_defs');
    11	
    12	const logger = log4js.getLogger('plugins');
    13	
    14	// Log the version of npm at startup.
    15	(async () => {
    16	  try {
    17	    const version = await runCmd(['npm', '--version'], {stdio: [null, 'string']});
    18	    logger.info(`npm --version: ${version}`);
    19	  } catch (err) {
    20	    logger.error(`Failed to get npm version: ${err.stack || err}`);
    21	    // This isn't a fatal error so don't re-throw.
    22	  }
    23	})();
    24	
    25	exports.prefix = 'ep_';
    26	
    27	exports.formatPlugins = () => Object.keys(defs.plugins).join(', ');
    28	
    29	exports.formatParts = () => defs.parts.map((part) => part.full_name).join('\n');
    30	
    31	exports.formatHooks = (hookSetName, html) => {
    32	  let hooks = new Map();
    33	  for (const [pluginName, def] of Object.entries(defs.plugins)) {
    34	    for (const part of def.parts) {
    35	      for (const [hookName, hookFnName] of Object.entries(part[hookSetName] || {})) {
    36	        let hookEntry = hooks.get(hookName);
    37	        if (!hookEntry) {
    38	          hookEntry = new Map();
    39	          hooks.set(hookName, hookEntry);
    40	        }
    41	        let pluginEntry = hookEntry.get(pluginName);
    42	        if (!pluginEntry) {
    43	          pluginEntry = new Map();
    44	          hookEntry.set(pluginName, pluginEntry);
    45	        }
    46	        pluginEntry.set(part.name, hookFnName);
    47	      }
    48	    }
    49	  }
    50	  const lines = [];
    51	  const sortStringKeys = (a, b) => String(a[0]).localeCompare(b[0]);
    52	  if (html) lines.push('<dl>');
    53	  hooks = new Map([...hooks].sort(sortStringKeys));
    54	  for (const [hookName, hookEntry] of hooks) {
    55	    lines.push(html ? `  <dt>${hookName}:</dt><dd><dl>` : `  ${hookName}:`);
    56	    const sortedHookEntry = new Map([...hookEntry].sort(sortStringKeys));
    57	    hooks.set(hookName, sortedHookEntry);
    58	    for (const [pluginName, pluginEntry] of sortedHookEntry) {
    59	      lines.push(html ? `    <dt>${pluginName}:</dt><dd><dl>` : `    ${pluginName}:`);
    60	      const sortedPluginEntry = new Map([...pluginEntry].sort(sortStringKeys));
    61	      sortedHookEntry.set(pluginName, sortedPluginEntry);
    62	      for (const [partName, hookFnName] of sortedPluginEntry) {
    63	        lines.push(html
    64	          ? `      <dt>${partName}:</dt><dd>${hookFnName}</dd>`
    65	          : `      ${partName}: ${hookFnName}`);
    66	      }
    67	      if (html) lines.push('    </dl></dd>');
    68	    }
    69	    if (html) lines.push('  </dl></dd>');
    70	  }
    71	  if (html) lines.push('</dl>');
    72	  return lines.join('\n');
    73	};
    74	
    75	exports.pathNormalization = (part, hookFnName, hookName) => {
    76	  const tmp = hookFnName.split(':'); // hookFnName might be something like 'C:\\foo.js:myFunc'.
    77	  // If there is a single colon assume it's 'filename:funcname' not 'C:\\filename'.
    78	  const functionName = (tmp.length > 1 ? tmp.pop() : null) || hookName;
    79	  const moduleName = tmp.join(':') || part.plugin;
    80	  const packageDir = path.dirname(defs.plugins[part.plugin].package.path);
    81	  const fileName = path.join(packageDir, moduleName);
    82	  return `${fileName}:${functionName}`;
    83	};
    84	
    85	exports.update = async () => {
    86	  const packages = await exports.getPackages();
    87	  const parts = {}; // Key is full name. sortParts converts this into a topologically sorted array.
    88	  const plugins = {};
    89	
    90	  // Load plugin metadata ep.json
    91	  await Promise.all(Object.keys(packages).map(async (pluginName) => {
    92	    logger.info(`Loading plugin ${pluginName}...`);
    93	    await loadPlugin(packages, pluginName, plugins, parts);
    94	  }));
    95	  logger.info(`Loaded ${Object.keys(packages).length} plugins`);
    96	
    97	  defs.plugins = plugins;
    98	  defs.parts = sortParts(parts);
    99	  defs.hooks = pluginUtils.extractHooks(defs.parts, 'hooks', exports.pathNormalization);
   100	  defs.loaded = true;
   101	  await Promise.all(Object.keys(defs.plugins).map(async (p) => {
   102	    const logger = log4js.getLogger(`plugin:${p}`);
   103	    await hooks.aCallAll(`init_${p}`, {logger});
   104	  }));
   105	};
   106	
   107	exports.getPackages = async () => {
   108	  logger.info('Running npm to get a list of installed plugins...');
   109	  // Notes:
   110	  //   * Do not pass `--prod` otherwise `npm ls` will fail if there is no `package.json`.
   111	  //   * The `--no-production` flag is required (or the `NODE_ENV` environment variable must be
   112	  //     unset or set to `development`) because otherwise `npm ls` will not mention any packages
   113	  //     that are not included in `package.json` (which is expected to not exist).
   114	  const cmd = ['npm', 'ls', '--long', '--json', '--depth=0', '--no-production'];
   115	  const {dependencies = {}} = JSON.parse(await runCmd(cmd, {stdio: [null, 'string']}));
   116	  await Promise.all(Object.entries(dependencies).map(async ([pkg, info]) => {
   117	    if (!pkg.startsWith(exports.prefix)) {
   118	      delete dependencies[pkg];
   119	      return;
   120	    }
   121	    info.realPath = await fs.realpath(info.path);
   122	  }));
   123	  return dependencies;
   124	};
   125	
   126	const loadPlugin = async (packages, pluginName, plugins, parts) => {
   127	  const pluginPath = path.resolve(packages[pluginName].path, 'ep.json');
   128	  try {
   129	    const data = await fs.readFile(pluginPath);
   130	    try {
   131	      const plugin = JSON.parse(data);
   132	      plugin.package = packages[pluginName];
   133	      plugins[pluginName] = plugin;
   134	      for (const part of plugin.parts) {
   135	        part.plugin = pluginName;
   136	        part.full_name = `${pluginName}/${part.name}`;
   137	        parts[part.full_name] = part;
   138	      }
   139	    } catch (err) {
   140	      logger.error(`Unable to parse plugin definition file ${pluginPath}: ${err.stack || err}`);
   141	    }
   142	  } catch (err) {
   143	    logger.error(`Unable to load plugin definition file ${pluginPath}: ${err.stack || err}`);
   144	  }
   145	};
   146	
   147	const partsToParentChildList = (parts) => {
   148	  const res = [];
   149	  for (const name of Object.keys(parts)) {
   150	    for (const childName of parts[name].post || []) {
   151	      res.push([name, childName]);
   152	    }
   153	    for (const parentName of parts[name].pre || []) {
   154	      res.push([parentName, name]);
   155	    }
   156	    if (!parts[name].pre && !parts[name].post) {
   157	      res.push([name, `:${name}`]); // Include apps with no dependency info
   158	    }
   159	  }
   160	  return res;
   161	};
   162	
   163	// Used only in Node, so no need for _
   164	const sortParts = (parts) => tsort(partsToParentChildList(parts))
   165	    .filter((name) => parts[name] !== undefined)
   166	    .map((name) => parts[name]);

Perhaps one of the plugins is no more supported ??

It seems breaking here

107	exports.getPackages = async () => {
   108	  logger.info('Running npm to get a list of installed plugins...');
   109	  // Notes:
   110	  //   * Do not pass `--prod` otherwise `npm ls` will fail if there is no `package.json`.
   111	  //   * The `--no-production` flag is required (or the `NODE_ENV` environment variable must be
   112	  //     unset or set to `development`) because otherwise `npm ls` will not mention any packages
   113	  //     that are not included in `package.json` (which is expected to not exist).
   114	  const cmd = ['npm', 'ls', '--long', '--json', '--depth=0', '--no-production'];
   115	  const {dependencies = {}} = JSON.parse(await runCmd(cmd, {stdio: [null, 'string']}));
   116	  await Promise.all(Object.entries(dependencies).map(async ([pkg, info]) => {
   117	    if (!pkg.startsWith(exports.prefix)) {
   118	      delete dependencies[pkg];
   119	      return;
   120	    }
   121	    info.realPath = await fs.realpath(info.path);
   122	  }));
   123	  return dependencies;
   124	};

Always a brake here, also on another server with last yunohost 1.2…

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.