Merge branch 'feature/codex-net-deployer'

# Conflicts:
#	DistTestCore/Marketplace/MarketplaceAccess.cs
This commit is contained in:
benbierens 2023-07-13 10:34:34 +02:00
commit a3a5adaa19
No known key found for this signature in database
GPG Key ID: FE44815D96D0A1AA
10 changed files with 72 additions and 32 deletions

View File

@ -20,7 +20,7 @@ namespace CodexNetDeployer
this.workflowCreator = workflowCreator; this.workflowCreator = workflowCreator;
this.lifecycle = lifecycle; this.lifecycle = lifecycle;
this.gethResult = gethResult; this.gethResult = gethResult;
this.validatorsLeft = numberOfValidators; validatorsLeft = numberOfValidators;
} }
public RunningContainer? Start(int i) public RunningContainer? Start(int i)
@ -86,6 +86,8 @@ namespace CodexNetDeployer
var marketplaceConfig = new MarketplaceInitialConfig(100000.Eth(), 0.TestTokens(), validatorsLeft > 0); var marketplaceConfig = new MarketplaceInitialConfig(100000.Eth(), 0.TestTokens(), validatorsLeft > 0);
marketplaceConfig.AccountIndexOverride = i; marketplaceConfig.AccountIndexOverride = i;
codexStart.MarketplaceConfig = marketplaceConfig; codexStart.MarketplaceConfig = marketplaceConfig;
codexStart.MetricsEnabled = config.RecordMetrics;
if (config.BlockTTL != Configuration.SecondsIn1Day) if (config.BlockTTL != Configuration.SecondsIn1Day)
{ {
codexStart.BlockTTL = config.BlockTTL; codexStart.BlockTTL = config.BlockTTL;

View File

@ -1,7 +1,6 @@
using ArgsUniform; using ArgsUniform;
using DistTestCore; using DistTestCore;
using DistTestCore.Codex; using DistTestCore.Codex;
using DistTestCore.Marketplace;
namespace CodexNetDeployer namespace CodexNetDeployer
{ {
@ -9,15 +8,6 @@ namespace CodexNetDeployer
{ {
public const int SecondsIn1Day = 24 * 60 * 60; public const int SecondsIn1Day = 24 * 60 * 60;
[Uniform("codex-image", "ci", "CODEXIMAGE", true, "Docker image of Codex.")]
public string CodexImage { get; set; } = CodexContainerRecipe.DockerImage;
[Uniform("geth-image", "gi", "GETHIMAGE", true, "Docker image of Geth.")]
public string GethImage { get; set; } = GethContainerRecipe.DockerImage;
[Uniform("contracts-image", "oi", "CONTRACTSIMAGE", true, "Docker image of Codex Contracts.")]
public string ContractsImage { get; set; } = CodexContractsContainerRecipe.DockerImage;
[Uniform("kube-config", "kc", "KUBECONFIG", false, "Path to Kubeconfig file. Use 'null' (default) to use local cluster.")] [Uniform("kube-config", "kc", "KUBECONFIG", false, "Path to Kubeconfig file. Use 'null' (default) to use local cluster.")]
public string KubeConfigFile { get; set; } = "null"; public string KubeConfigFile { get; set; } = "null";
@ -54,6 +44,9 @@ namespace CodexNetDeployer
[Uniform("block-ttl", "bt", "BLOCKTTL", false, "Block timeout in seconds. Default is 24 hours.")] [Uniform("block-ttl", "bt", "BLOCKTTL", false, "Block timeout in seconds. Default is 24 hours.")]
public int BlockTTL { get; set; } = SecondsIn1Day; public int BlockTTL { get; set; } = SecondsIn1Day;
[Uniform("record-metrics", "rm", "RECORDMETRICS", false, "If true, metrics will be collected for all Codex nodes.")]
public bool RecordMetrics { get; set; } = false;
public TestRunnerLocation RunnerLocation { get; set; } = TestRunnerLocation.InternalToCluster; public TestRunnerLocation RunnerLocation { get; set; } = TestRunnerLocation.InternalToCluster;
public List<string> Validate() public List<string> Validate()

View File

@ -27,6 +27,7 @@ namespace CodexNetDeployer
// We trick the Geth companion node into unlocking all of its accounts, by saying we want to start 999 codex nodes. // We trick the Geth companion node into unlocking all of its accounts, by saying we want to start 999 codex nodes.
var setup = new CodexSetup(999, config.CodexLogLevel); var setup = new CodexSetup(999, config.CodexLogLevel);
setup.WithStorageQuota(config.StorageQuota!.Value.MB()).EnableMarketplace(0.TestTokens()); setup.WithStorageQuota(config.StorageQuota!.Value.MB()).EnableMarketplace(0.TestTokens());
setup.MetricsEnabled = config.RecordMetrics;
Log("Creating Geth instance and deploying contracts..."); Log("Creating Geth instance and deploying contracts...");
var gethStarter = new GethStarter(lifecycle, workflowCreator); var gethStarter = new GethStarter(lifecycle, workflowCreator);
@ -51,7 +52,9 @@ namespace CodexNetDeployer
if (container != null) codexContainers.Add(container); if (container != null) codexContainers.Add(container);
} }
return new CodexDeployment(gethResults, codexContainers.ToArray(), CreateMetadata()); var prometheusContainer = StartMetricsService(lifecycle, setup, codexContainers);
return new CodexDeployment(gethResults, codexContainers.ToArray(), prometheusContainer, CreateMetadata());
} }
private (WorkflowCreator, TestLifecycle) CreateFacilities() private (WorkflowCreator, TestLifecycle) CreateFacilities()
@ -80,6 +83,15 @@ namespace CodexNetDeployer
return (workflowCreator, lifecycle); return (workflowCreator, lifecycle);
} }
private RunningContainer? StartMetricsService(TestLifecycle lifecycle, CodexSetup setup, List<RunningContainer> codexContainers)
{
if (!setup.MetricsEnabled) return null;
Log("Starting metrics service...");
var runningContainers = new RunningContainers(null!, null!, codexContainers.ToArray());
return lifecycle.PrometheusStarter.CollectMetricsFor(runningContainers).Containers.Single();
}
private string? GetKubeConfig(string kubeConfigFile) private string? GetKubeConfig(string kubeConfigFile)
{ {
if (string.IsNullOrEmpty(kubeConfigFile) || kubeConfigFile.ToLowerInvariant() == "null") return null; if (string.IsNullOrEmpty(kubeConfigFile) || kubeConfigFile.ToLowerInvariant() == "null") return null;
@ -89,9 +101,6 @@ namespace CodexNetDeployer
private DeploymentMetadata CreateMetadata() private DeploymentMetadata CreateMetadata()
{ {
return new DeploymentMetadata( return new DeploymentMetadata(
codexImage: config.CodexImage,
gethImage: config.GethImage,
contractsImage: config.ContractsImage,
kubeNamespace: config.KubeNamespace, kubeNamespace: config.KubeNamespace,
numberOfCodexNodes: config.NumberOfCodexNodes!.Value, numberOfCodexNodes: config.NumberOfCodexNodes!.Value,
numberOfValidators: config.NumberOfValidators!.Value, numberOfValidators: config.NumberOfValidators!.Value,

View File

@ -29,6 +29,13 @@ public class Program
return; return;
} }
if (!args.Any(a => a == "-y"))
{
Console.WriteLine("Does the above config look good? [y/n]");
if (Console.ReadLine()!.ToLowerInvariant() != "y") return;
Console.WriteLine("I think so too.");
}
var deployer = new Deployer(config); var deployer = new Deployer(config);
var deployment = deployer.Deploy(); var deployment = deployer.Deploy();

View File

@ -64,9 +64,9 @@ namespace ContinuousTests
{ {
cancelToken.ThrowIfCancellationRequested(); cancelToken.ThrowIfCancellationRequested();
log.Log($"Checking '{n.Address.Host}'..."); log.Log($"Checking {n.Container.Name} @ '{n.Address.Host}:{n.Address.Port}'...");
if (EnsureOnline(n)) if (EnsureOnline(log, n))
{ {
log.Log("OK"); log.Log("OK");
} }
@ -82,12 +82,14 @@ namespace ContinuousTests
} }
} }
private bool EnsureOnline(CodexAccess n) private bool EnsureOnline(BaseLog log, CodexAccess n)
{ {
try try
{ {
var info = n.GetDebugInfo(); var info = n.GetDebugInfo();
if (info == null || string.IsNullOrEmpty(info.id)) return false; if (info == null || string.IsNullOrEmpty(info.id)) return false;
log.Log($"Codex version: '{info.codex.version}' revision: '{info.codex.revision}'");
} }
catch catch
{ {

View File

@ -33,7 +33,7 @@ namespace DistTestCore.Codex
AddEnvVar("CODEX_LOG_LEVEL", config.LogLevel.ToString()!.ToUpperInvariant()); AddEnvVar("CODEX_LOG_LEVEL", config.LogLevel.ToString()!.ToUpperInvariant());
// This makes the node announce itself to its local (pod) IP address. // This makes the node announce itself to its local (pod) IP address.
AddEnvVar("CODEX_NAT_ADDR", "$(hostname --ip-address)"); AddEnvVar("NAT_IP_AUTO", "true");
var listenPort = AddInternalPort(); var listenPort = AddInternalPort();
AddEnvVar("CODEX_LISTEN_ADDRS", $"/ip4/0.0.0.0/tcp/{listenPort.Number}"); AddEnvVar("CODEX_LISTEN_ADDRS", $"/ip4/0.0.0.0/tcp/{listenPort.Number}");

View File

@ -5,26 +5,25 @@ namespace DistTestCore.Codex
{ {
public class CodexDeployment public class CodexDeployment
{ {
public CodexDeployment(GethStartResult gethStartResult, RunningContainer[] codexContainers, DeploymentMetadata metadata) public CodexDeployment(GethStartResult gethStartResult, RunningContainer[] codexContainers, RunningContainer? prometheusContainer, DeploymentMetadata metadata)
{ {
GethStartResult = gethStartResult; GethStartResult = gethStartResult;
CodexContainers = codexContainers; CodexContainers = codexContainers;
PrometheusContainer = prometheusContainer;
Metadata = metadata; Metadata = metadata;
} }
public GethStartResult GethStartResult { get; } public GethStartResult GethStartResult { get; }
public RunningContainer[] CodexContainers { get; } public RunningContainer[] CodexContainers { get; }
public RunningContainer? PrometheusContainer { get; }
public DeploymentMetadata Metadata { get; } public DeploymentMetadata Metadata { get; }
} }
public class DeploymentMetadata public class DeploymentMetadata
{ {
public DeploymentMetadata(string codexImage, string gethImage, string contractsImage, string kubeNamespace, int numberOfCodexNodes, int numberOfValidators, int storageQuotaMB, CodexLogLevel codexLogLevel, int initialTestTokens, int minPrice, int maxCollateral, int maxDuration) public DeploymentMetadata(string kubeNamespace, int numberOfCodexNodes, int numberOfValidators, int storageQuotaMB, CodexLogLevel codexLogLevel, int initialTestTokens, int minPrice, int maxCollateral, int maxDuration)
{ {
DeployDateTimeUtc = DateTime.UtcNow; DeployDateTimeUtc = DateTime.UtcNow;
CodexImage = codexImage;
GethImage = gethImage;
ContractsImage = contractsImage;
KubeNamespace = kubeNamespace; KubeNamespace = kubeNamespace;
NumberOfCodexNodes = numberOfCodexNodes; NumberOfCodexNodes = numberOfCodexNodes;
NumberOfValidators = numberOfValidators; NumberOfValidators = numberOfValidators;
@ -36,10 +35,7 @@ namespace DistTestCore.Codex
MaxDuration = maxDuration; MaxDuration = maxDuration;
} }
public string CodexImage { get; }
public DateTime DeployDateTimeUtc { get; } public DateTime DeployDateTimeUtc { get; }
public string GethImage { get; }
public string ContractsImage { get; }
public string KubeNamespace { get; } public string KubeNamespace { get; }
public int NumberOfCodexNodes { get; } public int NumberOfCodexNodes { get; }
public int NumberOfValidators { get; } public int NumberOfValidators { get; }

View File

@ -1,5 +1,6 @@
using DistTestCore.Codex; using DistTestCore.Codex;
using DistTestCore.Marketplace; using DistTestCore.Marketplace;
using DistTestCore.Metrics;
using KubernetesWorkflow; using KubernetesWorkflow;
using Logging; using Logging;
@ -23,7 +24,7 @@ namespace DistTestCore
var startupConfig = CreateStartupConfig(gethStartResult, codexSetup); var startupConfig = CreateStartupConfig(gethStartResult, codexSetup);
var containers = StartCodexContainers(startupConfig, codexSetup.NumberOfNodes, codexSetup.Location); var containers = StartCodexContainers(startupConfig, codexSetup.NumberOfNodes, codexSetup.Location);
var metricAccessFactory = lifecycle.PrometheusStarter.CollectMetricsFor(codexSetup, containers); var metricAccessFactory = CollectMetrics(codexSetup, containers);
var codexNodeFactory = new CodexNodeFactory(lifecycle, metricAccessFactory, gethStartResult.MarketplaceAccessFactory); var codexNodeFactory = new CodexNodeFactory(lifecycle, metricAccessFactory, gethStartResult.MarketplaceAccessFactory);
@ -57,6 +58,14 @@ namespace DistTestCore
workflow.DownloadContainerLog(container, logHandler); workflow.DownloadContainerLog(container, logHandler);
} }
private IMetricsAccessFactory CollectMetrics(CodexSetup codexSetup, RunningContainers containers)
{
if (!codexSetup.MetricsEnabled) return new MetricsUnavailableAccessFactory();
var runningContainers = lifecycle.PrometheusStarter.CollectMetricsFor(containers);
return new CodexNodeMetricsAccessFactory(lifecycle, runningContainers);
}
private StartupConfig CreateStartupConfig(GethStartResult gethStartResult, CodexSetup codexSetup) private StartupConfig CreateStartupConfig(GethStartResult gethStartResult, CodexSetup codexSetup)
{ {
var startupConfig = new StartupConfig(); var startupConfig = new StartupConfig();

View File

@ -12,10 +12,8 @@ namespace DistTestCore
{ {
} }
public IMetricsAccessFactory CollectMetricsFor(CodexSetup codexSetup, RunningContainers containers) public RunningContainers CollectMetricsFor(RunningContainers containers)
{ {
if (!codexSetup.MetricsEnabled) return new MetricsUnavailableAccessFactory();
LogStart($"Starting metrics server for {containers.Describe()}"); LogStart($"Starting metrics server for {containers.Describe()}");
var startupConfig = new StartupConfig(); var startupConfig = new StartupConfig();
startupConfig.Add(new PrometheusStartupConfig(GeneratePrometheusConfig(containers.Containers))); startupConfig.Add(new PrometheusStartupConfig(GeneratePrometheusConfig(containers.Containers)));
@ -26,7 +24,7 @@ namespace DistTestCore
LogEnd("Metrics server started."); LogEnd("Metrics server started.");
return new CodexNodeMetricsAccessFactory(lifecycle, runningContainers); return runningContainers;
} }
private string GeneratePrometheusConfig(RunningContainer[] nodes) private string GeneratePrometheusConfig(RunningContainer[] nodes)

View File

@ -0,0 +1,24 @@
using DistTestCore;
using NUnit.Framework;
namespace Tests.BasicTests
{
[TestFixture]
public class ThreeClientTest : AutoBootstrapDistTest
{
[Test]
public void ThreeClient()
{
var primary = SetupCodexNode();
var secondary = SetupCodexNode();
var testFile = GenerateTestFile(10.MB());
var contentId = primary.UploadFile(testFile);
var downloadedFile = secondary.DownloadContent(contentId);
testFile.AssertIsEqual(downloadedFile);
}
}
}