mirror of
https://github.com/plankanban/planka.git
synced 2026-02-05 08:50:08 +03:00
feat: Migrate file storage to unified data directory
This commit is contained in:
@@ -11,24 +11,9 @@ server/test
|
|||||||
server/.tmp
|
server/.tmp
|
||||||
server/.venv
|
server/.venv
|
||||||
|
|
||||||
server/views/*
|
server/views/index.ejs
|
||||||
!server/views/.gitkeep
|
|
||||||
|
|
||||||
server/public/*
|
server/data/*
|
||||||
!server/public/preloaded-favicons
|
!server/data/.gitkeep
|
||||||
!server/public/favicons
|
|
||||||
server/public/favicons/*
|
|
||||||
!server/public/favicons/.gitkeep
|
|
||||||
!server/public/user-avatars
|
|
||||||
server/public/user-avatars/*
|
|
||||||
!server/public/user-avatars/.gitkeep
|
|
||||||
!server/public/background-images
|
|
||||||
server/public/background-images/*
|
|
||||||
!server/public/background-images/.gitkeep
|
|
||||||
|
|
||||||
server/private/*
|
|
||||||
!server/private/attachments
|
|
||||||
server/private/attachments/*
|
|
||||||
!server/private/attachments/.gitkeep
|
|
||||||
|
|
||||||
client/dist
|
client/dist
|
||||||
|
|||||||
@@ -49,11 +49,7 @@ RUN python3 -m venv .venv \
|
|||||||
&& mv .env.sample .env \
|
&& mv .env.sample .env \
|
||||||
&& npm config set update-notifier false
|
&& npm config set update-notifier false
|
||||||
|
|
||||||
VOLUME /app/public/favicons
|
VOLUME /app/data
|
||||||
VOLUME /app/public/user-avatars
|
|
||||||
VOLUME /app/public/background-images
|
|
||||||
VOLUME /app/private/attachments
|
|
||||||
|
|
||||||
EXPOSE 1337
|
EXPOSE 1337
|
||||||
|
|
||||||
HEALTHCHECK --interval=10s --timeout=2s --start-period=15s \
|
HEALTHCHECK --interval=10s --timeout=2s --start-period=15s \
|
||||||
|
|||||||
@@ -54,17 +54,8 @@ spec:
|
|||||||
path: /
|
path: /
|
||||||
port: http
|
port: http
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- mountPath: /app/public/favicons
|
- mountPath: /app/data
|
||||||
subPath: favicons
|
subPath: data
|
||||||
name: planka
|
|
||||||
- mountPath: /app/public/user-avatars
|
|
||||||
subPath: user-avatars
|
|
||||||
name: planka
|
|
||||||
- mountPath: /app/public/background-images
|
|
||||||
subPath: background-images
|
|
||||||
name: planka
|
|
||||||
- mountPath: /app/private/attachments
|
|
||||||
subPath: attachments
|
|
||||||
name: planka
|
name: planka
|
||||||
{{- if .Values.securityContext.readOnlyRootFilesystem }}
|
{{- if .Values.securityContext.readOnlyRootFilesystem }}
|
||||||
- mountPath: /app/logs
|
- mountPath: /app/logs
|
||||||
|
|||||||
@@ -22,28 +22,16 @@ echo -n "Exporting postgres database ... "
|
|||||||
docker exec -t "$PLANKA_DOCKER_CONTAINER_POSTGRES" pg_dumpall -c -U postgres > "$BACKUP_DATETIME-backup/postgres.sql"
|
docker exec -t "$PLANKA_DOCKER_CONTAINER_POSTGRES" pg_dumpall -c -U postgres > "$BACKUP_DATETIME-backup/postgres.sql"
|
||||||
echo "Success!"
|
echo "Success!"
|
||||||
|
|
||||||
# Export Docker Voumes
|
# Export Docker Volume
|
||||||
echo -n "Exporting favicons ... "
|
echo -n "Exporting data volume ... "
|
||||||
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$BACKUP_DATETIME-backup:/backup" ubuntu cp -r /app/public/favicons /backup/favicons
|
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$BACKUP_DATETIME-backup:/backup" ubuntu cp -r /app/data /backup/data
|
||||||
echo "Success!"
|
|
||||||
echo -n "Exporting user-avatars ... "
|
|
||||||
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$BACKUP_DATETIME-backup:/backup" ubuntu cp -r /app/public/user-avatars /backup/user-avatars
|
|
||||||
echo "Success!"
|
|
||||||
echo -n "Exporting background-images ... "
|
|
||||||
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$BACKUP_DATETIME-backup:/backup" ubuntu cp -r /app/public/background-images /backup/background-images
|
|
||||||
echo "Success!"
|
|
||||||
echo -n "Exporting attachments ... "
|
|
||||||
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$BACKUP_DATETIME-backup:/backup" ubuntu cp -r /app/private/attachments /backup/attachments
|
|
||||||
echo "Success!"
|
echo "Success!"
|
||||||
|
|
||||||
# Create tgz
|
# Create tgz
|
||||||
echo -n "Creating final tarball $BACKUP_DATETIME-backup.tgz ... "
|
echo -n "Creating final tarball $BACKUP_DATETIME-backup.tgz ... "
|
||||||
tar -czf "$BACKUP_DATETIME-backup.tgz" \
|
tar -czf "$BACKUP_DATETIME-backup.tgz" \
|
||||||
"$BACKUP_DATETIME-backup/postgres.sql" \
|
"$BACKUP_DATETIME-backup/postgres.sql" \
|
||||||
"$BACKUP_DATETIME-backup/favicons" \
|
"$BACKUP_DATETIME-backup/data"
|
||||||
"$BACKUP_DATETIME-backup/user-avatars" \
|
|
||||||
"$BACKUP_DATETIME-backup/background-images" \
|
|
||||||
"$BACKUP_DATETIME-backup/attachments"
|
|
||||||
echo "Success!"
|
echo "Success!"
|
||||||
|
|
||||||
# Remove source files
|
# Remove source files
|
||||||
|
|||||||
@@ -3,10 +3,7 @@ services:
|
|||||||
image: ghcr.io/plankanban/planka:2.0.0-rc.4
|
image: ghcr.io/plankanban/planka:2.0.0-rc.4
|
||||||
restart: on-failure
|
restart: on-failure
|
||||||
volumes:
|
volumes:
|
||||||
- favicons:/app/public/favicons
|
- data:/app/data
|
||||||
- user-avatars:/app/public/user-avatars
|
|
||||||
- background-images:/app/public/background-images
|
|
||||||
- attachments:/app/private/attachments
|
|
||||||
# Optionally override this to your user/group
|
# Optionally override this to your user/group
|
||||||
# user: 1000:1000
|
# user: 1000:1000
|
||||||
# tmpfs:
|
# tmpfs:
|
||||||
@@ -132,8 +129,5 @@ services:
|
|||||||
retries: 5
|
retries: 5
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
favicons:
|
data:
|
||||||
user-avatars:
|
|
||||||
background-images:
|
|
||||||
attachments:
|
|
||||||
db-data:
|
db-data:
|
||||||
|
|||||||
@@ -19,18 +19,9 @@ echo -n "Importing postgres database ... "
|
|||||||
cat "$PLANKA_BACKUP_ARCHIVE/postgres.sql" | docker exec -i "$PLANKA_DOCKER_CONTAINER_POSTGRES" psql -U postgres
|
cat "$PLANKA_BACKUP_ARCHIVE/postgres.sql" | docker exec -i "$PLANKA_DOCKER_CONTAINER_POSTGRES" psql -U postgres
|
||||||
echo "Success!"
|
echo "Success!"
|
||||||
|
|
||||||
# Restore Docker Volumes
|
# Restore Docker Volume
|
||||||
echo -n "Importing favicons ... "
|
echo -n "Importing data volume ... "
|
||||||
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$PLANKA_BACKUP_ARCHIVE:/backup" ubuntu cp -rf /backup/favicons /app/public/
|
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$PLANKA_BACKUP_ARCHIVE:/backup" ubuntu cp -rf /backup/data/. /app/public/data
|
||||||
echo "Success!"
|
|
||||||
echo -n "Importing user-avatars ... "
|
|
||||||
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$PLANKA_BACKUP_ARCHIVE:/backup" ubuntu cp -rf /backup/user-avatars /app/public/
|
|
||||||
echo "Success!"
|
|
||||||
echo -n "Importing background-images ... "
|
|
||||||
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$PLANKA_BACKUP_ARCHIVE:/backup" ubuntu cp -rf /backup/background-images /app/public/
|
|
||||||
echo "Success!"
|
|
||||||
echo -n "Importing attachments ... "
|
|
||||||
docker run --rm --volumes-from "$PLANKA_DOCKER_CONTAINER_PLANKA" -v "$(pwd)/$PLANKA_BACKUP_ARCHIVE:/backup" ubuntu cp -rf /backup/attachments /app/private/
|
|
||||||
echo "Success!"
|
echo "Success!"
|
||||||
|
|
||||||
echo -n "Cleaning up temporary files and folders ... "
|
echo -n "Cleaning up temporary files and folders ... "
|
||||||
|
|||||||
@@ -20,17 +20,6 @@ test
|
|||||||
.tmp
|
.tmp
|
||||||
.venv
|
.venv
|
||||||
|
|
||||||
views/*
|
views/index.ejs
|
||||||
|
|
||||||
public/*
|
data/*
|
||||||
!public/preloaded-favicons
|
|
||||||
!public/favicons
|
|
||||||
public/favicons/*
|
|
||||||
!public/user-avatars
|
|
||||||
public/user-avatars/*
|
|
||||||
!public/background-images
|
|
||||||
public/background-images/*
|
|
||||||
|
|
||||||
private/*
|
|
||||||
!private/attachments
|
|
||||||
private/attachments/*
|
|
||||||
|
|||||||
21
server/.gitignore
vendored
21
server/.gitignore
vendored
@@ -134,22 +134,7 @@ swagger.json
|
|||||||
dist
|
dist
|
||||||
logs
|
logs
|
||||||
|
|
||||||
views/*
|
views/index.ejs
|
||||||
!views/.gitkeep
|
|
||||||
|
|
||||||
public/*
|
data/*
|
||||||
!public/preloaded-favicons
|
!data/.gitkeep
|
||||||
!public/favicons
|
|
||||||
public/favicons/*
|
|
||||||
!public/favicons/.gitkeep
|
|
||||||
!public/user-avatars
|
|
||||||
public/user-avatars/*
|
|
||||||
!public/user-avatars/.gitkeep
|
|
||||||
!public/background-images
|
|
||||||
public/background-images/*
|
|
||||||
!public/background-images/.gitkeep
|
|
||||||
|
|
||||||
private/*
|
|
||||||
!private/attachments
|
|
||||||
private/attachments/*
|
|
||||||
!private/attachments/.gitkeep
|
|
||||||
|
|||||||
@@ -7,12 +7,7 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
const PRELOADED_FAVICON_FILENAMES = fs
|
const PRELOADED_FAVICON_FILENAMES = fs
|
||||||
.readdirSync(
|
.readdirSync(path.join(sails.config.paths.public, 'preloaded-favicons'))
|
||||||
path.join(
|
|
||||||
sails.config.custom.uploadsBasePath,
|
|
||||||
sails.config.custom.preloadedFaviconsPathSegment,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.filter((filename) => filename.endsWith('.png'));
|
.filter((filename) => filename.endsWith('.png'));
|
||||||
|
|
||||||
const PRELOADED_FAVICON_HOSTNAMES_SET = new Set(
|
const PRELOADED_FAVICON_HOSTNAMES_SET = new Set(
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
* https://sailsjs.com/config/custom
|
* https://sailsjs.com/config/custom
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
const { URL } = require('url');
|
const { URL } = require('url');
|
||||||
const bytes = require('bytes');
|
const bytes = require('bytes');
|
||||||
const sails = require('sails');
|
const sails = require('sails');
|
||||||
@@ -48,12 +49,11 @@ module.exports.custom = {
|
|||||||
|
|
||||||
// Location to receive uploaded files in. Default (non-string value) is a Sails-specific location.
|
// Location to receive uploaded files in. Default (non-string value) is a Sails-specific location.
|
||||||
uploadsTempPath: null,
|
uploadsTempPath: null,
|
||||||
uploadsBasePath: sails.config.appPath,
|
uploadsBasePath: path.join(sails.config.appPath, 'data'),
|
||||||
|
|
||||||
preloadedFaviconsPathSegment: 'public/preloaded-favicons',
|
faviconsPathSegment: 'protected/favicons',
|
||||||
faviconsPathSegment: 'public/favicons',
|
userAvatarsPathSegment: 'protected/user-avatars',
|
||||||
userAvatarsPathSegment: 'public/user-avatars',
|
backgroundImagesPathSegment: 'protected/background-images',
|
||||||
backgroundImagesPathSegment: 'public/background-images',
|
|
||||||
attachmentsPathSegment: 'private/attachments',
|
attachmentsPathSegment: 'private/attachments',
|
||||||
|
|
||||||
defaultAdminEmail:
|
defaultAdminEmail:
|
||||||
|
|||||||
@@ -80,13 +80,13 @@ const serveStatic = async (prefix, getPathSegment, req, res) => {
|
|||||||
return readStream.pipe(res);
|
return readStream.pipe(res);
|
||||||
};
|
};
|
||||||
|
|
||||||
const publicStaticDirServer = (prefix, getPathSegment) => (req, res, next) => {
|
/* const publicStaticDirServer = (prefix, getPathSegment) => (req, res, next) => {
|
||||||
if (!req.url.startsWith(prefix)) {
|
if (!req.url.startsWith(prefix)) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
return serveStatic(prefix, getPathSegment, req, res);
|
return serveStatic(prefix, getPathSegment, req, res);
|
||||||
};
|
}; */
|
||||||
|
|
||||||
const protectedStaticDirServer = (prefix, getPathSegment) => (req, res, next) => {
|
const protectedStaticDirServer = (prefix, getPathSegment) => (req, res, next) => {
|
||||||
if (!req.url.startsWith(prefix)) {
|
if (!req.url.startsWith(prefix)) {
|
||||||
@@ -235,14 +235,6 @@ module.exports.routes = {
|
|||||||
|
|
||||||
'PATCH /api/_internal/config': '_internal/update-config',
|
'PATCH /api/_internal/config': '_internal/update-config',
|
||||||
|
|
||||||
'GET /preloaded-favicons/*': {
|
|
||||||
fn: publicStaticDirServer(
|
|
||||||
'/preloaded-favicons',
|
|
||||||
() => sails.config.custom.preloadedFaviconsPathSegment,
|
|
||||||
),
|
|
||||||
skipAssets: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
'GET /favicons/*': {
|
'GET /favicons/*': {
|
||||||
fn: protectedStaticDirServer('/favicons', () => sails.config.custom.faviconsPathSegment),
|
fn: protectedStaticDirServer('/favicons', () => sails.config.custom.faviconsPathSegment),
|
||||||
skipAssets: false,
|
skipAssets: false,
|
||||||
|
|||||||
@@ -24,7 +24,14 @@ const PrevActionTypes = {
|
|||||||
COMMENT_CARD: 'commentCard',
|
COMMENT_CARD: 'commentCard',
|
||||||
};
|
};
|
||||||
|
|
||||||
const PROJECT_BACKGROUND_IMAGES_PATH_SEGMENT = 'public/project-background-images';
|
const PrevPathSegments = {
|
||||||
|
PROJECT_BACKGROUND_IMAGES: 'public/project-background-images',
|
||||||
|
|
||||||
|
FAVICONS: 'public/favicons',
|
||||||
|
USER_AVATARS: 'public/user-avatars',
|
||||||
|
BACKGROUND_IMAGES: 'public/background-images',
|
||||||
|
ATTACHMENTS: 'private/attachments',
|
||||||
|
};
|
||||||
|
|
||||||
const readStreamToBuffer = (readStream) =>
|
const readStreamToBuffer = (readStream) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
@@ -600,7 +607,7 @@ const upgradeDatabase = async () => {
|
|||||||
const upgradeUserAvatars = async () => {
|
const upgradeUserAvatars = async () => {
|
||||||
const fileManager = sails.hooks['file-manager'].getInstance();
|
const fileManager = sails.hooks['file-manager'].getInstance();
|
||||||
|
|
||||||
const dirnames = await fileManager.listDir(sails.config.custom.userAvatarsPathSegment);
|
const dirnames = await fileManager.listDir(PrevPathSegments.USER_AVATARS);
|
||||||
const users = await knex('user_account').whereNotNull('avatar');
|
const users = await knex('user_account').whereNotNull('avatar');
|
||||||
|
|
||||||
if (dirnames) {
|
if (dirnames) {
|
||||||
@@ -608,21 +615,23 @@ const upgradeUserAvatars = async () => {
|
|||||||
|
|
||||||
for (const dirname of dirnames) {
|
for (const dirname of dirnames) {
|
||||||
const user = userByDirname[dirname];
|
const user = userByDirname[dirname];
|
||||||
const dirPathSegment = `${sails.config.custom.userAvatarsPathSegment}/${dirname}`;
|
const dirPathSegment = `${PrevPathSegments.USER_AVATARS}/${dirname}`;
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
const size = await fileManager.getSize(
|
const size = await fileManager.getSize(
|
||||||
`${dirPathSegment}/original.${user.avatar.extension}`,
|
`${dirPathSegment}/original.${user.avatar.extension}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await knex('user_account')
|
if (size) {
|
||||||
.update({
|
await knex('user_account')
|
||||||
avatar: knex.raw("?? || jsonb_build_object('sizeInBytes', ?::bigint)", [
|
.update({
|
||||||
'avatar',
|
avatar: knex.raw("?? || jsonb_build_object('sizeInBytes', ?::bigint)", [
|
||||||
size,
|
'avatar',
|
||||||
]),
|
size,
|
||||||
})
|
]),
|
||||||
.where('id', user.id);
|
})
|
||||||
|
.where('id', user.id);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
await fileManager.deleteDir(dirPathSegment);
|
await fileManager.deleteDir(dirPathSegment);
|
||||||
}
|
}
|
||||||
@@ -630,7 +639,7 @@ const upgradeUserAvatars = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const { avatar } of users) {
|
for (const { avatar } of users) {
|
||||||
const dirPathSegment = `${sails.config.custom.userAvatarsPathSegment}/${avatar.dirname}`;
|
const dirPathSegment = `${PrevPathSegments.USER_AVATARS}/${avatar.dirname}`;
|
||||||
|
|
||||||
const isExists = await fileManager.isExists(`${dirPathSegment}/cover-180.${avatar.extension}`);
|
const isExists = await fileManager.isExists(`${dirPathSegment}/cover-180.${avatar.extension}`);
|
||||||
|
|
||||||
@@ -675,11 +684,11 @@ const upgradeBackgroundImages = async () => {
|
|||||||
const fileManager = sails.hooks['file-manager'].getInstance();
|
const fileManager = sails.hooks['file-manager'].getInstance();
|
||||||
|
|
||||||
await fileManager.renameDir(
|
await fileManager.renameDir(
|
||||||
PROJECT_BACKGROUND_IMAGES_PATH_SEGMENT,
|
PrevPathSegments.PROJECT_BACKGROUND_IMAGES,
|
||||||
sails.config.custom.backgroundImagesPathSegment,
|
PrevPathSegments.BACKGROUND_IMAGES,
|
||||||
);
|
);
|
||||||
|
|
||||||
const dirnames = await fileManager.listDir(sails.config.custom.backgroundImagesPathSegment);
|
const dirnames = await fileManager.listDir(PrevPathSegments.BACKGROUND_IMAGES);
|
||||||
const backgroundImages = await knex('background_image');
|
const backgroundImages = await knex('background_image');
|
||||||
|
|
||||||
if (dirnames) {
|
if (dirnames) {
|
||||||
@@ -687,18 +696,20 @@ const upgradeBackgroundImages = async () => {
|
|||||||
|
|
||||||
for (const dirname of dirnames) {
|
for (const dirname of dirnames) {
|
||||||
const backgroundImage = backgroundImageByDirname[dirname];
|
const backgroundImage = backgroundImageByDirname[dirname];
|
||||||
const dirPathSegment = `${sails.config.custom.backgroundImagesPathSegment}/${dirname}`;
|
const dirPathSegment = `${PrevPathSegments.BACKGROUND_IMAGES}/${dirname}`;
|
||||||
|
|
||||||
if (backgroundImage) {
|
if (backgroundImage) {
|
||||||
const size = await fileManager.getSize(
|
const size = await fileManager.getSize(
|
||||||
`${dirPathSegment}/original.${backgroundImage.extension}`,
|
`${dirPathSegment}/original.${backgroundImage.extension}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
await knex('background_image')
|
if (size) {
|
||||||
.update({
|
await knex('background_image')
|
||||||
size_in_bytes: size,
|
.update({
|
||||||
})
|
size_in_bytes: size,
|
||||||
.where('id', backgroundImage.id);
|
})
|
||||||
|
.where('id', backgroundImage.id);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
await fileManager.deleteDir(dirPathSegment);
|
await fileManager.deleteDir(dirPathSegment);
|
||||||
}
|
}
|
||||||
@@ -706,7 +717,7 @@ const upgradeBackgroundImages = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const backgroundImage of backgroundImages) {
|
for (const backgroundImage of backgroundImages) {
|
||||||
const dirPathSegment = `${sails.config.custom.backgroundImagesPathSegment}/${backgroundImage.dirname}`;
|
const dirPathSegment = `${PrevPathSegments.BACKGROUND_IMAGES}/${backgroundImage.dirname}`;
|
||||||
|
|
||||||
const isExists = await fileManager.isExists(
|
const isExists = await fileManager.isExists(
|
||||||
`${dirPathSegment}/outside-360.${backgroundImage.extension}`,
|
`${dirPathSegment}/outside-360.${backgroundImage.extension}`,
|
||||||
@@ -755,7 +766,7 @@ const upgradeBackgroundImages = async () => {
|
|||||||
const upgradeFileAttachments = async () => {
|
const upgradeFileAttachments = async () => {
|
||||||
const fileManager = sails.hooks['file-manager'].getInstance();
|
const fileManager = sails.hooks['file-manager'].getInstance();
|
||||||
|
|
||||||
const dirnames = await fileManager.listDir(sails.config.custom.attachmentsPathSegment);
|
const dirnames = await fileManager.listDir(PrevPathSegments.ATTACHMENTS);
|
||||||
const attachments = await knex('attachment').where('type', Attachment.Types.FILE);
|
const attachments = await knex('attachment').where('type', Attachment.Types.FILE);
|
||||||
|
|
||||||
const fileReferenceIds = [];
|
const fileReferenceIds = [];
|
||||||
@@ -764,7 +775,7 @@ const upgradeFileAttachments = async () => {
|
|||||||
|
|
||||||
for (const dirname of dirnames) {
|
for (const dirname of dirnames) {
|
||||||
const attachment = attachmentByDirname[dirname];
|
const attachment = attachmentByDirname[dirname];
|
||||||
const dirPathSegment = `${sails.config.custom.attachmentsPathSegment}/${dirname}`;
|
const dirPathSegment = `${PrevPathSegments.ATTACHMENTS}/${dirname}`;
|
||||||
|
|
||||||
if (attachment) {
|
if (attachment) {
|
||||||
if (uuid.validate(dirname)) {
|
if (uuid.validate(dirname)) {
|
||||||
@@ -800,7 +811,7 @@ const upgradeFileAttachments = async () => {
|
|||||||
|
|
||||||
await fileManager.renameDir(
|
await fileManager.renameDir(
|
||||||
`${dirPathSegment}`,
|
`${dirPathSegment}`,
|
||||||
`${sails.config.custom.attachmentsPathSegment}/${id}`,
|
`${PrevPathSegments.ATTACHMENTS}/${id}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
@@ -833,7 +844,7 @@ const upgradeFileAttachments = async () => {
|
|||||||
.whereRaw("??->>'image' IS NOT NULL", 'data');
|
.whereRaw("??->>'image' IS NOT NULL", 'data');
|
||||||
|
|
||||||
for (const { data } of imageAttachments) {
|
for (const { data } of imageAttachments) {
|
||||||
const dirPathSegment = `${sails.config.custom.attachmentsPathSegment}/${data.fileReferenceId}`;
|
const dirPathSegment = `${PrevPathSegments.ATTACHMENTS}/${data.fileReferenceId}`;
|
||||||
const thumbnailsPathSegment = `${dirPathSegment}/thumbnails`;
|
const thumbnailsPathSegment = `${dirPathSegment}/thumbnails`;
|
||||||
|
|
||||||
const isExists = await fileManager.isExists(
|
const isExists = await fileManager.isExists(
|
||||||
@@ -895,6 +906,22 @@ const upgradeFileAttachments = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const upgradeDataStructure = async () => {
|
||||||
|
const fileManager = sails.hooks['file-manager'].getInstance();
|
||||||
|
|
||||||
|
await fileManager.renameDir(PrevPathSegments.FAVICONS, sails.config.custom.faviconsPathSegment);
|
||||||
|
|
||||||
|
await fileManager.renameDir(
|
||||||
|
PrevPathSegments.USER_AVATARS,
|
||||||
|
sails.config.custom.userAvatarsPathSegment,
|
||||||
|
);
|
||||||
|
|
||||||
|
await fileManager.renameDir(
|
||||||
|
PrevPathSegments.BACKGROUND_IMAGES,
|
||||||
|
sails.config.custom.backgroundImagesPathSegment,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
let migrations;
|
let migrations;
|
||||||
@@ -908,6 +935,7 @@ const upgradeFileAttachments = async () => {
|
|||||||
|
|
||||||
const isV1 = migrationNames[0] === '20180721020022_create_next_id_function.js';
|
const isV1 = migrationNames[0] === '20180721020022_create_next_id_function.js';
|
||||||
const isLatestV1 = migrationNames.at(-1) === '20250131202710_add_list_color.js';
|
const isLatestV1 = migrationNames.at(-1) === '20250131202710_add_list_color.js';
|
||||||
|
const isInitialV2 = migrationNames.at(-1) === '20250228000022_version_2.js';
|
||||||
|
|
||||||
if (isV1 && !isLatestV1) {
|
if (isV1 && !isLatestV1) {
|
||||||
throw new Error('Update to latest v1 first');
|
throw new Error('Update to latest v1 first');
|
||||||
@@ -919,9 +947,13 @@ const upgradeFileAttachments = async () => {
|
|||||||
await runStep('Upgrading database', upgradeDatabase);
|
await runStep('Upgrading database', upgradeDatabase);
|
||||||
}
|
}
|
||||||
|
|
||||||
await runStep('Upgrading user avatars', upgradeUserAvatars);
|
if (isV1 || isInitialV2) {
|
||||||
await runStep('Upgrading background images', upgradeBackgroundImages);
|
await runStep('Upgrading user avatars', upgradeUserAvatars);
|
||||||
await runStep('Upgrading file attachments', upgradeFileAttachments);
|
await runStep('Upgrading background images', upgradeBackgroundImages);
|
||||||
|
await runStep('Upgrading file attachments', upgradeFileAttachments);
|
||||||
|
}
|
||||||
|
|
||||||
|
await runStep('Upgrading data structure', upgradeDataStructure);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user