diff --git a/CodexNetDeployer/Deployer.cs b/CodexNetDeployer/Deployer.cs index 03f428a..40849b5 100644 --- a/CodexNetDeployer/Deployer.cs +++ b/CodexNetDeployer/Deployer.cs @@ -1,41 +1,84 @@ using DistTestCore; +using DistTestCore.Codex; +using DistTestCore.Marketplace; +using KubernetesWorkflow; +using System.ComponentModel; namespace CodexNetDeployer { public class Deployer { private readonly Configuration config; + private readonly NullLog log; + private readonly DefaultTimeSet timeset; public Deployer(Configuration config) { this.config = config; + log = new NullLog(); + timeset = new DefaultTimeSet(); } public void Deploy() { Log("Initializing..."); - var starter = CreateStarter(); + var (workflowCreator, lifecycle) = CreateFacilities(); Log("Preparing configuration..."); - var setup = new CodexSetup(config.NumberOfCodexNodes!.Value, config.CodexLogLevel); + // 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()); - Log("Creating resources..."); - var group = (CodexNodeGroup) starter.BringOnline(setup); + Log("Creating Geth instance and deploying contracts..."); + var gethStarter = new GethStarter(lifecycle, workflowCreator); + var gethResults = gethStarter.BringOnlineMarketplaceFor(setup); - var containers = group.Containers; - foreach (var container in containers.Containers) + Log("Geth started. Codex contracts deployed."); + + Log("Starting Codex nodes..."); + + // Each node must have its own IP, so it needs it own pod. Start them 1 at a time. + var bootstrapSpr = ""; // The first one will be used to bootstrap the others. + for (var i = 0; i < config.NumberOfCodexNodes; i++) { - var pod = container.Pod.PodInfo; - Log($"Container '{container.Name}' online. Pod: '{pod.Name}@{pod.Ip}' on '{pod.K8SNodeName}'."); + Console.Write($" - {i} = "); + var workflow = workflowCreator.CreateWorkflow(); + var workflowStartup = new StartupConfig(); + var codexStart = new CodexStartupConfig(config.CodexLogLevel); + workflowStartup.Add(codexStart); + if (!string.IsNullOrEmpty(bootstrapSpr)) codexStart.BootstrapSpr = bootstrapSpr; + codexStart.StorageQuota = config.StorageQuota.Value.MB(); + var marketplaceConfig = new MarketplaceInitialConfig(100000.Eth(), 0.TestTokens()); + marketplaceConfig.AccountIndexOverride = i; + codexStart.MarketplaceConfig = marketplaceConfig; + workflowStartup.Add(gethResults); + + var containers = workflow.Start(1, Location.Unspecified, new CodexContainerRecipe(), workflowStartup); + + var container = containers.Containers.First(); + var address = lifecycle.Configuration.GetAddress(container); + var codexNode = new CodexNode(log, timeset, address); + var debugInfo = codexNode.GetDebugInfo(); + + if (!string.IsNullOrWhiteSpace(debugInfo.spr)) + { + var pod = container.Pod.PodInfo; + Console.Write($"Online ({pod.Name} at {pod.Ip} on '{pod.K8SNodeName}'" + Environment.NewLine); + + if (string.IsNullOrEmpty(bootstrapSpr)) bootstrapSpr = debugInfo.spr; + } + else + { + Console.Write("Unknown failure." + Environment.NewLine); + } } } - private CodexStarter CreateStarter() + private (WorkflowCreator, TestLifecycle) CreateFacilities() { - var log = new NullLog(); var lifecycleConfig = new DistTestCore.Configuration ( - kubeConfigFile: config.KubeConfigFile, + kubeConfigFile: null, //config.KubeConfigFile, logPath: "null", logDebug: false, dataFilesPath: "notUsed", @@ -43,16 +86,16 @@ namespace CodexNetDeployer runnerLocation: config.RunnerLocation ); - var timeset = new DefaultTimeSet(); var kubeConfig = new KubernetesWorkflow.Configuration( k8sNamespacePrefix: config.KubeNamespace, - kubeConfigFile: config.KubeConfigFile, + kubeConfigFile: null, // config.KubeConfigFile, operationTimeout: timeset.K8sOperationTimeout(), retryDelay: timeset.WaitForK8sServiceDelay()); - var lifecycle = new TestLifecycle(log, lifecycleConfig, timeset); - var workflowCreator = new KubernetesWorkflow.WorkflowCreator(log, kubeConfig); - return new CodexStarter(lifecycle, workflowCreator); + var workflowCreator = new WorkflowCreator(log, kubeConfig); + var lifecycle = new TestLifecycle(log, lifecycleConfig, timeset, workflowCreator); + + return (workflowCreator, lifecycle); } private void Log(string msg) diff --git a/CodexNetDeployer/NullLog.cs b/CodexNetDeployer/NullLog.cs index c64190b..8417d39 100644 --- a/CodexNetDeployer/NullLog.cs +++ b/CodexNetDeployer/NullLog.cs @@ -15,10 +15,12 @@ namespace CodexNetDeployer public override void Log(string message) { + //Console.WriteLine(message); } public override void Debug(string message = "", int skipFrames = 0) { + //Console.WriteLine(message); } public override void Error(string message) diff --git a/CodexNetDeployer/Program.cs b/CodexNetDeployer/Program.cs index 6f61fc7..ce59a6d 100644 --- a/CodexNetDeployer/Program.cs +++ b/CodexNetDeployer/Program.cs @@ -9,6 +9,14 @@ public class Program { public static void Main(string[] args) { + args = new[] + { + @"--kube-config=C:\Users\Ben\.kube\codex-tests-ams3-dev-kubeconfig.yaml", + "--kube-namespace=testing-deployer", + "--nodes=3", + "--storage-quota=1024" + }; + var nl = Environment.NewLine; Console.WriteLine("CodexNetDeployer" + nl + nl); diff --git a/DistTestCore/Codex/CodexContainerRecipe.cs b/DistTestCore/Codex/CodexContainerRecipe.cs index f327927..4cf4be1 100644 --- a/DistTestCore/Codex/CodexContainerRecipe.cs +++ b/DistTestCore/Codex/CodexContainerRecipe.cs @@ -50,7 +50,7 @@ namespace DistTestCore.Codex { var gethConfig = startupConfig.Get(); var companionNode = gethConfig.CompanionNode; - var companionNodeAccount = companionNode.Accounts[Index]; + var companionNodeAccount = companionNode.Accounts[GetAccountIndex(config.MarketplaceConfig)]; Additional(companionNodeAccount); var ip = companionNode.RunningContainer.Pod.PodInfo.Ip; @@ -62,5 +62,11 @@ namespace DistTestCore.Codex AddEnvVar("PERSISTENCE", "1"); } } + + private int GetAccountIndex(MarketplaceInitialConfig marketplaceConfig) + { + if (marketplaceConfig.AccountIndexOverride != null) return marketplaceConfig.AccountIndexOverride.Value; + return Index; + } } } diff --git a/DistTestCore/Configuration.cs b/DistTestCore/Configuration.cs index 03514cd..fceb4e0 100644 --- a/DistTestCore/Configuration.cs +++ b/DistTestCore/Configuration.cs @@ -17,7 +17,7 @@ namespace DistTestCore { kubeConfigFile = GetNullableEnvVarOrDefault("KUBECONFIG", null); logPath = GetEnvVarOrDefault("LOGPATH", "CodexTestLogs"); - logDebug = GetEnvVarOrDefault("LOGDEBUG", "false").ToLowerInvariant() == "true"; + logDebug = GetEnvVarOrDefault("LOGDEBUG", "true").ToLowerInvariant() == "true"; dataFilesPath = GetEnvVarOrDefault("DATAFILEPATH", "TestDataFiles"); codexLogLevel = ParseEnum.Parse(GetEnvVarOrDefault("LOGLEVEL", nameof(CodexLogLevel.Trace))); runnerLocation = ParseEnum.Parse(GetEnvVarOrDefault("RUNNERLOCATION", nameof(TestRunnerLocation.ExternalToCluster))); diff --git a/DistTestCore/GethStarter.cs b/DistTestCore/GethStarter.cs index 92af53f..3b9a9b1 100644 --- a/DistTestCore/GethStarter.cs +++ b/DistTestCore/GethStarter.cs @@ -33,6 +33,8 @@ namespace DistTestCore private void TransferInitialBalance(MarketplaceNetwork marketplaceNetwork, MarketplaceInitialConfig marketplaceConfig, GethCompanionNodeInfo companionNode) { + if (marketplaceConfig.InitialTestTokens.Amount == 0) return; + var interaction = marketplaceNetwork.StartInteraction(lifecycle); var tokenAddress = marketplaceNetwork.Marketplace.TokenAddress; diff --git a/DistTestCore/Marketplace/MarketplaceInitialConfig.cs b/DistTestCore/Marketplace/MarketplaceInitialConfig.cs index 1b66199..b802f33 100644 --- a/DistTestCore/Marketplace/MarketplaceInitialConfig.cs +++ b/DistTestCore/Marketplace/MarketplaceInitialConfig.cs @@ -10,5 +10,6 @@ public Ether InitialEth { get; } public TestToken InitialTestTokens { get; } + public int? AccountIndexOverride { get; set; } } } diff --git a/DistTestCore/TestLifecycle.cs b/DistTestCore/TestLifecycle.cs index ffd34b1..667b96c 100644 --- a/DistTestCore/TestLifecycle.cs +++ b/DistTestCore/TestLifecycle.cs @@ -7,15 +7,18 @@ namespace DistTestCore { public class TestLifecycle { - private readonly WorkflowCreator workflowCreator; private DateTime testStart = DateTime.MinValue; public TestLifecycle(TestLog log, Configuration configuration, ITimeSet timeSet) + : this(log, configuration, timeSet, new WorkflowCreator(log, configuration.GetK8sConfiguration(timeSet))) + { + } + + public TestLifecycle(TestLog log, Configuration configuration, ITimeSet timeSet, WorkflowCreator workflowCreator) { Log = log; Configuration = configuration; TimeSet = timeSet; - workflowCreator = new WorkflowCreator(log, configuration.GetK8sConfiguration(timeSet)); FileManager = new FileManager(Log, configuration); CodexStarter = new CodexStarter(this, workflowCreator);