Skip to content

Commit

Permalink
feat: refactored into NodeResource for native provider
Browse files Browse the repository at this point in the history
  • Loading branch information
l0r1s committed Apr 5, 2023
1 parent b7e15b7 commit 3ac46f2
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getRandomPort, makeDir } from "@zombienet/utils";
import { genCmd, genCumulusCollatorCmd } from "../../cmdGenerator";
import { genCmd } from "../../cmdGenerator";
import { getUniqueName } from "../../configGenerator";
import {
P2P_PORT,
Expand All @@ -10,6 +10,7 @@ import {
import { Network } from "../../network";
import { Node, envVars } from "../../types";
import { getClient } from "../client";
import { NodeResource } from "./resources";

interface processEnvironment {
[key: string]: string;
Expand Down Expand Up @@ -60,58 +61,9 @@ export async function genNodeDef(
nodeSetup: Node,
): Promise<any> {
const client = getClient();
const name = nodeSetup.name;
const { rpcPort, wsPort, prometheusPort, p2pPort } = nodeSetup;
const ports = await getPorts(rpcPort, wsPort, prometheusPort, p2pPort);
const cfgPath = `${client.tmpDir}/${name}/cfg`;
await makeDir(cfgPath, true);

const dataPath = `${client.tmpDir}/${name}/data`;
await makeDir(dataPath, true);
const nodeResource = new NodeResource(client, namespace, nodeSetup);

const relayDataPath = `${client.tmpDir}/${name}/relay-data`;
await makeDir(relayDataPath, true);

let computedCommand;
if (nodeSetup.zombieRole === "cumulus-collator") {
computedCommand = await genCumulusCollatorCmd(
nodeSetup,
cfgPath,
dataPath,
relayDataPath,
false,
);
} else {
computedCommand = await genCmd(nodeSetup, cfgPath, dataPath, false);
}

return {
metadata: {
name: nodeSetup.name,
namespace: namespace,
labels: {
"zombie-role": nodeSetup.zombieRole
? nodeSetup.zombieRole
: nodeSetup.validator
? "authority"
: "full-node",
app: "zombienet",
"zombie-ns": namespace,
name: namespace,
instance: nodeSetup.name,
},
},
spec: {
cfgPath,
dataPath,
ports,
command: computedCommand,
env: nodeSetup.env.reduce((memo, item: envVars) => {
memo[item.name] = item.value;
return memo;
}, {} as processEnvironment),
},
};
return nodeResource.generateSpec();
}

async function getPorts(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { NodeResource } from "./node.resource";
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { getRandomPort, makeDir } from "@zombienet/utils";
import { genCmd, genCumulusCollatorCmd } from "../../../cmdGenerator";
import {
P2P_PORT,
PROMETHEUS_PORT,
RPC_HTTP_PORT,
RPC_WS_PORT,
} from "../../../constants";
import { Node, envVars } from "../../../types";
import { Client } from "../../client";
import {
NodeSpec,
Port,
PortProperty,
ProcessEnvironment,
ZombieRole,
} from "./types";

export class NodeResource {
protected readonly configPath: string;
protected readonly dataPath: string;
private readonly relayDataPath: string;

constructor(
client: Client,
protected readonly namespace: string,
protected readonly nodeSetupConfig: Node,
) {
const nodeRootPath = `${client.tmpDir}/${this.nodeSetupConfig.name}`;
this.configPath = `${nodeRootPath}/cfg`;
this.dataPath = `${nodeRootPath}/data`;
this.relayDataPath = `${nodeRootPath}/relay-data`;
}

public async generateSpec() {
await this.createDirectories();
const ports = await this.generatePorts();
const command = await this.generateCommand();
const zombieRole = this.getZombieRole();
const env = this.getEnv();
const nodeManifest = this.generateNodeSpec(ports, command, zombieRole, env);

return nodeManifest;
}

protected async createDirectories() {
try {
await makeDir(this.configPath, true);
await makeDir(this.dataPath, true);
await makeDir(this.relayDataPath, true);
} catch {
throw new Error(
`Error generating directories for ${this.nodeSetupConfig.name} resource`,
);
}
}

private async portFromNodeSetupConfigOrDefault(portProperty: PortProperty) {
if (this.nodeSetupConfig[portProperty]) {
return this.nodeSetupConfig[portProperty];
}

return getRandomPort();
}

private async generatePorts(): Promise<Port[]> {
return [
{
containerPort: PROMETHEUS_PORT,
name: "prometheus",
flag: "--prometheus-port",
hostPort: await this.portFromNodeSetupConfigOrDefault("prometheusPort"),
},
{
containerPort: RPC_HTTP_PORT,
name: "rpc",
flag: "--rpc-port",
hostPort: await this.portFromNodeSetupConfigOrDefault("rpcPort"),
},
{
containerPort: RPC_WS_PORT,
name: "rpc-ws",
flag: "--ws-port",
hostPort: await this.portFromNodeSetupConfigOrDefault("wsPort"),
},
{
containerPort: P2P_PORT,
name: "p2p",
flag: "--port",
hostPort: await this.portFromNodeSetupConfigOrDefault("p2pPort"),
},
];
}

protected generateCommand() {
if (this.nodeSetupConfig.zombieRole === "cumulus-collator") {
return genCumulusCollatorCmd(
this.nodeSetupConfig,
this.configPath,
this.dataPath,
this.relayDataPath,
false,
);
}

return genCmd(this.nodeSetupConfig, this.configPath, this.dataPath, false);
}

protected getZombieRole(): ZombieRole {
const { zombieRole, validator } = this.nodeSetupConfig;

if (zombieRole) return zombieRole;

return validator ? "authority" : "full-node";
}

protected getEnv() {
const { env } = this.nodeSetupConfig;

return env.reduce((memo, item: envVars) => {
memo[item.name] = item.value;
return memo;
}, {} as ProcessEnvironment);
}

protected generateNodeSpec(
ports: Port[],
command: string[],
zombieRole: ZombieRole,
env: ProcessEnvironment,
): NodeSpec {
return {
metadata: {
name: this.nodeSetupConfig.name,
namespace: this.namespace,
labels: {
"zombie-role": zombieRole,
app: "zombienet",
"zombie-ns": this.namespace,
name: this.namespace,
instance: this.nodeSetupConfig.name,
},
},
spec: {
cfgPath: this.configPath,
dataPath: this.dataPath,
ports,
command,
env,
},
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Node } from "../../../types";

export interface ProcessEnvironment {
[key: string]: string;
}

export type PortProperty = keyof NonNullable<Node["externalPorts"]>;

export type ZombieRole = Node["zombieRole"] | "authority" | "full-node";

export interface Port {
containerPort: number;
name: "prometheus" | "rpc" | "rpc-ws" | "p2p";
flag: string;
hostPort: number;
}

export interface NodeSpec {
metadata: {
name: string;
namespace: string;
labels: {
"zombie-role": ZombieRole;
app: "zombienet";
"zombie-ns": string;
name: string;
instance: string;
};
};
spec: {
cfgPath: string;
dataPath?: string;
ports: Port[];
command: string[];
env: ProcessEnvironment;
};
}

0 comments on commit 3ac46f2

Please sign in to comment.