setting up bootstrap geth node

This commit is contained in:
benbierens 2023-04-10 10:09:41 +02:00
parent adbcfb9974
commit 124a4e3738
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
4 changed files with 262 additions and 32 deletions

View File

@ -1,4 +1,5 @@
using CodexDistTestCore.Metrics;
using CodexDistTestCore.Marketplace;
using CodexDistTestCore.Metrics;
namespace CodexDistTestCore
{
@ -17,18 +18,25 @@ namespace CodexDistTestCore
private readonly TestLog log;
private readonly IFileManager fileManager;
private readonly MetricsAggregator metricsAggregator;
private readonly MarketplaceController marketplaceController;
public K8sManager(TestLog log, IFileManager fileManager)
{
this.log = log;
this.fileManager = fileManager;
metricsAggregator = new MetricsAggregator(log, this);
marketplaceController = new MarketplaceController(log, this);
}
public ICodexNodeGroup BringOnline(OfflineCodexNodes offline)
{
var online = CreateOnlineCodexNodes(offline);
if (offline.MarketplaceConfig != null)
{
BringOnlineMarketplace();
}
K8s(k => k.BringOnline(online, offline));
log.Log($"{online.Describe()} online.");
@ -52,10 +60,9 @@ namespace CodexDistTestCore
return online.Origin;
}
public void ExampleOfCMD(IOnlineCodexNode node)
public string ExecuteCommand(PodInfo pod, string containerName, string command, params string[] arguments)
{
var n = (OnlineCodexNode)node;
K8s(k => k.ExampleOfCommandExecution(n));
return K8s(k => k.ExecuteCommand(pod, containerName, command, arguments));
}
public void DeleteAllResources()
@ -77,9 +84,12 @@ namespace CodexDistTestCore
{
var spec = new K8sPrometheusSpecs(codexGroupNumberSource.GetNextServicePort(), prometheusNumber, config);
PrometheusInfo? info = null;
K8s(k => info = k.BringOnlinePrometheus(spec));
return info!;
return K8s(k => k.BringOnlinePrometheus(spec));
}
public PodInfo BringOnlineGethBootstrapNode()
{
return K8s(k => k.BringOnlineGethBootstrapNode());
}
public void DownloadAllMetrics()
@ -89,9 +99,12 @@ namespace CodexDistTestCore
private void BringOnlineMetrics(CodexNodeGroup group)
{
var onlineNodes = group.Nodes.Cast<OnlineCodexNode>().ToArray();
metricsAggregator.BeginCollectingMetricsFor(DowncastNodes(group));
}
metricsAggregator.BeginCollectingMetricsFor(onlineNodes);
private void BringOnlineMarketplace()
{
marketplaceController.BringOnlineMarketplace();
}
private CodexNodeGroup CreateOnlineCodexNodes(OfflineCodexNodes offline)
@ -124,5 +137,18 @@ namespace CodexDistTestCore
action(k8s);
k8s.Close();
}
private T K8s<T>(Func<K8sOperations, T> action)
{
var k8s = new K8sOperations(knownPods);
var result = action(k8s);
k8s.Close();
return result;
}
private static OnlineCodexNode[] DowncastNodes(CodexNodeGroup group)
{
return group.Nodes.Cast<OnlineCodexNode>().ToArray();
}
}
}

View File

