Fix Kaniko registry auth and push target for Harbor builds.
Mount docker config as config.json (Kaniko requirement), push via harbor-registry internal URL, and wire harbor_registry_user credentials in Helm/GitOps values. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -125,6 +125,15 @@ spec:
|
||||
name: {{ include "cloudhost-platform.secretName" . }}
|
||||
key: mizbansms-password
|
||||
{{- end }}
|
||||
{{- if .Values.registry.credentialsSecret }}
|
||||
- name: REGISTRY_USERNAME
|
||||
value: {{ .Values.registry.username | default "harbor_registry_user" | quote }}
|
||||
- name: REGISTRY_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.registry.credentialsSecret | quote }}
|
||||
key: {{ .Values.registry.credentialsPasswordKey | default "REGISTRY_CREDENTIAL_PASSWORD" | quote }}
|
||||
{{- end }}
|
||||
{{- include "cloudhost-platform.buildEnv" . | nindent 12 }}
|
||||
{{- range $key, $val := .Values.backend.env }}
|
||||
- name: {{ $key }}
|
||||
|
||||
@@ -28,6 +28,12 @@ images:
|
||||
tag: "1.0.0"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Kaniko push credentials — harbor_registry_user for harbor-registry:5000 (Harbor production).
|
||||
registry:
|
||||
credentialsSecret: ""
|
||||
credentialsPasswordKey: REGISTRY_CREDENTIAL_PASSWORD
|
||||
username: harbor_registry_user
|
||||
|
||||
# Kaniko job images — defaults pull from Harbor proxy-cache.
|
||||
# Override any line for a different registry/tag.
|
||||
build:
|
||||
|
||||
@@ -434,10 +434,10 @@ 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 }> {
|
||||
const registryUrl = this.registryService.getRegistryUrl();
|
||||
const registryPushUrl = this.registryService.getRegistryPushUrl();
|
||||
const buildNamespace = this.registryService.getBuildNamespace();
|
||||
const tag = `${Date.now()}`;
|
||||
const imageUri = this.registryService.buildImageReference(app.userId, app.name, tag);
|
||||
const imageUri = this.registryService.buildPushImageReference(app.userId, app.name, tag);
|
||||
|
||||
this.logger.log(`Starting image build for ${app.name} → ${imageUri}`);
|
||||
|
||||
@@ -534,7 +534,7 @@ export class BuildService {
|
||||
'--context=dir:///workspace/source',
|
||||
`--destination=${imageUri}`,
|
||||
'--cache=true',
|
||||
`--cache-repo=${registryUrl}/${app.userId}/cache`,
|
||||
`--cache-repo=${registryPushUrl}/${app.userId}/cache`,
|
||||
'--insecure',
|
||||
'--skip-tls-verify',
|
||||
'--single-snapshot',
|
||||
@@ -544,7 +544,10 @@ export class BuildService {
|
||||
const volumes: any[] = [
|
||||
{
|
||||
name: 'docker-config',
|
||||
secret: { secretName: 'registry-credentials' },
|
||||
secret: {
|
||||
secretName: 'registry-credentials',
|
||||
items: [{ key: '.dockerconfigjson', path: 'config.json' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'dockerfile',
|
||||
|
||||
@@ -35,13 +35,20 @@ export class RegistryService {
|
||||
return slash === -1 ? url : url.slice(0, slash);
|
||||
}
|
||||
|
||||
/** Push target host:port (may differ from pull URL on Harbor setups). */
|
||||
getRegistryPushHost(): string {
|
||||
/** Push target host[:port][/project] — Kaniko destination (may differ from pull URL on Harbor). */
|
||||
getRegistryPushUrl(): string {
|
||||
const buildNs = this.getBuildNamespace();
|
||||
const url = this.configService.get<string>('registry.url') || `registry.${buildNs}.svc.cluster.local:5000`;
|
||||
const normalized = url.replace(/^https?:\/\//, '');
|
||||
const slash = normalized.indexOf('/');
|
||||
return slash === -1 ? normalized : normalized.slice(0, slash);
|
||||
const url =
|
||||
this.configService.get<string>('registry.url') ||
|
||||
`registry.${buildNs}.svc.cluster.local:5000`;
|
||||
return url.replace(/^https?:\/\//, '');
|
||||
}
|
||||
|
||||
/** Push target host:port only, no repository path prefix. */
|
||||
getRegistryPushHost(): string {
|
||||
const url = this.getRegistryPushUrl();
|
||||
const slash = url.indexOf('/');
|
||||
return slash === -1 ? url : url.slice(0, slash);
|
||||
}
|
||||
|
||||
getRegistryCredentials(): { username: string; password: string } {
|
||||
@@ -55,6 +62,11 @@ export class RegistryService {
|
||||
return `${this.getRegistryUrl()}/${userId}/${appName}:${tag}`;
|
||||
}
|
||||
|
||||
/** Kaniko push target — uses registry.url (in-cluster harbor-registry on Harbor setups). */
|
||||
buildPushImageReference(userId: string, appName: string, tag: string): string {
|
||||
return `${this.getRegistryPushUrl()}/${userId}/${appName}:${tag}`;
|
||||
}
|
||||
|
||||
parseImageReference(imageRef: string): ParsedImageReference {
|
||||
const normalized = imageRef.replace(/^https?:\/\//, '');
|
||||
const slashIdx = normalized.indexOf('/');
|
||||
@@ -72,10 +84,20 @@ export class RegistryService {
|
||||
};
|
||||
}
|
||||
|
||||
/** Re-point any stored image (e.g. legacy external host) to the in-cluster registry. */
|
||||
/** Re-point any stored image (e.g. push host) to the pull registry URL for kubelet. */
|
||||
normalizeImageReference(imageRef: string): string {
|
||||
const { repository, tag } = this.parseImageReference(imageRef);
|
||||
return `${this.getRegistryUrl()}/${repository}:${tag}`;
|
||||
const pullBase = this.getRegistryUrl().replace(/\/$/, '');
|
||||
const slash = pullBase.indexOf('/');
|
||||
const pullPath = slash === -1 ? '' : pullBase.slice(slash + 1);
|
||||
let repo = repository;
|
||||
if (pullPath && (repo === pullPath || repo.startsWith(`${pullPath}/`))) {
|
||||
repo = repo === pullPath ? '' : repo.slice(pullPath.length + 1);
|
||||
}
|
||||
if (!repo) {
|
||||
throw new Error(`Invalid image reference after normalization: ${imageRef}`);
|
||||
}
|
||||
return `${pullBase}/${repo}:${tag}`;
|
||||
}
|
||||
|
||||
buildDockerConfigJson(): string {
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
namespace: cloudhost
|
||||
createNamespace: false
|
||||
|
||||
registry:
|
||||
credentialsSecret: harbor-core
|
||||
credentialsPasswordKey: REGISTRY_CREDENTIAL_PASSWORD
|
||||
username: harbor_registry_user
|
||||
|
||||
global:
|
||||
storageClass: local-path
|
||||
|
||||
|
||||
Reference in New Issue
Block a user