Skip to content

Commit

Permalink
fix#30 dedup overrides/upload files (#43)
Browse files Browse the repository at this point in the history
* fix#30 dedup overrides/upload files

* fix#41, logs running name and overrides

* add new line
  • Loading branch information
pepoviola authored Dec 21, 2021
1 parent a19b707 commit 8be8e87
Show file tree
Hide file tree
Showing 12 changed files with 185 additions and 48 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zombienet",
"version": "0.0.1",
"version": "1.1.0",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"author": "Javier Viola <[email protected]>",
Expand Down
11 changes: 10 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { LaunchConfig } from "./types";
import { run } from "./test-runner";
import { Command } from "commander";
import { debug } from "console";

const path = require("path");

const program = new Command("zombie-net");

const program = new Command("zombienet");

let network: Network;

Expand Down Expand Up @@ -79,6 +81,13 @@ program
.argument("<testFile>", "Feature file describing the tests")
.action(test);

program
.command("version")
.description("Prints zombienet version")
.action(() => {
console.log("1.1.0-alpha");
});

// spawn
async function spawn(
credsFile: string,
Expand Down
21 changes: 21 additions & 0 deletions src/colors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const reset = "\x1b[0m";

const colorMap = {
red: "\x1b[31m",
green: "\x1b[32m",
yellow: "\x1b[33m",
blue: "\x1b[34m",
magenta: "\x1b[35m",
cyan: "\x1b[36m"
};


const colorFns: any = {};
for( const [color, code] of Object.entries(colorMap)){
colorFns[color] = function (input: string): string {
let ret = `${code}${input}${reset}`;
return ret;
}
}

export const decorators = colorFns;
2 changes: 2 additions & 0 deletions src/configManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ export const zombieWrapperPath = resolve(
`../scripts/${ZOMBIE_WRAPPER}`
);

export const LOKI_URL_FOR_NODE = "https://grafana.parity-mgmt.parity.io/explore?orgId=1&left=%5B%22now-3h%22,%22now%22,%22loki.parity-zombienet%22,%7B%22expr%22:%22%7Bpod%3D~%5C%22{{namespace}}%2F{{podName}}%5C%22%7D%22,%22refId%22:%22A%22,%22range%22:true%7D%5D";

export async function generateNetworkSpec(config: LaunchConfig): Promise<ComputedNetwork> {
let globalOverrides: Override[] = [];
if(config.relaychain.default_overrides) {
Expand Down
32 changes: 27 additions & 5 deletions src/orchestrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
DEFAULT_CHAIN_SPEC_COMMAND,
zombieWrapperPath,
ZOMBIE_WRAPPER,
LOKI_URL_FOR_NODE,
} from "./configManager";
import { Network } from "./network";
import { NetworkNode } from "./networkNode";
Expand All @@ -39,6 +40,7 @@ import path, { resolve } from "path";
import { generateParachainFiles } from "./paras";
import { setupChainSpec } from "./providers/k8s";
import { getChainSpecRaw } from "./providers/k8s/chain-spec";
import { decorators } from "./colors";

const debug = require("debug")("zombie");

Expand Down Expand Up @@ -116,13 +118,13 @@ export async function start(
await client.createNamespace();

// Create bootnode and backchannel services
debug(`Creating bootnode and backchannel services`);
await client.createStaticResource("bootnode-service.yaml");
await client.createStaticResource("backchannel-service.yaml");
await client.createStaticResource("backchannel-pod.yaml");
debug(`Creating static resources (bootnode and backchannel services)`);
// await client.createStaticResource("bootnode-service.yaml");
// await client.createStaticResource("backchannel-service.yaml");
// await client.createStaticResource("backchannel-pod.yaml");

// create basic infra metrics if needed
// if (withMetrics) await client.staticSetup();
await client.staticSetup();
await client.createPodMonitor("pod-monitor.yaml", chainName);

// setup cleaner
Expand Down Expand Up @@ -197,6 +199,8 @@ export async function start(

const bootnodeIP = await client.getBootnodeIP();

const monitorIsAvailable = await client._isPodMonitorAvailable();

// Create nodes
for (const node of networkSpec.relaychain.nodes) {
// TODO: k8s don't see pods by name so in here we inject the bootnode ip
Expand Down Expand Up @@ -231,6 +235,24 @@ export async function start(
userDefinedTypes
);
network.addNode(networkNode);

// Display info about the current node
let msg = `\n\t${decorators.green(node.name)} running`;
if(node.overrides) {
msg += `\n\t\t with ${decorators.yellow("Overrides")}...\n`;
for(const override of node.overrides){
msg += `\t\t local_path: ${override.local_path}\n`;
msg += `\t\t remote name: ${override.remote_name}`;
}
}

console.log(msg);
console.log("\n");
if(monitorIsAvailable) {
const loki_url = LOKI_URL_FOR_NODE.replace(/{{namespace}}/, namespace).replace(/{{podName}}/, podDef.metadata.name);
console.log(`\t${decorators.green("Grafana logs url:")}`);
console.log(`\t\t${decorators.magenta(loki_url)}`);
}
}

console.log("\t All relay chain nodes spawned...");
Expand Down
35 changes: 19 additions & 16 deletions src/paras.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export async function generateParachainFiles(
const parachainFilesPath = `${tmpDir}/${parachain.id}`;
const stateLocalFilePath = `${parachainFilesPath}/${GENESIS_STATE_FILENAME}`;
const wasmLocalFilePath = `${parachainFilesPath}/${GENESIS_WASM_FILENAME}`;
const localMagicFilepath = `${tmpDir}/finished.txt`;
// const localMagicFilepath = `${tmpDir}/finished.txt`;
const client = getClient();

fs.mkdirSync(parachainFilesPath);
Expand All @@ -48,23 +48,25 @@ export async function generateParachainFiles(
overrides: [],
};
const podDef = await genPodDef(namespace, node);
const podName = podDef.metadata.name;

debug(
`launching ${podDef.metadata.name} pod with image ${podDef.spec.containers[0].image}`
`launching ${podName} pod with image ${podDef.spec.containers[0].image}`
);
debug(`command: ${podDef.spec.containers[0].command.join(" ")}`);

await client.createResource(podDef, true, false);
await client.wait_transfer_container(podDef.metadata.name);
await client.wait_transfer_container(podName);

await client.copyFileToPod(
podDef.metadata.name,
localMagicFilepath,
FINISH_MAGIC_FILE,
TRANSFER_CONTAINER_NAME
);
// await client.copyFileToPod(
// podDef.metadata.name,
// localMagicFilepath,
// FINISH_MAGIC_FILE,
// TRANSFER_CONTAINER_NAME
// );
await client.putLocalMagicFile(podName,TRANSFER_CONTAINER_NAME);

await client.wait_pod_ready(podDef.metadata.name);
await client.wait_pod_ready(podName);

if (parachain.genesisStateGenerator) {
await client.copyFileFromPod(
Expand All @@ -82,12 +84,13 @@ export async function generateParachainFiles(
);
}

// put file to terminate pod
await client.copyFileToPod(
podDef.metadata.name,
localMagicFilepath,
FINISH_MAGIC_FILE
);
// // put file to terminate pod
// await client.copyFileToPod(
// podDef.metadata.name,
// localMagicFilepath,
// FINISH_MAGIC_FILE
// );
await client.putLocalMagicFile(podName, podName);
}

if (parachain.genesisStatePath) {
Expand Down
3 changes: 3 additions & 0 deletions src/providers/k8s/chain-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ export async function getChainSpecRaw(namespace: string, image: string, chainNam
podName
);

// let's just wait 2 secs before download
await sleep(2000);

// We had some issues where the `raw` file is empty
// let's add some extra checks here to ensure we are ok.
let isValid = false;
Expand Down
11 changes: 10 additions & 1 deletion src/providers/k8s/dynResourceDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,18 @@ function make_transfer_containter(): any {
function make_volume_mounts(): [any, any] {
const volume_mounts = [
{ name: "tmp-cfg", mountPath: "/cfg", readOnly: false },
// { name: "shared", mountPath: "/shared", readOnly: true },
];

const devices = [{ name: "tmp-cfg" }];
const devices = [
{ name: "tmp-cfg" },
// {
// "name": "shared",
// "persistentVolumeClaim": {
// "claimName": "shared-pv-claim"
// }
// }
];

return [volume_mounts, devices];
}
Expand Down
70 changes: 48 additions & 22 deletions src/providers/k8s/kubeClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import execa from "execa";
import { resolve } from "path";
import { FINISH_MAGIC_FILE, TRANSFER_CONTAINER_NAME } from "../../configManager";
import { addMinutes, writeLocalJsonFile } from "../../utils";
import { addMinutes, writeLocalJsonFile, getSha256 } from "../../utils";
const fs = require("fs").promises;
import { spawn } from "child_process";
import { availableNetworks } from "@polkadot/util-crypto";
Expand Down Expand Up @@ -33,6 +33,10 @@ export function initClient(
return client;
}

// Here we cache each file we upload from local
// to just cp between pods and not upload again the same file.
const fileUploadCache: any = {};

export class KubeClient {
namespace: string;
configPath: string;
Expand Down Expand Up @@ -96,12 +100,14 @@ export class KubeClient {

async putLocalMagicFile(name: string, container?: string) {
const target = container? container : TRANSFER_CONTAINER_NAME;
await client.copyFileToPod(
name,
this.localMagicFilepath,
FINISH_MAGIC_FILE,
target
);
const r = await this.kubectl(["exec", name, "-c", target, "--", "/bin/touch", FINISH_MAGIC_FILE]);
debug(r);
// await client.copyFileToPod(
// name,
// this.localMagicFilepath,
// FINISH_MAGIC_FILE,
// target
// );
}

// accept a json def
Expand Down Expand Up @@ -237,10 +243,31 @@ export class KubeClient {
podFilePath: string,
container: string | undefined = undefined
) {
const args = ["cp", localFilePath, `${identifier}:${podFilePath}`];
if (container) args.push("-c", container);
debug("copyFileToPod", args);
const result = await this.kubectl(args, undefined, true);
const hashedName = getSha256(localFilePath);
const parts = localFilePath.split("/");
const fileName = parts[parts.length -1];
if(! fileUploadCache[hashedName]) {
console.log("es: "+localFilePath);
const args = ["cp", localFilePath, `fileserver:/usr/share/nginx/html/${hashedName}`];
// if (container) args.push("-c", container);
debug("copyFileToPod", args);
const result = await this.kubectl(args, undefined, true);
debug(result);
fileUploadCache[hashedName] = fileName;
}

// download the file in the container
const args = ["exec", identifier];
if(container) args.push("-c", container);
let extraArgs = ["--", "/usr/bin/wget", "-O", podFilePath, `http://fileserver/${hashedName}`];
debug("copyFileToPodFromFileServer", [...args, ...extraArgs]);
let result = await this.kubectl([...args, ...extraArgs], undefined, true);
debug(result);

if(container) args.push("-c", container);
extraArgs = ["--", "/bin/chmod", "+x", podFilePath];
debug("copyFileToPodFromFileServer", [...args, ...extraArgs]);
result = await this.kubectl([...args, ...extraArgs], undefined, true);
debug(result);
}

Expand Down Expand Up @@ -293,29 +320,28 @@ export class KubeClient {
];

const resources = [
{ type: "role", files: ["prometheus-role.yaml"] },
{ type: "binding", files: ["prometheus-role-binding.yaml"] },
{ type: "data-storage-classes", files: storageFiles },
{
type: "configs",
files: ["prometheus-config.yaml", "grafana-config.yaml"],
},
{
type: "services",
files: [
"bootnode-service.yaml",
"telemetry-service.yaml",
"prometheus-service.yaml",
"backchannel-service.yaml",
"fileserver-service.yaml"
],
},
{
type: "deployment",
files: [
"prometheus-deployment.yaml",
"grafana-deployment.yaml",
//"telemetry-deployment.yaml",
"backchannel-pod.yaml",
"fileserver-pod.yaml"
],
},
// {
// type: "pvc",
// files: [
// "shared-pvc.yaml"
// ]
// }
];

for (const resourceType of resources) {
Expand Down
7 changes: 5 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LaunchConfig, Node } from "./types";
import toml from "toml";
import { getUniqueName, WAIT_UNTIL_SCRIPT_SUFIX } from "./configManager";
import path from "path";
import { createHash } from "crypto";

export async function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
Expand Down Expand Up @@ -155,6 +156,8 @@ export function createTempNodeDef(name: string, image: string, chain: string, fu
};

return node;


}

export function getSha256(input: string): string {
return createHash('sha256').update(input).digest('hex');
}
27 changes: 27 additions & 0 deletions static-configs/fileserver-pod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "fileserver",
"labels": {
"app": "fileserver"
}
},
"spec": {
"hostname": "fileserver",
"containers": [
{
"image": "nginx:latest",
"name": "fileserver",
"imagePullPolicy": "Always",
"ports": [
{
"containerPort": 80
}
]
}
],
"restartPolicy": "OnFailure",
"volumes": []
}
}
Loading

0 comments on commit 8be8e87

Please sign in to comment.