@ -3,6 +3,7 @@ using CodexDistTestCore.Metrics;
using k8s;
using k8s.KubeConfigModels;
using k8s.Models;
using Nethereum.Merkle.Patricia;
using NUnit.Framework;
namespace CodexDistTestCore
@ -26,29 +27,6 @@ namespace CodexDistTestCore
client.Dispose();
}
private Task Callback(Stream stdIn, Stream stdOut, Stream stdErr)
{
using var streamReader = new StreamReader(stdOut);
var lines = new List<string>();
var line = streamReader.ReadLine();
while (line != null)
{
lines.Add(line);
line = streamReader.ReadLine();
}
Assert.That(lines.Any(l => l.Contains("FOO76543")));
return Task.CompletedTask;
}
public void ExampleOfCommandExecution(OnlineCodexNode node)
{
Utils.Wait(client.NamespacedPodExecAsync(
node.Group.PodInfo!.Name, K8sNamespace, node.Container.Name, new[] { "echo", "FOO76543" }, false, Callback, new CancellationToken()));
}
public void BringOnline(CodexNodeGroup online, OfflineCodexNodes offline)
{
EnsureTestNamespace();
@ -82,6 +60,13 @@ namespace CodexDistTestCore
logHandler.Log(stream);
}
public string ExecuteCommand(PodInfo pod, string containerName, string command, params string[] arguments)
{
var runner = new CommandRunner(client, pod, containerName, command, arguments);
runner.Run();
return runner.GetStdOut();
}
public PrometheusInfo BringOnlinePrometheus(K8sPrometheusSpecs spec)
{
EnsureTestNamespace();
@ -93,6 +78,14 @@ namespace CodexDistTestCore
return new PrometheusInfo(spec.ServicePort, FetchNewPod());
}
public PodInfo BringOnlineGethBootstrapNode()
{
EnsureTestNamespace();
return FetchNewPod();
}
private void FetchPodInfo(CodexNodeGroup online)
{
online.PodInfo = FetchNewPod();
@ -344,5 +337,50 @@ namespace CodexDistTestCore
{
return client.ListNamespace().Items.Any(n => n.Metadata.Name == K8sNamespace);
}
private class CommandRunner
{
private readonly Kubernetes client;
private readonly PodInfo pod;
private readonly string containerName;
private readonly string command;
private readonly string[] arguments;
private readonly List<string> lines = new List<string>();
public CommandRunner(Kubernetes client, PodInfo pod, string containerName, string command, string[] arguments)
{
this.client = client;
this.pod = pod;
this.containerName = containerName;
this.command = command;
this.arguments = arguments;
}
public void Run()
{
var input = new[] { command }.Concat(arguments).ToArray();
Utils.Wait(client.NamespacedPodExecAsync(
pod.Name, K8sCluster.K8sNamespace, containerName, input, false, Callback, new CancellationToken()));
}
public string GetStdOut()
{
return string.Join(Environment.NewLine, lines);
}
private Task Callback(Stream stdIn, Stream stdOut, Stream stdErr)
{
using var streamReader = new StreamReader(stdOut);
var line = streamReader.ReadLine();
while (line != null)
{
lines.Add(line);
line = streamReader.ReadLine();
}
return Task.CompletedTask;
}
}
}
}

View File

