aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/initializers/checker-after-init.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/initializers/checker-after-init.ts')
-rw-r--r--server/initializers/checker-after-init.ts188
1 files changed, 110 insertions, 78 deletions
diff --git a/server/initializers/checker-after-init.ts b/server/initializers/checker-after-init.ts
index 57ef0d218..635a32010 100644
--- a/server/initializers/checker-after-init.ts
+++ b/server/initializers/checker-after-init.ts
@@ -1,7 +1,7 @@
1import config from 'config' 1import config from 'config'
2import { uniq } from 'lodash' 2import { uniq } from 'lodash'
3import { URL } from 'url' 3import { URL } from 'url'
4import { getFFmpegVersion } from '@server/helpers/ffmpeg-utils' 4import { getFFmpegVersion } from '@server/helpers/ffmpeg'
5import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type' 5import { VideoRedundancyConfigFilter } from '@shared/models/redundancy/video-redundancy-config-filter.type'
6import { RecentlyAddedStrategy } from '../../shared/models/redundancy' 6import { RecentlyAddedStrategy } from '../../shared/models/redundancy'
7import { isProdInstance, isTestInstance, parseSemVersion } from '../helpers/core-utils' 7import { isProdInstance, isTestInstance, parseSemVersion } from '../helpers/core-utils'
@@ -31,8 +31,7 @@ async function checkActivityPubUrls () {
31 } 31 }
32} 32}
33 33
34// Some checks on configuration files 34// Some checks on configuration files or throw if there is an error
35// Return an error message, or null if everything is okay
36function checkConfig () { 35function checkConfig () {
37 36
38 // Moved configuration keys 37 // Moved configuration keys
@@ -40,61 +39,124 @@ function checkConfig () {
40 logger.warn('services.csp-logger configuration has been renamed to csp.report_uri. Please update your configuration file.') 39 logger.warn('services.csp-logger configuration has been renamed to csp.report_uri. Please update your configuration file.')
41 } 40 }
42 41
43 // Email verification 42 checkEmailConfig()
43 checkNSFWPolicyConfig()
44 checkLocalRedundancyConfig()
45 checkRemoteRedundancyConfig()
46 checkStorageConfig()
47 checkTranscodingConfig()
48 checkBroadcastMessageConfig()
49 checkSearchConfig()
50 checkLiveConfig()
51 checkObjectStorageConfig()
52 checkVideoEditorConfig()
53}
54
55// We get db by param to not import it in this file (import orders)
56async function clientsExist () {
57 const totalClients = await OAuthClientModel.countTotal()
58
59 return totalClients !== 0
60}
61
62// We get db by param to not import it in this file (import orders)
63async function usersExist () {
64 const totalUsers = await UserModel.countTotal()
65
66 return totalUsers !== 0
67}
68
69// We get db by param to not import it in this file (import orders)
70async function applicationExist () {
71 const totalApplication = await ApplicationModel.countTotal()
72
73 return totalApplication !== 0
74}
75
76async function checkFFmpegVersion () {
77 const version = await getFFmpegVersion()
78 const { major, minor } = parseSemVersion(version)
79
80 if (major < 4 || (major === 4 && minor < 1)) {
81 logger.warn('Your ffmpeg version (%s) is outdated. PeerTube supports ffmpeg >= 4.1. Please upgrade.', version)
82 }
83}
84
85// ---------------------------------------------------------------------------
86
87export {
88 checkConfig,
89 clientsExist,
90 checkFFmpegVersion,
91 usersExist,
92 applicationExist,
93 checkActivityPubUrls
94}
95
96// ---------------------------------------------------------------------------
97
98function checkEmailConfig () {
44 if (!isEmailEnabled()) { 99 if (!isEmailEnabled()) {
45 if (CONFIG.SIGNUP.ENABLED && CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) { 100 if (CONFIG.SIGNUP.ENABLED && CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION) {
46 return 'Emailer is disabled but you require signup email verification.' 101 throw new Error('Emailer is disabled but you require signup email verification.')
47 } 102 }
48 103
49 if (CONFIG.CONTACT_FORM.ENABLED) { 104 if (CONFIG.CONTACT_FORM.ENABLED) {
50 logger.warn('Emailer is disabled so the contact form will not work.') 105 logger.warn('Emailer is disabled so the contact form will not work.')
51 } 106 }
52 } 107 }
108}
53 109
54 // NSFW policy 110function checkNSFWPolicyConfig () {
55 const defaultNSFWPolicy = CONFIG.INSTANCE.DEFAULT_NSFW_POLICY 111 const defaultNSFWPolicy = CONFIG.INSTANCE.DEFAULT_NSFW_POLICY
56 { 112
57 const available = [ 'do_not_list', 'blur', 'display' ] 113 const available = [ 'do_not_list', 'blur', 'display' ]
58 if (available.includes(defaultNSFWPolicy) === false) { 114 if (available.includes(defaultNSFWPolicy) === false) {
59 return 'NSFW policy setting should be ' + available.join(' or ') + ' instead of ' + defaultNSFWPolicy 115 throw new Error('NSFW policy setting should be ' + available.join(' or ') + ' instead of ' + defaultNSFWPolicy)
60 }
61 } 116 }
117}
62 118
63 // Redundancies 119function checkLocalRedundancyConfig () {
64 const redundancyVideos = CONFIG.REDUNDANCY.VIDEOS.STRATEGIES 120 const redundancyVideos = CONFIG.REDUNDANCY.VIDEOS.STRATEGIES
121
65 if (isArray(redundancyVideos)) { 122 if (isArray(redundancyVideos)) {
66 const available = [ 'most-views', 'trending', 'recently-added' ] 123 const available = [ 'most-views', 'trending', 'recently-added' ]
124
67 for (const r of redundancyVideos) { 125 for (const r of redundancyVideos) {
68 if (available.includes(r.strategy) === false) { 126 if (available.includes(r.strategy) === false) {
69 return 'Videos redundancy should have ' + available.join(' or ') + ' strategy instead of ' + r.strategy 127 throw new Error('Videos redundancy should have ' + available.join(' or ') + ' strategy instead of ' + r.strategy)
70 } 128 }
71 129
72 // Lifetime should not be < 10 hours 130 // Lifetime should not be < 10 hours
73 if (!isTestInstance() && r.minLifetime < 1000 * 3600 * 10) { 131 if (!isTestInstance() && r.minLifetime < 1000 * 3600 * 10) {
74 return 'Video redundancy minimum lifetime should be >= 10 hours for strategy ' + r.strategy 132 throw new Error('Video redundancy minimum lifetime should be >= 10 hours for strategy ' + r.strategy)
75 } 133 }
76 } 134 }
77 135
78 const filtered = uniq(redundancyVideos.map(r => r.strategy)) 136 const filtered = uniq(redundancyVideos.map(r => r.strategy))
79 if (filtered.length !== redundancyVideos.length) { 137 if (filtered.length !== redundancyVideos.length) {
80 return 'Redundancy video entries should have unique strategies' 138 throw new Error('Redundancy video entries should have unique strategies')
81 } 139 }
82 140
83 const recentlyAddedStrategy = redundancyVideos.find(r => r.strategy === 'recently-added') as RecentlyAddedStrategy 141 const recentlyAddedStrategy = redundancyVideos.find(r => r.strategy === 'recently-added') as RecentlyAddedStrategy
84 if (recentlyAddedStrategy && isNaN(recentlyAddedStrategy.minViews)) { 142 if (recentlyAddedStrategy && isNaN(recentlyAddedStrategy.minViews)) {
85 return 'Min views in recently added strategy is not a number' 143 throw new Error('Min views in recently added strategy is not a number')
86 } 144 }
87 } else { 145 } else {
88 return 'Videos redundancy should be an array (you must uncomment lines containing - too)' 146 throw new Error('Videos redundancy should be an array (you must uncomment lines containing - too)')
89 } 147 }
148}
90 149
91 // Remote redundancies 150function checkRemoteRedundancyConfig () {
92 const acceptFrom = CONFIG.REMOTE_REDUNDANCY.VIDEOS.ACCEPT_FROM 151 const acceptFrom = CONFIG.REMOTE_REDUNDANCY.VIDEOS.ACCEPT_FROM
93 const acceptFromValues = new Set<VideoRedundancyConfigFilter>([ 'nobody', 'anybody', 'followings' ]) 152 const acceptFromValues = new Set<VideoRedundancyConfigFilter>([ 'nobody', 'anybody', 'followings' ])
153
94 if (acceptFromValues.has(acceptFrom) === false) { 154 if (acceptFromValues.has(acceptFrom) === false) {
95 return 'remote_redundancy.videos.accept_from has an incorrect value' 155 throw new Error('remote_redundancy.videos.accept_from has an incorrect value')
96 } 156 }
157}
97 158
159function checkStorageConfig () {
98 // Check storage directory locations 160 // Check storage directory locations
99 if (isProdInstance()) { 161 if (isProdInstance()) {
100 const configStorage = config.get('storage') 162 const configStorage = config.get('storage')
@@ -111,71 +173,76 @@ function checkConfig () {
111 if (CONFIG.STORAGE.VIDEOS_DIR === CONFIG.STORAGE.REDUNDANCY_DIR) { 173 if (CONFIG.STORAGE.VIDEOS_DIR === CONFIG.STORAGE.REDUNDANCY_DIR) {
112 logger.warn('Redundancy directory should be different than the videos folder.') 174 logger.warn('Redundancy directory should be different than the videos folder.')
113 } 175 }
176}
114 177
115 // Transcoding 178function checkTranscodingConfig () {
116 if (CONFIG.TRANSCODING.ENABLED) { 179 if (CONFIG.TRANSCODING.ENABLED) {
117 if (CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false && CONFIG.TRANSCODING.HLS.ENABLED === false) { 180 if (CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false && CONFIG.TRANSCODING.HLS.ENABLED === false) {
118 return 'You need to enable at least WebTorrent transcoding or HLS transcoding.' 181 throw new Error('You need to enable at least WebTorrent transcoding or HLS transcoding.')
119 } 182 }
120 183
121 if (CONFIG.TRANSCODING.CONCURRENCY <= 0) { 184 if (CONFIG.TRANSCODING.CONCURRENCY <= 0) {
122 return 'Transcoding concurrency should be > 0' 185 throw new Error('Transcoding concurrency should be > 0')
123 } 186 }
124 } 187 }
125 188
126 if (CONFIG.IMPORT.VIDEOS.HTTP.ENABLED || CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED) { 189 if (CONFIG.IMPORT.VIDEOS.HTTP.ENABLED || CONFIG.IMPORT.VIDEOS.TORRENT.ENABLED) {
127 if (CONFIG.IMPORT.VIDEOS.CONCURRENCY <= 0) { 190 if (CONFIG.IMPORT.VIDEOS.CONCURRENCY <= 0) {
128 return 'Video import concurrency should be > 0' 191 throw new Error('Video import concurrency should be > 0')
129 } 192 }
130 } 193 }
194}
131 195
132 // Broadcast message 196function checkBroadcastMessageConfig () {
133 if (CONFIG.BROADCAST_MESSAGE.ENABLED) { 197 if (CONFIG.BROADCAST_MESSAGE.ENABLED) {
134 const currentLevel = CONFIG.BROADCAST_MESSAGE.LEVEL 198 const currentLevel = CONFIG.BROADCAST_MESSAGE.LEVEL
135 const available = [ 'info', 'warning', 'error' ] 199 const available = [ 'info', 'warning', 'error' ]
136 200
137 if (available.includes(currentLevel) === false) { 201 if (available.includes(currentLevel) === false) {
138 return 'Broadcast message level should be ' + available.join(' or ') + ' instead of ' + currentLevel 202 throw new Error('Broadcast message level should be ' + available.join(' or ') + ' instead of ' + currentLevel)
139 } 203 }
140 } 204 }
205}
141 206
142 // Search index 207function checkSearchConfig () {
143 if (CONFIG.SEARCH.SEARCH_INDEX.ENABLED === true) { 208 if (CONFIG.SEARCH.SEARCH_INDEX.ENABLED === true) {
144 if (CONFIG.SEARCH.REMOTE_URI.USERS === false) { 209 if (CONFIG.SEARCH.REMOTE_URI.USERS === false) {
145 return 'You cannot enable search index without enabling remote URI search for users.' 210 throw new Error('You cannot enable search index without enabling remote URI search for users.')
146 } 211 }
147 } 212 }
213}
148 214
149 // Live 215function checkLiveConfig () {
150 if (CONFIG.LIVE.ENABLED === true) { 216 if (CONFIG.LIVE.ENABLED === true) {
151 if (CONFIG.LIVE.ALLOW_REPLAY === true && CONFIG.TRANSCODING.ENABLED === false) { 217 if (CONFIG.LIVE.ALLOW_REPLAY === true && CONFIG.TRANSCODING.ENABLED === false) {
152 return 'Live allow replay cannot be enabled if transcoding is not enabled.' 218 throw new Error('Live allow replay cannot be enabled if transcoding is not enabled.')
153 } 219 }
154 220
155 if (CONFIG.LIVE.RTMP.ENABLED === false && CONFIG.LIVE.RTMPS.ENABLED === false) { 221 if (CONFIG.LIVE.RTMP.ENABLED === false && CONFIG.LIVE.RTMPS.ENABLED === false) {
156 return 'You must enable at least RTMP or RTMPS' 222 throw new Error('You must enable at least RTMP or RTMPS')
157 } 223 }
158 224
159 if (CONFIG.LIVE.RTMPS.ENABLED) { 225 if (CONFIG.LIVE.RTMPS.ENABLED) {
160 if (!CONFIG.LIVE.RTMPS.KEY_FILE) { 226 if (!CONFIG.LIVE.RTMPS.KEY_FILE) {
161 return 'You must specify a key file to enabled RTMPS' 227 throw new Error('You must specify a key file to enabled RTMPS')
162 } 228 }
163 229
164 if (!CONFIG.LIVE.RTMPS.CERT_FILE) { 230 if (!CONFIG.LIVE.RTMPS.CERT_FILE) {
165 return 'You must specify a cert file to enable RTMPS' 231 throw new Error('You must specify a cert file to enable RTMPS')
166 } 232 }
167 } 233 }
168 } 234 }
235}
169 236
170 // Object storage 237function checkObjectStorageConfig () {
171 if (CONFIG.OBJECT_STORAGE.ENABLED === true) { 238 if (CONFIG.OBJECT_STORAGE.ENABLED === true) {
172 239
173 if (!CONFIG.OBJECT_STORAGE.VIDEOS.BUCKET_NAME) { 240 if (!CONFIG.OBJECT_STORAGE.VIDEOS.BUCKET_NAME) {
174 return 'videos_bucket should be set when object storage support is enabled.' 241 throw new Error('videos_bucket should be set when object storage support is enabled.')
175 } 242 }
176 243
177 if (!CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS.BUCKET_NAME) { 244 if (!CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS.BUCKET_NAME) {
178 return 'streaming_playlists_bucket should be set when object storage support is enabled.' 245 throw new Error('streaming_playlists_bucket should be set when object storage support is enabled.')
179 } 246 }
180 247
181 if ( 248 if (
@@ -183,53 +250,18 @@ function checkConfig () {
183 CONFIG.OBJECT_STORAGE.VIDEOS.PREFIX === CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS.PREFIX 250 CONFIG.OBJECT_STORAGE.VIDEOS.PREFIX === CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS.PREFIX
184 ) { 251 ) {
185 if (CONFIG.OBJECT_STORAGE.VIDEOS.PREFIX === '') { 252 if (CONFIG.OBJECT_STORAGE.VIDEOS.PREFIX === '') {
186 return 'Object storage bucket prefixes should be set when the same bucket is used for both types of video.' 253 throw new Error('Object storage bucket prefixes should be set when the same bucket is used for both types of video.')
187 } else {
188 return 'Object storage bucket prefixes should be set to different values when the same bucket is used for both types of video.'
189 } 254 }
255
256 throw new Error(
257 'Object storage bucket prefixes should be set to different values when the same bucket is used for both types of video.'
258 )
190 } 259 }
191 } 260 }
192
193 return null
194}
195
196// We get db by param to not import it in this file (import orders)
197async function clientsExist () {
198 const totalClients = await OAuthClientModel.countTotal()
199
200 return totalClients !== 0
201}
202
203// We get db by param to not import it in this file (import orders)
204async function usersExist () {
205 const totalUsers = await UserModel.countTotal()
206
207 return totalUsers !== 0
208} 261}
209 262
210// We get db by param to not import it in this file (import orders) 263function checkVideoEditorConfig () {
211async function applicationExist () { 264 if (CONFIG.VIDEO_EDITOR.ENABLED === true && CONFIG.TRANSCODING.ENABLED === false) {
212 const totalApplication = await ApplicationModel.countTotal() 265 throw new Error('Video editor cannot be enabled if transcoding is disabled')
213
214 return totalApplication !== 0
215}
216
217async function checkFFmpegVersion () {
218 const version = await getFFmpegVersion()
219 const { major, minor } = parseSemVersion(version)
220
221 if (major < 4 || (major === 4 && minor < 1)) {
222 logger.warn('Your ffmpeg version (%s) is outdated. PeerTube supports ffmpeg >= 4.1. Please upgrade.', version)
223 } 266 }
224} 267}
225
226// ---------------------------------------------------------------------------
227
228export {
229 checkConfig,
230 clientsExist,
231 checkFFmpegVersion,
232 usersExist,
233 applicationExist,
234 checkActivityPubUrls
235}