From ef0ec4233a865500a63ea719976c354bd2c2a5e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Am=C3=A9lie=20Loulergue?= Date: Wed, 18 Dec 2024 11:21:15 +0100 Subject: [PATCH] add upload default images on init if needed --- local/default/default.webp | Bin 0 -> 16730 bytes local/default/error.webp | Bin 0 -> 10614 bytes package.json | 2 +- src/api/server.ts | 104 +++++++++++++++++++++++++++---------- 4 files changed, 79 insertions(+), 27 deletions(-) create mode 100644 local/default/default.webp create mode 100644 local/default/error.webp diff --git a/local/default/default.webp b/local/default/default.webp new file mode 100644 index 0000000000000000000000000000000000000000..206667609ccc89297bc7cdde3c6a8f01b2ea7498 GIT binary patch literal 16730 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Ý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 literal 0 HcmV?d00001 diff --git a/local/default/error.webp b/local/default/error.webp new file mode 100644 index 0000000000000000000000000000000000000000..65726a91a5320e564037ee982529f104112591ff GIT binary patch literal 10614 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 Q=C&d4YoGuC0000002H#|zyJUM literal 0 HcmV?d00001 diff --git a/package.json b/package.json index fb379c0..34bf73f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "scripts": { "format": "prettier --write .", - "dev:api": "cd src/api && npm run dev", + "dev:api": "export IMAGES_UPLOAD_PATH=../../local/default && export IMAGES_UPLOAD_NAMESPACE=DEV && export IMAGES_UPLOAD_DESTINATION=default && cd src/api && npm run dev", "docker:dev": "docker compose -f docker-compose.dev.yml up --build -d", "docker": "docker compose up --build -d" }, diff --git a/src/api/server.ts b/src/api/server.ts index a8dd08e..004213e 100644 --- a/src/api/server.ts +++ b/src/api/server.ts @@ -1,53 +1,61 @@ import app from './app'; import { logger } from './utils/logs/winston'; -import fs from 'fs'; import { redisHandler } from './catalog/redis/connection'; import { getLastDump } from './delegated-storage/index'; import { minioClient } from './delegated-storage/s3/connection'; -import fetch from 'node-fetch'; import { deleteCatalogItem, getCatalog } from './catalog'; +import { promisify } from 'util'; +import FormData from 'form-data'; +import fetch from 'node-fetch'; +import fs from 'fs'; +import path from 'path'; + +const readdir = promisify(fs.readdir); +const stat = promisify(fs.stat); const port = parseInt(process.env.PORT, 10) || 3001; const standalone = process.env.DELEGATED_STORAGE_METHOD === 'STANDALONE'; +const imagesUploadPath = process.env.IMAGES_UPLOAD_PATH || ''; +const imagesUploadNamespace = process.env.IMAGES_UPLOAD_NAMESPACE || ''; +const imagesUploadDestination = process.env.IMAGES_UPLOAD_DESTINATION || ''; const checkAccessToBackup = async () => { - console.log('CHECK ACCESS BACKUP :::', process.env.DELEGATED_STORAGE_HOST) - const backupUrl = `${process.env.DELEGATED_STORAGE_HOST}${process.env.DELEGATED_STORAGE_READINESS_CHECK}`; + const backupUrl = `${ process.env.DELEGATED_STORAGE_HOST }${ process.env.DELEGATED_STORAGE_READINESS_CHECK }`; const checkBackup = await fetch(backupUrl); if (checkBackup.status !== 200) { - logger.error(`Backup status response on ${process.env.DELEGATED_STORAGE_READINESS_CHECK}: ${checkBackup.status}`); - throw new Error(`Backup access failed: ${checkBackup.status}`); + logger.error(`Backup status response on ${ process.env.DELEGATED_STORAGE_READINESS_CHECK }: ${ checkBackup.status }`); + throw new Error(`Backup access failed: ${ checkBackup.status }`); } if (process.env.DELEGATED_STORAGE_METHOD === 'S3') { const bucketName = process.env.S3_BUCKET_NAME; const bucketExists = await minioClient.bucketExists(bucketName); if (!bucketExists) { await minioClient.makeBucket(bucketName, 'us-east-1'); - logger.info(`Bucket check OK: "${bucketName}" created successfully.`); + logger.info(`Bucket check OK: "${ bucketName }" created successfully.`); } else { - logger.info(`Bucket check OK: "${bucketName}" already exists.`); + logger.info(`Bucket check OK: "${ bucketName }" already exists.`); } } - logger.info(`Backup access OK: ${backupUrl}`); + logger.info(`Backup access OK: ${ backupUrl }`); }; const connectToRedisWithRetry = async (maxRetries, delay) => { let attempts = 0; - while (attempts < maxRetries) { + while ( attempts < maxRetries ) { try { await redisHandler.connectClient(); - const {data:catalog} = await getCatalog() - if(catalog.length){ - for (const item of catalog){ - if(item.unique_name.includes('/tests/')){ - await deleteCatalogItem(item.unique_name) + const { data: catalog } = await getCatalog(); + if (catalog.length) { + for ( const item of catalog ) { + if (item.unique_name.includes('/tests/')) { + await deleteCatalogItem(item.unique_name); } } } return; - } catch (err) { + } catch ( err ) { attempts++; - logger.error(`Failed to connect to Redis. Attempt ${attempts} of ${maxRetries}. Retrying in ${delay / 1000} seconds...`); + logger.error(`Failed to connect to Redis. Attempt ${ attempts } of ${ maxRetries }. Retrying in ${ delay / 1000 } seconds...`); if (attempts < maxRetries) { await new Promise((resolve) => setTimeout(resolve, delay)); } else { @@ -68,35 +76,79 @@ const createStandaloneFolderAndCatalog = () => { } }; -(async () => { +const uploadImages = async (dirPath) => { + if (!fs.existsSync(dirPath)) { + logger.error(`Path does not exist: ${ dirPath }`); + return; + } + + const files = await readdir(dirPath); + for ( const file of files ) { + const filePath = path.join(dirPath, file); + const fileStat = await stat(filePath); + if (fileStat.isFile()) { + console.log(`Uploading file: ${ file }`); + + const stream = fs.createReadStream(filePath); + const form = new FormData(); + form.append('namespace', imagesUploadNamespace); + form.append('destination', imagesUploadDestination); + form.append('file', stream, { filename: file }); + try { + const response = await fetch('http://localhost:3001/palpatine/file', { + method: 'POST', + body: form, + headers: { + 'Authorization': 'Bearer cooltokenyeah' + } + }); + + if (response.status !== 200) { + const error = await response.json(); + logger.error(`Failed to upload file: ${ file }, Error: ${ JSON.stringify(error) }`); + } else { + logger.info(`Successfully uploaded file: ${ file }`); + } + } catch ( error ) { + logger.error(`Error uploading file: ${ file }, ${ error }`); + } + } + } +}; + +( async () => { try { if (!standalone) { await checkAccessToBackup(); await connectToRedisWithRetry(3, 10000); await redisHandler.disconnectClient(); - const dbDump = fs.existsSync(`${process.env.DUMP_FOLDER_PATH}/dump.rdb`); + const dbDump = fs.existsSync(`${ process.env.DUMP_FOLDER_PATH }/dump.rdb`); if (!dbDump) { - logger.info("dump.rdb doesn't exists : getting latest dump from backup āœ…"); + logger.info('dump.rdb doesn\'t exist: getting latest dump from backup āœ…'); await getLastDump(); } else { - logger.info('dump.rdb already exists : skipping getting latest dump from backup šŸ”†'); + logger.info('dump.rdb already exists: skipping getting latest dump from backup šŸ”†'); } } if (standalone) { createStandaloneFolderAndCatalog(); } + app.listen(port, async () => { - logger.info(`\nāœØ ${standalone ? 'Using fs in standalone mode' : 'Connected to Redis'}, server running => http://localhost:${port}\n`); + logger.info(`\nāœØ ${ standalone ? + 'Using fs in standalone mode' : + 'Connected to Redis' }, server running => http://localhost:${ port }\n`); + await uploadImages(imagesUploadPath); }); - } catch (err) { - logger.error(`Error starting app => ${err}`); + } catch ( err ) { + logger.error(`Error starting app => ${ err }`); process.exit(1); } -})(); +} )(); app.on('error', (err) => { - logger.error(`${err}`); + logger.error(`${ err }`); process.exit(1); });