diff --git a/backend/LexBoxApi/LexBoxKernel.cs b/backend/LexBoxApi/LexBoxKernel.cs index 2d6569dba..47f9a946a 100644 --- a/backend/LexBoxApi/LexBoxKernel.cs +++ b/backend/LexBoxApi/LexBoxKernel.cs @@ -54,6 +54,7 @@ public static void AddLexBoxApi(this IServiceCollection services, services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddHostedService(); services.AddTransient(); services.AddScoped(); services.AddScoped(); diff --git a/backend/LexBoxApi/Services/HgService.cs b/backend/LexBoxApi/Services/HgService.cs index 7db803e4c..7e6752e49 100644 --- a/backend/LexBoxApi/Services/HgService.cs +++ b/backend/LexBoxApi/Services/HgService.cs @@ -18,7 +18,7 @@ namespace LexBoxApi.Services; -public partial class HgService : IHgService +public partial class HgService : IHgService, IHostedService { private const string DELETED_REPO_FOLDER = "_____deleted_____"; private const string TEMP_REPO_FOLDER = "_____temp_____"; @@ -292,7 +292,8 @@ private async Task ExecuteHgCommandServerCommand(string code, strin return response.Content; } - private static readonly string[] InvalidRepoNames = { DELETED_REPO_FOLDER, TEMP_REPO_FOLDER, "api" }; + private static readonly string[] SpecialDirectoryNames = [DELETED_REPO_FOLDER, TEMP_REPO_FOLDER]; + private static readonly IEnumerable InvalidRepoNames = SpecialDirectoryNames.Append("api"); private void AssertIsSafeRepoName(string name) { @@ -366,6 +367,28 @@ public static string DetermineProjectUrlPrefix(HgType type, HgConfig hgConfig) $"Unknown request, HG request type: {type}") }; } + + public Task StartAsync(CancellationToken cancellationToken) + { + var repoContainerDirectories = SpecialDirectoryNames + .Concat(Enumerable.Range('a', 'z' - 'a' + 1).Select(c => ((char)c).ToString())) + .Concat(Enumerable.Range(0, 10).Select(c => c.ToString())); + + foreach (var directory in repoContainerDirectories) + { + var path = Path.Combine(_options.Value.RepoPath, directory); + var dirInfo = Directory.CreateDirectory(path); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + dirInfo.UnixFileMode = Permissions; + } + + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) + { + return Task.CompletedTask; + } } public class LogResponse diff --git a/deployment/base/hg-deployment.yaml b/deployment/base/hg-deployment.yaml index 2253cd61f..d7c2bd5f3 100644 --- a/deployment/base/hg-deployment.yaml +++ b/deployment/base/hg-deployment.yaml @@ -170,21 +170,3 @@ spec: items: - key: hgweb.hgrc path: hgweb.hgrc - - initContainers: - - name: init-repo-structure - securityContext: - runAsUser: 33 - runAsGroup: 33 # www-data - runAsNonRoot: true - image: busybox:1.36.1 - command: - - 'sh' - - '-c' - - | - cd /repos - mkdir -p a b c d e f g h i j k l m n o p q r s t u v w x y z - mkdir -p 0 1 2 3 4 5 6 7 8 9 - volumeMounts: - - name: repos - mountPath: /repos diff --git a/deployment/base/lexbox-deployment.yaml b/deployment/base/lexbox-deployment.yaml index 8d141d288..4c8489e5e 100644 --- a/deployment/base/lexbox-deployment.yaml +++ b/deployment/base/lexbox-deployment.yaml @@ -246,3 +246,21 @@ spec: configMapKeyRef: name: app-config key: environment-name + - name: set-repo-structure-owner-to-www-data + securityContext: + # Make sure we're authorized to set ownership + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + image: busybox:1.36.1 + command: + - 'sh' + - '-c' + - | + cd /repos + chown www-data:www-data . + # Only necessary if directories already exist with the wrong ownership + find . -maxdepth 1 -type d ! -name lost+found -exec chown www-data:www-data {} + + volumeMounts: + - name: repos + mountPath: /repos