fix(apps): always attempt K8s cleanup on delete, cluster service fixes
- Delete endpoint no longer requires clusterId && latestImageTag - Clusters: getDefault fallback logic, reassign apps on delete - Unit tests for cluster default/delete logic
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import { Injectable, NotFoundException, Logger, Inject, forwardRef } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import * as fs from 'fs';
|
||||
import { Deployment } from './entities/deployment.entity';
|
||||
import { ApplicationsService } from '../applications/applications.service';
|
||||
import { KubernetesService } from '../kubernetes/kubernetes.service';
|
||||
import { BuildService } from '../build/build.service';
|
||||
import { DeploymentStatus } from '../common/enums';
|
||||
import { SnapshotsService } from '../snapshots/snapshots.service';
|
||||
|
||||
@Injectable()
|
||||
export class DeploymentsService {
|
||||
@@ -19,22 +19,11 @@ export class DeploymentsService {
|
||||
private applicationsService: ApplicationsService,
|
||||
private kubernetesService: KubernetesService,
|
||||
private buildService: BuildService,
|
||||
@Inject(forwardRef(() => SnapshotsService))
|
||||
private snapshotsService: SnapshotsService,
|
||||
) {}
|
||||
|
||||
async triggerDeployment(applicationId: string, userId: string): Promise<Deployment> {
|
||||
const app = await this.applicationsService.findOne(applicationId, userId);
|
||||
|
||||
// Auto-snapshot before deploying (capture current state for rollback)
|
||||
try {
|
||||
const version = `v${Date.now()}`;
|
||||
await this.snapshotsService.createPreDeploySnapshot(app.id, userId, version);
|
||||
this.logger.log(`Pre-deploy snapshot created for ${app.name}`);
|
||||
} catch (e: any) {
|
||||
this.logger.warn(`Pre-deploy snapshot failed for ${app.name}: ${e.message} — continuing deploy`);
|
||||
}
|
||||
|
||||
// Create deployment record
|
||||
const deployment = this.deploymentsRepository.create({
|
||||
applicationId: app.id,
|
||||
@@ -69,6 +58,26 @@ export class DeploymentsService {
|
||||
await this.updateStatus(deploymentId, DeploymentStatus.DEPLOYING);
|
||||
const k8sResources = await this.kubernetesService.deployApplication(app, imageUri);
|
||||
|
||||
// Step 3.5: Restore DB dump if one was uploaded (must happen after deploy creates the namespace + DB)
|
||||
if (app.dbDumpPath && fs.existsSync(app.dbDumpPath)) {
|
||||
this.logger.log(`Restoring DB dump for ${app.name} from ${app.dbDumpPath}`);
|
||||
try {
|
||||
// Wait for the database pod to be Ready before restoring
|
||||
await this.kubernetesService.waitForDatabaseReady(app, 120_000);
|
||||
// Re-fetch app to ensure we have latest data
|
||||
const freshApp = await this.applicationsService.findOne(app.id);
|
||||
const result = await this.kubernetesService.restoreDatabaseDump(freshApp, freshApp.dbDumpPath!);
|
||||
if (result.success) {
|
||||
this.logger.log(`DB dump restored successfully for ${app.name}`);
|
||||
} else {
|
||||
this.logger.warn(`DB dump restore failed for ${app.name}: ${result.logs}`);
|
||||
}
|
||||
} catch (e: any) {
|
||||
this.logger.warn(`DB dump restore error for ${app.name}: ${e.message}`);
|
||||
// Don't fail the deployment — DB restore is a best-effort step
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4: Mark success
|
||||
await this.deploymentsRepository.update(deploymentId, {
|
||||
status: DeploymentStatus.RUNNING,
|
||||
@@ -185,15 +194,6 @@ export class DeploymentsService {
|
||||
throw new NotFoundException('No source code available. Upload code or set a git URL first.');
|
||||
}
|
||||
|
||||
// Auto-snapshot before redeploy
|
||||
try {
|
||||
const version = `v${Date.now()}`;
|
||||
await this.snapshotsService.createPreDeploySnapshot(app.id, userId, version);
|
||||
this.logger.log(`Pre-redeploy snapshot created for ${app.name}`);
|
||||
} catch (e: any) {
|
||||
this.logger.warn(`Pre-redeploy snapshot failed for ${app.name}: ${e.message} — continuing`);
|
||||
}
|
||||
|
||||
// Create new deployment record
|
||||
const deployment = this.deploymentsRepository.create({
|
||||
applicationId: app.id,
|
||||
|
||||
Reference in New Issue
Block a user