1import { genericIngressTmpl } from '../../k8sF/generic1IngressTmplF.mts'2import { generic3DeploymentTmpl } from '../../k8sF/genericDeploymentF.mts'3import { getKuboInitScript } from './kuboInitScriptF.mts'4import { genericNodePortTmpl } from '../../k8sF/generic1NodePortTmplF.mts'5import { genericPvcTmplA } from '../../k8sF/genericPvcF.mts'6import { pvcVolumeMounts } from '../../k8sF/pvcVolumeMountsF.mts'7import { assertTruthy } from '../../../sharedF/assertsF/assertTruthyAI.mts'8import { resourcesAction } from '../../k8sF/resourcesActionF.mts'9import { getKlusterCtx } from '../../k8sF/ctxF/klusterCtxF.mts'10import { getCurKlusterCfg } from '../../k8sF/ctxF/klusterCtxF.mts'11import * as _ from 'lodash-es'13const kuboDeploymentTmpl = ({name, isPrivate}: {name: string, isPrivate?: boolean}) => {14 const image = 'ipfs/kubo:latest'15 const kuboInitScript = getKuboInitScript({isPrivate})16 const {volumeMounts, volumes} = pvcVolumeMounts({name: 'ipfs-data', mountPath: '/data/ipfs'})18 return generic3DeploymentTmpl({19 name,20 spec: {21 containers: [{22 name: 'kubo',23 image,24 command: ['/bin/sh', '-c', kuboInitScript],25 env: [{name: 'IPFS_PATH', value: '/data/ipfs'}],26 ports: [27 {name: 'gateway', containerPort: 8080},28 {name: 'api', containerPort: 5001}29 ],30 volumeMounts,31 resources: {32 limits: {cpu: '1', memory: '2Gi'},33 requests: {cpu: '500m', memory: '1Gi'}34 }35 }],36 volumes37 }38 })39}41const ipfsSvcTmpl = ({name}: {name: string}) => {42 return {43 kind: 'Service',44 apiVersion: 'v1',45 metadata: {46 name47 },48 spec: {49 type: 'ClusterIP',50 selector: {51 name52 },53 ports: [54 {port: 80, targetPort: 8080, name: 'gateway'},55 {port: 5001, targetPort: 5001, name: 'api'}56 ]57 }58 }59}61export const syncIpfs = async ({hostname, apiHostname, name='ipfs', peerConfig}: {hostname: string, apiHostname: string, name?: string, peerConfig?: {isPrivate?: boolean, externalIp?: string, nodePort?: number}}) => {62 assertTruthy(hostname, {hostname, apiHostname})63 assertTruthy(apiHostname, {hostname, apiHostname})64 const isPrivate = peerConfig?.isPrivate65 const ctx = getKlusterCtx()66 const clusterCfg = ctx.cluster_name ? getCurKlusterCfg(ctx.cluster_name) : undefined67 const vipSuffix = ctx.klusterVipHostname?.replace('*', '') ?? clusterCfg?.klusterVipHostname?.replace('*', '')68 const extSuffix = _.flatten(_.compact([ctx.klustCertsH, clusterCfg?.klustCertsH]).flatMap((certsH) => _.values(certsH))).map((hn) => hn.replace('*', '')).find((s) => s !== vipSuffix)69 const deriveAlt = (hn: string) => {70 if (!vipSuffix || !extSuffix) return [hn]71 if (hn.includes(vipSuffix)) return [hn, hn.replace(vipSuffix, extSuffix)]72 if (hn.includes(extSuffix)) return [hn, hn.replace(extSuffix, vipSuffix)]73 return [hn]74 }75 const hostnameA = deriveAlt(hostname)76 const apiHostnameA = deriveAlt(apiHostname)77 const dnsExclude = {'external-dns.alpha.kubernetes.io/exclude': 'true'}78 const resources = [79 ...await genericPvcTmplA({name: 'ipfs-data', sizeGb: 10}),80 kuboDeploymentTmpl({name, isPrivate}),81 ipfsSvcTmpl({name}),82 genericIngressTmpl({name, hostnameA, portNo: 80, ingressAnnotationsH: dnsExclude}),84 name: `${name}-api`,85 hostnameA: apiHostnameA,86 svcName: name,87 portNo: 5001,88 ingressAnnotationsH: {89 ...dnsExclude,90 'nginx.ingress.kubernetes.io/proxy-body-size': '100m',91 },92 }),93 ...(peerConfig?.externalIp ? [genericNodePortTmpl({94 name: `${name}-4001`, nodePort: peerConfig.nodePort ?? 30202, svcPort: 4001, inclUdp: true,95 selector: {name}, externalTrafficPolicy: 'Local'96 })] : []),97 ]98 await resourcesAction({resources})99}