From 0ab734f94768be442ed8b8e24911cc6cb6b6de69 Mon Sep 17 00:00:00 2001 From: Rostislav Dugin Date: Sat, 27 Dec 2025 20:49:43 +0300 Subject: [PATCH] FEATURE (cpu): Move CPU settings to DB level from backup config level --- .../backups/backups/controller_test.go | 1 + .../usecases/mongodb/create_backup_uc.go | 7 ++ .../usecases/postgresql/create_backup_uc.go | 7 +- .../backups/config/controller_test.go | 7 +- .../internal/features/backups/config/model.go | 7 -- .../features/backups/config/service.go | 1 - .../features/backups/config/testing.go | 1 - .../features/databases/controller_test.go | 8 ++ .../databases/databases/mongodb/model.go | 5 ++ .../databases/databases/postgresql/model.go | 6 ++ .../internal/features/databases/service.go | 21 +++--- .../internal/features/databases/testing.go | 1 + .../healthcheck/attempt/controller_test.go | 1 + .../healthcheck/config/controller_test.go | 1 + .../features/restores/controller_test.go | 1 + .../usecases/mongodb/restore_backup_uc.go | 10 +++ .../usecases/postgresql/restore_backup_uc.go | 2 +- .../tests/mongodb_backup_restore_test.go | 2 + .../tests/postgresql_backup_restore_test.go | 5 ++ ...1227165710_move_cpu_count_to_databases.sql | 25 +++++++ .../src/entity/backups/model/BackupConfig.ts | 1 - .../model/mongodb/MongodbDatabase.ts | 1 + .../model/postgresql/PostgresqlDatabase.ts | 1 + .../features/backups/ui/BackupsComponent.tsx | 2 +- .../backups/ui/EditBackupConfigComponent.tsx | 45 +++-------- .../databases/ui/CreateDatabaseComponent.tsx | 6 +- .../ui/edit/EditDatabaseBaseInfoComponent.tsx | 5 +- .../edit/EditMongoDbSpecificDataComponent.tsx | 74 +++++++++++++------ .../EditPostgreSqlSpecificDataComponent.tsx | 36 ++++++++- .../show/ShowMongoDbSpecificDataComponent.tsx | 5 ++ .../users/ui/AdminPasswordComponent.tsx | 2 +- .../features/users/ui/AuthNavbarComponent.tsx | 2 +- .../src/widgets/main/MainScreenComponent.tsx | 5 +- 33 files changed, 208 insertions(+), 96 deletions(-) create mode 100644 backend/migrations/20251227165710_move_cpu_count_to_databases.sql diff --git a/backend/internal/features/backups/backups/controller_test.go b/backend/internal/features/backups/backups/controller_test.go index c378d37..fec0dd6 100644 --- a/backend/internal/features/backups/backups/controller_test.go +++ b/backend/internal/features/backups/backups/controller_test.go @@ -585,6 +585,7 @@ func createTestDatabase( Username: "postgres", Password: "postgres", Database: &testDbName, + CpuCount: 1, }, } diff --git a/backend/internal/features/backups/backups/usecases/mongodb/create_backup_uc.go b/backend/internal/features/backups/backups/usecases/mongodb/create_backup_uc.go index 02589a5..73a86fe 100644 --- a/backend/internal/features/backups/backups/usecases/mongodb/create_backup_uc.go +++ b/backend/internal/features/backups/backups/usecases/mongodb/create_backup_uc.go @@ -106,6 +106,13 @@ func (uc *CreateMongodbBackupUsecase) buildMongodumpArgs( "--gzip", } + // Use numParallelCollections based on CPU count + // Cap between 1 and 16 to balance performance and resource usage + parallelCollections := max(1, min(mdb.CpuCount, 16)) + if parallelCollections > 1 { + args = append(args, "--numParallelCollections="+fmt.Sprintf("%d", parallelCollections)) + } + return args } diff --git a/backend/internal/features/backups/backups/usecases/postgresql/create_backup_uc.go b/backend/internal/features/backups/backups/usecases/postgresql/create_backup_uc.go index 727723c..6742417 100644 --- a/backend/internal/features/backups/backups/usecases/postgresql/create_backup_uc.go +++ b/backend/internal/features/backups/backups/usecases/postgresql/create_backup_uc.go @@ -139,7 +139,7 @@ func (uc *CreatePostgresqlBackupUsecase) streamToStorage( cmd := exec.CommandContext(ctx, pgBin, args...) uc.logger.Info("Executing PostgreSQL backup command", "command", cmd.String()) - if err := uc.setupPgEnvironment(cmd, pgpassFile, db.Postgresql.IsHttps, password, backupConfig.CpuCount, pgBin); err != nil { + if err := uc.setupPgEnvironment(cmd, pgpassFile, db.Postgresql.IsHttps, password, db.Postgresql.CpuCount, pgBin); err != nil { return nil, err } @@ -335,6 +335,11 @@ func (uc *CreatePostgresqlBackupUsecase) buildPgDumpArgs(pg *pgtypes.PostgresqlD "--verbose", } + // Add parallel jobs based on CPU count + if pg.CpuCount > 1 { + args = append(args, "-j", strconv.Itoa(pg.CpuCount)) + } + for _, schema := range pg.IncludeSchemas { args = append(args, "-n", schema) } diff --git a/backend/internal/features/backups/config/controller_test.go b/backend/internal/features/backups/config/controller_test.go index 21b9d8d..277846e 100644 --- a/backend/internal/features/backups/config/controller_test.go +++ b/backend/internal/features/backups/config/controller_test.go @@ -109,7 +109,6 @@ func Test_SaveBackupConfig_PermissionsEnforced(t *testing.T) { SendNotificationsOn: []BackupNotificationType{ NotificationBackupFailed, }, - CpuCount: 2, IsRetryIfFailed: true, MaxFailedTriesCount: 3, } @@ -129,7 +128,6 @@ func Test_SaveBackupConfig_PermissionsEnforced(t *testing.T) { assert.Equal(t, database.ID, response.DatabaseID) assert.True(t, response.IsBackupsEnabled) assert.Equal(t, period.PeriodWeek, response.StorePeriod) - assert.Equal(t, 2, response.CpuCount) } else { assert.Contains(t, string(testResp.Body), "insufficient permissions") } @@ -158,7 +156,6 @@ func Test_SaveBackupConfig_WhenUserIsNotWorkspaceMember_ReturnsForbidden(t *test SendNotificationsOn: []BackupNotificationType{ NotificationBackupFailed, }, - CpuCount: 2, IsRetryIfFailed: true, MaxFailedTriesCount: 3, } @@ -290,7 +287,6 @@ func Test_GetBackupConfigByDbID_ReturnsDefaultConfigForNewDatabase(t *testing.T) assert.Equal(t, database.ID, response.DatabaseID) assert.False(t, response.IsBackupsEnabled) assert.Equal(t, period.PeriodWeek, response.StorePeriod) - assert.Equal(t, 1, response.CpuCount) assert.True(t, response.IsRetryIfFailed) assert.Equal(t, 3, response.MaxFailedTriesCount) assert.NotNil(t, response.BackupInterval) @@ -387,7 +383,6 @@ func Test_SaveBackupConfig_WithEncryptionNone_ConfigSaved(t *testing.T) { SendNotificationsOn: []BackupNotificationType{ NotificationBackupFailed, }, - CpuCount: 2, IsRetryIfFailed: true, MaxFailedTriesCount: 3, Encryption: BackupEncryptionNone, @@ -427,7 +422,6 @@ func Test_SaveBackupConfig_WithEncryptionEncrypted_ConfigSaved(t *testing.T) { SendNotificationsOn: []BackupNotificationType{ NotificationBackupFailed, }, - CpuCount: 2, IsRetryIfFailed: true, MaxFailedTriesCount: 3, Encryption: BackupEncryptionEncrypted, @@ -466,6 +460,7 @@ func createTestDatabaseViaAPI( Username: "postgres", Password: "postgres", Database: &testDbName, + CpuCount: 1, }, } diff --git a/backend/internal/features/backups/config/model.go b/backend/internal/features/backups/config/model.go index fadc7cd..82b425c 100644 --- a/backend/internal/features/backups/config/model.go +++ b/backend/internal/features/backups/config/model.go @@ -30,8 +30,6 @@ type BackupConfig struct { IsRetryIfFailed bool `json:"isRetryIfFailed" gorm:"column:is_retry_if_failed;type:boolean;not null"` MaxFailedTriesCount int `json:"maxFailedTriesCount" gorm:"column:max_failed_tries_count;type:int;not null"` - CpuCount int `json:"cpuCount" gorm:"type:int;not null"` - Encryption BackupEncryption `json:"encryption" gorm:"column:encryption;type:text;not null;default:'NONE'"` } @@ -82,10 +80,6 @@ func (b *BackupConfig) Validate() error { return errors.New("store period is required") } - if b.CpuCount == 0 { - return errors.New("cpu count is required") - } - if b.IsRetryIfFailed && b.MaxFailedTriesCount <= 0 { return errors.New("max failed tries count must be greater than 0") } @@ -109,7 +103,6 @@ func (b *BackupConfig) Copy(newDatabaseID uuid.UUID) *BackupConfig { SendNotificationsOn: b.SendNotificationsOn, IsRetryIfFailed: b.IsRetryIfFailed, MaxFailedTriesCount: b.MaxFailedTriesCount, - CpuCount: b.CpuCount, Encryption: b.Encryption, } } diff --git a/backend/internal/features/backups/config/service.go b/backend/internal/features/backups/config/service.go index 78dc2ae..4cfda9d 100644 --- a/backend/internal/features/backups/config/service.go +++ b/backend/internal/features/backups/config/service.go @@ -168,7 +168,6 @@ func (s *BackupConfigService) initializeDefaultConfig( NotificationBackupFailed, NotificationBackupSuccess, }, - CpuCount: 1, IsRetryIfFailed: true, MaxFailedTriesCount: 3, Encryption: BackupEncryptionNone, diff --git a/backend/internal/features/backups/config/testing.go b/backend/internal/features/backups/config/testing.go index 2df6dc6..883d87e 100644 --- a/backend/internal/features/backups/config/testing.go +++ b/backend/internal/features/backups/config/testing.go @@ -28,7 +28,6 @@ func EnableBackupsForTestDatabase( NotificationBackupFailed, NotificationBackupSuccess, }, - CpuCount: 1, } backupConfig, err := GetBackupConfigService().SaveBackupConfig(backupConfig) diff --git a/backend/internal/features/databases/controller_test.go b/backend/internal/features/databases/controller_test.go index faac649..a43de9c 100644 --- a/backend/internal/features/databases/controller_test.go +++ b/backend/internal/features/databases/controller_test.go @@ -100,6 +100,7 @@ func Test_CreateDatabase_PermissionsEnforced(t *testing.T) { Username: "postgres", Password: "postgres", Database: &testDbName, + CpuCount: 1, }, } @@ -143,6 +144,7 @@ func Test_CreateDatabase_WhenUserIsNotWorkspaceMember_ReturnsForbidden(t *testin Username: "postgres", Password: "postgres", Database: &testDbName, + CpuCount: 1, }, } @@ -747,6 +749,7 @@ func createTestDatabaseViaAPI( Username: "postgres", Password: "postgres", Database: &testDbName, + CpuCount: 1, }, } @@ -790,6 +793,7 @@ func Test_CreateDatabase_PasswordIsEncryptedInDB(t *testing.T) { Username: "postgres", Password: plainPassword, Database: &testDbName, + CpuCount: 1, }, } @@ -862,6 +866,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) { Username: "postgres", Password: "original-password-secret", Database: &testDbName, + CpuCount: 1, }, } }, @@ -879,6 +884,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) { Username: "updated_user", Password: "", Database: &testDbName, + CpuCount: 1, }, } }, @@ -961,6 +967,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) { Database: "test_db", AuthDatabase: "admin", IsHttps: false, + CpuCount: 1, }, } }, @@ -979,6 +986,7 @@ func Test_DatabaseSensitiveDataLifecycle_AllTypes(t *testing.T) { Database: "updated_test_db", AuthDatabase: "admin", IsHttps: false, + CpuCount: 1, }, } }, diff --git a/backend/internal/features/databases/databases/mongodb/model.go b/backend/internal/features/databases/databases/mongodb/model.go index 521faaf..4aeedfd 100644 --- a/backend/internal/features/databases/databases/mongodb/model.go +++ b/backend/internal/features/databases/databases/mongodb/model.go @@ -30,6 +30,7 @@ type MongodbDatabase struct { Database string `json:"database" gorm:"type:text;not null"` AuthDatabase string `json:"authDatabase" gorm:"type:text;not null;default:'admin'"` IsHttps bool `json:"isHttps" gorm:"type:boolean;default:false"` + CpuCount int `json:"cpuCount" gorm:"column:cpu_count;type:int;not null;default:1"` } func (m *MongodbDatabase) TableName() string { @@ -52,6 +53,9 @@ func (m *MongodbDatabase) Validate() error { if m.Database == "" { return errors.New("database is required") } + if m.CpuCount <= 0 { + return errors.New("cpu count must be greater than 0") + } return nil } @@ -109,6 +113,7 @@ func (m *MongodbDatabase) Update(incoming *MongodbDatabase) { m.Database = incoming.Database m.AuthDatabase = incoming.AuthDatabase m.IsHttps = incoming.IsHttps + m.CpuCount = incoming.CpuCount if incoming.Password != "" { m.Password = incoming.Password diff --git a/backend/internal/features/databases/databases/postgresql/model.go b/backend/internal/features/databases/databases/postgresql/model.go index fe30435..9eb9236 100644 --- a/backend/internal/features/databases/databases/postgresql/model.go +++ b/backend/internal/features/databases/databases/postgresql/model.go @@ -34,6 +34,7 @@ type PostgresqlDatabase struct { // backup settings IncludeSchemas []string `json:"includeSchemas" gorm:"-"` IncludeSchemasString string `json:"-" gorm:"column:include_schemas;type:text;not null;default:''"` + CpuCount int `json:"cpuCount" gorm:"column:cpu_count;type:int;not null;default:1"` // restore settings (not saved to DB) IsExcludeExtensions bool `json:"isExcludeExtensions" gorm:"-"` @@ -80,6 +81,10 @@ func (p *PostgresqlDatabase) Validate() error { return errors.New("password is required") } + if p.CpuCount <= 0 { + return errors.New("cpu count must be greater than 0") + } + return nil } @@ -110,6 +115,7 @@ func (p *PostgresqlDatabase) Update(incoming *PostgresqlDatabase) { p.Database = incoming.Database p.IsHttps = incoming.IsHttps p.IncludeSchemas = incoming.IncludeSchemas + p.CpuCount = incoming.CpuCount if incoming.Password != "" { p.Password = incoming.Password diff --git a/backend/internal/features/databases/service.go b/backend/internal/features/databases/service.go index 15195a0..3fa754a 100644 --- a/backend/internal/features/databases/service.go +++ b/backend/internal/features/databases/service.go @@ -396,15 +396,17 @@ func (s *DatabaseService) CopyDatabase( case DatabaseTypePostgres: if existingDatabase.Postgresql != nil { newDatabase.Postgresql = &postgresql.PostgresqlDatabase{ - ID: uuid.Nil, - DatabaseID: nil, - Version: existingDatabase.Postgresql.Version, - Host: existingDatabase.Postgresql.Host, - Port: existingDatabase.Postgresql.Port, - Username: existingDatabase.Postgresql.Username, - Password: existingDatabase.Postgresql.Password, - Database: existingDatabase.Postgresql.Database, - IsHttps: existingDatabase.Postgresql.IsHttps, + ID: uuid.Nil, + DatabaseID: nil, + Version: existingDatabase.Postgresql.Version, + Host: existingDatabase.Postgresql.Host, + Port: existingDatabase.Postgresql.Port, + Username: existingDatabase.Postgresql.Username, + Password: existingDatabase.Postgresql.Password, + Database: existingDatabase.Postgresql.Database, + IsHttps: existingDatabase.Postgresql.IsHttps, + IncludeSchemas: existingDatabase.Postgresql.IncludeSchemas, + CpuCount: existingDatabase.Postgresql.CpuCount, } } case DatabaseTypeMysql: @@ -448,6 +450,7 @@ func (s *DatabaseService) CopyDatabase( Database: existingDatabase.Mongodb.Database, AuthDatabase: existingDatabase.Mongodb.AuthDatabase, IsHttps: existingDatabase.Mongodb.IsHttps, + CpuCount: existingDatabase.Mongodb.CpuCount, } } } diff --git a/backend/internal/features/databases/testing.go b/backend/internal/features/databases/testing.go index d1b5c72..ee523bf 100644 --- a/backend/internal/features/databases/testing.go +++ b/backend/internal/features/databases/testing.go @@ -25,6 +25,7 @@ func CreateTestDatabase( Port: 5432, Username: "postgres", Password: "postgres", + CpuCount: 1, }, Notifiers: []notifiers.Notifier{ diff --git a/backend/internal/features/healthcheck/attempt/controller_test.go b/backend/internal/features/healthcheck/attempt/controller_test.go index ef8fbbf..393bb0c 100644 --- a/backend/internal/features/healthcheck/attempt/controller_test.go +++ b/backend/internal/features/healthcheck/attempt/controller_test.go @@ -217,6 +217,7 @@ func createTestDatabaseViaAPI( Username: "postgres", Password: "postgres", Database: &testDbName, + CpuCount: 1, }, } diff --git a/backend/internal/features/healthcheck/config/controller_test.go b/backend/internal/features/healthcheck/config/controller_test.go index 6312f29..b9be184 100644 --- a/backend/internal/features/healthcheck/config/controller_test.go +++ b/backend/internal/features/healthcheck/config/controller_test.go @@ -305,6 +305,7 @@ func createTestDatabaseViaAPI( Username: "postgres", Password: "postgres", Database: &testDbName, + CpuCount: 1, }, } diff --git a/backend/internal/features/restores/controller_test.go b/backend/internal/features/restores/controller_test.go index 928fd4f..693fea0 100644 --- a/backend/internal/features/restores/controller_test.go +++ b/backend/internal/features/restores/controller_test.go @@ -295,6 +295,7 @@ func createTestDatabase( Username: "postgres", Password: "postgres", Database: &testDbName, + CpuCount: 1, }, } diff --git a/backend/internal/features/restores/usecases/mongodb/restore_backup_uc.go b/backend/internal/features/restores/usecases/mongodb/restore_backup_uc.go index cbd15f4..451abda 100644 --- a/backend/internal/features/restores/usecases/mongodb/restore_backup_uc.go +++ b/backend/internal/features/restores/usecases/mongodb/restore_backup_uc.go @@ -111,6 +111,16 @@ func (uc *RestoreMongodbBackupUsecase) buildMongorestoreArgs( args = append(args, "--nsInclude="+mdb.Database+".*") } + // Use numInsertionWorkersPerCollection based on CPU count + // Cap between 1 and 16 to balance performance and resource usage + parallelWorkers := max(1, min(mdb.CpuCount, 16)) + if parallelWorkers > 1 { + args = append( + args, + "--numInsertionWorkersPerCollection="+fmt.Sprintf("%d", parallelWorkers), + ) + } + return args } diff --git a/backend/internal/features/restores/usecases/postgresql/restore_backup_uc.go b/backend/internal/features/restores/usecases/postgresql/restore_backup_uc.go index 0182a7d..0ff81e2 100644 --- a/backend/internal/features/restores/usecases/postgresql/restore_backup_uc.go +++ b/backend/internal/features/restores/usecases/postgresql/restore_backup_uc.go @@ -67,7 +67,7 @@ func (uc *RestorePostgresqlBackupUsecase) Execute( // Use parallel jobs based on CPU count (same as backup) // Cap between 1 and 8 to avoid overwhelming the server - parallelJobs := max(1, min(backupConfig.CpuCount, 8)) + parallelJobs := max(1, min(restoringToDB.Postgresql.CpuCount, 8)) args := []string{ "-Fc", // expect custom format (same as backup) diff --git a/backend/internal/features/tests/mongodb_backup_restore_test.go b/backend/internal/features/tests/mongodb_backup_restore_test.go index c2e11b5..13f382d 100644 --- a/backend/internal/features/tests/mongodb_backup_restore_test.go +++ b/backend/internal/features/tests/mongodb_backup_restore_test.go @@ -394,6 +394,7 @@ func createMongodbDatabaseViaAPI( AuthDatabase: authDatabase, Version: version, IsHttps: false, + CpuCount: 1, }, } @@ -440,6 +441,7 @@ func createMongodbRestoreViaAPI( AuthDatabase: authDatabase, Version: version, IsHttps: false, + CpuCount: 1, }, } diff --git a/backend/internal/features/tests/postgresql_backup_restore_test.go b/backend/internal/features/tests/postgresql_backup_restore_test.go index 1c89e4c..ada311a 100644 --- a/backend/internal/features/tests/postgresql_backup_restore_test.go +++ b/backend/internal/features/tests/postgresql_backup_restore_test.go @@ -1269,6 +1269,7 @@ func createDatabaseViaAPI( Username: username, Password: password, Database: &database, + CpuCount: 1, }, } @@ -1387,6 +1388,7 @@ func createRestoreWithOptionsViaAPI( Password: password, Database: &database, IsExcludeExtensions: isExcludeExtensions, + CpuCount: 1, }, } @@ -1424,6 +1426,7 @@ func createDatabaseWithSchemasViaAPI( Password: password, Database: &database, IncludeSchemas: includeSchemas, + CpuCount: 1, }, } @@ -1476,6 +1479,7 @@ func createSupabaseDatabaseViaAPI( Database: &database, IsHttps: true, IncludeSchemas: includeSchemas, + CpuCount: 1, }, } @@ -1522,6 +1526,7 @@ func createSupabaseRestoreViaAPI( Password: password, Database: &database, IsHttps: true, + CpuCount: 1, }, } diff --git a/backend/migrations/20251227165710_move_cpu_count_to_databases.sql b/backend/migrations/20251227165710_move_cpu_count_to_databases.sql new file mode 100644 index 0000000..84e7a8a --- /dev/null +++ b/backend/migrations/20251227165710_move_cpu_count_to_databases.sql @@ -0,0 +1,25 @@ +-- +goose Up +-- +goose StatementBegin +ALTER TABLE backup_configs DROP COLUMN cpu_count; +-- +goose StatementEnd + +-- +goose StatementBegin +ALTER TABLE postgresql_databases ADD COLUMN cpu_count INT NOT NULL DEFAULT 1; +-- +goose StatementEnd + +-- +goose StatementBegin +ALTER TABLE mongodb_databases ADD COLUMN cpu_count INT NOT NULL DEFAULT 1; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +ALTER TABLE backup_configs ADD COLUMN cpu_count INT NOT NULL DEFAULT 1; +-- +goose StatementEnd + +-- +goose StatementBegin +ALTER TABLE postgresql_databases DROP COLUMN cpu_count; +-- +goose StatementEnd + +-- +goose StatementBegin +ALTER TABLE mongodb_databases DROP COLUMN cpu_count; +-- +goose StatementEnd diff --git a/frontend/src/entity/backups/model/BackupConfig.ts b/frontend/src/entity/backups/model/BackupConfig.ts index d6ff84b..77fb00e 100644 --- a/frontend/src/entity/backups/model/BackupConfig.ts +++ b/frontend/src/entity/backups/model/BackupConfig.ts @@ -12,7 +12,6 @@ export interface BackupConfig { backupInterval?: Interval; storage?: Storage; sendNotificationsOn: BackupNotificationType[]; - cpuCount: number; isRetryIfFailed: boolean; maxFailedTriesCount: number; encryption: BackupEncryption; diff --git a/frontend/src/entity/databases/model/mongodb/MongodbDatabase.ts b/frontend/src/entity/databases/model/mongodb/MongodbDatabase.ts index 9417d75..ddc1f25 100644 --- a/frontend/src/entity/databases/model/mongodb/MongodbDatabase.ts +++ b/frontend/src/entity/databases/model/mongodb/MongodbDatabase.ts @@ -10,4 +10,5 @@ export interface MongodbDatabase { database: string; authDatabase: string; useTls: boolean; + cpuCount: number; } diff --git a/frontend/src/entity/databases/model/postgresql/PostgresqlDatabase.ts b/frontend/src/entity/databases/model/postgresql/PostgresqlDatabase.ts index 6f14fbc..990fe5b 100644 --- a/frontend/src/entity/databases/model/postgresql/PostgresqlDatabase.ts +++ b/frontend/src/entity/databases/model/postgresql/PostgresqlDatabase.ts @@ -14,6 +14,7 @@ export interface PostgresqlDatabase { // backup settings includeSchemas?: string[]; + cpuCount: number; // restore settings (not saved to DB) isExcludeExtensions?: boolean; diff --git a/frontend/src/features/backups/ui/BackupsComponent.tsx b/frontend/src/features/backups/ui/BackupsComponent.tsx index b3708db..1f824e6 100644 --- a/frontend/src/features/backups/ui/BackupsComponent.tsx +++ b/frontend/src/features/backups/ui/BackupsComponent.tsx @@ -541,7 +541,7 @@ export const BackupsComponent = ({ database, isCanManageDBs, scrollContainerRef

