1import { getS3Cfg, getOptS3Cfg } from '../../../bktF/serverF/getS3CfgF.mts'2import * as _ from 'lodash-es'3import { envHToA } from '../../k8sF/envHToAF.mts'4import { secretTemplate } from '../../k8sF/k8sSecF.mts'5import { getKlusterCtx, type KubeResource } from '../../k8sF/ctxF/klusterCtxF.mts'6import { genBktSecret } from '../../bktF/genBktSecretF.mts'7import { kubeSvcTmpl } from '../../k8sF/kubeSvcTmplF.mts'8import * as minioActions from './minioActionsF.mts'9import { minioKubeCtx } from './minioKubeCtxF.mts'10import { genericIngressTmpl } from '../../k8sF/generic1IngressTmplF.mts'11import { availActionsCtx } from '../../ctxF/availActionsCtxF.mts'12import { kubeActionPvc } from '../../k8sF/pvcF/kubeActionPvcF.mts'13import { resourcesAction } from '../../k8sF/resourcesActionF.mts'14import { ensureBucket } from '../../../bktF/deployF/ensureBucketF.mts'15import { throwIf } from '../../../sharedF/throwErrorF/throwIfF.mts'16import { deployLabel } from '../../k8sF/kubeLabelsF.mts'18const reservedMinioBktNames = ['minio', 'admin', 'console', '.minio.sys']20export const minioPrefix = 'minio-'21export const minioBktNameToKubeName = ({bucket_name}: {bucket_name: string}) => {22 return minioPrefix + bucket_name23}26export const k8sMinio = async (props2: {bucket_name?: string, bucketHostname?: string, sizeGb?: number} & Record<string, unknown>) => {27 props2.bucket_name ||= props2.bucketHostname!.split('.')[0]29 let {30 bucket_name,31 bucketHostname,32 ...props33 } = props235 const minioCfg = _.merge({}, getKlusterCtx(), props2)36 const {cluster_name, action} = minioCfg37 let cfg = getOptS3Cfg({bucket_name})38 if (!cfg) {39 await genBktSecret({bucket_name, endpoint: `https://${bucketHostname}`, autoYes: true})41 }42 const {endpoint, secretAccessKey, accessKeyId} = cfg44 const name = minioBktNameToKubeName({bucket_name})45 const hostname = _.replace(endpoint, 'https://', '')47 minioKubeCtx.enterWith({...minioCfg, accessKeyId, secretAccessKey })49 const portNo = 900050 const deployRes = {51 apiVersion: 'apps/v1',52 kind: 'Deployment',53 metadata: { name },54 spec: {55 selector: {56 matchLabels: { name }57 },58 strategy: {59 type: 'Recreate'60 },61 template: {62 metadata: {63 labels: { name, [deployLabel]: name }64 },65 spec: {66 volumes: [67 {68 name: 'storage',69 persistentVolumeClaim: {70 claimName: name71 }72 }73 ],74 containers: [75 {76 name: 'minio',77 image: 'minio/minio:latest',79 command: ['/bin/sh', '-c'],80 args: [81 `mkdir -p /storage/${bucket_name} && minio server /storage`82 ],83 envFrom: [{84 secretRef: {85 name86 }87 }],88 ports: [89 {90 containerPort: portNo,91 }92 ],93 volumeMounts: [94 {95 name: 'storage',96 mountPath: '/storage'97 }98 ]99 }100 ]101 }102 }103 }104 }106 let resources: KubeResource[] = [107 secretTemplate({name, secretsH: {108 MINIO_ROOT_USER: accessKeyId,109 MINIO_ROOT_PASSWORD: secretAccessKey,110 MINIO_ACCESS_KEY: accessKeyId,111 MINIO_SECRET_KEY: secretAccessKey112 }}),113 kubeSvcTmpl({name, portNo}),114 deployRes,115 genericIngressTmpl({name, hostname, portNo}),116 ]118 let promises = []120 availActionsCtx.enterWith({...availActionsCtx.getStore(), ...minioActions})122 await kubeActionPvc({name, ...props})124 promises.push(resourcesAction({resources, action, cluster_name}))126 await Promise.all(promises)128 if (action === 'apply') {129 try {130 await ensureBucket({bucket_name})131 } catch (e) {132 console.log(`ensureBucket: bucket may be LAN-only, skipping remote check (${e instanceof Error ? e.message : e})`)133 }134 }136 if (action == 'info') {137 console.log('use action "creds" to show more')138 }139}