@ -0,0 +1,128 @@
using CodexDistTestCore.Config;
using k8s.Models;
namespace CodexDistTestCore.Marketplace
{
public class K8sGethBoostrapSpecs
{
public const string ContainerName = "dtest-gethb";
private const string dockerImage = "thatbenbierens/prometheus-envconf:latest"; // todo - bake modified geth image and post it.
private const string portName = "gethb";
private const string genesisJsonBase64 = "ewogICAgImNvbmZpZyI6IHsKICAgICAgImNoYWluSWQiOiAxMjM0NSwKICAgICAgImhvbWVzdGVhZEJsb2NrIjogMCwKICAgICAgImVpcDE1MEJsb2NrIjogMCwKICAgICAgImVpcDE1NUJsb2NrIjogMCwKICAgICAgImVpcDE1OEJsb2NrIjogMCwKICAgICAgImJ5emFudGl1bUJsb2NrIjogMCwKICAgICAgImNvbnN0YW50aW5vcGxlQmxvY2siOiAwLAogICAgICAicGV0ZXJzYnVyZ0Jsb2NrIjogMCwKICAgICAgImlzdGFuYnVsQmxvY2siOiAwLAogICAgICAibXVpckdsYWNpZXJCbG9jayI6IDAsCiAgICAgICJiZXJsaW5CbG9jayI6IDAsCiAgICAgICJsb25kb25CbG9jayI6IDAsCiAgICAgICJhcnJvd0dsYWNpZXJCbG9jayI6IDAsCiAgICAgICJncmF5R2xhY2llckJsb2NrIjogMCwKICAgICAgImNsaXF1ZSI6IHsKICAgICAgICAicGVyaW9kIjogNSwKICAgICAgICAiZXBvY2giOiAzMDAwMAogICAgICB9CiAgICB9LAogICAgImRpZmZpY3VsdHkiOiAiMSIsCiAgICAiZ2FzTGltaXQiOiAiODAwMDAwMDAwIiwKICAgICJleHRyYWRhdGEiOiAiMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwN2RmOWE4NzVhMTc0YjNiYzU2NWU2NDI0YTAwNTBlYmMxYjJkMWQ4MjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAiLAogICAgImFsbG9jIjogewogICAgICAiQUNDT1VOVF9IRVJFIjogeyAiYmFsYW5jZSI6ICI1MDAwMDAiIH0KICAgIH0KICB9";
public K8sGethBoostrapSpecs(int servicePort)
{
ServicePort = servicePort;
}
public int ServicePort { get; }
public string GetDeploymentName()
{
return "test-gethb";
}
public V1Deployment CreateGethBootstrapDeployment()
{
var deploymentSpec = new V1Deployment
{
ApiVersion = "apps/v1",
Metadata = new V1ObjectMeta
{
Name = GetDeploymentName(),
NamespaceProperty = K8sCluster.K8sNamespace
},
Spec = new V1DeploymentSpec
{
Replicas = 1,
Selector = new V1LabelSelector
{
MatchLabels = CreateSelector()
},
Template = new V1PodTemplateSpec
{
Metadata = new V1ObjectMeta
{
Labels = CreateSelector()
},
Spec = new V1PodSpec
{
Containers = new List<V1Container>
{
new V1Container
{
Name = ContainerName,
Image = dockerImage,
Ports = new List<V1ContainerPort>
{
new V1ContainerPort
{
ContainerPort = 9090,
Name = portName
}
},
Env = new List<V1EnvVar>
{
new V1EnvVar
{
Name = "GETH_ARGS",
Value = "--qwerty"
},
new V1EnvVar
{
Name = "GENSIS_JSON",
Value = genesisJsonBase64
},
new V1EnvVar
{
Name = "IS_BOOTSTRAP",
Value = "1"
}
}
}
}
}
}
}
};
return deploymentSpec;
}
public V1Service CreateGethBootstrapService()
{
var serviceSpec = new V1Service
{
ApiVersion = "v1",
Metadata = new V1ObjectMeta
{
Name = "codex-gethb-service",
NamespaceProperty = K8sCluster.K8sNamespace
},
Spec = new V1ServiceSpec
{
Type = "NodePort",
Selector = CreateSelector(),
Ports = new List<V1ServicePort>
{
new V1ServicePort
{
Name = "gethb-service",
Protocol = "TCP",
Port = 9090,
TargetPort = portName,
NodePort = ServicePort
}
}
}
};
return serviceSpec;
}
private Dictionary<string, string> CreateSelector()
{
return new Dictionary<string, string> { { "test-gethb", "dtest-gethb" } };
}
}
}

View File

@ -0,0 +1,38 @@
namespace CodexDistTestCore.Marketplace
{
public class MarketplaceController
{
private readonly TestLog log;
private readonly K8sManager k8sManager;
private PodInfo? gethBootstrapNode;
private string bootstrapAccount = string.Empty;
private string bootstrapGenesisJson = string.Empty;
public MarketplaceController(TestLog log, K8sManager k8sManager)
{
this.log = log;
this.k8sManager = k8sManager;
}
public void BringOnlineMarketplace()
{
if (gethBootstrapNode != null) return;
log.Log("Starting Geth bootstrap node...");
gethBootstrapNode = k8sManager.BringOnlineGethBootstrapNode();
ExtractAccountAndGenesisJson();
log.Log("Geth boothstrap node started.");
}
private void ExtractAccountAndGenesisJson()
{
bootstrapAccount = ExecuteCommand("cat", "account_string.txt");
bootstrapGenesisJson = ExecuteCommand("cat", "genesis.json");
}
private string ExecuteCommand(string command, params string[] arguments)
{
return k8sManager.ExecuteCommand(gethBootstrapNode!, K8sGethBoostrapSpecs.ContainerName, command, arguments);
}
}
}