import { NodeSSH } from 'node-ssh';
import { execMustSucceed } from './utils/ssh';
import {
waitForAnyNodeColocationCapability,
waitForHelmReleaseDeployed,
waitForNamespacePodsOrServicesReady,
} from './utils/helm';
const VOLCANO_RELEASE_NAME = 'volcano';
const VOLCANO_NAMESPACE = 'volcano-system';
const VOLCANO_CHART = 'volcano-sh/volcano';
const VOLCANO_VERSION = '1.9.0';
const COLOCATION_RELEASE_NAME = 'colocation-package';
const COLOCATION_NAMESPACE = 'default';
const COLOCATION_NAMESPACE_FALLBACK = 'cluster-system';
const COLOCATION_CHART = 'oci://cr.openfuyao.cn/charts/colocation-package';
const COLOCATION_VERSION = '0.0.0-latest';
const shellArg = (raw: string): string => {
return `'${raw.replace(/'/g, `"'"'`)}'`;
};
export const installColocationDependencies = async (ssh: NodeSSH): Promise<void> => {
await execMustSucceed(
ssh,
'helm repo list | grep "^volcano-sh" >/dev/null 2>&1 || helm repo add volcano-sh https://volcano-sh.github.io/helm-charts',
);
await execMustSucceed(ssh, 'helm repo update');
await ssh.execCommand(
`helm uninstall ${shellArg(COLOCATION_RELEASE_NAME)} -n ${shellArg(COLOCATION_NAMESPACE)} --ignore-not-found`,
);
await ssh.execCommand(
`helm uninstall ${shellArg(COLOCATION_RELEASE_NAME)} -n ${shellArg(COLOCATION_NAMESPACE_FALLBACK)} --ignore-not-found`,
);
await ssh.execCommand(
`helm uninstall ${shellArg(VOLCANO_RELEASE_NAME)} -n ${shellArg(VOLCANO_NAMESPACE)} --ignore-not-found`,
);
await execMustSucceed(
ssh,
`helm install ${shellArg(VOLCANO_RELEASE_NAME)} ${shellArg(VOLCANO_CHART)} --version ${shellArg(VOLCANO_VERSION)} -n ${shellArg(VOLCANO_NAMESPACE)} --create-namespace`,
);
await waitForHelmReleaseDeployed(ssh, VOLCANO_RELEASE_NAME, VOLCANO_NAMESPACE, 240000, 5000);
let installedNamespace = COLOCATION_NAMESPACE;
const installResult = await ssh.execCommand(
`helm install ${shellArg(COLOCATION_RELEASE_NAME)} ${shellArg(COLOCATION_CHART)} --version ${shellArg(COLOCATION_VERSION)} -n ${shellArg(COLOCATION_NAMESPACE)} --create-namespace`,
);
if ((installResult.code ?? 1) !== 0) {
const stderr = installResult.stderr || '';
const shouldFallback = stderr.includes('meta.helm.sh/release-namespace')
&& stderr.includes(COLOCATION_NAMESPACE_FALLBACK);
if (!shouldFallback) {
const stdout = installResult.stdout?.trim() ?? '';
throw new Error(`command failed: helm install colocation-package\nstdout: ${stdout}\nstderr: ${stderr.trim()}`);
}
await execMustSucceed(
ssh,
`helm install ${shellArg(COLOCATION_RELEASE_NAME)} ${shellArg(COLOCATION_CHART)} --version ${shellArg(COLOCATION_VERSION)} -n ${shellArg(COLOCATION_NAMESPACE_FALLBACK)} --create-namespace`,
);
installedNamespace = COLOCATION_NAMESPACE_FALLBACK;
}
await waitForHelmReleaseDeployed(ssh, COLOCATION_RELEASE_NAME, installedNamespace, 240000, 5000);
await waitForNamespacePodsOrServicesReady(ssh, VOLCANO_NAMESPACE, 240000, 5000);
await waitForNamespacePodsOrServicesReady(ssh, 'openfuyao-colocation', 240000, 5000);
// 节点能力检测是异步收敛过程,setup阶段先尽量等待,避免进入用例时全量节点开关仍为 disabled。
try {
await waitForAnyNodeColocationCapability(ssh, 300000, 5000);
} catch (err) {
const detail = err instanceof Error ? err.message : String(err);
console.warn(`[colocation-setup] node capability not ready yet: ${detail}`);
}
};
export const uninstallColocationDependencies = async (ssh: NodeSSH): Promise<void> => {
await ssh.execCommand(
`helm uninstall ${shellArg(COLOCATION_RELEASE_NAME)} -n ${shellArg(COLOCATION_NAMESPACE)} --ignore-not-found`,
);
await ssh.execCommand(
`helm uninstall ${shellArg(COLOCATION_RELEASE_NAME)} -n ${shellArg(COLOCATION_NAMESPACE_FALLBACK)} --ignore-not-found`,
);
await ssh.execCommand(
`helm uninstall ${shellArg(VOLCANO_RELEASE_NAME)} -n ${shellArg(VOLCANO_NAMESPACE)} --ignore-not-found`,
);
};