|
| 1 | +using System.Security.Cryptography; |
| 2 | +using System.Text; |
1 | 3 | using System.Text.Json; |
2 | 4 | using System.Text.Json.Serialization; |
3 | 5 | using GithubActionsOrchestrator.Database; |
@@ -49,36 +51,12 @@ public static void Main(string[] args) |
49 | 51 | .CreateLogger(); |
50 | 52 |
|
51 | 53 |
|
52 | | - string configDir = Environment.GetEnvironmentVariable("CONFIG_DIR") ?? |
53 | | - Directory.CreateTempSubdirectory().FullName; |
54 | | - |
55 | | - // Setup pool config |
56 | | - string configPath = Path.Combine(configDir, "config.json"); |
57 | | - if (!File.Exists(configPath)) |
58 | | - { |
59 | | - Log.Error($"Unable to read config file at {configPath}"); |
60 | | - return; |
61 | | - } |
62 | | - |
63 | | - string configJson = File.ReadAllText(configPath); |
64 | | - JsonSerializerOptions options = new() |
65 | | - { |
66 | | - Converters = |
67 | | - { |
68 | | - new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) |
69 | | - } |
70 | | - }; |
71 | | - Config = JsonSerializer.Deserialize<AutoScalerConfiguration>(configJson, options) ?? |
72 | | - throw new Exception("Unable to parse configuration"); |
73 | 54 |
|
74 | | - if (string.IsNullOrWhiteSpace(Config.HetznerToken)) |
| 55 | + if (!LoadConfiguration()) |
75 | 56 | { |
76 | | - Log.Error($"Hetzner cloud token not set in {configPath}"); |
| 57 | + Log.Error("Unable to do initial config load. Aborting."); |
77 | 58 | return; |
78 | 59 | } |
79 | | - |
80 | | - |
81 | | - Log.Information($"Loaded {Config.TargetConfigs.Count} targets and {Config.Sizes.Count} sizes."); |
82 | 60 |
|
83 | 61 | // Prepare metrics |
84 | 62 | using KestrelMetricServer server = new(port: 9000); |
@@ -153,6 +131,67 @@ public static void Main(string[] args) |
153 | 131 | app.Run(Program.Config.ListenUrl); |
154 | 132 | } |
155 | 133 |
|
| 134 | + static string GetFileHash(string filePath) |
| 135 | + { |
| 136 | + using SHA256 sha256 = SHA256.Create(); |
| 137 | + // Open the file and compute the hash |
| 138 | + using FileStream stream = File.OpenRead(filePath); |
| 139 | + byte[] hashBytes = sha256.ComputeHash(stream); |
| 140 | + // Convert the byte array to a hexadecimal string |
| 141 | + StringBuilder hashString = new StringBuilder(); |
| 142 | + foreach (byte b in hashBytes) |
| 143 | + { |
| 144 | + hashString.Append(b.ToString("x2")); // Convert each byte to a hexadecimal string |
| 145 | + } |
| 146 | + return hashString.ToString(); |
| 147 | + } |
| 148 | + |
| 149 | + |
| 150 | + public static bool LoadConfiguration() |
| 151 | + { |
| 152 | + string configDir = Environment.GetEnvironmentVariable("CONFIG_DIR") ?? |
| 153 | + Directory.CreateTempSubdirectory().FullName; |
| 154 | + // Setup pool config |
| 155 | + string configPath = Path.Combine(configDir, "config.json"); |
| 156 | + if (!File.Exists(configPath)) |
| 157 | + { |
| 158 | + Log.Error($"Unable to locate config file at {configPath}"); |
| 159 | + return false; |
| 160 | + } |
| 161 | + string configFileHash = GetFileHash(configPath); |
| 162 | + |
| 163 | + if (configFileHash == LoadedConfigHash) |
| 164 | + { |
| 165 | + return true; |
| 166 | + } |
| 167 | + |
| 168 | + Log.Information("Loading/refreshing configuration..."); |
| 169 | + |
| 170 | + string configJson = File.ReadAllText(configPath); |
| 171 | + JsonSerializerOptions options = new() |
| 172 | + { |
| 173 | + Converters = |
| 174 | + { |
| 175 | + new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) |
| 176 | + } |
| 177 | + }; |
| 178 | + var loadedConfig = JsonSerializer.Deserialize<AutoScalerConfiguration>(configJson, options) ?? |
| 179 | + throw new Exception("Unable to parse configuration"); |
| 180 | + |
| 181 | + if (string.IsNullOrWhiteSpace(loadedConfig.HetznerToken)) |
| 182 | + { |
| 183 | + Log.Error($"Hetzner cloud token not set in {configPath}"); |
| 184 | + return false; |
| 185 | + } |
| 186 | + |
| 187 | + Config = loadedConfig; |
| 188 | + LoadedConfigHash = configFileHash; |
| 189 | + Log.Information($"Loaded {Config.TargetConfigs.Count} targets and {Config.Sizes.Count} sizes."); |
| 190 | + return true; |
| 191 | + } |
| 192 | + |
| 193 | + public static string LoadedConfigHash { get; set; } |
| 194 | + |
156 | 195 | private static async Task<IResult> GithubWebhookHandler(HttpRequest request, [FromServices] CloudController cloud, [FromServices] ILogger<Program> logger, [FromServices] RunnerQueue poolMgr) |
157 | 196 | { |
158 | 197 | // Verify webhook HMAC - TODO |
|
0 commit comments