aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server.ts2
-rw-r--r--server/controllers/api/plugins.ts6
-rw-r--r--server/helpers/requests.ts15
-rw-r--r--server/initializers/constants.ts1
-rw-r--r--server/lib/plugins/plugin-index.ts15
-rw-r--r--server/lib/schedulers/plugins-check-scheduler.ts30
6 files changed, 51 insertions, 18 deletions
diff --git a/server.ts b/server.ts
index f6fae3718..67abf4b5c 100644
--- a/server.ts
+++ b/server.ts
@@ -113,6 +113,7 @@ import { RemoveOldHistoryScheduler } from './server/lib/schedulers/remove-old-hi
113import { isHTTPSignatureDigestValid } from './server/helpers/peertube-crypto' 113import { isHTTPSignatureDigestValid } from './server/helpers/peertube-crypto'
114import { PeerTubeSocket } from './server/lib/peertube-socket' 114import { PeerTubeSocket } from './server/lib/peertube-socket'
115import { updateStreamingPlaylistsInfohashesIfNeeded } from './server/lib/hls' 115import { updateStreamingPlaylistsInfohashesIfNeeded } from './server/lib/hls'
116import { PluginsCheckScheduler } from './server/lib/schedulers/plugins-check-scheduler'
116 117
117// ----------- Command line ----------- 118// ----------- Command line -----------
118 119
@@ -250,6 +251,7 @@ async function startApplication () {
250 VideosRedundancyScheduler.Instance.enable() 251 VideosRedundancyScheduler.Instance.enable()
251 RemoveOldHistoryScheduler.Instance.enable() 252 RemoveOldHistoryScheduler.Instance.enable()
252 RemoveOldViewsScheduler.Instance.enable() 253 RemoveOldViewsScheduler.Instance.enable()
254 PluginsCheckScheduler.Instance.enable()
253 255
254 // Redis initialization 256 // Redis initialization
255 Redis.Instance.init() 257 Redis.Instance.init()
diff --git a/server/controllers/api/plugins.ts b/server/controllers/api/plugins.ts
index 114cc49b6..bb410e891 100644
--- a/server/controllers/api/plugins.ts
+++ b/server/controllers/api/plugins.ts
@@ -180,5 +180,11 @@ async function listAvailablePlugins (req: express.Request, res: express.Response
180 180
181 const resultList = await listAvailablePluginsFromIndex(query) 181 const resultList = await listAvailablePluginsFromIndex(query)
182 182
183 if (!resultList) {
184 return res.status(503)
185 .json({ error: 'Plugin index unavailable. Please retry later' })
186 .end()
187 }
188
183 return res.json(resultList) 189 return res.json(resultList)
184} 190}
diff --git a/server/helpers/requests.ts b/server/helpers/requests.ts
index 2e30c94a1..80476d649 100644
--- a/server/helpers/requests.ts
+++ b/server/helpers/requests.ts
@@ -1,18 +1,22 @@
1import * as Bluebird from 'bluebird' 1import * as Bluebird from 'bluebird'
2import { createWriteStream, remove } from 'fs-extra' 2import { createWriteStream, remove } from 'fs-extra'
3import * as request from 'request' 3import * as request from 'request'
4import { ACTIVITY_PUB } from '../initializers/constants' 4import { ACTIVITY_PUB, WEBSERVER } from '../initializers/constants'
5import { processImage } from './image-utils' 5import { processImage } from './image-utils'
6import { join } from 'path' 6import { join } from 'path'
7import { logger } from './logger' 7import { logger } from './logger'
8import { CONFIG } from '../initializers/config' 8import { CONFIG } from '../initializers/config'
9 9
10const packageJSON = require('../../../package.json')
11
10function doRequest <T> ( 12function doRequest <T> (
11 requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean }, 13 requestOptions: request.CoreOptions & request.UriOptions & { activityPub?: boolean },
12 bodyKBLimit = 1000 // 1MB 14 bodyKBLimit = 1000 // 1MB
13): Bluebird<{ response: request.RequestResponse, body: T }> { 15): Bluebird<{ response: request.RequestResponse, body: T }> {
16 if (!(requestOptions.headers)) requestOptions.headers = {}
17 requestOptions.headers['User-Agent'] = getUserAgent()
18
14 if (requestOptions.activityPub === true) { 19 if (requestOptions.activityPub === true) {
15 if (!Array.isArray(requestOptions.headers)) requestOptions.headers = {}
16 requestOptions.headers['accept'] = ACTIVITY_PUB.ACCEPT_HEADER 20 requestOptions.headers['accept'] = ACTIVITY_PUB.ACCEPT_HEADER
17 } 21 }
18 22
@@ -27,6 +31,9 @@ function doRequestAndSaveToFile (
27 destPath: string, 31 destPath: string,
28 bodyKBLimit = 10000 // 10MB 32 bodyKBLimit = 10000 // 10MB
29) { 33) {
34 if (!requestOptions.headers) requestOptions.headers = {}
35 requestOptions.headers['User-Agent'] = getUserAgent()
36
30 return new Bluebird<void>((res, rej) => { 37 return new Bluebird<void>((res, rej) => {
31 const file = createWriteStream(destPath) 38 const file = createWriteStream(destPath)
32 file.on('finish', () => res()) 39 file.on('finish', () => res())
@@ -60,6 +67,10 @@ async function downloadImage (url: string, destDir: string, destName: string, si
60 } 67 }
61} 68}
62 69
70function getUserAgent () {
71 return `PeerTube/${packageJSON.version} (+${WEBSERVER.URL})`
72}
73
63// --------------------------------------------------------------------------- 74// ---------------------------------------------------------------------------
64 75
65export { 76export {
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 06e8c070b..367ae8d45 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -618,6 +618,7 @@ if (isTestInstance() === true) {
618 SCHEDULER_INTERVALS_MS.removeOldHistory = 5000 618 SCHEDULER_INTERVALS_MS.removeOldHistory = 5000
619 SCHEDULER_INTERVALS_MS.removeOldViews = 5000 619 SCHEDULER_INTERVALS_MS.removeOldViews = 5000
620 SCHEDULER_INTERVALS_MS.updateVideos = 5000 620 SCHEDULER_INTERVALS_MS.updateVideos = 5000
621 SCHEDULER_INTERVALS_MS.checkPlugins = 10000
621 REPEAT_JOBS[ 'videos-views' ] = { every: 5000 } 622 REPEAT_JOBS[ 'videos-views' ] = { every: 5000 }
622 623
623 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1 624 REDUNDANCY.VIDEOS.RANDOMIZED_FACTOR = 1
diff --git a/server/lib/plugins/plugin-index.ts b/server/lib/plugins/plugin-index.ts
index 4a8a90ec8..63cd47e63 100644
--- a/server/lib/plugins/plugin-index.ts
+++ b/server/lib/plugins/plugin-index.ts
@@ -27,13 +27,18 @@ async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList)
27 27
28 const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins' 28 const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins'
29 29
30 const { body } = await doRequest({ uri, qs, json: true }) 30 try {
31 const { body } = await doRequest({ uri, qs, json: true })
31 32
32 logger.debug('Got result from PeerTube index.', { body }) 33 logger.debug('Got result from PeerTube index.', { body })
33 34
34 await addInstanceInformation(body) 35 await addInstanceInformation(body)
35 36
36 return body as ResultList<PeerTubePluginIndex> 37 return body as ResultList<PeerTubePluginIndex>
38 } catch (err) {
39 logger.error('Cannot list available plugins from index %s.', uri, { err })
40 return undefined
41 }
37} 42}
38 43
39async function addInstanceInformation (result: ResultList<PeerTubePluginIndex>) { 44async function addInstanceInformation (result: ResultList<PeerTubePluginIndex>) {
@@ -53,7 +58,7 @@ async function getLatestPluginsVersion (npmNames: string[]): Promise<PeertubePlu
53 58
54 const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins/latest-version' 59 const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins/latest-version'
55 60
56 const { body } = await doRequest({ uri, body: bodyRequest }) 61 const { body } = await doRequest({ uri, body: bodyRequest, json: true, method: 'POST' })
57 62
58 return body 63 return body
59} 64}
diff --git a/server/lib/schedulers/plugins-check-scheduler.ts b/server/lib/schedulers/plugins-check-scheduler.ts
index 9c60dbcd4..8dfdd5177 100644
--- a/server/lib/schedulers/plugins-check-scheduler.ts
+++ b/server/lib/schedulers/plugins-check-scheduler.ts
@@ -1,6 +1,5 @@
1import { logger } from '../../helpers/logger' 1import { logger } from '../../helpers/logger'
2import { AbstractScheduler } from './abstract-scheduler' 2import { AbstractScheduler } from './abstract-scheduler'
3import { retryTransactionWrapper } from '../../helpers/database-utils'
4import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants' 3import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants'
5import { CONFIG } from '../../initializers/config' 4import { CONFIG } from '../../initializers/config'
6import { PluginModel } from '../../models/server/plugin' 5import { PluginModel } from '../../models/server/plugin'
@@ -19,13 +18,13 @@ export class PluginsCheckScheduler extends AbstractScheduler {
19 } 18 }
20 19
21 protected async internalExecute () { 20 protected async internalExecute () {
22 return retryTransactionWrapper(this.checkLatestPluginsVersion.bind(this)) 21 return this.checkLatestPluginsVersion()
23 } 22 }
24 23
25 private async checkLatestPluginsVersion () { 24 private async checkLatestPluginsVersion () {
26 if (CONFIG.PLUGINS.INDEX.ENABLED === false) return 25 if (CONFIG.PLUGINS.INDEX.ENABLED === false) return
27 26
28 logger.info('Checkin latest plugins version.') 27 logger.info('Checking latest plugins version.')
29 28
30 const plugins = await PluginModel.listInstalled() 29 const plugins = await PluginModel.listInstalled()
31 30
@@ -39,19 +38,28 @@ export class PluginsCheckScheduler extends AbstractScheduler {
39 } 38 }
40 39
41 const npmNames = Object.keys(pluginIndex) 40 const npmNames = Object.keys(pluginIndex)
42 const results = await getLatestPluginsVersion(npmNames)
43 41
44 for (const result of results) { 42 try {
45 const plugin = pluginIndex[result.npmName] 43 const results = await getLatestPluginsVersion(npmNames)
46 if (!result.latestVersion) continue
47 44
48 if (plugin.latestVersion !== result.latestVersion && compareSemVer(plugin.latestVersion, result.latestVersion) < 0) { 45 for (const result of results) {
49 plugin.latestVersion = result.latestVersion 46 const plugin = pluginIndex[ result.npmName ]
50 await plugin.save() 47 if (!result.latestVersion) continue
48
49 if (
50 !plugin.latestVersion ||
51 (plugin.latestVersion !== result.latestVersion && compareSemVer(plugin.latestVersion, result.latestVersion) < 0)
52 ) {
53 plugin.latestVersion = result.latestVersion
54 await plugin.save()
55
56 logger.info('Plugin %s has a new latest version %s.', PluginModel.buildNpmName(plugin.name, plugin.type), plugin.latestVersion)
57 }
51 } 58 }
59 } catch (err) {
60 logger.error('Cannot get latest plugins version.', { npmNames, err })
52 } 61 }
53 } 62 }
54
55 } 63 }
56 64
57 static get Instance () { 65 static get Instance () {