aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2018-12-04 17:08:55 +0100
committerChocobozzz <me@florianbigard.com>2018-12-04 17:08:55 +0100
commitb9fffa297f49a84df8ffd0d7b842599bc88a8e3e (patch)
tree49a12ebebf4d533e8b273abbb9492350a233101d
parent6040f87d143a5fa01db79867ece8197c3ce7be47 (diff)
downloadPeerTube-b9fffa297f49a84df8ffd0d7b842599bc88a8e3e.tar.gz
PeerTube-b9fffa297f49a84df8ffd0d7b842599bc88a8e3e.tar.zst
PeerTube-b9fffa297f49a84df8ffd0d7b842599bc88a8e3e.zip
Create redundancy endpoint
-rw-r--r--server/controllers/static.ts6
-rw-r--r--server/initializers/constants.ts1
-rw-r--r--server/lib/schedulers/videos-redundancy-scheduler.ts4
-rw-r--r--server/models/redundancy/video-redundancy.ts4
-rw-r--r--server/models/video/video.ts10
-rw-r--r--server/tests/api/redundancy/redundancy.ts27
-rw-r--r--support/nginx/peertube9
7 files changed, 38 insertions, 23 deletions
diff --git a/server/controllers/static.ts b/server/controllers/static.ts
index f16a7d72b..55e7392a1 100644
--- a/server/controllers/static.ts
+++ b/server/controllers/static.ts
@@ -37,12 +37,12 @@ staticRouter.use(
37staticRouter.use( 37staticRouter.use(
38 STATIC_PATHS.WEBSEED, 38 STATIC_PATHS.WEBSEED,
39 cors(), 39 cors(),
40 express.static(CONFIG.STORAGE.VIDEOS_DIR) 40 express.static(CONFIG.STORAGE.VIDEOS_DIR, { fallthrough: false }) // 404 because we don't have this video
41) 41)
42staticRouter.use( 42staticRouter.use(
43 STATIC_PATHS.WEBSEED, 43 STATIC_PATHS.REDUNDANCY,
44 cors(), 44 cors(),
45 express.static(CONFIG.STORAGE.REDUNDANCY_DIR, { fallthrough: false }) // 404, because we don't have this video 45 express.static(CONFIG.STORAGE.REDUNDANCY_DIR, { fallthrough: false }) // 404 because we don't have this video
46) 46)
47 47
48staticRouter.use( 48staticRouter.use(
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts
index 876aa1cf5..7195ae6c5 100644
--- a/server/initializers/constants.ts
+++ b/server/initializers/constants.ts
@@ -571,6 +571,7 @@ const STATIC_PATHS = {
571 THUMBNAILS: '/static/thumbnails/', 571 THUMBNAILS: '/static/thumbnails/',
572 TORRENTS: '/static/torrents/', 572 TORRENTS: '/static/torrents/',
573 WEBSEED: '/static/webseed/', 573 WEBSEED: '/static/webseed/',
574 REDUNDANCY: '/static/redundancy/',
574 AVATARS: '/static/avatars/', 575 AVATARS: '/static/avatars/',
575 VIDEO_CAPTIONS: '/static/video-captions/' 576 VIDEO_CAPTIONS: '/static/video-captions/'
576} 577}
diff --git a/server/lib/schedulers/videos-redundancy-scheduler.ts b/server/lib/schedulers/videos-redundancy-scheduler.ts
index 8b7f33539..2a99a665d 100644
--- a/server/lib/schedulers/videos-redundancy-scheduler.ts
+++ b/server/lib/schedulers/videos-redundancy-scheduler.ts
@@ -145,13 +145,13 @@ export class VideosRedundancyScheduler extends AbstractScheduler {
145 145
146 const tmpPath = await downloadWebTorrentVideo({ magnetUri }, VIDEO_IMPORT_TIMEOUT) 146 const tmpPath = await downloadWebTorrentVideo({ magnetUri }, VIDEO_IMPORT_TIMEOUT)
147 147
148 const destPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename(file)) 148 const destPath = join(CONFIG.STORAGE.REDUNDANCY_DIR, video.getVideoFilename(file))
149 await rename(tmpPath, destPath) 149 await rename(tmpPath, destPath)
150 150
151 const createdModel = await VideoRedundancyModel.create({ 151 const createdModel = await VideoRedundancyModel.create({
152 expiresOn: this.buildNewExpiration(redundancy.minLifetime), 152 expiresOn: this.buildNewExpiration(redundancy.minLifetime),
153 url: getVideoCacheFileActivityPubUrl(file), 153 url: getVideoCacheFileActivityPubUrl(file),
154 fileUrl: video.getVideoFileUrl(file, CONFIG.WEBSERVER.URL), 154 fileUrl: video.getVideoRedundancyUrl(file, CONFIG.WEBSERVER.URL),
155 strategy: redundancy.strategy, 155 strategy: redundancy.strategy,
156 videoFileId: file.id, 156 videoFileId: file.id,
157 actorId: serverActor.id 157 actorId: serverActor.id
diff --git a/server/models/redundancy/video-redundancy.ts b/server/models/redundancy/video-redundancy.ts
index 9de4356b4..dd37dad22 100644
--- a/server/models/redundancy/video-redundancy.ts
+++ b/server/models/redundancy/video-redundancy.ts
@@ -15,7 +15,7 @@ import {
15import { ActorModel } from '../activitypub/actor' 15import { ActorModel } from '../activitypub/actor'
16import { getVideoSort, throwIfNotValid } from '../utils' 16import { getVideoSort, throwIfNotValid } from '../utils'
17import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc' 17import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc'
18import { CONFIG, CONSTRAINTS_FIELDS, VIDEO_EXT_MIMETYPE } from '../../initializers' 18import { CONFIG, CONSTRAINTS_FIELDS, STATIC_PATHS, VIDEO_EXT_MIMETYPE } from '../../initializers'
19import { VideoFileModel } from '../video/video-file' 19import { VideoFileModel } from '../video/video-file'
20import { getServerActor } from '../../helpers/utils' 20import { getServerActor } from '../../helpers/utils'
21import { VideoModel } from '../video/video' 21import { VideoModel } from '../video/video'
@@ -124,7 +124,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
124 const logIdentifier = `${videoFile.Video.uuid}-${videoFile.resolution}` 124 const logIdentifier = `${videoFile.Video.uuid}-${videoFile.resolution}`
125 logger.info('Removing duplicated video file %s.', logIdentifier) 125 logger.info('Removing duplicated video file %s.', logIdentifier)
126 126
127 videoFile.Video.removeFile(videoFile) 127 videoFile.Video.removeFile(videoFile, true)
128 .catch(err => logger.error('Cannot delete %s files.', logIdentifier, { err })) 128 .catch(err => logger.error('Cannot delete %s files.', logIdentifier, { err }))
129 129
130 return undefined 130 return undefined
diff --git a/server/models/video/video.ts b/server/models/video/video.ts
index 0f18d9f0c..e8cb5aa88 100644
--- a/server/models/video/video.ts
+++ b/server/models/video/video.ts
@@ -1538,8 +1538,10 @@ export class VideoModel extends Model<VideoModel> {
1538 .catch(err => logger.warn('Cannot delete preview %s.', previewPath, { err })) 1538 .catch(err => logger.warn('Cannot delete preview %s.', previewPath, { err }))
1539 } 1539 }
1540 1540
1541 removeFile (videoFile: VideoFileModel) { 1541 removeFile (videoFile: VideoFileModel, isRedundancy = false) {
1542 const filePath = join(CONFIG.STORAGE.VIDEOS_DIR, this.getVideoFilename(videoFile)) 1542 const baseDir = isRedundancy ? CONFIG.STORAGE.REDUNDANCY_DIR : CONFIG.STORAGE.VIDEOS_DIR
1543
1544 const filePath = join(baseDir, this.getVideoFilename(videoFile))
1543 return remove(filePath) 1545 return remove(filePath)
1544 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err })) 1546 .catch(err => logger.warn('Cannot delete file %s.', filePath, { err }))
1545 } 1547 }
@@ -1617,6 +1619,10 @@ export class VideoModel extends Model<VideoModel> {
1617 return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile) 1619 return baseUrlHttp + STATIC_PATHS.WEBSEED + this.getVideoFilename(videoFile)
1618 } 1620 }
1619 1621
1622 getVideoRedundancyUrl (videoFile: VideoFileModel, baseUrlHttp: string) {
1623 return baseUrlHttp + STATIC_PATHS.REDUNDANCY + this.getVideoFilename(videoFile)
1624 }
1625
1620 getVideoFileDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) { 1626 getVideoFileDownloadUrl (videoFile: VideoFileModel, baseUrlHttp: string) {
1621 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile) 1627 return baseUrlHttp + STATIC_DOWNLOAD_PATHS.VIDEOS + this.getVideoFilename(videoFile)
1622 } 1628 }
diff --git a/server/tests/api/redundancy/redundancy.ts b/server/tests/api/redundancy/redundancy.ts
index a8a2f305f..5b29a503a 100644
--- a/server/tests/api/redundancy/redundancy.ts
+++ b/server/tests/api/redundancy/redundancy.ts
@@ -136,7 +136,7 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
136 if (!videoUUID) videoUUID = video1Server2UUID 136 if (!videoUUID) videoUUID = video1Server2UUID
137 137
138 const webseeds = [ 138 const webseeds = [
139 'http://localhost:9001/static/webseed/' + videoUUID, 139 'http://localhost:9001/static/redundancy/' + videoUUID,
140 'http://localhost:9002/static/webseed/' + videoUUID 140 'http://localhost:9002/static/webseed/' + videoUUID
141 ] 141 ]
142 142
@@ -148,20 +148,23 @@ async function check2Webseeds (strategy: VideoRedundancyStrategy, videoUUID?: st
148 for (const file of video.files) { 148 for (const file of video.files) {
149 checkMagnetWebseeds(file, webseeds, server) 149 checkMagnetWebseeds(file, webseeds, server)
150 150
151 // Only servers 1 and 2 have the video 151 await makeGetRequest({
152 if (server.serverNumber !== 3) { 152 url: servers[0].url,
153 await makeGetRequest({ 153 statusCodeExpected: 200,
154 url: server.url, 154 path: '/static/redundancy/' + `${videoUUID}-${file.resolution.id}.mp4`,
155 statusCodeExpected: 200, 155 contentType: null
156 path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`, 156 })
157 contentType: null 157 await makeGetRequest({
158 }) 158 url: servers[1].url,
159 } 159 statusCodeExpected: 200,
160 path: '/static/webseed/' + `${videoUUID}-${file.resolution.id}.mp4`,
161 contentType: null
162 })
160 } 163 }
161 } 164 }
162 165
163 for (const directory of [ 'test1', 'test2' ]) { 166 for (const directory of [ 'test1/redundancy', 'test2/videos' ]) {
164 const files = await readdir(join(root(), directory, 'videos')) 167 const files = await readdir(join(root(), directory))
165 expect(files).to.have.length.at.least(4) 168 expect(files).to.have.length.at.least(4)
166 169
167 for (const resolution of [ 240, 360, 480, 720 ]) { 170 for (const resolution of [ 240, 360, 480, 720 ]) {
diff --git a/support/nginx/peertube b/support/nginx/peertube
index b00031133..e0b006088 100644
--- a/support/nginx/peertube
+++ b/support/nginx/peertube
@@ -105,7 +105,7 @@ server {
105 } 105 }
106 106
107 # Bypass PeerTube for performance reasons. Could be removed 107 # Bypass PeerTube for performance reasons. Could be removed
108 location /static/webseed { 108 location ~ ^/static/(webseed|redundancy)/ {
109 # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client 109 # Clients usually have 4 simultaneous webseed connections, so the real limit is 3MB/s per client
110 limit_rate 800k; 110 limit_rate 800k;
111 111
@@ -128,7 +128,12 @@ server {
128 access_log off; 128 access_log off;
129 } 129 }
130 130
131 alias /var/www/peertube/storage/videos; 131 root /var/www/peertube/storage;
132
133 rewrite ^/static/webseed/(.*)$ /videos/$1 break;
134 rewrite ^/static/redundancy/(.*)$ /redundancy/$1 break;
135
136 try_files $uri /;
132 } 137 }
133 138
134 # Websocket tracker 139 # Websocket tracker