mirror of
https://github.com/logos-storage/logos-storage-nim-cs-dist-tests.git
synced 2026-01-07 16:03:07 +00:00
Implements api compatiblity checker
This commit is contained in:
parent
bce9a2c124
commit
e72c1b037c
91
ProjectPlugins/CodexPlugin/ApiChecker.cs
Normal file
91
ProjectPlugins/CodexPlugin/ApiChecker.cs
Normal file
@ -0,0 +1,91 @@
|
||||
using Core;
|
||||
using KubernetesWorkflow.Types;
|
||||
using Logging;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace CodexPlugin
|
||||
{
|
||||
public class ApiChecker
|
||||
{
|
||||
// <INSERT-OPENAPI-YAML-HASH>
|
||||
private const string OpenApiYamlHash = "5E-B8-2A-E3-61-0C-D6-11-F7-F6-19-4C-F9-35-CA-8B-D1-FF-51-52-1E-E7-A3-7A-5D-0C-2A-3D-50-93-5E-55";
|
||||
private const string OpenApiFilePath = "/codex/openapi.yaml";
|
||||
private const string DisableEnvironmentVariable = "CODEXPLUGIN_DISABLE_APICHECK";
|
||||
|
||||
private const bool Disable = false;
|
||||
|
||||
private const string Warning =
|
||||
"Warning: CodexPlugin was unable to find the openapi.yaml file in the Codex container. Are you running an old version of Codex? " +
|
||||
"Plugin will continue as normal, but API compatibility is not guaranteed!";
|
||||
|
||||
private const string Failure =
|
||||
"Codex API compatibility check failed! " +
|
||||
"openapi.yaml used by CodexPlugin does not match openapi.yaml in Codex container. Please update the openapi.yaml in " +
|
||||
"'ProjectPlugins/CodexPlugin' and rebuild this project. If you wish to disable API compatibility checking, please set " +
|
||||
$"the environment variable '{DisableEnvironmentVariable}' or set the disable bool in 'ProjectPlugins/CodexPlugin/ApiChecker.cs'.";
|
||||
|
||||
private static bool checkPassed = false;
|
||||
|
||||
private readonly IPluginTools pluginTools;
|
||||
private readonly ILog log;
|
||||
|
||||
public ApiChecker(IPluginTools pluginTools)
|
||||
{
|
||||
this.pluginTools = pluginTools;
|
||||
log = pluginTools.GetLog();
|
||||
|
||||
if (string.IsNullOrEmpty(OpenApiYamlHash)) throw new Exception("OpenAPI yaml hash was not inserted by pre-build trigger.");
|
||||
}
|
||||
|
||||
public void CheckCompatibility(RunningContainers[] containers)
|
||||
{
|
||||
if (checkPassed) return;
|
||||
|
||||
Log("CodexPlugin is checking API compatibility...");
|
||||
|
||||
if (Disable || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable(DisableEnvironmentVariable)))
|
||||
{
|
||||
Log("API compatibility checking has been disabled.");
|
||||
checkPassed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var workflow = pluginTools.CreateWorkflow();
|
||||
var container = containers.First().Containers.First();
|
||||
var containerApi = workflow.ExecuteCommand(container, "cat", OpenApiFilePath);
|
||||
|
||||
if (string.IsNullOrEmpty(containerApi))
|
||||
{
|
||||
log.Error(Warning);
|
||||
|
||||
checkPassed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var containerHash = Hash(containerApi);
|
||||
if (containerHash == OpenApiYamlHash)
|
||||
{
|
||||
Log("API compatibility check passed.");
|
||||
checkPassed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
log.Error(Failure);
|
||||
throw new Exception(Failure);
|
||||
}
|
||||
|
||||
private string Hash(string file)
|
||||
{
|
||||
var fileBytes = Encoding.ASCII.GetBytes(file);
|
||||
var sha = SHA256.Create();
|
||||
var hash = sha.ComputeHash(fileBytes);
|
||||
return BitConverter.ToString(hash);
|
||||
}
|
||||
|
||||
private void Log(string msg)
|
||||
{
|
||||
log.Log(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,8 +9,6 @@ namespace CodexPlugin
|
||||
private readonly IPluginTools tools;
|
||||
private readonly CodexLogLevel defaultLogLevel = CodexLogLevel.Trace;
|
||||
|
||||
private const string OpenApiYamlHash = "8B-DD-61-54-42-D7-28-8F-5A-A0-AF-C2-A4-53-A7-08-B6-C7-02-FD-59-1A-01-A9-B4-7D-E4-81-FA-84-23-7F";
|
||||
|
||||
public CodexPlugin(IPluginTools tools)
|
||||
{
|
||||
codexStarter = new CodexStarter(tools);
|
||||
|
||||
@ -9,11 +9,14 @@ namespace CodexPlugin
|
||||
{
|
||||
private readonly IPluginTools pluginTools;
|
||||
private readonly CodexContainerRecipe recipe = new CodexContainerRecipe();
|
||||
private readonly ApiChecker apiChecker;
|
||||
private DebugInfoVersion? versionResponse;
|
||||
|
||||
public CodexStarter(IPluginTools pluginTools)
|
||||
{
|
||||
this.pluginTools = pluginTools;
|
||||
|
||||
apiChecker = new ApiChecker(pluginTools);
|
||||
}
|
||||
|
||||
public RunningContainers[] BringOnline(CodexSetup codexSetup)
|
||||
@ -25,6 +28,8 @@ namespace CodexPlugin
|
||||
|
||||
var containers = StartCodexContainers(startupConfig, codexSetup.NumberOfNodes, codexSetup.Location);
|
||||
|
||||
apiChecker.CheckCompatibility(containers);
|
||||
|
||||
foreach (var rc in containers)
|
||||
{
|
||||
var podInfo = GetPodInfo(rc);
|
||||
|
||||
@ -3,8 +3,30 @@
|
||||
public static class Program
|
||||
{
|
||||
private const string OpenApiFile = "../CodexPlugin/openapi.yaml";
|
||||
private const string Search = "<CODEX_OPENAPI_HASH_HERE>";
|
||||
private const string TargetFile = "CodexPlugin.cs";
|
||||
private const string Search = "<INSERT-OPENAPI-YAML-HASH>";
|
||||
private const string TargetFile = "ApiChecker.cs";
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("Injecting hash of 'openapi.yaml'...");
|
||||
|
||||
var hash = CreateHash();
|
||||
// This hash is used to verify that the Codex docker image being used is compatible
|
||||
// with the openapi.yaml being used by the Codex plugin.
|
||||
// If the openapi.yaml files don't match, an exception is thrown.
|
||||
|
||||
SearchAndInject(hash);
|
||||
|
||||
// This program runs as the pre-build trigger for "CodexPlugin".
|
||||
// You might be wondering why this work isn't done by a shell script.
|
||||
// This is because this project is being run on many different platforms.
|
||||
// (Mac, Unix, Win, but also desktop/cloud containers.)
|
||||
// In order to not go insane trying to make a shell script that works in all possible cases,
|
||||
// instead we use the one tool that's definitely installed in all platforms and locations
|
||||
// when you're trying to run this plugin.
|
||||
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
|
||||
private static string CreateHash()
|
||||
{
|
||||
@ -14,23 +36,22 @@ public static class Program
|
||||
return BitConverter.ToString(hash);
|
||||
}
|
||||
|
||||
private static void SearchAndReplace(string hash)
|
||||
private static void SearchAndInject(string hash)
|
||||
{
|
||||
var lines = File.ReadAllLines(TargetFile);
|
||||
lines = lines.Select(l => l.Replace(Search, hash)).ToArray();
|
||||
Inject(lines, hash);
|
||||
File.WriteAllLines(TargetFile, lines);
|
||||
}
|
||||
|
||||
public static void Main(string[] args)
|
||||
private static void Inject(string[] lines, string hash)
|
||||
{
|
||||
Console.WriteLine("Injecting hash of 'openapi.yaml'...");
|
||||
// This hash is used to verify that the Codex docker image being used is compatible
|
||||
// with the openapi.yaml being used by the Codex plugin.
|
||||
// If the openapi.yaml files don't match, an exception is thrown.
|
||||
|
||||
var hash = CreateHash();
|
||||
SearchAndReplace(hash);
|
||||
|
||||
Console.WriteLine("Done!");
|
||||
for (var i = 0; i < lines.Length; i++)
|
||||
{
|
||||
if (lines[i].Contains(Search))
|
||||
{
|
||||
lines[i + 1] = $" private const string OpenApiYamlHash = \"{hash}\";";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user