Use in-cluster registry for builds and deploys; improve logging and cluster ops.
Remove external registry Ingress (repo.3fase.ir) and route Kaniko push and app pulls through the internal ClusterIP registry. Add RegistryService, ensure StorageClass and pull secrets on deploy, make Elasticsearch install/repair more resilient, and add per-cluster Deploy Elastic controls in admin UI. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import { promisify } from 'util';
|
||||
import { Application } from '../applications/entities/application.entity';
|
||||
import { AppRuntime } from '../common/enums';
|
||||
import { ClustersService } from '../clusters/clusters.service';
|
||||
import { RegistryService } from '../kubernetes/registry.service';
|
||||
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
@@ -48,6 +49,7 @@ export class BuildService {
|
||||
constructor(
|
||||
private configService: ConfigService,
|
||||
private clustersService: ClustersService,
|
||||
private registryService: RegistryService,
|
||||
) {}
|
||||
|
||||
private beginBuildSession(deploymentId: string): void {
|
||||
@@ -213,16 +215,12 @@ export class BuildService {
|
||||
* Returns { imageUri, buildLog } — the full image URI and the build logs.
|
||||
*/
|
||||
async buildImage(app: Application, deploymentId?: string): Promise<{ imageUri: string; buildLog: string }> {
|
||||
// Internal registry (used by Kaniko inside K8s for pushing)
|
||||
const internalRegistryUrl = this.configService.get<string>('registry.url') || 'registry.cloudhost-builds.svc.cluster.local:5000';
|
||||
// External registry URL (used by kubelet for pulling — NodePort or external)
|
||||
const pullRegistryUrl = this.configService.get<string>('registry.pullUrl') || 'localhost:30500';
|
||||
const buildNamespace = this.configService.get<string>('build.namespace') || 'cloudhost-builds';
|
||||
const registryUrl = this.registryService.getRegistryUrl();
|
||||
const buildNamespace = this.registryService.getBuildNamespace();
|
||||
const tag = `${Date.now()}`;
|
||||
const pushImageUri = `${internalRegistryUrl}/${app.userId}/${app.name}:${tag}`;
|
||||
const pullImageUri = `${pullRegistryUrl}/${app.userId}/${app.name}:${tag}`;
|
||||
const imageUri = this.registryService.buildImageReference(app.userId, app.name, tag);
|
||||
|
||||
this.logger.log(`Starting image build for ${app.name} → push: ${pushImageUri}, pull: ${pullImageUri}`);
|
||||
this.logger.log(`Starting image build for ${app.name} → ${imageUri}`);
|
||||
|
||||
if (deploymentId) {
|
||||
this.beginBuildSession(deploymentId);
|
||||
@@ -295,9 +293,9 @@ export class BuildService {
|
||||
const kanikoArgs = [
|
||||
'--dockerfile=/workspace/Dockerfile',
|
||||
'--context=dir:///workspace/source',
|
||||
`--destination=${pushImageUri}`,
|
||||
`--destination=${imageUri}`,
|
||||
'--cache=true',
|
||||
`--cache-repo=${internalRegistryUrl}/${app.userId}/cache`,
|
||||
`--cache-repo=${registryUrl}/${app.userId}/cache`,
|
||||
'--insecure',
|
||||
'--skip-tls-verify',
|
||||
'--single-snapshot',
|
||||
@@ -484,8 +482,8 @@ export class BuildService {
|
||||
buildLog = await this.getBuildLogs(coreApi, buildPodName, buildNamespace!);
|
||||
} catch {}
|
||||
|
||||
this.logger.log(`Build completed successfully: ${pullImageUri}`);
|
||||
return { imageUri: pullImageUri, buildLog };
|
||||
this.logger.log(`Build completed successfully: ${imageUri}`);
|
||||
return { imageUri, buildLog };
|
||||
} catch (error: any) {
|
||||
if (error instanceof BuildCancelledError || error?.name === 'BuildCancelledError') {
|
||||
throw error;
|
||||
@@ -826,18 +824,11 @@ export class BuildService {
|
||||
} catch (err: any) {
|
||||
if (err.statusCode === 404 || err.body?.code === 404) {
|
||||
this.logger.log(`Secret "${registrySecretName}" not found in "${namespace}" — creating it`);
|
||||
const registryUrl = this.configService.get<string>('registry.url') || 'registry.cloudhost-builds.svc.cluster.local:5000';
|
||||
// Create a docker config that allows insecure push (for internal registry)
|
||||
const dockerConfig = JSON.stringify({
|
||||
auths: {
|
||||
[registryUrl]: { auth: '' },
|
||||
},
|
||||
});
|
||||
await coreApi.createNamespacedSecret(namespace, {
|
||||
metadata: { name: registrySecretName, namespace },
|
||||
type: 'kubernetes.io/dockerconfigjson',
|
||||
data: {
|
||||
'.dockerconfigjson': Buffer.from(dockerConfig).toString('base64'),
|
||||
'.dockerconfigjson': Buffer.from(this.registryService.buildDockerConfigJson()).toString('base64'),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user