mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-03 17:59:37 +02:00
Simplify s3 error log
This commit is contained in:
parent
6b0ae9f082
commit
5b887a77ae
4 changed files with 44 additions and 30 deletions
|
@ -7,9 +7,9 @@ import { createReadStream, createWriteStream } from 'fs'
|
||||||
import { ensureDir } from 'fs-extra/esm'
|
import { ensureDir } from 'fs-extra/esm'
|
||||||
import { dirname } from 'path'
|
import { dirname } from 'path'
|
||||||
import { Readable } from 'stream'
|
import { Readable } from 'stream'
|
||||||
import { getInternalUrl } from './urls.js'
|
|
||||||
import { getClient } from './shared/client.js'
|
import { getClient } from './shared/client.js'
|
||||||
import { lTags } from './shared/logger.js'
|
import { lTags } from './shared/logger.js'
|
||||||
|
import { getInternalUrl } from './urls.js'
|
||||||
|
|
||||||
import type { _Object, ObjectCannedACL, PutObjectCommandInput, S3Client } from '@aws-sdk/client-s3'
|
import type { _Object, ObjectCannedACL, PutObjectCommandInput, S3Client } from '@aws-sdk/client-s3'
|
||||||
|
|
||||||
|
@ -31,6 +31,9 @@ async function listKeysOfPrefix (prefix: string, bucketInfo: BucketInfo, continu
|
||||||
})
|
})
|
||||||
|
|
||||||
const listedObjects = await s3Client.send(listCommand)
|
const listedObjects = await s3Client.send(listCommand)
|
||||||
|
.catch(err => {
|
||||||
|
throw parseS3Error(err)
|
||||||
|
})
|
||||||
|
|
||||||
if (isArray(listedObjects.Contents) !== true) return []
|
if (isArray(listedObjects.Contents) !== true) return []
|
||||||
|
|
||||||
|
@ -115,6 +118,9 @@ async function updateObjectACL (options: {
|
||||||
|
|
||||||
const client = await getClient()
|
const client = await getClient()
|
||||||
await client.send(command)
|
await client.send(command)
|
||||||
|
.catch(err => {
|
||||||
|
throw parseS3Error(err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePrefixACL (options: {
|
async function updatePrefixACL (options: {
|
||||||
|
@ -167,6 +173,9 @@ async function removeObjectByFullKey (fullKey: string, bucketInfo: Pick<BucketIn
|
||||||
const client = await getClient()
|
const client = await getClient()
|
||||||
|
|
||||||
return client.send(command)
|
return client.send(command)
|
||||||
|
.catch(err => {
|
||||||
|
throw parseS3Error(err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function removePrefix (prefix: string, bucketInfo: BucketInfo) {
|
async function removePrefix (prefix: string, bucketInfo: BucketInfo) {
|
||||||
|
@ -208,6 +217,9 @@ async function makeAvailable (options: {
|
||||||
|
|
||||||
const client = await getClient()
|
const client = await getClient()
|
||||||
const response = await client.send(command)
|
const response = await client.send(command)
|
||||||
|
.catch(err => {
|
||||||
|
throw parseS3Error(err)
|
||||||
|
})
|
||||||
|
|
||||||
const file = createWriteStream(destination)
|
const file = createWriteStream(destination)
|
||||||
await pipelinePromise(response.Body as Readable, file)
|
await pipelinePromise(response.Body as Readable, file)
|
||||||
|
@ -238,6 +250,9 @@ async function createObjectReadStream (options: {
|
||||||
|
|
||||||
const client = await getClient()
|
const client = await getClient()
|
||||||
const response = await client.send(command)
|
const response = await client.send(command)
|
||||||
|
.catch(err => {
|
||||||
|
throw parseS3Error(err)
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
response,
|
response,
|
||||||
|
@ -262,6 +277,9 @@ async function getObjectStorageFileSize (options: {
|
||||||
|
|
||||||
const client = await getClient()
|
const client = await getClient()
|
||||||
const response = await client.send(command)
|
const response = await client.send(command)
|
||||||
|
.catch(err => {
|
||||||
|
throw parseS3Error(err)
|
||||||
|
})
|
||||||
|
|
||||||
return response.ContentLength
|
return response.ContentLength
|
||||||
}
|
}
|
||||||
|
@ -269,20 +287,20 @@ async function getObjectStorageFileSize (options: {
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export {
|
export {
|
||||||
type BucketInfo,
|
|
||||||
buildKey,
|
buildKey,
|
||||||
storeObject,
|
createObjectReadStream,
|
||||||
storeContent,
|
getObjectStorageFileSize,
|
||||||
storeStream,
|
listKeysOfPrefix,
|
||||||
|
makeAvailable,
|
||||||
removeObject,
|
removeObject,
|
||||||
removeObjectByFullKey,
|
removeObjectByFullKey,
|
||||||
removePrefix,
|
removePrefix,
|
||||||
makeAvailable,
|
storeContent,
|
||||||
|
storeObject,
|
||||||
|
storeStream,
|
||||||
updateObjectACL,
|
updateObjectACL,
|
||||||
updatePrefixACL,
|
updatePrefixACL,
|
||||||
listKeysOfPrefix,
|
type BucketInfo
|
||||||
createObjectReadStream,
|
|
||||||
getObjectStorageFileSize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -368,6 +386,9 @@ async function applyOnPrefix (options: {
|
||||||
})
|
})
|
||||||
|
|
||||||
const listedObjects = await s3Client.send(listCommand)
|
const listedObjects = await s3Client.send(listCommand)
|
||||||
|
.catch(err => {
|
||||||
|
throw parseS3Error(err)
|
||||||
|
})
|
||||||
|
|
||||||
if (isArray(listedObjects.Contents) !== true) {
|
if (isArray(listedObjects.Contents) !== true) {
|
||||||
const message = `Cannot apply function on ${commandPrefix} prefix in bucket ${bucketInfo.BUCKET_NAME}: no files listed.`
|
const message = `Cannot apply function on ${commandPrefix} prefix in bucket ${bucketInfo.BUCKET_NAME}: no files listed.`
|
||||||
|
@ -380,6 +401,9 @@ async function applyOnPrefix (options: {
|
||||||
const command = commandBuilder(object)
|
const command = commandBuilder(object)
|
||||||
|
|
||||||
return s3Client.send(command)
|
return s3Client.send(command)
|
||||||
|
.catch(err => {
|
||||||
|
throw parseS3Error(err)
|
||||||
|
})
|
||||||
}, { concurrency: 10 })
|
}, { concurrency: 10 })
|
||||||
|
|
||||||
// Repeat if not all objects could be listed at once (limit of 1000?)
|
// Repeat if not all objects could be listed at once (limit of 1000?)
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
import { loggerTagsFactory } from '@server/helpers/logger.js'
|
import { loggerTagsFactory } from '@server/helpers/logger.js'
|
||||||
|
|
||||||
const lTags = loggerTagsFactory('object-storage')
|
export const lTags = loggerTagsFactory('object-storage')
|
||||||
|
|
||||||
export {
|
|
||||||
lTags
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { VideoPrivacy, VideoPrivacyType, VideoState } from '@peertube/peertube-models'
|
import { VideoPrivacy, VideoPrivacyType, VideoState } from '@peertube/peertube-models'
|
||||||
import { VideoModel } from '@server/models/video/video.js'
|
import { VideoModel } from '@server/models/video/video.js'
|
||||||
import { MScheduleVideoUpdate } from '@server/types/models/index.js'
|
import { MScheduleVideoUpdate } from '@server/types/models/index.js'
|
||||||
import { logger } from '../../helpers/logger.js'
|
import { logger, loggerTagsFactory } from '../../helpers/logger.js'
|
||||||
import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants.js'
|
import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants.js'
|
||||||
import { sequelizeTypescript } from '../../initializers/database.js'
|
import { sequelizeTypescript } from '../../initializers/database.js'
|
||||||
import { ScheduleVideoUpdateModel } from '../../models/video/schedule-video-update.js'
|
import { ScheduleVideoUpdateModel } from '../../models/video/schedule-video-update.js'
|
||||||
|
@ -12,8 +12,9 @@ import { VideoPathManager } from '../video-path-manager.js'
|
||||||
import { setVideoPrivacy } from '../video-privacy.js'
|
import { setVideoPrivacy } from '../video-privacy.js'
|
||||||
import { AbstractScheduler } from './abstract-scheduler.js'
|
import { AbstractScheduler } from './abstract-scheduler.js'
|
||||||
|
|
||||||
export class UpdateVideosScheduler extends AbstractScheduler {
|
const lTags = loggerTagsFactory('update-videos-scheduler')
|
||||||
|
|
||||||
|
export class UpdateVideosScheduler extends AbstractScheduler {
|
||||||
private static instance: AbstractScheduler
|
private static instance: AbstractScheduler
|
||||||
|
|
||||||
protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.UPDATE_VIDEOS
|
protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.UPDATE_VIDEOS
|
||||||
|
@ -40,7 +41,7 @@ export class UpdateVideosScheduler extends AbstractScheduler {
|
||||||
|
|
||||||
if (published) Notifier.Instance.notifyOnVideoPublishedAfterScheduledUpdate(video)
|
if (published) Notifier.Instance.notifyOnVideoPublishedAfterScheduledUpdate(video)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error('Cannot update video', { err })
|
logger.error('Cannot update video', { err, ...lTags(videoOnly.uuid) })
|
||||||
}
|
}
|
||||||
|
|
||||||
mutexReleaser()
|
mutexReleaser()
|
||||||
|
|
|
@ -12,7 +12,7 @@ const validPrivacySet = new Set<VideoPrivacyType>([
|
||||||
VideoPrivacy.PASSWORD_PROTECTED
|
VideoPrivacy.PASSWORD_PROTECTED
|
||||||
])
|
])
|
||||||
|
|
||||||
function setVideoPrivacy (video: MVideo, newPrivacy: VideoPrivacyType) {
|
export function setVideoPrivacy (video: MVideo, newPrivacy: VideoPrivacyType) {
|
||||||
if (video.privacy === VideoPrivacy.PRIVATE && newPrivacy !== VideoPrivacy.PRIVATE) {
|
if (video.privacy === VideoPrivacy.PRIVATE && newPrivacy !== VideoPrivacy.PRIVATE) {
|
||||||
video.publishedAt = new Date()
|
video.publishedAt = new Date()
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,15 @@ function setVideoPrivacy (video: MVideo, newPrivacy: VideoPrivacyType) {
|
||||||
video.privacy = newPrivacy
|
video.privacy = newPrivacy
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVideoInPrivateDirectory (privacy: VideoPrivacyType) {
|
export function isVideoInPrivateDirectory (privacy: VideoPrivacyType) {
|
||||||
return validPrivacySet.has(privacy)
|
return validPrivacySet.has(privacy)
|
||||||
}
|
}
|
||||||
|
|
||||||
function isVideoInPublicDirectory (privacy: VideoPrivacyType) {
|
export function isVideoInPublicDirectory (privacy: VideoPrivacyType) {
|
||||||
return !isVideoInPrivateDirectory(privacy)
|
return !isVideoInPrivateDirectory(privacy)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function moveFilesIfPrivacyChanged (video: MVideoFullLight, oldPrivacy: VideoPrivacyType) {
|
export async function moveFilesIfPrivacyChanged (video: MVideoFullLight, oldPrivacy: VideoPrivacyType) {
|
||||||
// Now public, previously private
|
// Now public, previously private
|
||||||
if (isVideoInPublicDirectory(video.privacy) && isVideoInPrivateDirectory(oldPrivacy)) {
|
if (isVideoInPublicDirectory(video.privacy) && isVideoInPrivateDirectory(oldPrivacy)) {
|
||||||
await moveFiles({ type: 'private-to-public', video })
|
await moveFiles({ type: 'private-to-public', video })
|
||||||
|
@ -46,15 +46,8 @@ async function moveFilesIfPrivacyChanged (video: MVideoFullLight, oldPrivacy: Vi
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
// ---------------------------------------------------------------------------
|
||||||
setVideoPrivacy,
|
// Private
|
||||||
|
|
||||||
isVideoInPrivateDirectory,
|
|
||||||
isVideoInPublicDirectory,
|
|
||||||
|
|
||||||
moveFilesIfPrivacyChanged
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
type MoveType = 'private-to-public' | 'public-to-private'
|
type MoveType = 'private-to-public' | 'public-to-private'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue