1import * as _ from 'lodash-es'2import { getDeploymentTmpl, getDockerfileCfgMap } from "./docker_registry.mts"3import { kubeSvcTmpl } from '../../kubeSvcTmplF.mts'4import { secretTemplate } from '../../k8sSecF.mts'5import { getCreds, regcredSecTempl } from '../../../dockerF/dockRegF.mts'6import { doExec } from '../../../../serverF/execF.mts'7import { scryptSync } from 'node:crypto'8import { getKlusterCtx } from '../../ctxF/klusterCtxF.mts'9import { getAction } from '../../../ctxF/actionCtxF.mts'11import { resActionsH } from '../../resActionsF/res1ActionF.mts'12import { getImagePullSecrets, ensureSaPullSecret } from '../../../dockerF/dockRegF/getImagePullSecretsF.mts'13import { betLog } from '../../../../sharedF/betterConsLogF.mts'14import { getDockRegKubeResA } from '../../../dockerF/dockRegF/getDockRegKubeResAF.mts'15import { inspect3KubeRes } from '../../inspectKubeResF.mts'16import { genericIngressTmpl } from '../../generic1IngressTmplF.mts'17import { kubeActionPvc } from '../../pvcF/kubeActionPvcF.mts'18import { resourcesAction } from '../../resourcesActionF.mts'19import { criticalPriorityClassTmpl } from '../../priorityClassF.mts'20import { buildHelpStr } from '../../../cliF/cliBaseF.mts'21import { k8sBuiltinActions } from '../../cliF/k8sCliBaseF.mts'22import { importMetaUrlCtx } from '../../../../serverF/importMetaUrlCtxF.mts'23import { getImportMetaUrlPath } from '../../../../serverF/isDirectlyRunF.mts'24import { absPathToPtPath } from '../../../../serverF/pathF/absPathToPtPathF.mts'25import { ptnodeBin } from '../../../constantsF.mts'26import { assertDefined } from '../../../../sharedF/assertsF/assertDefinedF.mts'27import { dockRegGc } from '../../../dockerF/dockRegGcAI.mts'29const dockregIngressAnnotationsH = {30 'nginx.ingress.kubernetes.io/proxy-body-size': '2g',31 'nginx.ingress.kubernetes.io/client-body-buffer-size': '100m',32}34export const k8sDockerReg = async ({35 pvcReplicaCnt, sizeGb=100, 36 dockreg_host, dockLanHost,37 REGISTRY_HTTP_SECRET,38}: {39 pvcReplicaCnt?: number, sizeGb?: number,40 dockreg_host?: string, dockLanHost?: string,41 REGISTRY_HTTP_SECRET?: string,42}) => {43 const {cluster_name} = getKlusterCtx()45 assertDefined(dockreg_host || dockLanHost)46 const name = (dockreg_host || dockLanHost)!.split('.')[0]48 const htpasswd_secret_name = [name, 'htpasswd'].join('-')50 if (action === 'help') {51 const actionsH = {52 ..._.pick(k8sBuiltinActions, ['apply', 'delete', 'info', 'fexec']),53 ..._.pick(resActionsH(), ['logs', 'pods']),54 uses: {cliDescript: 'show k8s resources using this registry'},55 gc: {cliDescript: dockRegGc.cliDescript},56 }57 const {importMetaUrl} = importMetaUrlCtx.getStore() || {}58 const rawPath = importMetaUrl ? getImportMetaUrlPath(importMetaUrl as any) : null59 const epPath = rawPath ? absPathToPtPath(rawPath as Parameters<typeof absPathToPtPath>[0]) : '<sync.mjs>'60 console.log(buildHelpStr({scriptName: `${ptnodeBin} ${epPath} --steps=${name}`, actionsH: actionsH as any}))62 return63 }65 if (action == 'uses') {66 const resA = await getDockRegKubeResA({dockReg: name})68 return69 }71 if (action == 'gc') {73 return74 }76 let secretsH = {}77 if (action == 'apply') {79 if (!REGISTRY_HTTP_SECRET) {80 REGISTRY_HTTP_SECRET = scryptSync(username + password, 'REGISTRY_HTTP_SECRET', 32).toString('base64url')81 }83 // hardcode 'docker' — this is a local `docker run` for htpasswd generation, not a k8s build (kanikojob doesn't work here)84 const {stdout: htpasswd} = await doExec(`docker run --entrypoint htpasswd httpd:2 -Bbn ${username} ${password}`)86 secretsH = { htpasswd }87 } else {88 REGISTRY_HTTP_SECRET ||= ''89 }91 const regConfigName = `${name}-regconfig`93 const resources = [95 getDockerfileCfgMap({regConfigName}),96 getDeploymentTmpl({name, htpasswd_secret_name, regConfigName}),97 kubeSvcTmpl({name, portNo: 80}),98 secretTemplate({name, secretsH: {99 REGISTRY_HTTP_SECRET100 }}),101 secretTemplate({name: htpasswd_secret_name, secretsH}),102 regcredSecTempl({dockreg_host: dockreg_host!, dockLanHost}),103 genericIngressTmpl({name, hostname: dockreg_host!, ingressAnnotationsH: dockregIngressAnnotationsH}),104 ]105 if (dockLanHost) {106 resources.push(genericIngressTmpl({name: name + '-lan', svcName: name, hostname: dockLanHost, ingressAnnotationsH: dockregIngressAnnotationsH}))107 }109 await kubeActionPvc({action, name, sizeGb, pvcReplicaCnt})110 await resourcesAction({resources, action, cluster_name})112 if (_.includes(['apply', 'delete'], action)) {113 const imagePullSecrets = await getImagePullSecrets()114 if (action == 'apply') {115 await ensureSaPullSecret({secretName: imagePullSecrets[0].name, action, cluster_name})116 }117 }119}