1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-03 09:49:20 +02:00

Simplify s3 error log

This commit is contained in:
Chocobozzz 2025-06-24 15:56:47 +02:00
parent 6b0ae9f082
commit 5b887a77ae
No known key found for this signature in database
GPG key ID: 583A612D890159BE
4 changed files with 44 additions and 30 deletions

View file

@ -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?)

View file

@ -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
}

View file

@ -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()

View file

@ -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'