mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-01 21:31:04 +00:00
Fix Account/Backup (#2642)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
a17d24c965
commit
54e62d9547
@ -283,10 +283,17 @@ export function devTool (
|
|||||||
|
|
||||||
program
|
program
|
||||||
.command('backup-restore <dirName> <workspace> [date]')
|
.command('backup-restore <dirName> <workspace> [date]')
|
||||||
|
.option('-m, --merge', 'Enable merge of remote and backup content.', false)
|
||||||
.description('dump workspace transactions and minio resources')
|
.description('dump workspace transactions and minio resources')
|
||||||
.action(async (dirName: string, workspace: string, date, cmd) => {
|
.action(async (dirName: string, workspace: string, date, cmd: { merge: boolean }) => {
|
||||||
const storage = await createFileBackupStorage(dirName)
|
const storage = await createFileBackupStorage(dirName)
|
||||||
return await restore(transactorUrl, getWorkspaceId(workspace, productId), storage, parseInt(date ?? '-1'))
|
return await restore(
|
||||||
|
transactorUrl,
|
||||||
|
getWorkspaceId(workspace, productId),
|
||||||
|
storage,
|
||||||
|
parseInt(date ?? '-1'),
|
||||||
|
cmd.merge
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
program
|
program
|
||||||
|
@ -25,8 +25,6 @@ interface Config {
|
|||||||
MinioEndpoint: string
|
MinioEndpoint: string
|
||||||
MinioAccessKey: string
|
MinioAccessKey: string
|
||||||
MinioSecretKey: string
|
MinioSecretKey: string
|
||||||
|
|
||||||
ProductId: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const envMap: { [key in keyof Config]: string } = {
|
const envMap: { [key in keyof Config]: string } = {
|
||||||
@ -38,8 +36,7 @@ const envMap: { [key in keyof Config]: string } = {
|
|||||||
Interval: 'INTERVAL',
|
Interval: 'INTERVAL',
|
||||||
MinioEndpoint: 'MINIO_ENDPOINT',
|
MinioEndpoint: 'MINIO_ENDPOINT',
|
||||||
MinioAccessKey: 'MINIO_ACCESS_KEY',
|
MinioAccessKey: 'MINIO_ACCESS_KEY',
|
||||||
MinioSecretKey: 'MINIO_SECRET_KEY',
|
MinioSecretKey: 'MINIO_SECRET_KEY'
|
||||||
ProductId: 'PRODUCT_ID'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const required: Array<keyof Config> = [
|
const required: Array<keyof Config> = [
|
||||||
@ -63,8 +60,7 @@ const config: Config = (() => {
|
|||||||
Interval: parseInt(process.env[envMap.Interval] ?? '3600'),
|
Interval: parseInt(process.env[envMap.Interval] ?? '3600'),
|
||||||
MinioEndpoint: process.env[envMap.MinioEndpoint],
|
MinioEndpoint: process.env[envMap.MinioEndpoint],
|
||||||
MinioAccessKey: process.env[envMap.MinioAccessKey],
|
MinioAccessKey: process.env[envMap.MinioAccessKey],
|
||||||
MinioSecretKey: process.env[envMap.MinioSecretKey],
|
MinioSecretKey: process.env[envMap.MinioSecretKey]
|
||||||
ProductId: process.env[envMap.ProductId] ?? ''
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const missingEnv = required.filter((key) => params[key] === undefined).map((key) => envMap[key])
|
const missingEnv = required.filter((key) => params[key] === undefined).map((key) => envMap[key])
|
||||||
|
@ -19,9 +19,21 @@ import { setMetadata } from '@hcengineering/platform'
|
|||||||
import { backup, createMinioBackupStorage } from '@hcengineering/server-backup'
|
import { backup, createMinioBackupStorage } from '@hcengineering/server-backup'
|
||||||
import serverToken from '@hcengineering/server-token'
|
import serverToken from '@hcengineering/server-token'
|
||||||
import got from 'got'
|
import got from 'got'
|
||||||
|
import { ObjectId } from 'mongodb'
|
||||||
import config from './config'
|
import config from './config'
|
||||||
|
|
||||||
async function getWorkspaces (): Promise<string[]> {
|
/**
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
export interface Workspace {
|
||||||
|
_id: ObjectId
|
||||||
|
workspace: string
|
||||||
|
organisation: string
|
||||||
|
accounts: ObjectId[]
|
||||||
|
productId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getWorkspaces (): Promise<Workspace[]> {
|
||||||
const { body }: { body: { error?: string, result?: any[] } } = await got.post(config.AccountsURL, {
|
const { body }: { body: { error?: string, result?: any[] } } = await got.post(config.AccountsURL, {
|
||||||
json: {
|
json: {
|
||||||
method: 'listWorkspaces',
|
method: 'listWorkspaces',
|
||||||
@ -34,7 +46,7 @@ async function getWorkspaces (): Promise<string[]> {
|
|||||||
throw Error(body.error)
|
throw Error(body.error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (body.result ?? []).map((x) => x.workspace)
|
return (body.result as Workspace[]) ?? []
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PlatformWorker {
|
export class PlatformWorker {
|
||||||
@ -79,8 +91,12 @@ export class PlatformWorker {
|
|||||||
for (const ws of workspaces) {
|
for (const ws of workspaces) {
|
||||||
console.log('\n\nBACKUP WORKSPACE ', ws)
|
console.log('\n\nBACKUP WORKSPACE ', ws)
|
||||||
try {
|
try {
|
||||||
const storage = await createMinioBackupStorage(this.minio, getWorkspaceId('backups', config.ProductId), ws)
|
const storage = await createMinioBackupStorage(
|
||||||
await backup(config.TransactorURL, getWorkspaceId(ws, config.ProductId), storage)
|
this.minio,
|
||||||
|
getWorkspaceId('backups', ws.productId),
|
||||||
|
ws.workspace
|
||||||
|
)
|
||||||
|
await backup(config.TransactorURL, getWorkspaceId(ws.workspace, ws.productId), storage)
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.error('\n\nFAILED to BACKUP', ws, err)
|
console.error('\n\nFAILED to BACKUP', ws, err)
|
||||||
}
|
}
|
||||||
|
@ -377,7 +377,9 @@ export async function createAccount (
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export async function listWorkspaces (db: Db, productId: string): Promise<Workspace[]> {
|
export async function listWorkspaces (db: Db, productId: string): Promise<Workspace[]> {
|
||||||
return await db.collection<Workspace>(WORKSPACE_COLLECTION).find(withProductId(productId, {})).toArray()
|
return (await db.collection<Workspace>(WORKSPACE_COLLECTION).find(withProductId(productId, {})).toArray()).map(
|
||||||
|
(it) => ({ ...it, productId })
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -326,7 +326,8 @@ export async function restore (
|
|||||||
transactorUrl: string,
|
transactorUrl: string,
|
||||||
workspaceId: WorkspaceId,
|
workspaceId: WorkspaceId,
|
||||||
storage: BackupStorage,
|
storage: BackupStorage,
|
||||||
date: number
|
date: number,
|
||||||
|
merge?: boolean
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const infoFile = 'backup.json.gz'
|
const infoFile = 'backup.json.gz'
|
||||||
|
|
||||||
@ -357,6 +358,7 @@ export async function restore (
|
|||||||
mode: 'backup',
|
mode: 'backup',
|
||||||
model: 'upgrade'
|
model: 'upgrade'
|
||||||
})) as unknown as CoreClient & BackupClient
|
})) as unknown as CoreClient & BackupClient
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (const c of domains) {
|
for (const c of domains) {
|
||||||
console.log('loading server changeset for', c)
|
console.log('loading server changeset for', c)
|
||||||
@ -514,7 +516,7 @@ export async function restore (
|
|||||||
}
|
}
|
||||||
|
|
||||||
await sendChunk(undefined, 0)
|
await sendChunk(undefined, 0)
|
||||||
if (docsToRemove.length > 0) {
|
if (docsToRemove.length > 0 && merge !== true) {
|
||||||
console.log('cleanup', docsToRemove.length)
|
console.log('cleanup', docsToRemove.length)
|
||||||
await connection.clean(c, docsToRemove)
|
await connection.clean(c, docsToRemove)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user