mirror of
https://github.com/logos-storage/logos-storage-nim-cs-dist-tests.git
synced 2026-01-08 00:13:08 +00:00
extracts codex wrapper
This commit is contained in:
parent
d6afc6874b
commit
2c549c5410
12
ProjectPlugins/CodexPlugin/BinaryCodexStarter.cs
Normal file
12
ProjectPlugins/CodexPlugin/BinaryCodexStarter.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using CodexClient;
|
||||||
|
|
||||||
|
namespace CodexPlugin
|
||||||
|
{
|
||||||
|
public class BinaryCodexStarter : ICodexStarter
|
||||||
|
{
|
||||||
|
public ICodexInstance[] BringOnline(CodexSetup codexSetup)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
70
ProjectPlugins/CodexPlugin/CodexContainerProcessControl.cs
Normal file
70
ProjectPlugins/CodexPlugin/CodexContainerProcessControl.cs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
using CodexClient;
|
||||||
|
using Core;
|
||||||
|
using KubernetesWorkflow;
|
||||||
|
using KubernetesWorkflow.Types;
|
||||||
|
using Logging;
|
||||||
|
|
||||||
|
namespace CodexPlugin
|
||||||
|
{
|
||||||
|
public class CodexContainerProcessControl : IProcessControl
|
||||||
|
{
|
||||||
|
private readonly IPluginTools tools;
|
||||||
|
private readonly RunningPod pod;
|
||||||
|
private readonly Action onStop;
|
||||||
|
private readonly ContainerCrashWatcher crashWatcher;
|
||||||
|
|
||||||
|
public CodexContainerProcessControl(IPluginTools tools, RunningPod pod, Action onStop)
|
||||||
|
{
|
||||||
|
this.tools = tools;
|
||||||
|
this.pod = pod;
|
||||||
|
this.onStop = onStop;
|
||||||
|
|
||||||
|
crashWatcher = tools.CreateWorkflow().CreateCrashWatcher(pod.Containers.Single());
|
||||||
|
crashWatcher.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop(bool waitTillStopped)
|
||||||
|
{
|
||||||
|
Log($"Stopping node...");
|
||||||
|
var workflow = tools.CreateWorkflow();
|
||||||
|
workflow.Stop(pod, waitTillStopped);
|
||||||
|
crashWatcher.Stop();
|
||||||
|
onStop();
|
||||||
|
Log("Stopped.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDownloadedLog DownloadLog(LogFile file)
|
||||||
|
{
|
||||||
|
var workflow = tools.CreateWorkflow();
|
||||||
|
return workflow.DownloadContainerLog(pod.Containers.Single());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteDataDirFolder()
|
||||||
|
{
|
||||||
|
var container = pod.Containers.Single();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var dataDirVar = container.Recipe.EnvVars.Single(e => e.Name == "CODEX_DATA_DIR");
|
||||||
|
var dataDir = dataDirVar.Value;
|
||||||
|
var workflow = tools.CreateWorkflow();
|
||||||
|
workflow.ExecuteCommand(container, "rm", "-Rfv", $"/codex/{dataDir}/repo");
|
||||||
|
Log("Deleted repo folder.");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log("Unable to delete repo folder: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasCrashed()
|
||||||
|
{
|
||||||
|
return crashWatcher.HasCrashed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Log(string message)
|
||||||
|
{
|
||||||
|
tools.GetLog().Log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,10 +10,13 @@ namespace CodexPlugin
|
|||||||
private readonly IPluginTools tools;
|
private readonly IPluginTools tools;
|
||||||
private readonly CodexLogLevel defaultLogLevel = CodexLogLevel.Trace;
|
private readonly CodexLogLevel defaultLogLevel = CodexLogLevel.Trace;
|
||||||
private readonly CodexHooksFactory hooksFactory = new CodexHooksFactory();
|
private readonly CodexHooksFactory hooksFactory = new CodexHooksFactory();
|
||||||
|
private readonly ProcessControlMap processControlMap = new ProcessControlMap();
|
||||||
|
private readonly CodexWrapper codexWrapper;
|
||||||
|
|
||||||
public CodexPlugin(IPluginTools tools)
|
public CodexPlugin(IPluginTools tools)
|
||||||
{
|
{
|
||||||
codexStarter = new ContainerCodexStarter(tools, hooksFactory);
|
codexStarter = new ContainerCodexStarter(tools, processControlMap);
|
||||||
|
codexWrapper = new CodexWrapper(tools, processControlMap, hooksFactory);
|
||||||
this.tools = tools;
|
this.tools = tools;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,13 +24,13 @@ namespace CodexPlugin
|
|||||||
|
|
||||||
public void Announce()
|
public void Announce()
|
||||||
{
|
{
|
||||||
Log($"Loaded with Codex ID: '{codexStarter.GetCodexId()}' - Revision: {codexStarter.GetCodexRevision()}");
|
Log($"Loaded with Codex ID: '{codexWrapper.GetCodexId()}' - Revision: {codexWrapper.GetCodexRevision()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddMetadata(IAddMetadata metadata)
|
public void AddMetadata(IAddMetadata metadata)
|
||||||
{
|
{
|
||||||
metadata.Add("codexid", codexStarter.GetCodexId());
|
metadata.Add("codexid", codexWrapper.GetCodexId());
|
||||||
metadata.Add("codexrevision", codexStarter.GetCodexRevision());
|
metadata.Add("codexrevision", codexWrapper.GetCodexRevision());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Decommission()
|
public void Decommission()
|
||||||
@ -43,7 +46,7 @@ namespace CodexPlugin
|
|||||||
public ICodexNodeGroup WrapCodexContainers(ICodexInstance[] instances)
|
public ICodexNodeGroup WrapCodexContainers(ICodexInstance[] instances)
|
||||||
{
|
{
|
||||||
instances = instances.Select(c => SerializeGate.Gate(c as CodexInstance)).ToArray();
|
instances = instances.Select(c => SerializeGate.Gate(c as CodexInstance)).ToArray();
|
||||||
return codexStarter.WrapCodexContainers(instances);
|
return codexWrapper.WrapCodexInstances(instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WireUpMarketplace(ICodexNodeGroup result, Action<ICodexSetup> setup)
|
public void WireUpMarketplace(ICodexNodeGroup result, Action<ICodexSetup> setup)
|
||||||
|
|||||||
80
ProjectPlugins/CodexPlugin/CodexWrapper.cs
Normal file
80
ProjectPlugins/CodexPlugin/CodexWrapper.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using CodexClient;
|
||||||
|
using CodexClient.Hooks;
|
||||||
|
using Core;
|
||||||
|
using Logging;
|
||||||
|
|
||||||
|
namespace CodexPlugin
|
||||||
|
{
|
||||||
|
public class CodexWrapper
|
||||||
|
{
|
||||||
|
private readonly IPluginTools pluginTools;
|
||||||
|
private readonly ProcessControlMap processControlMap;
|
||||||
|
private readonly CodexHooksFactory hooksFactory;
|
||||||
|
private DebugInfoVersion? versionResponse;
|
||||||
|
|
||||||
|
public CodexWrapper(IPluginTools pluginTools, ProcessControlMap processControlMap, CodexHooksFactory hooksFactory)
|
||||||
|
{
|
||||||
|
this.pluginTools = pluginTools;
|
||||||
|
this.processControlMap = processControlMap;
|
||||||
|
this.hooksFactory = hooksFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetCodexId()
|
||||||
|
{
|
||||||
|
if (versionResponse != null) return versionResponse.Version;
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetCodexRevision()
|
||||||
|
{
|
||||||
|
if (versionResponse != null) return versionResponse.Revision;
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICodexNodeGroup WrapCodexInstances(ICodexInstance[] instances)
|
||||||
|
{
|
||||||
|
var codexNodeFactory = new CodexNodeFactory(
|
||||||
|
log: pluginTools.GetLog(),
|
||||||
|
fileManager: pluginTools.GetFileManager(),
|
||||||
|
hooksFactory: hooksFactory,
|
||||||
|
httpFactory: pluginTools,
|
||||||
|
processControlFactory: processControlMap);
|
||||||
|
|
||||||
|
var group = CreateCodexGroup(instances, codexNodeFactory);
|
||||||
|
|
||||||
|
pluginTools.GetLog().Log($"Codex version: {group.Version}");
|
||||||
|
versionResponse = group.Version;
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CodexNodeGroup CreateCodexGroup(ICodexInstance[] instances, CodexNodeFactory codexNodeFactory)
|
||||||
|
{
|
||||||
|
var nodes = instances.Select(codexNodeFactory.CreateCodexNode).ToArray();
|
||||||
|
var group = new CodexNodeGroup(pluginTools, nodes);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Stopwatch.Measure(pluginTools.GetLog(), "EnsureOnline", group.EnsureOnline);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
CodexNodesNotOnline(instances);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CodexNodesNotOnline(ICodexInstance[] instances)
|
||||||
|
{
|
||||||
|
pluginTools.GetLog().Log("Codex nodes failed to start");
|
||||||
|
var log = pluginTools.GetLog();
|
||||||
|
foreach (var i in instances)
|
||||||
|
{
|
||||||
|
var pc = processControlMap.Get(i);
|
||||||
|
pc.DownloadLog(log.CreateSubfile(i.Name + "_failed_to_start"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,7 @@
|
|||||||
using CodexClient;
|
using CodexClient;
|
||||||
using CodexClient.Hooks;
|
|
||||||
using Core;
|
using Core;
|
||||||
using KubernetesWorkflow;
|
using KubernetesWorkflow;
|
||||||
using KubernetesWorkflow.Types;
|
using KubernetesWorkflow.Types;
|
||||||
using Logging;
|
|
||||||
using Utils;
|
using Utils;
|
||||||
|
|
||||||
namespace CodexPlugin
|
namespace CodexPlugin
|
||||||
@ -11,24 +9,17 @@ namespace CodexPlugin
|
|||||||
public class ContainerCodexStarter : ICodexStarter
|
public class ContainerCodexStarter : ICodexStarter
|
||||||
{
|
{
|
||||||
private readonly IPluginTools pluginTools;
|
private readonly IPluginTools pluginTools;
|
||||||
private readonly CodexHooksFactory hooksFactory;
|
private readonly ProcessControlMap processControlMap;
|
||||||
private readonly CodexContainerRecipe recipe = new CodexContainerRecipe();
|
private readonly CodexContainerRecipe recipe = new CodexContainerRecipe();
|
||||||
private readonly ApiChecker apiChecker;
|
private readonly ApiChecker apiChecker;
|
||||||
private readonly Dictionary<string, CodexContainerProcessControl> processControlMap = new Dictionary<string, CodexContainerProcessControl>();
|
|
||||||
private DebugInfoVersion? versionResponse;
|
|
||||||
|
|
||||||
public ContainerCodexStarter(IPluginTools pluginTools, CodexHooksFactory hooksFactory)
|
public ContainerCodexStarter(IPluginTools pluginTools, ProcessControlMap processControlMap)
|
||||||
{
|
{
|
||||||
this.pluginTools = pluginTools;
|
this.pluginTools = pluginTools;
|
||||||
this.hooksFactory = hooksFactory;
|
this.processControlMap = processControlMap;
|
||||||
apiChecker = new ApiChecker(pluginTools);
|
apiChecker = new ApiChecker(pluginTools);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IProcessControl CreateProcessControl(ICodexInstance instance)
|
|
||||||
{
|
|
||||||
return processControlMap[instance.Name];
|
|
||||||
}
|
|
||||||
|
|
||||||
public ICodexInstance[] BringOnline(CodexSetup codexSetup)
|
public ICodexInstance[] BringOnline(CodexSetup codexSetup)
|
||||||
{
|
{
|
||||||
LogSeparator();
|
LogSeparator();
|
||||||
@ -52,35 +43,6 @@ namespace CodexPlugin
|
|||||||
return containers.Select(CreateInstance).ToArray();
|
return containers.Select(CreateInstance).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICodexNodeGroup WrapCodexContainers(ICodexInstance[] instances)
|
|
||||||
{
|
|
||||||
var codexNodeFactory = new CodexNodeFactory(
|
|
||||||
log: pluginTools.GetLog(),
|
|
||||||
fileManager: pluginTools.GetFileManager(),
|
|
||||||
hooksFactory: hooksFactory,
|
|
||||||
httpFactory: pluginTools,
|
|
||||||
processControlFactory: this);
|
|
||||||
|
|
||||||
var group = CreateCodexGroup(instances, codexNodeFactory);
|
|
||||||
|
|
||||||
Log($"Codex version: {group.Version}");
|
|
||||||
versionResponse = group.Version;
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetCodexId()
|
|
||||||
{
|
|
||||||
if (versionResponse != null) return versionResponse.Version;
|
|
||||||
return recipe.Image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetCodexRevision()
|
|
||||||
{
|
|
||||||
if (versionResponse != null) return versionResponse.Revision;
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
|
|
||||||
private StartupConfig CreateStartupConfig(CodexSetup codexSetup)
|
private StartupConfig CreateStartupConfig(CodexSetup codexSetup)
|
||||||
{
|
{
|
||||||
var startupConfig = new StartupConfig();
|
var startupConfig = new StartupConfig();
|
||||||
@ -109,46 +71,17 @@ namespace CodexPlugin
|
|||||||
return workflow.GetPodInfo(rc);
|
return workflow.GetPodInfo(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CodexNodeGroup CreateCodexGroup(ICodexInstance[] instances, CodexNodeFactory codexNodeFactory)
|
|
||||||
{
|
|
||||||
var nodes = instances.Select(codexNodeFactory.CreateCodexNode).ToArray();
|
|
||||||
var group = new CodexNodeGroup(pluginTools, nodes);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Stopwatch.Measure(pluginTools.GetLog(), "EnsureOnline", group.EnsureOnline);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
CodexNodesNotOnline(instances);
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ICodexInstance CreateInstance(RunningPod pod)
|
private ICodexInstance CreateInstance(RunningPod pod)
|
||||||
{
|
{
|
||||||
var instance = CodexInstanceContainerExtension.CreateFromPod(pod);
|
var instance = CodexInstanceContainerExtension.CreateFromPod(pod);
|
||||||
var processControl = new CodexContainerProcessControl(pluginTools, pod, onStop: () =>
|
var processControl = new CodexContainerProcessControl(pluginTools, pod, onStop: () =>
|
||||||
{
|
{
|
||||||
processControlMap.Remove(instance.Name);
|
processControlMap.Remove(instance);
|
||||||
});
|
});
|
||||||
processControlMap.Add(instance.Name, processControl);
|
processControlMap.Add(instance, processControl);
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CodexNodesNotOnline(ICodexInstance[] instances)
|
|
||||||
{
|
|
||||||
Log("Codex nodes failed to start");
|
|
||||||
var log = pluginTools.GetLog();
|
|
||||||
foreach (var i in instances)
|
|
||||||
{
|
|
||||||
var pc = processControlMap[i.Name];
|
|
||||||
pc.DownloadLog(log.CreateSubfile(i.Name + "_failed_to_start"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogSeparator()
|
private void LogSeparator()
|
||||||
{
|
{
|
||||||
Log("----------------------------------------------------------------------------");
|
Log("----------------------------------------------------------------------------");
|
||||||
@ -166,66 +99,4 @@ namespace CodexPlugin
|
|||||||
pluginTools.GetLog().Log(message);
|
pluginTools.GetLog().Log(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CodexContainerProcessControl : IProcessControl
|
|
||||||
{
|
|
||||||
private readonly IPluginTools tools;
|
|
||||||
private readonly RunningPod pod;
|
|
||||||
private readonly Action onStop;
|
|
||||||
private readonly ContainerCrashWatcher crashWatcher;
|
|
||||||
|
|
||||||
public CodexContainerProcessControl(IPluginTools tools, RunningPod pod, Action onStop)
|
|
||||||
{
|
|
||||||
this.tools = tools;
|
|
||||||
this.pod = pod;
|
|
||||||
this.onStop = onStop;
|
|
||||||
|
|
||||||
crashWatcher = tools.CreateWorkflow().CreateCrashWatcher(pod.Containers.Single());
|
|
||||||
crashWatcher.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Stop(bool waitTillStopped)
|
|
||||||
{
|
|
||||||
Log($"Stopping node...");
|
|
||||||
var workflow = tools.CreateWorkflow();
|
|
||||||
workflow.Stop(pod, waitTillStopped);
|
|
||||||
crashWatcher.Stop();
|
|
||||||
onStop();
|
|
||||||
Log("Stopped.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDownloadedLog DownloadLog(LogFile file)
|
|
||||||
{
|
|
||||||
var workflow = tools.CreateWorkflow();
|
|
||||||
return workflow.DownloadContainerLog(pod.Containers.Single());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteDataDirFolder()
|
|
||||||
{
|
|
||||||
var container = pod.Containers.Single();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var dataDirVar = container.Recipe.EnvVars.Single(e => e.Name == "CODEX_DATA_DIR");
|
|
||||||
var dataDir = dataDirVar.Value;
|
|
||||||
var workflow = tools.CreateWorkflow();
|
|
||||||
workflow.ExecuteCommand(container, "rm", "-Rfv", $"/codex/{dataDir}/repo");
|
|
||||||
Log("Deleted repo folder.");
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Log("Unable to delete repo folder: " + e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool HasCrashed()
|
|
||||||
{
|
|
||||||
return crashWatcher.HasCrashed();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Log(string message)
|
|
||||||
{
|
|
||||||
tools.GetLog().Log(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,11 +2,8 @@
|
|||||||
|
|
||||||
namespace CodexPlugin
|
namespace CodexPlugin
|
||||||
{
|
{
|
||||||
public interface ICodexStarter : IProcessControlFactory
|
public interface ICodexStarter
|
||||||
{
|
{
|
||||||
string GetCodexId();
|
|
||||||
string GetCodexRevision();
|
|
||||||
ICodexInstance[] BringOnline(CodexSetup codexSetup);
|
ICodexInstance[] BringOnline(CodexSetup codexSetup);
|
||||||
ICodexNodeGroup WrapCodexContainers(ICodexInstance[] instances);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
29
ProjectPlugins/CodexPlugin/ProcessControlMap.cs
Normal file
29
ProjectPlugins/CodexPlugin/ProcessControlMap.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using CodexClient;
|
||||||
|
|
||||||
|
namespace CodexPlugin
|
||||||
|
{
|
||||||
|
public class ProcessControlMap : IProcessControlFactory
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, IProcessControl> processControlMap = new Dictionary<string, IProcessControl>();
|
||||||
|
|
||||||
|
public void Add(ICodexInstance instance, IProcessControl control)
|
||||||
|
{
|
||||||
|
processControlMap.Add(instance.Name, control);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(ICodexInstance instance)
|
||||||
|
{
|
||||||
|
processControlMap.Remove(instance.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IProcessControl CreateProcessControl(ICodexInstance instance)
|
||||||
|
{
|
||||||
|
return Get(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IProcessControl Get(ICodexInstance instance)
|
||||||
|
{
|
||||||
|
return processControlMap[instance.Name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user