From b6b2d05be01921ce72600cacc61938ea3caa674e Mon Sep 17 00:00:00 2001 From: Florent Date: Mon, 10 Jul 2023 12:24:55 +0200 Subject: [PATCH] Abort when MinIO bucket does not have versioning enabled #545 (#546) Co-authored-by: Florent FAYOLLE --- app/server/lib/FlexServer.ts | 2 +- app/server/lib/ICreate.ts | 6 +- app/server/lib/MinIOExternalStorage.ts | 5 ++ .../lib/configureMinIOExternalStorage.ts | 13 ++++ app/server/mergedServerMain.ts | 71 ++++++++++--------- stubs/app/server/lib/create.ts | 3 +- stubs/app/server/server.ts | 4 +- 7 files changed, 67 insertions(+), 37 deletions(-) diff --git a/app/server/lib/FlexServer.ts b/app/server/lib/FlexServer.ts index a99fc160..eed447c9 100644 --- a/app/server/lib/FlexServer.ts +++ b/app/server/lib/FlexServer.ts @@ -1124,7 +1124,6 @@ export class FlexServer implements GristServer { await this.loadConfig(); this.addComm(); - await this.create.configure?.(); if (!isSingleUserMode()) { const externalStorage = appSettings.section('externalStorage'); const haveExternalStorage = Object.values(externalStorage.nested) @@ -1135,6 +1134,7 @@ export class FlexServer implements GristServer { this._disableExternalStorage = true; externalStorage.flag('active').set(false); } + await this.create.configure?.(); const workers = this._docWorkerMap; const docWorkerId = await this._addSelfAsWorker(workers); diff --git a/app/server/lib/ICreate.ts b/app/server/lib/ICreate.ts index b49942fd..f876fa9c 100644 --- a/app/server/lib/ICreate.ts +++ b/app/server/lib/ICreate.ts @@ -50,6 +50,7 @@ export interface ICreateActiveDocOptions { export interface ICreateStorageOptions { name: string; check(): boolean; + checkBackend?(): Promise; create(purpose: 'doc'|'meta', extraPrefix: string): ExternalStorage|undefined; } @@ -119,7 +120,10 @@ export function makeSimpleCreator(opts: { }, async configure() { for (const s of storage || []) { - if (s.check()) { break; } + if (s.check()) { + await s.checkBackend?.(); + break; + } } }, ...(opts.shell && { diff --git a/app/server/lib/MinIOExternalStorage.ts b/app/server/lib/MinIOExternalStorage.ts index dafa738a..fe70ea4b 100644 --- a/app/server/lib/MinIOExternalStorage.ts +++ b/app/server/lib/MinIOExternalStorage.ts @@ -107,6 +107,11 @@ export class MinIOExternalStorage implements ExternalStorage { } } + public async hasVersioning(): Promise { + const versioning = await this._s3.getBucketVersioning(this.bucket); + return versioning && versioning.Status === 'Enabled'; + } + public async versions(key: string, options?: { includeDeleteMarkers?: boolean }) { const results: minio.BucketItem[] = []; await new Promise((resolve, reject) => { diff --git a/app/server/lib/configureMinIOExternalStorage.ts b/app/server/lib/configureMinIOExternalStorage.ts index c34a4755..2cac4d2c 100644 --- a/app/server/lib/configureMinIOExternalStorage.ts +++ b/app/server/lib/configureMinIOExternalStorage.ts @@ -60,3 +60,16 @@ export function checkMinIOExternalStorage() { region }; } + +export async function checkMinIOBucket() { + const options = checkMinIOExternalStorage(); + if (!options) { + throw new Error('Configuration check failed for MinIO backend storage.'); + } + + const externalStorage = new MinIOExternalStorage(options.bucket, options); + if (!await externalStorage.hasVersioning()) { + await externalStorage.close(); + throw new Error(`FATAL: the MinIO bucket "${options.bucket}" does not have versioning enabled`); + } +} diff --git a/app/server/mergedServerMain.ts b/app/server/mergedServerMain.ts index c4dddc52..c4d294ce 100644 --- a/app/server/mergedServerMain.ts +++ b/app/server/mergedServerMain.ts @@ -106,44 +106,49 @@ export async function main(port: number, serverTypes: ServerType[], server.addApiMiddleware(); await server.addBillingMiddleware(); - await server.start(); - - if (includeHome) { - server.addUsage(); - if (!includeDocs) { - server.addDocApiForwarder(); + try { + await server.start(); + + if (includeHome) { + server.addUsage(); + if (!includeDocs) { + server.addDocApiForwarder(); + } + server.addJsonSupport(); + await server.addLandingPages(); + // todo: add support for home api to standalone app + server.addHomeApi(); + server.addBillingApi(); + server.addNotifier(); + server.addTelemetry(); + await server.addHousekeeper(); + await server.addLoginRoutes(); + server.addAccountPage(); + server.addBillingPages(); + server.addWelcomePaths(); + server.addLogEndpoint(); + server.addGoogleAuthEndpoint(); } - server.addJsonSupport(); - await server.addLandingPages(); - // todo: add support for home api to standalone app - server.addHomeApi(); - server.addBillingApi(); - server.addNotifier(); - server.addTelemetry(); - await server.addHousekeeper(); - await server.addLoginRoutes(); - server.addAccountPage(); - server.addBillingPages(); - server.addWelcomePaths(); - server.addLogEndpoint(); - server.addGoogleAuthEndpoint(); - } - if (includeDocs) { - server.addJsonSupport(); - server.addTelemetry(); - await server.addDoc(); - } + if (includeDocs) { + server.addJsonSupport(); + server.addTelemetry(); + await server.addDoc(); + } - if (includeHome) { - server.addClientSecrets(); - } + if (includeHome) { + server.addClientSecrets(); + } - server.finalize(); + server.finalize(); - server.checkOptionCombinations(); - server.summary(); - return server; + server.checkOptionCombinations(); + server.summary(); + return server; + } catch(e) { + await server.close(); + throw e; + } } diff --git a/stubs/app/server/lib/create.ts b/stubs/app/server/lib/create.ts index 98c11b52..370d0c5a 100644 --- a/stubs/app/server/lib/create.ts +++ b/stubs/app/server/lib/create.ts @@ -1,4 +1,4 @@ -import { checkMinIOExternalStorage, +import { checkMinIOBucket, checkMinIOExternalStorage, configureMinIOExternalStorage } from 'app/server/lib/configureMinIOExternalStorage'; import { makeSimpleCreator } from 'app/server/lib/ICreate'; import { Telemetry } from 'app/server/lib/Telemetry'; @@ -12,6 +12,7 @@ export const create = makeSimpleCreator({ { name: 'minio', check: () => checkMinIOExternalStorage() !== undefined, + checkBackend: () => checkMinIOBucket(), create: configureMinIOExternalStorage, }, ], diff --git a/stubs/app/server/server.ts b/stubs/app/server/server.ts index dc462275..9ea30b40 100644 --- a/stubs/app/server/server.ts +++ b/stubs/app/server/server.ts @@ -117,5 +117,7 @@ export async function main() { } if (require.main === module) { - main().catch((err) => console.error(err)); + main().catch((err) => { + console.error(err); + }); }