Correctly cleanup permanent live empty directories
This commit is contained in:
parent
be7bc3a6a9
commit
71bdad9f5e
|
@ -269,7 +269,7 @@ describe('Save replay setting', function () {
|
||||||
await publishLiveAndDelete({ permanent: false, replay: false })
|
await publishLiveAndDelete({ permanent: false, replay: false })
|
||||||
|
|
||||||
await checkVideosExist(liveVideoUUID, 0, HttpStatusCode.NOT_FOUND_404)
|
await checkVideosExist(liveVideoUUID, 0, HttpStatusCode.NOT_FOUND_404)
|
||||||
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false })
|
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false, deleted: true })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -381,7 +381,7 @@ describe('Save replay setting', function () {
|
||||||
await publishLiveAndDelete({ permanent: false, replay: true, replaySettings: { privacy: VideoPrivacy.PUBLIC } })
|
await publishLiveAndDelete({ permanent: false, replay: true, replaySettings: { privacy: VideoPrivacy.PUBLIC } })
|
||||||
|
|
||||||
await checkVideosExist(liveVideoUUID, 0, HttpStatusCode.NOT_FOUND_404)
|
await checkVideosExist(liveVideoUUID, 0, HttpStatusCode.NOT_FOUND_404)
|
||||||
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false })
|
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false, deleted: true })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -563,7 +563,14 @@ describe('Save replay setting', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should have cleaned up the live files', async function () {
|
it('Should have cleaned up the live files', async function () {
|
||||||
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false })
|
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should delete the empty live and also delete the empty directory', async function () {
|
||||||
|
await servers[0].videos.remove({ id: liveVideoUUID })
|
||||||
|
await waitJobs(servers)
|
||||||
|
|
||||||
|
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: true, deleted: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
|
it('Should correctly terminate the stream on blacklist and blacklist the saved replay video', async function () {
|
||||||
|
@ -586,7 +593,7 @@ describe('Save replay setting', function () {
|
||||||
await servers[1].videos.get({ id: videoId, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
await servers[1].videos.get({ id: videoId, expectedStatus: HttpStatusCode.NOT_FOUND_404 })
|
||||||
}
|
}
|
||||||
|
|
||||||
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false })
|
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should correctly terminate the stream on delete and not save the video', async function () {
|
it('Should correctly terminate the stream on delete and not save the video', async function () {
|
||||||
|
@ -602,7 +609,7 @@ describe('Save replay setting', function () {
|
||||||
expect(replay).to.not.exist
|
expect(replay).to.not.exist
|
||||||
|
|
||||||
await checkVideosExist(liveVideoUUID, 1, HttpStatusCode.NOT_FOUND_404)
|
await checkVideosExist(liveVideoUUID, 1, HttpStatusCode.NOT_FOUND_404)
|
||||||
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: false })
|
await checkLiveCleanup({ server: servers[0], videoUUID: liveVideoUUID, permanent: true, deleted: true })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -16,14 +16,21 @@ async function checkLiveCleanup (options: {
|
||||||
videoUUID: string
|
videoUUID: string
|
||||||
permanent: boolean
|
permanent: boolean
|
||||||
savedResolutions?: number[]
|
savedResolutions?: number[]
|
||||||
|
deleted?: boolean // default false
|
||||||
}) {
|
}) {
|
||||||
const { server, videoUUID, permanent, savedResolutions = [] } = options
|
const { server, videoUUID, permanent, savedResolutions = [], deleted = false } = options
|
||||||
|
|
||||||
const basePath = server.servers.buildDirectory('streaming-playlists')
|
const basePath = server.servers.buildDirectory('streaming-playlists')
|
||||||
const hlsPath = join(basePath, 'hls', videoUUID)
|
const hlsPath = join(basePath, 'hls', videoUUID)
|
||||||
|
const hlsPathExists = await pathExists(hlsPath)
|
||||||
|
|
||||||
|
if (deleted) {
|
||||||
|
expect(hlsPathExists).to.be.false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (permanent) {
|
if (permanent) {
|
||||||
if (!await pathExists(hlsPath)) return
|
if (!hlsPathExists) return
|
||||||
|
|
||||||
const files = await readdir(hlsPath)
|
const files = await readdir(hlsPath)
|
||||||
expect(files.filter(f => f !== 'replay')).to.have.lengthOf(0)
|
expect(files.filter(f => f !== 'replay')).to.have.lengthOf(0)
|
||||||
|
@ -32,15 +39,13 @@ async function checkLiveCleanup (options: {
|
||||||
if (await pathExists(replayDir)) {
|
if (await pathExists(replayDir)) {
|
||||||
expect(await readdir(replayDir)).to.have.lengthOf(0)
|
expect(await readdir(replayDir)).to.have.lengthOf(0)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (savedResolutions.length === 0) {
|
||||||
|
return checkUnsavedLiveCleanup(server, videoUUID, hlsPath)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return checkSavedLiveCleanup(hlsPath, savedResolutions)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (savedResolutions.length === 0) {
|
|
||||||
return checkUnsavedLiveCleanup(server, videoUUID, hlsPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
return checkSavedLiveCleanup(hlsPath, savedResolutions)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { pathExists, remove } from 'fs-extra/esm'
|
import { pathExists, remove } from 'fs-extra/esm'
|
||||||
import { readdir } from 'fs/promises'
|
import { readdir, rmdir } from 'fs/promises'
|
||||||
import { basename, join } from 'path'
|
import { basename, join } from 'path'
|
||||||
import { LiveVideoLatencyMode, LiveVideoLatencyModeType, FileStorage } from '@peertube/peertube-models'
|
import { LiveVideoLatencyMode, LiveVideoLatencyModeType, FileStorage, VideoState } from '@peertube/peertube-models'
|
||||||
import { logger } from '@server/helpers/logger.js'
|
import { logger } from '@server/helpers/logger.js'
|
||||||
import { VIDEO_LIVE } from '@server/initializers/constants.js'
|
import { VIDEO_LIVE } from '@server/initializers/constants.js'
|
||||||
import { MStreamingPlaylist, MStreamingPlaylistVideo, MVideo } from '@server/types/models/index.js'
|
import { MStreamingPlaylist, MStreamingPlaylistVideo, MVideo } from '@server/types/models/index.js'
|
||||||
import { listHLSFileKeysOf, removeHLSFileObjectStorageByFullKey, removeHLSObjectStorage } from '../object-storage/index.js'
|
import { listHLSFileKeysOf, removeHLSFileObjectStorageByFullKey, removeHLSObjectStorage } from '../object-storage/index.js'
|
||||||
import { getLiveDirectory } from '../paths.js'
|
import { getLiveDirectory, getLiveReplayBaseDirectory } from '../paths.js'
|
||||||
|
|
||||||
function buildConcatenatedName (segmentOrPlaylistPath: string) {
|
function buildConcatenatedName (segmentOrPlaylistPath: string) {
|
||||||
const num = basename(segmentOrPlaylistPath).match(/^(\d+)(-|\.)/)
|
const num = basename(segmentOrPlaylistPath).match(/^(\d+)(-|\.)/)
|
||||||
|
@ -17,6 +17,17 @@ function buildConcatenatedName (segmentOrPlaylistPath: string) {
|
||||||
async function cleanupAndDestroyPermanentLive (video: MVideo, streamingPlaylist: MStreamingPlaylist) {
|
async function cleanupAndDestroyPermanentLive (video: MVideo, streamingPlaylist: MStreamingPlaylist) {
|
||||||
await cleanupTMPLiveFiles(video, streamingPlaylist)
|
await cleanupTMPLiveFiles(video, streamingPlaylist)
|
||||||
|
|
||||||
|
if (video.state === VideoState.WAITING_FOR_LIVE) {
|
||||||
|
// Try to delete local filesystem empty paths
|
||||||
|
// Object storage doesn't have the concept of directories so we don't need to duplicate the logic here
|
||||||
|
try {
|
||||||
|
await rmdir(getLiveReplayBaseDirectory(video))
|
||||||
|
await rmdir(getLiveDirectory(video))
|
||||||
|
} catch (err) {
|
||||||
|
logger.debug('Cannot cleanup permanent local live files', { err })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await streamingPlaylist.destroy()
|
await streamingPlaylist.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue