2023-06-22 08:17:12 +00:00
|
|
|
|
using DistTestCore;
|
2023-06-22 12:37:37 +00:00
|
|
|
|
using DistTestCore.Codex;
|
|
|
|
|
using KubernetesWorkflow;
|
2023-06-26 13:37:16 +00:00
|
|
|
|
using Logging;
|
2023-06-22 08:17:12 +00:00
|
|
|
|
|
|
|
|
|
namespace CodexNetDeployer
|
|
|
|
|
{
|
|
|
|
|
public class Deployer
|
|
|
|
|
{
|
|
|
|
|
private readonly Configuration config;
|
2023-06-22 12:37:37 +00:00
|
|
|
|
private readonly NullLog log;
|
|
|
|
|
private readonly DefaultTimeSet timeset;
|
2023-06-22 08:17:12 +00:00
|
|
|
|
|
|
|
|
|
public Deployer(Configuration config)
|
|
|
|
|
{
|
|
|
|
|
this.config = config;
|
2023-06-22 12:37:37 +00:00
|
|
|
|
log = new NullLog();
|
|
|
|
|
timeset = new DefaultTimeSet();
|
2023-06-22 08:17:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-23 06:44:27 +00:00
|
|
|
|
public CodexDeployment Deploy()
|
2023-06-22 08:33:21 +00:00
|
|
|
|
{
|
|
|
|
|
Log("Initializing...");
|
2023-06-22 12:37:37 +00:00
|
|
|
|
var (workflowCreator, lifecycle) = CreateFacilities();
|
2023-06-22 08:33:21 +00:00
|
|
|
|
|
|
|
|
|
Log("Preparing configuration...");
|
2023-06-22 12:37:37 +00:00
|
|
|
|
// 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);
|
|
|
|
|
setup.WithStorageQuota(config.StorageQuota!.Value.MB()).EnableMarketplace(0.TestTokens());
|
2023-07-11 08:59:41 +00:00
|
|
|
|
setup.MetricsEnabled = config.RecordMetrics;
|
2023-06-22 08:33:21 +00:00
|
|
|
|
|
2023-06-22 12:37:37 +00:00
|
|
|
|
Log("Creating Geth instance and deploying contracts...");
|
|
|
|
|
var gethStarter = new GethStarter(lifecycle, workflowCreator);
|
|
|
|
|
var gethResults = gethStarter.BringOnlineMarketplaceFor(setup);
|
2023-06-22 08:33:21 +00:00
|
|
|
|
|
2023-06-22 12:37:37 +00:00
|
|
|
|
Log("Geth started. Codex contracts deployed.");
|
2023-06-23 06:44:27 +00:00
|
|
|
|
Log("Warning: It can take up to 45 minutes for the Geth node to finish unlocking all if its 1000 preconfigured accounts.");
|
2023-06-22 12:37:37 +00:00
|
|
|
|
|
2023-06-30 07:54:13 +00:00
|
|
|
|
// It takes a second for the geth node to unlock a single account. Let's assume 3.
|
|
|
|
|
// We can't start the codex nodes until their accounts are definitely unlocked. So
|
|
|
|
|
// We wait:
|
|
|
|
|
Thread.Sleep(TimeSpan.FromSeconds(3.0 * config.NumberOfCodexNodes!.Value));
|
|
|
|
|
|
2023-06-22 12:37:37 +00:00
|
|
|
|
Log("Starting Codex nodes...");
|
|
|
|
|
|
|
|
|
|
// Each node must have its own IP, so it needs it own pod. Start them 1 at a time.
|
2023-06-28 06:48:46 +00:00
|
|
|
|
var codexStarter = new CodexNodeStarter(config, workflowCreator, lifecycle, gethResults, config.NumberOfValidators!.Value);
|
2023-06-23 06:44:27 +00:00
|
|
|
|
var codexContainers = new List<RunningContainer>();
|
2023-06-22 12:37:37 +00:00
|
|
|
|
for (var i = 0; i < config.NumberOfCodexNodes; i++)
|
2023-06-22 08:33:21 +00:00
|
|
|
|
{
|
2023-06-23 06:44:27 +00:00
|
|
|
|
var container = codexStarter.Start(i);
|
|
|
|
|
if (container != null) codexContainers.Add(container);
|
2023-06-22 08:33:21 +00:00
|
|
|
|
}
|
2023-06-23 06:44:27 +00:00
|
|
|
|
|
2023-07-11 10:21:48 +00:00
|
|
|
|
var prometheusContainer = StartMetricsService(lifecycle, setup, codexContainers);
|
2023-07-11 08:59:41 +00:00
|
|
|
|
|
2023-07-11 10:21:48 +00:00
|
|
|
|
return new CodexDeployment(gethResults, codexContainers.ToArray(), prometheusContainer, CreateMetadata());
|
2023-06-22 08:33:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-22 12:37:37 +00:00
|
|
|
|
private (WorkflowCreator, TestLifecycle) CreateFacilities()
|
2023-06-22 08:17:12 +00:00
|
|
|
|
{
|
2023-06-27 06:29:39 +00:00
|
|
|
|
var kubeConfig = GetKubeConfig(config.KubeConfigFile);
|
|
|
|
|
|
2023-06-22 08:17:12 +00:00
|
|
|
|
var lifecycleConfig = new DistTestCore.Configuration
|
|
|
|
|
(
|
2023-06-27 06:29:39 +00:00
|
|
|
|
kubeConfigFile: kubeConfig,
|
2023-06-22 08:17:12 +00:00
|
|
|
|
logPath: "null",
|
|
|
|
|
logDebug: false,
|
|
|
|
|
dataFilesPath: "notUsed",
|
2023-06-22 08:33:21 +00:00
|
|
|
|
codexLogLevel: config.CodexLogLevel,
|
2023-06-22 08:17:12 +00:00
|
|
|
|
runnerLocation: config.RunnerLocation
|
|
|
|
|
);
|
|
|
|
|
|
2023-06-27 06:29:39 +00:00
|
|
|
|
var kubeFlowConfig = new KubernetesWorkflow.Configuration(
|
2023-06-22 08:17:12 +00:00
|
|
|
|
k8sNamespacePrefix: config.KubeNamespace,
|
2023-06-27 06:29:39 +00:00
|
|
|
|
kubeConfigFile: kubeConfig,
|
2023-06-22 08:17:12 +00:00
|
|
|
|
operationTimeout: timeset.K8sOperationTimeout(),
|
|
|
|
|
retryDelay: timeset.WaitForK8sServiceDelay());
|
|
|
|
|
|
2023-06-27 06:29:39 +00:00
|
|
|
|
var workflowCreator = new WorkflowCreator(log, kubeFlowConfig, testNamespacePostfix: string.Empty);
|
2023-06-22 12:37:37 +00:00
|
|
|
|
var lifecycle = new TestLifecycle(log, lifecycleConfig, timeset, workflowCreator);
|
|
|
|
|
|
|
|
|
|
return (workflowCreator, lifecycle);
|
2023-06-22 08:33:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-07-11 10:21:48 +00:00
|
|
|
|
private RunningContainer? StartMetricsService(TestLifecycle lifecycle, CodexSetup setup, List<RunningContainer> codexContainers)
|
2023-07-11 08:59:41 +00:00
|
|
|
|
{
|
2023-07-11 10:21:48 +00:00
|
|
|
|
if (!setup.MetricsEnabled) return null;
|
|
|
|
|
|
2023-07-11 08:59:41 +00:00
|
|
|
|
Log("Starting metrics service...");
|
|
|
|
|
var runningContainers = new RunningContainers(null!, null!, codexContainers.ToArray());
|
2023-07-11 10:21:48 +00:00
|
|
|
|
return lifecycle.PrometheusStarter.CollectMetricsFor(runningContainers).Containers.Single();
|
2023-07-11 08:59:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-27 06:29:39 +00:00
|
|
|
|
private string? GetKubeConfig(string kubeConfigFile)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(kubeConfigFile) || kubeConfigFile.ToLowerInvariant() == "null") return null;
|
|
|
|
|
return kubeConfigFile;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-23 07:08:18 +00:00
|
|
|
|
private DeploymentMetadata CreateMetadata()
|
|
|
|
|
{
|
|
|
|
|
return new DeploymentMetadata(
|
|
|
|
|
kubeNamespace: config.KubeNamespace,
|
|
|
|
|
numberOfCodexNodes: config.NumberOfCodexNodes!.Value,
|
|
|
|
|
numberOfValidators: config.NumberOfValidators!.Value,
|
|
|
|
|
storageQuotaMB: config.StorageQuota!.Value,
|
2023-06-28 06:48:46 +00:00
|
|
|
|
codexLogLevel: config.CodexLogLevel,
|
|
|
|
|
initialTestTokens: config.InitialTestTokens,
|
|
|
|
|
minPrice: config.MinPrice,
|
|
|
|
|
maxCollateral: config.MaxCollateral,
|
|
|
|
|
maxDuration: config.MaxDuration);
|
2023-06-23 07:08:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-06-22 08:33:21 +00:00
|
|
|
|
private void Log(string msg)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(msg);
|
2023-06-22 08:17:12 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|