aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-12-03 09:52:03 +0100
committerChocobozzz <me@florianbigard.com>2021-12-03 10:14:17 +0100
commitca87d95bcbfec9241e5840267862bace8b0197fa (patch)
tree8cc01322ac3140e0ab191770cae0e03b84ab2bb9 /server
parent8406a9e8eec261e563d99c92f8a18b6bd3e46e0f (diff)
downloadPeerTube-ca87d95bcbfec9241e5840267862bace8b0197fa.tar.gz
PeerTube-ca87d95bcbfec9241e5840267862bace8b0197fa.tar.zst
PeerTube-ca87d95bcbfec9241e5840267862bace8b0197fa.zip
Fix plugin upgrade
Correctly decache all plugin paths
Diffstat (limited to 'server')
-rw-r--r--server/helpers/decache.ts78
-rw-r--r--server/initializers/config.ts4
-rw-r--r--server/lib/plugins/plugin-manager.ts8
3 files changed, 84 insertions, 6 deletions
diff --git a/server/helpers/decache.ts b/server/helpers/decache.ts
new file mode 100644
index 000000000..e31973b7a
--- /dev/null
+++ b/server/helpers/decache.ts
@@ -0,0 +1,78 @@
1// Thanks: https://github.com/dwyl/decache
2// We reuse this file to also uncache plugin base path
3
4import { extname } from 'path'
5
6function decachePlugin (pluginPath: string, libraryPath: string) {
7 const moduleName = find(libraryPath)
8
9 if (!moduleName) return
10
11 searchCache(moduleName, function (mod) {
12 delete require.cache[mod.id]
13 })
14
15 removeCachedPath(pluginPath)
16}
17
18function decacheModule (name: string) {
19 const moduleName = find(name)
20
21 if (!moduleName) return
22
23 searchCache(moduleName, function (mod) {
24 delete require.cache[mod.id]
25 })
26
27 removeCachedPath(moduleName)
28}
29
30// ---------------------------------------------------------------------------
31
32export {
33 decacheModule,
34 decachePlugin
35}
36
37// ---------------------------------------------------------------------------
38
39function find (moduleName: string) {
40 try {
41 return require.resolve(moduleName)
42 } catch {
43 return ''
44 }
45}
46
47function searchCache (moduleName: string, callback: (current: NodeModule) => void) {
48 const resolvedModule = require.resolve(moduleName)
49 let mod: NodeModule
50 const visited = {}
51
52 if (resolvedModule && ((mod = require.cache[resolvedModule]) !== undefined)) {
53 // Recursively go over the results
54 (function run (current) {
55 visited[current.id] = true
56
57 current.children.forEach(function (child) {
58 if (extname(child.filename) !== '.node' && !visited[child.id]) {
59 run(child)
60 }
61 })
62
63 // Call the specified callback providing the
64 // found module
65 callback(current)
66 })(mod)
67 }
68};
69
70function removeCachedPath (pluginPath: string) {
71 const pathCache = (module.constructor as any)._pathCache
72
73 Object.keys(pathCache).forEach(function (cacheKey) {
74 if (cacheKey.includes(pluginPath)) {
75 delete pathCache[cacheKey]
76 }
77 })
78}
diff --git a/server/initializers/config.ts b/server/initializers/config.ts
index dadda2a77..f3a7c6b6b 100644
--- a/server/initializers/config.ts
+++ b/server/initializers/config.ts
@@ -1,7 +1,7 @@
1import bytes from 'bytes' 1import bytes from 'bytes'
2import { IConfig } from 'config' 2import { IConfig } from 'config'
3import decache from 'decache'
4import { dirname, join } from 'path' 3import { dirname, join } from 'path'
4import { decacheModule } from '@server/helpers/decache'
5import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type' 5import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type'
6import { BroadcastMessageLevel } from '@shared/models/server' 6import { BroadcastMessageLevel } from '@shared/models/server'
7import { VideosRedundancyStrategy } from '../../shared/models' 7import { VideosRedundancyStrategy } from '../../shared/models'
@@ -497,7 +497,7 @@ export function reloadConfig () {
497 delete require.cache[fileName] 497 delete require.cache[fileName]
498 } 498 }
499 499
500 decache('config') 500 decacheModule('config')
501 } 501 }
502 502
503 purge() 503 purge()
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts
index d4d2a7edc..8add72a85 100644
--- a/server/lib/plugins/plugin-manager.ts
+++ b/server/lib/plugins/plugin-manager.ts
@@ -1,8 +1,8 @@
1import decache from 'decache'
2import express from 'express' 1import express from 'express'
3import { createReadStream, createWriteStream } from 'fs' 2import { createReadStream, createWriteStream } from 'fs'
4import { ensureDir, outputFile, readJSON } from 'fs-extra' 3import { ensureDir, outputFile, readJSON } from 'fs-extra'
5import { basename, join } from 'path' 4import { basename, join } from 'path'
5import { decachePlugin } from '@server/helpers/decache'
6import { MOAuthTokenUser, MUser } from '@server/types/models' 6import { MOAuthTokenUser, MUser } from '@server/types/models'
7import { getCompleteLocale } from '@shared/core-utils' 7import { getCompleteLocale } from '@shared/core-utils'
8import { ClientScript, PluginPackageJson, PluginTranslation, PluginTranslationPaths, RegisterServerHookOptions } from '@shared/models' 8import { ClientScript, PluginPackageJson, PluginTranslation, PluginTranslationPaths, RegisterServerHookOptions } from '@shared/models'
@@ -312,12 +312,12 @@ export class PluginManager implements ServerHook {
312 logger.error('Cannot install plugin %s, removing it...', toInstall, { err: rootErr }) 312 logger.error('Cannot install plugin %s, removing it...', toInstall, { err: rootErr })
313 313
314 try { 314 try {
315 await this.uninstall(npmName) 315 // await this.uninstall(npmName)
316 } catch (err) { 316 } catch (err) {
317 logger.error('Cannot uninstall plugin %s after failed installation.', toInstall, { err }) 317 logger.error('Cannot uninstall plugin %s after failed installation.', toInstall, { err })
318 318
319 try { 319 try {
320 await removeNpmPlugin(npmName) 320 // await removeNpmPlugin(npmName)
321 } catch (err) { 321 } catch (err) {
322 logger.error('Cannot remove plugin %s after failed installation.', toInstall, { err }) 322 logger.error('Cannot remove plugin %s after failed installation.', toInstall, { err })
323 } 323 }
@@ -420,7 +420,7 @@ export class PluginManager implements ServerHook {
420 420
421 // Delete cache if needed 421 // Delete cache if needed
422 const modulePath = join(pluginPath, packageJSON.library) 422 const modulePath = join(pluginPath, packageJSON.library)
423 decache(modulePath) 423 decachePlugin(pluginPath, modulePath)
424 const library: PluginLibrary = require(modulePath) 424 const library: PluginLibrary = require(modulePath)
425 425
426 if (!isLibraryCodeValid(library)) { 426 if (!isLibraryCodeValid(library)) {