Backups

{!isBackupConfigLoading && !backupConfig?.isBackupsEnabled && ( -
+
Scheduled backups are disabled (you can enable it back in the backup configuration)
)} diff --git a/frontend/src/features/backups/ui/EditBackupConfigComponent.tsx b/frontend/src/features/backups/ui/EditBackupConfigComponent.tsx index 4598862..23db3ac 100644 --- a/frontend/src/features/backups/ui/EditBackupConfigComponent.tsx +++ b/frontend/src/features/backups/ui/EditBackupConfigComponent.tsx @@ -154,7 +154,6 @@ export const EditBackupConfigComponent = ({ timeOfDay: '00:00', }, storage: undefined, - cpuCount: 1, storePeriod: Period.THREE_MONTH, sendNotificationsOn: [], isRetryIfFailed: true, @@ -201,7 +200,6 @@ export const EditBackupConfigComponent = ({ !backupConfig.isBackupsEnabled || (Boolean(backupConfig.storePeriod) && Boolean(backupConfig.storage?.id) && - Boolean(backupConfig.cpuCount) && Boolean(backupConfig.encryption) && Boolean(backupInterval?.interval) && (!backupInterval || @@ -211,16 +209,18 @@ export const EditBackupConfigComponent = ({ return (
-
-
Backups enabled
- { - updateBackupConfig({ isBackupsEnabled: checked }); - }} - size="small" - /> -
+ {database.id && ( +
+
Backups enabled
+ { + updateBackupConfig({ isBackupsEnabled: checked }); + }} + size="small" + /> +
+ )} {backupConfig.isBackupsEnabled && ( <> @@ -404,27 +404,6 @@ export const EditBackupConfigComponent = ({
)} -
-
CPU count
-
- updateBackupConfig({ cpuCount: value || 1 })} - size="small" - className="w-full max-w-[200px] grow" - /> - - - - -
-
-
Store period
diff --git a/frontend/src/features/databases/ui/CreateDatabaseComponent.tsx b/frontend/src/features/databases/ui/CreateDatabaseComponent.tsx index 28fc18c..b6835aa 100644 --- a/frontend/src/features/databases/ui/CreateDatabaseComponent.tsx +++ b/frontend/src/features/databases/ui/CreateDatabaseComponent.tsx @@ -31,8 +31,6 @@ const createInitialDatabase = (workspaceId: string): Database => workspaceId, storePeriod: Period.MONTH, - postgresql: {} as PostgresqlDatabase, - type: DatabaseType.POSTGRES, storage: {} as unknown as Storage, @@ -52,13 +50,13 @@ const initializeDatabaseTypeData = (db: Database): Database => { switch (db.type) { case DatabaseType.POSTGRES: - return { ...base, postgresql: db.postgresql ?? ({} as PostgresqlDatabase) }; + return { ...base, postgresql: db.postgresql ?? ({ cpuCount: 1 } as PostgresqlDatabase) }; case DatabaseType.MYSQL: return { ...base, mysql: db.mysql ?? ({} as MysqlDatabase) }; case DatabaseType.MARIADB: return { ...base, mariadb: db.mariadb ?? ({} as MariadbDatabase) }; case DatabaseType.MONGODB: - return { ...base, mongodb: db.mongodb ?? ({} as MongodbDatabase) }; + return { ...base, mongodb: db.mongodb ?? ({ cpuCount: 1 } as MongodbDatabase) }; default: return db; } diff --git a/frontend/src/features/databases/ui/edit/EditDatabaseBaseInfoComponent.tsx b/frontend/src/features/databases/ui/edit/EditDatabaseBaseInfoComponent.tsx index 09f4e99..1fb3fb8 100644 --- a/frontend/src/features/databases/ui/edit/EditDatabaseBaseInfoComponent.tsx +++ b/frontend/src/features/databases/ui/edit/EditDatabaseBaseInfoComponent.tsx @@ -65,7 +65,8 @@ export const EditDatabaseBaseInfoComponent = ({ switch (newType) { case DatabaseType.POSTGRES: - updatedDatabase.postgresql = editingDatabase.postgresql ?? ({} as PostgresqlDatabase); + updatedDatabase.postgresql = + editingDatabase.postgresql ?? ({ cpuCount: 1 } as PostgresqlDatabase); break; case DatabaseType.MYSQL: updatedDatabase.mysql = editingDatabase.mysql ?? ({} as MysqlDatabase); @@ -74,7 +75,7 @@ export const EditDatabaseBaseInfoComponent = ({ updatedDatabase.mariadb = editingDatabase.mariadb ?? ({} as MariadbDatabase); break; case DatabaseType.MONGODB: - updatedDatabase.mongodb = editingDatabase.mongodb ?? ({} as MongodbDatabase); + updatedDatabase.mongodb = editingDatabase.mongodb ?? ({ cpuCount: 1 } as MongodbDatabase); break; } diff --git a/frontend/src/features/databases/ui/edit/EditMongoDbSpecificDataComponent.tsx b/frontend/src/features/databases/ui/edit/EditMongoDbSpecificDataComponent.tsx index c9a423e..b7b216d 100644 --- a/frontend/src/features/databases/ui/edit/EditMongoDbSpecificDataComponent.tsx +++ b/frontend/src/features/databases/ui/edit/EditMongoDbSpecificDataComponent.tsx @@ -1,5 +1,5 @@ -import { CopyOutlined, DownOutlined, UpOutlined } from '@ant-design/icons'; -import { App, Button, Input, InputNumber, Switch } from 'antd'; +import { CopyOutlined, DownOutlined, InfoCircleOutlined, UpOutlined } from '@ant-design/icons'; +import { App, Button, Input, InputNumber, Switch, Tooltip } from 'antd'; import { useEffect, useState } from 'react'; import { type Database, databaseApi } from '../../../../entity/databases'; @@ -78,6 +78,7 @@ export const EditMongoDbSpecificDataComponent = ({ database: result.database, authDatabase: result.authDatabase, useTls: result.useTls, + cpuCount: 1, }, }; @@ -285,7 +286,7 @@ export const EditMongoDbSpecificDataComponent = ({
)} -
+
Use TLS
-
+
+
CPU count
+
+ { + if (!editingDatabase.mongodb) return; + + setEditingDatabase({ + ...editingDatabase, + mongodb: { ...editingDatabase.mongodb, cpuCount: value || 1 }, + }); + setIsConnectionTested(false); + }} + size="small" + className="max-w-[200px] grow" + /> + + + + +
+
+ +
setShowAdvanced(!isShowAdvanced)} @@ -318,24 +348,26 @@ export const EditMongoDbSpecificDataComponent = ({
{isShowAdvanced && ( -
-
Auth database
- { - if (!editingDatabase.mongodb) return; + <> +
+
Auth database
+ { + if (!editingDatabase.mongodb) return; - setEditingDatabase({ - ...editingDatabase, - mongodb: { ...editingDatabase.mongodb, authDatabase: e.target.value.trim() }, - }); - setIsConnectionTested(false); - }} - size="small" - className="max-w-[200px] grow" - placeholder="admin" - /> -
+ setEditingDatabase({ + ...editingDatabase, + mongodb: { ...editingDatabase.mongodb, authDatabase: e.target.value.trim() }, + }); + setIsConnectionTested(false); + }} + size="small" + className="max-w-[200px] grow" + placeholder="admin" + /> +
+ )}
diff --git a/frontend/src/features/databases/ui/edit/EditPostgreSqlSpecificDataComponent.tsx b/frontend/src/features/databases/ui/edit/EditPostgreSqlSpecificDataComponent.tsx index 4d72864..81183cb 100644 --- a/frontend/src/features/databases/ui/edit/EditPostgreSqlSpecificDataComponent.tsx +++ b/frontend/src/features/databases/ui/edit/EditPostgreSqlSpecificDataComponent.tsx @@ -82,6 +82,7 @@ export const EditPostgreSqlSpecificDataComponent = ({ password: result.password, database: result.database, isHttps: result.isHttps, + cpuCount: 1, }, }; @@ -338,7 +339,7 @@ export const EditPostgreSqlSpecificDataComponent = ({
)} -
+
Use HTTPS
-
+ {isRestoreMode && ( +
+
CPU count
+
+ { + if (!editingDatabase.postgresql) return; + + setEditingDatabase({ + ...editingDatabase, + postgresql: { ...editingDatabase.postgresql, cpuCount: value || 1 }, + }); + setIsConnectionTested(false); + }} + size="small" + className="max-w-[75px] grow" + /> + + + + +
+
+ )} + +
setShowAdvanced(!isShowAdvanced)} diff --git a/frontend/src/features/databases/ui/show/ShowMongoDbSpecificDataComponent.tsx b/frontend/src/features/databases/ui/show/ShowMongoDbSpecificDataComponent.tsx index 09ff395..2fc6d88 100644 --- a/frontend/src/features/databases/ui/show/ShowMongoDbSpecificDataComponent.tsx +++ b/frontend/src/features/databases/ui/show/ShowMongoDbSpecificDataComponent.tsx @@ -43,6 +43,11 @@ export const ShowMongoDbSpecificDataComponent = ({ database }: Props) => {
{database.mongodb.authDatabase}
)} + +
+
CPU count
+
{database.mongodb?.cpuCount || 1}
+
); }; diff --git a/frontend/src/features/users/ui/AdminPasswordComponent.tsx b/frontend/src/features/users/ui/AdminPasswordComponent.tsx index 859b5e1..cf364f1 100644 --- a/frontend/src/features/users/ui/AdminPasswordComponent.tsx +++ b/frontend/src/features/users/ui/AdminPasswordComponent.tsx @@ -130,7 +130,7 @@ export function AdminPasswordComponent({ }} type="primary" > - Set Password + Set password {adminPasswordError && ( diff --git a/frontend/src/features/users/ui/AuthNavbarComponent.tsx b/frontend/src/features/users/ui/AuthNavbarComponent.tsx index 6af603e..dff9ec7 100644 --- a/frontend/src/features/users/ui/AuthNavbarComponent.tsx +++ b/frontend/src/features/users/ui/AuthNavbarComponent.tsx @@ -7,7 +7,7 @@ export function AuthNavbarComponent() {
- +
diff --git a/frontend/src/widgets/main/MainScreenComponent.tsx b/frontend/src/widgets/main/MainScreenComponent.tsx index 8825b3a..c81e85a 100644 --- a/frontend/src/widgets/main/MainScreenComponent.tsx +++ b/frontend/src/widgets/main/MainScreenComponent.tsx @@ -193,10 +193,7 @@ export const MainScreenComponent = () => {