UNPKG

@kosko/helm

Version:

Load Helm charts in kosko.

1 lines 21.4 kB
{"version":3,"file":"index.node.cjs","sources":["../src/fs.ts","../src/load.ts"],"sourcesContent":["import { getErrorCode } from \"@kosko/common-utils\";\nimport { cp, rename, rm, stat } from \"node:fs/promises\";\n\nexport async function move(src: string, dest: string): Promise<void> {\n try {\n await rename(src, dest);\n } catch (err) {\n if (getErrorCode(err) !== \"EXDEV\") throw err;\n\n await cp(src, dest, {\n recursive: true,\n errorOnExist: true,\n preserveTimestamps: true\n });\n await rm(src, { recursive: true, force: true });\n }\n}\n\nexport async function fileExists(path: string): Promise<boolean> {\n try {\n const stats = await stat(path);\n return stats.isFile();\n } catch (err) {\n if (getErrorCode(err) !== \"ENOENT\") throw err;\n return false;\n }\n}\n","import { LoadOptions, loadString, Manifest } from \"@kosko/yaml\";\nimport tmp from \"tmp-promise\";\nimport { writeFile, readFile, mkdir } from \"node:fs/promises\";\nimport {\n spawn,\n booleanArg,\n stringArg,\n stringArrayArg\n} from \"@kosko/exec-utils\";\nimport stringify from \"fast-safe-stringify\";\nimport { getErrorCode, isRecord } from \"@kosko/common-utils\";\nimport getCacheDir from \"cachedir\";\nimport { createHash } from \"node:crypto\";\nimport { dirname, join } from \"node:path\";\nimport { env } from \"node:process\";\nimport { readdir } from \"node:fs/promises\";\nimport yaml from \"js-yaml\";\nimport { fileExists, move } from \"./fs\";\n\nconst FILE_EXIST_ERROR_CODES = new Set([\"EEXIST\", \"ENOTEMPTY\"]);\nconst OCI_PREFIX = \"oci://\";\n\nconst defaultCacheDir = getCacheDir(\"kosko-helm\");\n\n/**\n * @public\n */\nexport interface CacheOptions {\n /**\n * When cache is enabled, the chart is pulled and stored in the cache\n * directory. Although Helm has its own cache, implementing our own cache\n * is faster. Local charts are never cached.\n *\n * @defaultValue `true`\n */\n enabled?: boolean;\n\n /**\n * The path of the cache directory. You can also use `KOSKO_HELM_CACHE_DIR`\n * environment variable to set the cache directory. This option always takes\n * precedence over the environment variable.\n *\n * @defaultValue\n * - Linux: `$XDG_CACHE_HOME/kosko-helm` or `~/.cache/kosko-helm`\n * - macOS: `~/Library/Caches/kosko-helm`\n * - Windows: `$LOCALAPPDATA/kosko-helm` or `~/AppData/Local/kosko-helm`\n */\n dir?: string;\n}\n\n/**\n * @public\n */\nexport interface PullOptions {\n /**\n * The path of a local chart or the name of a remote chart.\n */\n chart: string;\n\n /**\n * Verify certificates of HTTPS-enabled servers using this CA bundle.\n */\n caFile?: string;\n\n /**\n * Identify HTTPS client using this SSL certificate file.\n */\n certFile?: string;\n\n /**\n * Use development versions, too. Equivalent to version '\\>0.0.0-0'. If\n * `version` is set, this is ignored.\n */\n devel?: boolean;\n\n /**\n * Skip tls certificate checks for the chart download.\n */\n insecureSkipTlsVerify?: boolean;\n\n /**\n * Identify HTTPS client using this SSL key file.\n */\n keyFile?: string;\n\n /**\n * Location of public keys used for verification.\n *\n * @defaultValue `~/.gnupg/pubring.gpg`\n */\n keyring?: string;\n\n /**\n * Pass credentials to all domains.\n */\n passCredentials?: boolean;\n\n /**\n * Chart repository password where to locate the requested chart.\n */\n password?: string;\n\n /**\n * Chart repository url where to locate the requested chart.\n */\n repo?: string;\n\n /**\n * Chart repository username where to locate the requested chart.\n */\n username?: string;\n\n /**\n * Verify the package before using it.\n */\n verify?: boolean;\n\n /**\n * Specify the exact chart version to use. If this is not specified, the\n * latest version is used.\n */\n version?: string;\n\n /**\n * Cache options.\n */\n cache?: CacheOptions;\n}\n\n/**\n * @public\n */\nexport interface TemplateOptions {\n /**\n * Name of the release.\n */\n name?: string;\n\n /**\n * Kubernetes API versions used for `Capabilities.APIVersions`.\n */\n apiVersions?: string[];\n\n /**\n * Run helm dependency update before installing the chart.\n */\n dependencyUpdate?: boolean;\n\n /**\n * Add a custom description.\n */\n description?: string;\n\n /**\n * Generate the name (and omit the `name` parameter).\n */\n generateName?: boolean;\n\n /**\n * Include CRDs in the templated output.\n */\n includeCrds?: boolean;\n\n /**\n * Set `.Release.IsUpgrade` instead of `.Release.IsInstall`.\n */\n isUpgrade?: boolean;\n\n /**\n * Kubernetes version used for `Capabilities.KubeVersion`.\n */\n kubeVersion?: string;\n\n /**\n * Specify template used to name the release.\n */\n nameTemplate?: string;\n\n /**\n * Namespace scope for this request.\n */\n namespace?: string;\n\n /**\n * Prevent hooks from running during install.\n */\n noHooks?: boolean;\n\n /**\n * The path to an executable to be used for post rendering. If it exists in\n * `$PATH`, the binary will be used, otherwise it will try to look for the\n * executable at the given path.\n */\n postRenderer?: string;\n\n /**\n * Arguments to the post-renderer.\n *\n * @defaultValue `[]`\n */\n postRendererArgs?: string[];\n\n /**\n * Skip tests from templated output.\n */\n skipTests?: boolean;\n\n /**\n * Time to wait for any individual Kubernetes operation (like Jobs for hooks)\n *\n * @defaultValue `5m0s`\n */\n timeout?: string;\n\n /**\n * Specify values.\n */\n values?: unknown;\n}\n\nfunction removeBase64Padding(str: string): string {\n const index = str.indexOf(\"=\");\n return index === -1 ? str : str.substring(0, index);\n}\n\nfunction genHash(value: string): string {\n const hash = createHash(\"sha1\");\n\n hash.write(value);\n\n return removeBase64Padding(hash.digest(\"base64url\"));\n}\n\nfunction genObjectHash(value: unknown): string {\n return genHash(stringify(value));\n}\n\nasync function runHelm(args: readonly string[]) {\n try {\n return await spawn(\"helm\", args);\n } catch (err) {\n if (getErrorCode(err) !== \"ENOENT\") throw err;\n\n throw new Error(\n `\"loadChart\" requires Helm CLI installed in your environment. More info: https://kosko.dev/docs/components/loading-helm-chart`\n );\n }\n}\n\nasync function chartManifestExists(path: string) {\n try {\n return isRecord(await getChartMetadata(path));\n } catch {\n //\n }\n return false;\n}\n\nasync function isLocalChart(\n options: Pick<PullOptions, \"repo\" | \"chart\">\n): Promise<boolean> {\n // If repo is set, it's a remote chart\n if (options.repo) return false;\n\n // OCI charts are always remote\n if (options.chart.startsWith(OCI_PREFIX)) return false;\n\n return chartManifestExists(options.chart);\n}\n\nasync function getChartMetadata(\n chart: string\n): Promise<Record<string, unknown> | undefined> {\n const { stdout: content } = await runHelm([\"show\", \"chart\", chart]);\n const metadata = yaml.load(content);\n\n if (isRecord(metadata)) return metadata;\n}\n\nfunction getPullArgs(options: PullOptions): string[] {\n return [\n options.chart,\n ...stringArg(\"ca-file\", options.caFile),\n ...stringArg(\"cert-file\", options.certFile),\n ...booleanArg(\"devel\", options.devel),\n ...booleanArg(\"insecure-skip-tls-verify\", options.insecureSkipTlsVerify),\n ...stringArg(\"key-file\", options.keyFile),\n ...stringArg(\"keyring\", options.keyring),\n ...booleanArg(\"pass-credentials\", options.passCredentials),\n ...stringArg(\"password\", options.password),\n ...stringArg(\"repo\", options.repo),\n ...stringArg(\"username\", options.username),\n ...booleanArg(\"verify\", options.verify),\n ...stringArg(\"version\", options.version)\n ];\n}\n\nasync function moveChartToCacheDir(src: string, dest: string): Promise<void> {\n // Skip if the chart already exists in the cache directory\n if (await fileExists(dest)) return;\n\n await mkdir(dirname(dest), { recursive: true });\n\n try {\n await move(src, dest);\n } catch (err) {\n const code = getErrorCode(err);\n\n if (!code) throw err;\n\n // If the target already exists, it probably means that another\n // process has already pulled the chart. In this case, we can ignore the\n // error and return the cache path.\n if (FILE_EXIST_ERROR_CODES.has(code)) {\n return;\n }\n\n // Windows throws EPERM error when the target already exists.\n //\n // https://github.com/nodejs/node/issues/29481\n if (code === \"EPERM\") {\n return;\n }\n\n throw err;\n }\n}\n\nasync function pullChart(options: PullOptions): Promise<string | undefined> {\n // Skip cache if disabled\n if (options.cache?.enabled === false) return;\n\n // Skip cache if version is not set\n if (!options.version) return;\n\n // Skip cache if it's a local chart\n if (await isLocalChart(options)) return;\n\n const cacheDir =\n options.cache?.dir || env.KOSKO_HELM_CACHE_DIR || defaultCacheDir;\n const indexHash = genObjectHash({\n c: options.chart,\n d: options.devel,\n r: options.repo,\n v: options.version\n });\n const indexPath = join(cacheDir, \"index-\" + indexHash);\n\n // Read the index file to get the cache path\n try {\n const content = await readFile(indexPath, \"utf8\");\n if (content) {\n // The content read by current process might be empty due to race condition.\n return join(cacheDir, content);\n }\n } catch (err) {\n if (getErrorCode(err) !== \"ENOENT\") throw err;\n }\n\n // Create a temporary directory for the chart, because when there are multiple\n // processes pulling the same chart, sometimes Helm fails because files already\n // exist in the cache directory.\n const tmpDir = await tmp.dir({ prefix: \"kosko-helm\", unsafeCleanup: true });\n\n try {\n // Pull the chart\n await runHelm([\n \"pull\",\n ...getPullArgs(options),\n \"--destination\",\n tmpDir.path\n ]);\n\n // Get the chart path\n const files = await readdir(tmpDir.path);\n if (files.length === 0) return;\n const chartPath = join(tmpDir.path, files[0]);\n\n // Get chart version\n const chartMeta = await getChartMetadata(chartPath);\n const chartVersion = chartMeta?.version;\n\n if (typeof chartVersion !== \"string\") return;\n\n const chartHash = genObjectHash({\n c: options.chart,\n r: options.repo,\n v: chartVersion\n });\n const dest = join(cacheDir, chartHash);\n\n // Move the chart to the cache directory\n await moveChartToCacheDir(chartPath, dest);\n\n // Write index file\n await writeFile(indexPath, chartHash);\n\n return dest;\n } finally {\n await tmpDir.cleanup();\n }\n}\n\nasync function writeValues(values: unknown) {\n const file = await tmp.file();\n\n await writeFile(file.path, stringify(values));\n\n return file;\n}\n\nasync function renderChart(options: ChartOptions) {\n const args: string[] = [\n \"template\",\n ...(options.name ? [options.name] : []),\n ...getPullArgs(options),\n ...stringArrayArg(\"api-versions\", options.apiVersions),\n ...booleanArg(\"dependency-update\", options.dependencyUpdate),\n ...stringArg(\"description\", options.description),\n ...booleanArg(\"generate-name\", options.generateName),\n ...booleanArg(\"include-crds\", options.includeCrds),\n ...booleanArg(\"is-upgrade\", options.isUpgrade),\n ...stringArg(\"kube-version\", options.kubeVersion),\n ...stringArg(\"name-template\", options.nameTemplate),\n ...stringArg(\"namespace\", options.namespace),\n ...booleanArg(\"no-hooks\", options.noHooks),\n ...stringArg(\"post-renderer\", options.postRenderer),\n ...stringArrayArg(\"post-renderer-args\", options.postRendererArgs),\n ...booleanArg(\"skip-tests\", options.skipTests),\n ...stringArg(\"timeout\", options.timeout)\n ];\n let valueFile: tmp.FileResult | undefined;\n\n if (options.values) {\n valueFile = await writeValues(options.values);\n args.push(\"--values\", valueFile.path);\n }\n\n try {\n return await runHelm(args);\n } finally {\n await valueFile?.cleanup();\n }\n}\n\n/**\n * @public\n */\nexport interface ChartOptions\n extends LoadOptions,\n PullOptions,\n TemplateOptions {}\n\n/**\n * @public\n */\nexport function loadChart(options: ChartOptions): () => Promise<Manifest[]> {\n const { transform, ...opts } = options;\n\n return async () => {\n const cachedChart = await pullChart(opts);\n const { stdout } = await renderChart({\n ...opts,\n ...(cachedChart && { chart: cachedChart, repo: undefined })\n });\n\n return loadString(stdout, { transform });\n };\n}\n"],"names":["move","src","dest","rename","err","getErrorCode","cp","recursive","errorOnExist","preserveTimestamps","rm","force","fileExists","path","stats","stat","isFile","FILE_EXIST_ERROR_CODES","Set","defaultCacheDir","getCacheDir","genObjectHash","value","hash","createHash","write","removeBase64Padding","str","index","indexOf","substring","digest","stringify","runHelm","args","spawn","chartManifestExists","isRecord","getChartMetadata","isLocalChart","options","repo","chart","startsWith","stdout","content","metadata","yaml","load","getPullArgs","stringArg","caFile","certFile","booleanArg","devel","insecureSkipTlsVerify","keyFile","keyring","passCredentials","password","username","verify","version","moveChartToCacheDir","mkdir","dirname","code","has","pullChart","cache","enabled","cacheDir","dir","env","KOSKO_HELM_CACHE_DIR","indexPath","join","c","d","r","v","readFile","tmpDir","tmp","prefix","unsafeCleanup","files","readdir","length","chartPath","chartMeta","chartVersion","chartHash","writeFile","cleanup","writeValues","values","file","renderChart","valueFile","name","stringArrayArg","apiVersions","dependencyUpdate","description","generateName","includeCrds","isUpgrade","kubeVersion","nameTemplate","namespace","noHooks","postRenderer","postRendererArgs","skipTests","timeout","push","loadChart","transform","opts","cachedChart","undefined","loadString"],"mappings":"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"}