mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-22 03:14:40 +03:00
UBERF-8569: Backup service regions support (#7090)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
fcc6788aef
commit
492225b2bf
4
.vscode/launch.json
vendored
4
.vscode/launch.json
vendored
@ -299,8 +299,10 @@
|
|||||||
"ACCOUNTS_URL": "http://localhost:3000",
|
"ACCOUNTS_URL": "http://localhost:3000",
|
||||||
"STORAGE": "minio|localhost?accessKey=minioadmin&secretKey=minioadmin",
|
"STORAGE": "minio|localhost?accessKey=minioadmin&secretKey=minioadmin",
|
||||||
"WORKSPACE_STORAGE": "minio|localhost?accessKey=minioadmin&secretKey=minioadmin",
|
"WORKSPACE_STORAGE": "minio|localhost?accessKey=minioadmin&secretKey=minioadmin",
|
||||||
"MONGO_URL": "mongodb://localhost:27017",
|
"DB_URL": "mongodb://localhost:27017",
|
||||||
|
"MODEL_JSON": "${workspaceRoot}/models/all/bundle/model.json",
|
||||||
"SECRET": "secret",
|
"SECRET": "secret",
|
||||||
|
"REGION": "pg",
|
||||||
"BUCKET_NAME":"backups",
|
"BUCKET_NAME":"backups",
|
||||||
"INTERVAL":"30",
|
"INTERVAL":"30",
|
||||||
},
|
},
|
||||||
|
@ -816,11 +816,14 @@ export async function listWorkspaces (
|
|||||||
ctx: MeasureContext,
|
ctx: MeasureContext,
|
||||||
db: AccountDB,
|
db: AccountDB,
|
||||||
branding: Branding | null,
|
branding: Branding | null,
|
||||||
token: string
|
token: string,
|
||||||
|
region?: string | null
|
||||||
): Promise<WorkspaceInfo[]> {
|
): Promise<WorkspaceInfo[]> {
|
||||||
decodeToken(ctx, token) // Just verify token is valid
|
decodeToken(ctx, token) // Just verify token is valid
|
||||||
|
|
||||||
return (await db.workspace.find({})).filter((it) => it.disabled !== true).map(trimWorkspaceInfo)
|
return (await db.workspace.find(region != null ? { region } : {}))
|
||||||
|
.filter((it) => it.disabled !== true)
|
||||||
|
.map(trimWorkspaceInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -29,8 +29,9 @@ interface Config extends Omit<BackupConfig, 'Token'> {
|
|||||||
|
|
||||||
SkipWorkspaces: string
|
SkipWorkspaces: string
|
||||||
|
|
||||||
MongoURL: string
|
|
||||||
DbURL: string
|
DbURL: string
|
||||||
|
|
||||||
|
Region: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const envMap: { [key in keyof Config]: string } = {
|
const envMap: { [key in keyof Config]: string } = {
|
||||||
@ -41,11 +42,11 @@ const envMap: { [key in keyof Config]: string } = {
|
|||||||
Interval: 'INTERVAL',
|
Interval: 'INTERVAL',
|
||||||
CoolDown: 'COOL_DOWN',
|
CoolDown: 'COOL_DOWN',
|
||||||
Timeout: 'TIMEOUT',
|
Timeout: 'TIMEOUT',
|
||||||
MongoURL: 'MONGO_URL',
|
|
||||||
DbURL: 'DB_URL',
|
DbURL: 'DB_URL',
|
||||||
SkipWorkspaces: 'SKIP_WORKSPACES',
|
SkipWorkspaces: 'SKIP_WORKSPACES',
|
||||||
Storage: 'STORAGE',
|
Storage: 'STORAGE',
|
||||||
WorkspaceStorage: 'WORKSPACE_STORAGE'
|
WorkspaceStorage: 'WORKSPACE_STORAGE',
|
||||||
|
Region: 'REGION'
|
||||||
}
|
}
|
||||||
|
|
||||||
const required: Array<keyof Config> = [
|
const required: Array<keyof Config> = [
|
||||||
@ -53,7 +54,6 @@ const required: Array<keyof Config> = [
|
|||||||
'Secret',
|
'Secret',
|
||||||
'ServiceID',
|
'ServiceID',
|
||||||
'BucketName',
|
'BucketName',
|
||||||
'MongoURL',
|
|
||||||
'DbURL',
|
'DbURL',
|
||||||
'Storage',
|
'Storage',
|
||||||
'WorkspaceStorage'
|
'WorkspaceStorage'
|
||||||
@ -68,11 +68,11 @@ const config: Config = (() => {
|
|||||||
Interval: parseInt(process.env[envMap.Interval] ?? '3600'),
|
Interval: parseInt(process.env[envMap.Interval] ?? '3600'),
|
||||||
Timeout: parseInt(process.env[envMap.Timeout] ?? '3600'),
|
Timeout: parseInt(process.env[envMap.Timeout] ?? '3600'),
|
||||||
CoolDown: parseInt(process.env[envMap.CoolDown] ?? '300'),
|
CoolDown: parseInt(process.env[envMap.CoolDown] ?? '300'),
|
||||||
MongoURL: process.env[envMap.MongoURL],
|
|
||||||
DbURL: process.env[envMap.DbURL],
|
DbURL: process.env[envMap.DbURL],
|
||||||
SkipWorkspaces: process.env[envMap.SkipWorkspaces] ?? '',
|
SkipWorkspaces: process.env[envMap.SkipWorkspaces] ?? '',
|
||||||
WorkspaceStorage: process.env[envMap.WorkspaceStorage],
|
WorkspaceStorage: process.env[envMap.WorkspaceStorage],
|
||||||
Storage: process.env[envMap.Storage]
|
Storage: process.env[envMap.Storage],
|
||||||
|
Region: process.env[envMap.Region] ?? ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const missingEnv = required.filter((key) => params[key] === undefined).map((key) => envMap[key])
|
const missingEnv = required.filter((key) => params[key] === undefined).map((key) => envMap[key])
|
||||||
|
@ -58,7 +58,8 @@ export function startBackup (
|
|||||||
workspaceStorageAdapter,
|
workspaceStorageAdapter,
|
||||||
(ctx, workspace, branding, externalStorage) => {
|
(ctx, workspace, branding, externalStorage) => {
|
||||||
return getConfig(ctx, mainDbUrl, workspace, branding, externalStorage)
|
return getConfig(ctx, mainDbUrl, workspace, branding, externalStorage)
|
||||||
}
|
},
|
||||||
|
config.Region
|
||||||
)
|
)
|
||||||
|
|
||||||
process.on('SIGINT', shutdown)
|
process.on('SIGINT', shutdown)
|
||||||
|
@ -66,7 +66,8 @@ class BackupWorker {
|
|||||||
workspace: WorkspaceIdWithUrl,
|
workspace: WorkspaceIdWithUrl,
|
||||||
branding: Branding | null,
|
branding: Branding | null,
|
||||||
externalStorage: StorageAdapter
|
externalStorage: StorageAdapter
|
||||||
) => DbConfiguration
|
) => DbConfiguration,
|
||||||
|
readonly region: string
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
canceled = false
|
canceled = false
|
||||||
@ -113,7 +114,8 @@ class BackupWorker {
|
|||||||
const workspacesIgnore = new Set(this.config.SkipWorkspaces.split(';'))
|
const workspacesIgnore = new Set(this.config.SkipWorkspaces.split(';'))
|
||||||
ctx.info('skipped workspaces', { workspacesIgnore })
|
ctx.info('skipped workspaces', { workspacesIgnore })
|
||||||
let skipped = 0
|
let skipped = 0
|
||||||
const workspaces = (await listAccountWorkspaces(this.config.Token)).filter((it) => {
|
const allWorkspaces = await listAccountWorkspaces(this.config.Token, this.region)
|
||||||
|
const workspaces = allWorkspaces.filter((it) => {
|
||||||
const lastBackup = it.backupInfo?.lastBackup ?? 0
|
const lastBackup = it.backupInfo?.lastBackup ?? 0
|
||||||
if ((Date.now() - lastBackup) / 1000 < this.config.Interval) {
|
if ((Date.now() - lastBackup) / 1000 < this.config.Interval) {
|
||||||
// No backup required, interval not elapsed
|
// No backup required, interval not elapsed
|
||||||
@ -337,9 +339,10 @@ export function backupService (
|
|||||||
workspace: WorkspaceIdWithUrl,
|
workspace: WorkspaceIdWithUrl,
|
||||||
branding: Branding | null,
|
branding: Branding | null,
|
||||||
externalStorage: StorageAdapter
|
externalStorage: StorageAdapter
|
||||||
) => DbConfiguration
|
) => DbConfiguration,
|
||||||
|
region: string
|
||||||
): () => void {
|
): () => void {
|
||||||
const backupWorker = new BackupWorker(storage, config, pipelineFactory, workspaceStorageAdapter, getConfig)
|
const backupWorker = new BackupWorker(storage, config, pipelineFactory, workspaceStorageAdapter, getConfig, region)
|
||||||
|
|
||||||
const shutdown = (): void => {
|
const shutdown = (): void => {
|
||||||
void backupWorker.close()
|
void backupWorker.close()
|
||||||
|
@ -29,7 +29,7 @@ export interface LoginInfo {
|
|||||||
email: string
|
email: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listAccountWorkspaces (token: string): Promise<BaseWorkspaceInfo[]> {
|
export async function listAccountWorkspaces (token: string, region: string | null = null): Promise<BaseWorkspaceInfo[]> {
|
||||||
const accountsUrl = getAccoutsUrlOrFail()
|
const accountsUrl = getAccoutsUrlOrFail()
|
||||||
const workspaces = await (
|
const workspaces = await (
|
||||||
await fetch(accountsUrl, {
|
await fetch(accountsUrl, {
|
||||||
@ -39,7 +39,7 @@ export async function listAccountWorkspaces (token: string): Promise<BaseWorkspa
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
method: 'listWorkspaces',
|
method: 'listWorkspaces',
|
||||||
params: [token]
|
params: [token, region]
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
).json()
|
).json()
|
||||||
|
Loading…
Reference in New Issue
Block a user