Fix plugin upgrade
Correctly decache all plugin paths
This commit is contained in:
parent
8406a9e8ee
commit
ca87d95bcb
6 changed files with 85 additions and 19 deletions
|
@ -155,6 +155,7 @@ search:
|
||||||
federation:
|
federation:
|
||||||
videos:
|
videos:
|
||||||
federate_unlisted: true
|
federate_unlisted: true
|
||||||
|
cleanup_remote_interactions: false
|
||||||
|
|
||||||
views:
|
views:
|
||||||
videos:
|
videos:
|
||||||
|
|
|
@ -90,7 +90,6 @@
|
||||||
"cookie-parser": "^1.4.3",
|
"cookie-parser": "^1.4.3",
|
||||||
"cors": "^2.8.1",
|
"cors": "^2.8.1",
|
||||||
"create-torrent": "^5.0.0",
|
"create-torrent": "^5.0.0",
|
||||||
"decache": "^4.6.0",
|
|
||||||
"deep-object-diff": "^1.1.0",
|
"deep-object-diff": "^1.1.0",
|
||||||
"email-templates": "^8.0.3",
|
"email-templates": "^8.0.3",
|
||||||
"execa": "^5.1.1",
|
"execa": "^5.1.1",
|
||||||
|
|
78
server/helpers/decache.ts
Normal file
78
server/helpers/decache.ts
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
// Thanks: https://github.com/dwyl/decache
|
||||||
|
// We reuse this file to also uncache plugin base path
|
||||||
|
|
||||||
|
import { extname } from 'path'
|
||||||
|
|
||||||
|
function decachePlugin (pluginPath: string, libraryPath: string) {
|
||||||
|
const moduleName = find(libraryPath)
|
||||||
|
|
||||||
|
if (!moduleName) return
|
||||||
|
|
||||||
|
searchCache(moduleName, function (mod) {
|
||||||
|
delete require.cache[mod.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
removeCachedPath(pluginPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
function decacheModule (name: string) {
|
||||||
|
const moduleName = find(name)
|
||||||
|
|
||||||
|
if (!moduleName) return
|
||||||
|
|
||||||
|
searchCache(moduleName, function (mod) {
|
||||||
|
delete require.cache[mod.id]
|
||||||
|
})
|
||||||
|
|
||||||
|
removeCachedPath(moduleName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
export {
|
||||||
|
decacheModule,
|
||||||
|
decachePlugin
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
function find (moduleName: string) {
|
||||||
|
try {
|
||||||
|
return require.resolve(moduleName)
|
||||||
|
} catch {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function searchCache (moduleName: string, callback: (current: NodeModule) => void) {
|
||||||
|
const resolvedModule = require.resolve(moduleName)
|
||||||
|
let mod: NodeModule
|
||||||
|
const visited = {}
|
||||||
|
|
||||||
|
if (resolvedModule && ((mod = require.cache[resolvedModule]) !== undefined)) {
|
||||||
|
// Recursively go over the results
|
||||||
|
(function run (current) {
|
||||||
|
visited[current.id] = true
|
||||||
|
|
||||||
|
current.children.forEach(function (child) {
|
||||||
|
if (extname(child.filename) !== '.node' && !visited[child.id]) {
|
||||||
|
run(child)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// Call the specified callback providing the
|
||||||
|
// found module
|
||||||
|
callback(current)
|
||||||
|
})(mod)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function removeCachedPath (pluginPath: string) {
|
||||||
|
const pathCache = (module.constructor as any)._pathCache
|
||||||
|
|
||||||
|
Object.keys(pathCache).forEach(function (cacheKey) {
|
||||||
|
if (cacheKey.includes(pluginPath)) {
|
||||||
|
delete pathCache[cacheKey]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import bytes from 'bytes'
|
import bytes from 'bytes'
|
||||||
import { IConfig } from 'config'
|
import { IConfig } from 'config'
|
||||||
import decache from 'decache'
|
|
||||||
import { dirname, join } from 'path'
|
import { dirname, join } from 'path'
|
||||||
|
import { decacheModule } from '@server/helpers/decache'
|
||||||
import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type'
|
import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type'
|
||||||
import { BroadcastMessageLevel } from '@shared/models/server'
|
import { BroadcastMessageLevel } from '@shared/models/server'
|
||||||
import { VideosRedundancyStrategy } from '../../shared/models'
|
import { VideosRedundancyStrategy } from '../../shared/models'
|
||||||
|
@ -497,7 +497,7 @@ export function reloadConfig () {
|
||||||
delete require.cache[fileName]
|
delete require.cache[fileName]
|
||||||
}
|
}
|
||||||
|
|
||||||
decache('config')
|
decacheModule('config')
|
||||||
}
|
}
|
||||||
|
|
||||||
purge()
|
purge()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import decache from 'decache'
|
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import { createReadStream, createWriteStream } from 'fs'
|
import { createReadStream, createWriteStream } from 'fs'
|
||||||
import { ensureDir, outputFile, readJSON } from 'fs-extra'
|
import { ensureDir, outputFile, readJSON } from 'fs-extra'
|
||||||
import { basename, join } from 'path'
|
import { basename, join } from 'path'
|
||||||
|
import { decachePlugin } from '@server/helpers/decache'
|
||||||
import { MOAuthTokenUser, MUser } from '@server/types/models'
|
import { MOAuthTokenUser, MUser } from '@server/types/models'
|
||||||
import { getCompleteLocale } from '@shared/core-utils'
|
import { getCompleteLocale } from '@shared/core-utils'
|
||||||
import { ClientScript, PluginPackageJson, PluginTranslation, PluginTranslationPaths, RegisterServerHookOptions } from '@shared/models'
|
import { ClientScript, PluginPackageJson, PluginTranslation, PluginTranslationPaths, RegisterServerHookOptions } from '@shared/models'
|
||||||
|
@ -312,12 +312,12 @@ export class PluginManager implements ServerHook {
|
||||||
logger.error('Cannot install plugin %s, removing it...', toInstall, { err: rootErr })
|
logger.error('Cannot install plugin %s, removing it...', toInstall, { err: rootErr })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.uninstall(npmName)
|
// await this.uninstall(npmName)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Cannot uninstall plugin %s after failed installation.', toInstall, { err })
|
logger.error('Cannot uninstall plugin %s after failed installation.', toInstall, { err })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await removeNpmPlugin(npmName)
|
// await removeNpmPlugin(npmName)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Cannot remove plugin %s after failed installation.', toInstall, { err })
|
logger.error('Cannot remove plugin %s after failed installation.', toInstall, { err })
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ export class PluginManager implements ServerHook {
|
||||||
|
|
||||||
// Delete cache if needed
|
// Delete cache if needed
|
||||||
const modulePath = join(pluginPath, packageJSON.library)
|
const modulePath = join(pluginPath, packageJSON.library)
|
||||||
decache(modulePath)
|
decachePlugin(pluginPath, modulePath)
|
||||||
const library: PluginLibrary = require(modulePath)
|
const library: PluginLibrary = require(modulePath)
|
||||||
|
|
||||||
if (!isLibraryCodeValid(library)) {
|
if (!isLibraryCodeValid(library)) {
|
||||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -2613,11 +2613,6 @@ call-me-maybe@^1.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
|
resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
|
||||||
integrity sha1-JtII6onje1y95gJQoV8DHBak1ms=
|
integrity sha1-JtII6onje1y95gJQoV8DHBak1ms=
|
||||||
|
|
||||||
callsite@^1.0.0:
|
|
||||||
version "1.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
|
|
||||||
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
|
|
||||||
|
|
||||||
callsites@^3.0.0:
|
callsites@^3.0.0:
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||||
|
@ -3229,13 +3224,6 @@ debuglog@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||||
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
|
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
|
||||||
|
|
||||||
decache@^4.6.0:
|
|
||||||
version "4.6.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/decache/-/decache-4.6.0.tgz#87026bc6e696759e82d57a3841c4e251a30356e8"
|
|
||||||
integrity sha512-PppOuLiz+DFeaUvFXEYZjLxAkKiMYH/do/b/MxpDe/8AgKBi5GhZxridoVIbBq72GDbL36e4p0Ce2jTGUwwU+w==
|
|
||||||
dependencies:
|
|
||||||
callsite "^1.0.0"
|
|
||||||
|
|
||||||
decamelize@^1.2.0:
|
decamelize@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||||
|
|
Loading…
Reference in a new issue