feat: add amd64 node support
This commit is contained in:
+390
-40
@@ -19,6 +19,7 @@ import { basename, resolve } from "node:path";
|
||||
import type { ComposeSpecification } from "../schema/docker.d";
|
||||
import type { Service } from "../schema/docker.d";
|
||||
import { IMAGE_REGISTRY, LABELS } from "../const";
|
||||
import { getComposeArchPlacement } from "./arch";
|
||||
import { getServicePostgresClaim, isPostgresVolumeEntry } from "./database";
|
||||
import { toEnvVars } from "./format";
|
||||
import { deepMerge } from "./shared";
|
||||
@@ -32,6 +33,10 @@ type NormalizedMount = {
|
||||
configKey?: string;
|
||||
subPath?: string;
|
||||
sizeLimit?: string;
|
||||
requestedStorage?: string;
|
||||
diskTag?: string[];
|
||||
replicaCount?: number;
|
||||
dataLocality?: "none";
|
||||
};
|
||||
|
||||
type NormalizedPort = {
|
||||
@@ -41,9 +46,19 @@ type NormalizedPort = {
|
||||
hostPort?: number;
|
||||
protocol: "TCP" | "UDP";
|
||||
host?: string;
|
||||
routingKind?: "ingress" | "ingressroute";
|
||||
paths?: string[];
|
||||
};
|
||||
|
||||
type ServiceVolume = NonNullable<Service["volumes"]>[number];
|
||||
type ComposeVolumes = ComposeSpecification["volumes"];
|
||||
|
||||
const DefaultNamedVolumeStorage = {
|
||||
requestedStorage: "1Gi",
|
||||
diskTag: ["fast"],
|
||||
replicaCount: 2,
|
||||
dataLocality: "none" as const,
|
||||
};
|
||||
|
||||
function toPortNumber(value: number | string | undefined): number | undefined {
|
||||
if (typeof value === "number") return value;
|
||||
@@ -105,6 +120,126 @@ function toKubeName(value: string): string {
|
||||
.slice(0, 63);
|
||||
}
|
||||
|
||||
function normalizeStorageSize(value: unknown): string | undefined {
|
||||
if (value === undefined || value === null) return;
|
||||
const size = String(value).trim();
|
||||
if (!size) return;
|
||||
return size;
|
||||
}
|
||||
|
||||
function normalizeDiskTags(value: unknown): string[] | undefined {
|
||||
if (value === undefined || value === null) return;
|
||||
|
||||
const tags = (Array.isArray(value) ? value : [value])
|
||||
.flatMap((entry) => String(entry).split(","))
|
||||
.map((entry) => entry.trim())
|
||||
.filter(Boolean);
|
||||
|
||||
return tags.length > 0 ? [...new Set(tags)] : undefined;
|
||||
}
|
||||
|
||||
function normalizeReplicaCount(value: unknown): number | undefined {
|
||||
if (value === undefined || value === null || value === "") return;
|
||||
const count = Number(value);
|
||||
return Number.isInteger(count) ? count : undefined;
|
||||
}
|
||||
|
||||
function parseStorageSpec(value: string): {
|
||||
requestedStorage?: string;
|
||||
diskTag?: string[];
|
||||
replicaCount?: number;
|
||||
dataLocality?: "none";
|
||||
} {
|
||||
const [sizePart, placementPart] = value
|
||||
.split(/\s+on\s+/i, 2)
|
||||
.map((part) => part?.trim());
|
||||
|
||||
if (!placementPart) {
|
||||
return {
|
||||
requestedStorage: normalizeStorageSize(sizePart),
|
||||
};
|
||||
}
|
||||
|
||||
const placementMatch = /^(?:(?<replicas>\d+)\s+)?(?<tags>.+)$/.exec(
|
||||
placementPart,
|
||||
);
|
||||
|
||||
return {
|
||||
requestedStorage: normalizeStorageSize(sizePart),
|
||||
diskTag: normalizeDiskTags(placementMatch?.groups?.tags),
|
||||
replicaCount: normalizeReplicaCount(placementMatch?.groups?.replicas),
|
||||
dataLocality: "none",
|
||||
};
|
||||
}
|
||||
|
||||
function parseNamedVolumeSize(source: string):
|
||||
| {
|
||||
source: string;
|
||||
requestedStorage?: string;
|
||||
diskTag?: string[];
|
||||
replicaCount?: number;
|
||||
dataLocality?: "none";
|
||||
}
|
||||
| undefined {
|
||||
const match = /^(?<name>[^()]+)\((?<size>[^()]+)\)$/.exec(source.trim());
|
||||
if (!match?.groups) return;
|
||||
|
||||
const name = match.groups.name?.trim();
|
||||
const { requestedStorage, diskTag, replicaCount, dataLocality } =
|
||||
parseStorageSpec(match.groups.size ?? "");
|
||||
if (!name) return;
|
||||
|
||||
return {
|
||||
source: name,
|
||||
requestedStorage,
|
||||
diskTag,
|
||||
replicaCount,
|
||||
dataLocality,
|
||||
};
|
||||
}
|
||||
|
||||
function resolveVolumeSource(source: string | undefined): {
|
||||
source: string | undefined;
|
||||
requestedStorage?: string;
|
||||
diskTag?: string[];
|
||||
replicaCount?: number;
|
||||
dataLocality?: "none";
|
||||
} {
|
||||
if (!source || isBindSource(source)) return { source };
|
||||
|
||||
const sized = parseNamedVolumeSize(source);
|
||||
if (!sized) return { source };
|
||||
if (!sized.source) {
|
||||
throw new Error(`Invalid volume source ${source}. Expected name(size).`);
|
||||
}
|
||||
|
||||
return sized;
|
||||
}
|
||||
|
||||
function getVolumeExtensionSize(
|
||||
volume: { [key: string]: unknown } | undefined,
|
||||
): string | undefined {
|
||||
return normalizeStorageSize(volume?.["x-size"]);
|
||||
}
|
||||
|
||||
function getVolumeExtensionDiskTag(
|
||||
volume: { [key: string]: unknown } | undefined,
|
||||
): string[] | undefined {
|
||||
return normalizeDiskTags(volume?.["x-diskTag"]);
|
||||
}
|
||||
|
||||
function getVolumeExtensionReplicaCount(
|
||||
volume: { [key: string]: unknown } | undefined,
|
||||
): number | undefined {
|
||||
return normalizeReplicaCount(volume?.["x-replicaCount"]);
|
||||
}
|
||||
|
||||
function getVolumeExtensionDataLocality(
|
||||
volume: { [key: string]: unknown } | undefined,
|
||||
): "none" | undefined {
|
||||
return volume?.["x-dataLocality"] === "none" ? "none" : undefined;
|
||||
}
|
||||
|
||||
function toBindVolumeName(source: string): string {
|
||||
return toKubeName(`bind-${Bun.hash(source).toString(36)}`);
|
||||
}
|
||||
@@ -149,10 +284,13 @@ function parseStringMount(
|
||||
const maybeMode = parts.at(-1);
|
||||
const hasMode = maybeMode === "ro" || maybeMode === "rw";
|
||||
const target = parts.at(hasMode ? -2 : -1);
|
||||
const source = parts.slice(0, hasMode ? -2 : -1).join(":");
|
||||
const rawSource = parts.slice(0, hasMode ? -2 : -1).join(":");
|
||||
|
||||
if (!target) return;
|
||||
|
||||
const { source, requestedStorage, diskTag, replicaCount, dataLocality } =
|
||||
resolveVolumeSource(rawSource || undefined);
|
||||
|
||||
return {
|
||||
name:
|
||||
source && isBindSource(source)
|
||||
@@ -168,6 +306,10 @@ function parseStringMount(
|
||||
target,
|
||||
configKey: source ? basename(source) : undefined,
|
||||
readOnly: hasMode ? maybeMode === "ro" : undefined,
|
||||
requestedStorage,
|
||||
diskTag,
|
||||
replicaCount,
|
||||
dataLocality,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -187,35 +329,114 @@ function toMount(
|
||||
return;
|
||||
}
|
||||
|
||||
const { source, requestedStorage, diskTag, replicaCount, dataLocality } =
|
||||
resolveVolumeSource(entry.source);
|
||||
|
||||
return {
|
||||
name: entry.source
|
||||
name: source
|
||||
? entry.type === "bind"
|
||||
? toBindVolumeName(entry.source)
|
||||
: `${entry.type}-${toKubeName(entry.source) || index}`
|
||||
? toBindVolumeName(source)
|
||||
: `${entry.type}-${toKubeName(source) || index}`
|
||||
: `${entry.type}-${index}`,
|
||||
kind:
|
||||
entry.type === "bind" &&
|
||||
entry.source &&
|
||||
isConfigFileSource(entry.source, cwd)
|
||||
entry.type === "bind" && source && isConfigFileSource(source, cwd)
|
||||
? "config-file"
|
||||
: entry.type,
|
||||
source: entry.source,
|
||||
source,
|
||||
target: entry.target,
|
||||
readOnly: toBoolean(entry.read_only),
|
||||
configKey: entry.source ? basename(entry.source) : undefined,
|
||||
configKey: source ? basename(source) : undefined,
|
||||
subPath: entry.volume?.subpath,
|
||||
sizeLimit:
|
||||
entry.type === "tmpfs" && entry.tmpfs?.size !== undefined
|
||||
? String(entry.tmpfs.size)
|
||||
: undefined,
|
||||
requestedStorage: requestedStorage ?? getVolumeExtensionSize(entry.volume),
|
||||
diskTag: diskTag ?? getVolumeExtensionDiskTag(entry.volume),
|
||||
replicaCount: replicaCount ?? getVolumeExtensionReplicaCount(entry.volume),
|
||||
dataLocality: dataLocality ?? getVolumeExtensionDataLocality(entry.volume),
|
||||
};
|
||||
}
|
||||
|
||||
function toMounts(service: Service, cwd = process.cwd()): NormalizedMount[] {
|
||||
function getTopLevelVolumeSize(
|
||||
volumes: ComposeVolumes,
|
||||
source: string | undefined,
|
||||
): string | undefined {
|
||||
if (!source || !volumes) return;
|
||||
|
||||
const volume = volumes[source] as { [key: string]: unknown } | undefined;
|
||||
return getVolumeExtensionSize(volume);
|
||||
}
|
||||
|
||||
function getTopLevelVolumeDiskTag(
|
||||
volumes: ComposeVolumes,
|
||||
source: string | undefined,
|
||||
): string[] | undefined {
|
||||
if (!source || !volumes) return;
|
||||
|
||||
const volume = volumes[source] as { [key: string]: unknown } | undefined;
|
||||
return getVolumeExtensionDiskTag(volume);
|
||||
}
|
||||
|
||||
function getTopLevelVolumeReplicaCount(
|
||||
volumes: ComposeVolumes,
|
||||
source: string | undefined,
|
||||
): number | undefined {
|
||||
if (!source || !volumes) return;
|
||||
|
||||
const volume = volumes[source] as { [key: string]: unknown } | undefined;
|
||||
return getVolumeExtensionReplicaCount(volume);
|
||||
}
|
||||
|
||||
function getTopLevelVolumeDataLocality(
|
||||
volumes: ComposeVolumes,
|
||||
source: string | undefined,
|
||||
): "none" | undefined {
|
||||
if (!source || !volumes) return;
|
||||
|
||||
const volume = volumes[source] as { [key: string]: unknown } | undefined;
|
||||
return getVolumeExtensionDataLocality(volume);
|
||||
}
|
||||
|
||||
function toMounts(
|
||||
service: Service,
|
||||
cwd = process.cwd(),
|
||||
volumes: ComposeVolumes = {},
|
||||
): NormalizedMount[] {
|
||||
const mounts =
|
||||
service.volumes?.flatMap((entry, index) => {
|
||||
const mount = toMount(entry, index, cwd);
|
||||
return mount ? [mount] : [];
|
||||
if (!mount) return [];
|
||||
|
||||
return [
|
||||
{
|
||||
...mount,
|
||||
requestedStorage:
|
||||
mount.requestedStorage ??
|
||||
getTopLevelVolumeSize(volumes, mount.source) ??
|
||||
(mount.kind === "volume" && mount.source
|
||||
? DefaultNamedVolumeStorage.requestedStorage
|
||||
: undefined),
|
||||
diskTag:
|
||||
mount.diskTag ??
|
||||
getTopLevelVolumeDiskTag(volumes, mount.source) ??
|
||||
(mount.kind === "volume" && mount.source
|
||||
? DefaultNamedVolumeStorage.diskTag
|
||||
: undefined),
|
||||
replicaCount:
|
||||
mount.replicaCount ??
|
||||
getTopLevelVolumeReplicaCount(volumes, mount.source) ??
|
||||
(mount.kind === "volume" && mount.source
|
||||
? DefaultNamedVolumeStorage.replicaCount
|
||||
: undefined),
|
||||
dataLocality:
|
||||
mount.dataLocality ??
|
||||
getTopLevelVolumeDataLocality(volumes, mount.source) ??
|
||||
(mount.kind === "volume" && mount.source
|
||||
? DefaultNamedVolumeStorage.dataLocality
|
||||
: undefined),
|
||||
},
|
||||
];
|
||||
}) ?? [];
|
||||
|
||||
const tmpfs = (Array.isArray(service.tmpfs) ? service.tmpfs : [service.tmpfs])
|
||||
@@ -300,6 +521,47 @@ function toVolumes(
|
||||
});
|
||||
}
|
||||
|
||||
function normalizeProtectedPaths(value: string): string[] {
|
||||
return [
|
||||
...new Set(
|
||||
value
|
||||
.split(",")
|
||||
.map((segment) => segment.trim())
|
||||
.filter(Boolean)
|
||||
.map((segment) => (segment.startsWith("/") ? segment : `/${segment}`)),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
function parsePortRoute(value: string): {
|
||||
portSpec: string;
|
||||
routingKind?: "ingress" | "ingressroute";
|
||||
paths?: string[];
|
||||
} {
|
||||
const protectedMatch =
|
||||
/^(?<portSpec>.+):protected(?:\((?<paths>[^)]*)\))?$/.exec(value);
|
||||
if (!protectedMatch?.groups) return { portSpec: value };
|
||||
|
||||
const portSpec = protectedMatch.groups.portSpec?.trim();
|
||||
if (!portSpec) {
|
||||
throw new Error(`Invalid protected port syntax ${value}.`);
|
||||
}
|
||||
|
||||
const rawPaths = protectedMatch.groups.paths?.trim();
|
||||
if (rawPaths === undefined) {
|
||||
return { portSpec, routingKind: "ingressroute" };
|
||||
}
|
||||
|
||||
const paths = normalizeProtectedPaths(rawPaths);
|
||||
if (paths.length === 0) {
|
||||
throw new Error(
|
||||
`Invalid protected port syntax ${value}. Expected one or more paths.`,
|
||||
);
|
||||
}
|
||||
|
||||
return { portSpec, routingKind: "ingressroute", paths };
|
||||
}
|
||||
|
||||
function toPorts(service: Service): NormalizedPort[] {
|
||||
const ports =
|
||||
service.ports?.flatMap<NormalizedPort>((entry, index) => {
|
||||
@@ -315,8 +577,10 @@ function toPorts(service: Service): NormalizedPort[] {
|
||||
}
|
||||
|
||||
if (typeof entry === "string") {
|
||||
const [portSpec, protocolSpec] = entry.split("/");
|
||||
if (!portSpec) return [];
|
||||
const [rawPortSpec, protocolSpec] = entry.split("/");
|
||||
if (!rawPortSpec) return [];
|
||||
|
||||
const { portSpec, routingKind, paths } = parsePortRoute(rawPortSpec);
|
||||
|
||||
const segments = portSpec.split(":");
|
||||
const target = toPortNumber(segments.at(-1));
|
||||
@@ -336,6 +600,8 @@ function toPorts(service: Service): NormalizedPort[] {
|
||||
hostPort: published,
|
||||
host,
|
||||
protocol: toProtocol(protocolSpec),
|
||||
routingKind: host ? (routingKind ?? "ingress") : undefined,
|
||||
paths,
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -353,6 +619,7 @@ function toPorts(service: Service): NormalizedPort[] {
|
||||
hostPort: published,
|
||||
host: toHostname(entry.host_ip),
|
||||
protocol: toProtocol(entry.protocol),
|
||||
routingKind: toHostname(entry.host_ip) ? "ingress" : undefined,
|
||||
},
|
||||
];
|
||||
}) ?? [];
|
||||
@@ -373,12 +640,7 @@ function toPorts(service: Service): NormalizedPort[] {
|
||||
];
|
||||
}) ?? [];
|
||||
|
||||
const deduped = new Map<string, NormalizedPort>();
|
||||
for (const port of [...ports, ...exposedPorts]) {
|
||||
deduped.set(`${port.containerPort}:${port.protocol}`, port);
|
||||
}
|
||||
|
||||
return [...deduped.values()];
|
||||
return [...ports, ...exposedPorts];
|
||||
}
|
||||
|
||||
function toContainerPorts(
|
||||
@@ -386,30 +648,49 @@ function toContainerPorts(
|
||||
): V1ContainerPort[] | undefined {
|
||||
if (ports.length === 0) return;
|
||||
|
||||
return ports.map((port) => ({
|
||||
name: port.name,
|
||||
containerPort: port.containerPort,
|
||||
hostPort: port.hostPort,
|
||||
protocol: port.protocol,
|
||||
}));
|
||||
const deduped = new Map<string, V1ContainerPort>();
|
||||
|
||||
for (const port of ports) {
|
||||
deduped.set(`${port.containerPort}:${port.protocol}`, {
|
||||
name: port.name,
|
||||
containerPort: port.containerPort,
|
||||
hostPort: port.hostPort,
|
||||
protocol: port.protocol,
|
||||
});
|
||||
}
|
||||
|
||||
return [...deduped.values()];
|
||||
}
|
||||
|
||||
function toServicePorts(ports: NormalizedPort[]): V1ServicePort[] | undefined {
|
||||
if (ports.length === 0) return;
|
||||
|
||||
return ports.map((port) => ({
|
||||
name: port.name,
|
||||
port: port.servicePort,
|
||||
targetPort: port.containerPort,
|
||||
protocol: port.protocol,
|
||||
}));
|
||||
const deduped = new Map<string, V1ServicePort>();
|
||||
|
||||
for (const port of ports) {
|
||||
deduped.set(`${port.servicePort}:${port.protocol}`, {
|
||||
name: port.name,
|
||||
port: port.servicePort,
|
||||
targetPort: port.containerPort,
|
||||
protocol: port.protocol,
|
||||
});
|
||||
}
|
||||
|
||||
return [...deduped.values()];
|
||||
}
|
||||
|
||||
function toIngressRules(name: string, ports: NormalizedPort[]) {
|
||||
const seenHosts = new Set<string>();
|
||||
|
||||
return ports.flatMap((port) => {
|
||||
if (!port.host || seenHosts.has(port.host)) return [];
|
||||
if (
|
||||
!port.host ||
|
||||
port.routingKind === "ingressroute" ||
|
||||
seenHosts.has(port.host)
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
seenHosts.add(port.host);
|
||||
|
||||
return [
|
||||
@@ -423,7 +704,7 @@ function toIngressRules(name: string, ports: NormalizedPort[]) {
|
||||
backend: {
|
||||
service: {
|
||||
name,
|
||||
port: { name: port.name },
|
||||
port: { number: port.servicePort },
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -434,6 +715,55 @@ function toIngressRules(name: string, ports: NormalizedPort[]) {
|
||||
});
|
||||
}
|
||||
|
||||
function toIngressRoute(
|
||||
project: string,
|
||||
name: string,
|
||||
ports: NormalizedPort[],
|
||||
): KubernetesObject | undefined {
|
||||
const routes = ports.flatMap((port) => {
|
||||
if (!port.host || port.routingKind !== "ingressroute") return [];
|
||||
|
||||
const matches =
|
||||
port.paths && port.paths.length > 0
|
||||
? port.paths.map(
|
||||
(path) => `Host(\`${port.host}\`) && PathPrefix(\`${path}\`)`,
|
||||
)
|
||||
: [`Host(\`${port.host}\`)`];
|
||||
|
||||
return matches.map((match) => ({
|
||||
kind: "Rule",
|
||||
match,
|
||||
middlewares: [
|
||||
{
|
||||
name: "cf-auth",
|
||||
namespace: "routing",
|
||||
},
|
||||
],
|
||||
services: [
|
||||
{
|
||||
name,
|
||||
port: port.servicePort,
|
||||
},
|
||||
],
|
||||
}));
|
||||
});
|
||||
|
||||
if (routes.length === 0) return;
|
||||
|
||||
return {
|
||||
apiVersion: "traefik.io/v1alpha1",
|
||||
kind: "IngressRoute",
|
||||
metadata: {
|
||||
name,
|
||||
namespace: project,
|
||||
labels: LABELS,
|
||||
},
|
||||
spec: {
|
||||
routes,
|
||||
},
|
||||
} as KubernetesObject;
|
||||
}
|
||||
|
||||
function toEnvFilePaths(
|
||||
envFile: Service["env_file"],
|
||||
): { path: string; required: boolean }[] {
|
||||
@@ -502,11 +832,13 @@ async function readEnvFiles(
|
||||
export function serviceToDeployment(
|
||||
project: string,
|
||||
name: string,
|
||||
compose: ComposeSpecification,
|
||||
service: Service,
|
||||
cwd = process.cwd(),
|
||||
extraEnv: Record<string, string> = {},
|
||||
volumes: ComposeVolumes = {},
|
||||
): V1Deployment {
|
||||
const mounts = toMounts(service, cwd);
|
||||
const mounts = toMounts(service, cwd, volumes);
|
||||
const ports = toPorts(service);
|
||||
const hasEnvSecret =
|
||||
Boolean(service.env_file) ||
|
||||
@@ -541,6 +873,7 @@ export function serviceToDeployment(
|
||||
},
|
||||
spec: {
|
||||
restartPolicy: "Always",
|
||||
...getComposeArchPlacement(compose),
|
||||
volumes: toVolumes(project, mounts),
|
||||
containers: [
|
||||
deepMerge(
|
||||
@@ -620,10 +953,11 @@ export function volumesToPvc(
|
||||
project: string,
|
||||
service: Service,
|
||||
cwd = process.cwd(),
|
||||
volumes: ComposeVolumes = {},
|
||||
): V1PersistentVolumeClaim[] {
|
||||
const claims = new Map<string, V1PersistentVolumeClaim>();
|
||||
|
||||
for (const mount of toMounts(service, cwd)) {
|
||||
for (const mount of toMounts(service, cwd, volumes)) {
|
||||
const claimName =
|
||||
mount.kind === "bind"
|
||||
? mount.source
|
||||
@@ -647,11 +981,16 @@ export function volumesToPvc(
|
||||
accessModes: ["ReadWriteMany"],
|
||||
resources: {
|
||||
requests: {
|
||||
storage: "1Gi",
|
||||
storage: mount.requestedStorage ?? "1Gi",
|
||||
},
|
||||
},
|
||||
...(mount.diskTag ? { diskTag: mount.diskTag } : {}),
|
||||
...(mount.replicaCount !== undefined
|
||||
? { replicaCount: mount.replicaCount }
|
||||
: {}),
|
||||
...(mount.dataLocality ? { dataLocality: mount.dataLocality } : {}),
|
||||
},
|
||||
});
|
||||
} as V1PersistentVolumeClaim);
|
||||
}
|
||||
|
||||
return [...claims.values()];
|
||||
@@ -661,10 +1000,11 @@ export function volumesToConfigMaps(
|
||||
project: string,
|
||||
service: Service,
|
||||
cwd = process.cwd(),
|
||||
volumes: ComposeVolumes = {},
|
||||
): V1ConfigMap[] {
|
||||
const configMaps = new Map<string, V1ConfigMap>();
|
||||
|
||||
for (const mount of toMounts(service, cwd)) {
|
||||
for (const mount of toMounts(service, cwd, volumes)) {
|
||||
if (mount.kind !== "config-file" || !mount.source || !mount.configKey)
|
||||
continue;
|
||||
|
||||
@@ -751,11 +1091,16 @@ export async function composeToKubernetes(
|
||||
resources.set(getResourceKey(namespace), namespace);
|
||||
|
||||
for (const [name, service] of Object.entries(compose.services ?? {})) {
|
||||
for (const pvc of volumesToPvc(project, service, cwd)) {
|
||||
for (const pvc of volumesToPvc(project, service, cwd, compose.volumes)) {
|
||||
resources.set(getResourceKey(pvc), pvc);
|
||||
}
|
||||
|
||||
for (const configMap of volumesToConfigMaps(project, service, cwd)) {
|
||||
for (const configMap of volumesToConfigMaps(
|
||||
project,
|
||||
service,
|
||||
cwd,
|
||||
compose.volumes,
|
||||
)) {
|
||||
resources.set(getResourceKey(configMap), configMap);
|
||||
}
|
||||
|
||||
@@ -775,14 +1120,19 @@ export async function composeToKubernetes(
|
||||
const deployment = serviceToDeployment(
|
||||
project,
|
||||
name,
|
||||
compose,
|
||||
service,
|
||||
cwd,
|
||||
serviceEnv[name] ?? {},
|
||||
compose.volumes,
|
||||
);
|
||||
resources.set(getResourceKey(deployment), deployment);
|
||||
|
||||
const ingress = serviceToIngress(project, name, service);
|
||||
if (ingress) resources.set(getResourceKey(ingress), ingress);
|
||||
|
||||
const ingressRoute = toIngressRoute(project, name, toPorts(service));
|
||||
if (ingressRoute) resources.set(getResourceKey(ingressRoute), ingressRoute);
|
||||
}
|
||||
|
||||
return [...resources.values()];
|
||||
|
||||
Reference in New Issue
Block a user