From b4f219a704d232e67a881c04a8910c58f336eacf Mon Sep 17 00:00:00 2001 From: ChiaraBm Date: Tue, 15 Apr 2025 14:38:18 +0200 Subject: [PATCH] Extracted all TODO static values to configuration parameters --- .../Abstractions/Server.Create.cs | 1 + .../Abstractions/Server.Destroy.cs | 6 +-- .../Abstractions/Server.Installation.cs | 1 + .../Abstractions/Server.cs | 8 +++- .../Configuration/AppConfiguration.cs | 12 +++++- .../ServerConfigurationExtensions.cs | 39 +++++++++++-------- .../Controllers/Servers/UploadController.cs | 18 +++++---- .../Models/ServerConsole.cs | 11 ++++-- .../Services/ServerService.cs | 9 ++++- 9 files changed, 71 insertions(+), 34 deletions(-) diff --git a/MoonlightServers.Daemon/Abstractions/Server.Create.cs b/MoonlightServers.Daemon/Abstractions/Server.Create.cs index 0511e76..80cf8a8 100644 --- a/MoonlightServers.Daemon/Abstractions/Server.Create.cs +++ b/MoonlightServers.Daemon/Abstractions/Server.Create.cs @@ -21,6 +21,7 @@ public partial class Server var dockerClient = ServiceProvider.GetRequiredService(); var parameters = Configuration.ToRuntimeCreateParameters( + appConfiguration: AppConfiguration, hostPath: RuntimeVolumePath, containerName: RuntimeContainerName ); diff --git a/MoonlightServers.Daemon/Abstractions/Server.Destroy.cs b/MoonlightServers.Daemon/Abstractions/Server.Destroy.cs index 74e04c2..29bb911 100644 --- a/MoonlightServers.Daemon/Abstractions/Server.Destroy.cs +++ b/MoonlightServers.Daemon/Abstractions/Server.Destroy.cs @@ -1,4 +1,5 @@ using Docker.DotNet; +using MoonlightServers.Daemon.Configuration; namespace MoonlightServers.Daemon.Abstractions; @@ -19,12 +20,11 @@ public partial class Server if (container.State.Running) { // Stop container when running - await LogToConsole("Stopping container"); - + await dockerClient.Containers.StopContainerAsync(container.ID, new() { - WaitBeforeKillSeconds = 30 // TODO: Config + WaitBeforeKillSeconds = (uint)AppConfiguration.Server.WaitBeforeKillSeconds }); } diff --git a/MoonlightServers.Daemon/Abstractions/Server.Installation.cs b/MoonlightServers.Daemon/Abstractions/Server.Installation.cs index 17c9983..545f3f1 100644 --- a/MoonlightServers.Daemon/Abstractions/Server.Installation.cs +++ b/MoonlightServers.Daemon/Abstractions/Server.Installation.cs @@ -50,6 +50,7 @@ public partial class Server // Creating container configuration var parameters = Configuration.ToInstallationCreateParameters( + appConfiguration: AppConfiguration, RuntimeVolumePath, InstallationVolumePath, InstallationContainerName, diff --git a/MoonlightServers.Daemon/Abstractions/Server.cs b/MoonlightServers.Daemon/Abstractions/Server.cs index e5bf503..144d8aa 100644 --- a/MoonlightServers.Daemon/Abstractions/Server.cs +++ b/MoonlightServers.Daemon/Abstractions/Server.cs @@ -1,5 +1,6 @@ using Docker.DotNet.Models; using Microsoft.AspNetCore.SignalR; +using MoonlightServers.Daemon.Configuration; using MoonlightServers.Daemon.Enums; using MoonlightServers.Daemon.Http.Hubs; using MoonlightServers.Daemon.Models; @@ -36,20 +37,23 @@ public partial class Server private StateMachine StateMachine; private ServerConfiguration Configuration; private CancellationTokenSource Cancellation; + private AppConfiguration AppConfiguration; public Server( ILogger logger, IServiceProvider serviceProvider, ServerConfiguration configuration, - IHubContext webSocketHub + IHubContext webSocketHub, + AppConfiguration appConfiguration ) { Logger = logger; ServiceProvider = serviceProvider; Configuration = configuration; WebSocketHub = webSocketHub; + AppConfiguration = appConfiguration; - Console = new(); + Console = new(AppConfiguration.Server.ConsoleMessageCacheLimit); Cancellation = new(); RuntimeContainerName = $"moonlight-runtime-{Configuration.Id}"; diff --git a/MoonlightServers.Daemon/Configuration/AppConfiguration.cs b/MoonlightServers.Daemon/Configuration/AppConfiguration.cs index 6c09d5b..7166a46 100644 --- a/MoonlightServers.Daemon/Configuration/AppConfiguration.cs +++ b/MoonlightServers.Daemon/Configuration/AppConfiguration.cs @@ -9,6 +9,7 @@ public class AppConfiguration public SecurityData Security { get; set; } = new(); public RemoteData Remote { get; set; } = new(); public FilesData Files { get; set; } = new(); + public ServerData Server { get; set; } = new(); public class RemoteData { @@ -45,6 +46,15 @@ public class AppConfiguration public class FilesData { - public int UploadLimit { get; set; } = 500; + public int UploadSizeLimit { get; set; } = 1024 * 2; + public int UploadChunkSize { get; set; } = 20; + } + + public class ServerData + { + public int WaitBeforeKillSeconds { get; set; } = 30; + public int TmpFsSize { get; set; } = 100; + public float MemoryOverheadMultiplier { get; set; } = 0.05f; + public int ConsoleMessageCacheLimit { get; set; } = 250; } } \ No newline at end of file diff --git a/MoonlightServers.Daemon/Extensions/ServerConfigurationExtensions.cs b/MoonlightServers.Daemon/Extensions/ServerConfigurationExtensions.cs index 2b04e7f..0cb0e50 100644 --- a/MoonlightServers.Daemon/Extensions/ServerConfigurationExtensions.cs +++ b/MoonlightServers.Daemon/Extensions/ServerConfigurationExtensions.cs @@ -1,6 +1,7 @@ using Docker.DotNet.Models; using Mono.Unix.Native; using MoonCore.Helpers; +using MoonlightServers.Daemon.Configuration; using MoonlightServers.Daemon.Models.Cache; using MoonlightServers.DaemonShared.PanelSide.Http.Responses; @@ -30,11 +31,15 @@ public static class ServerConfigurationExtensions StopCommand = response.StopCommand }; } - - public static CreateContainerParameters ToRuntimeCreateParameters(this ServerConfiguration configuration, - string hostPath, string containerName) + + public static CreateContainerParameters ToRuntimeCreateParameters( + this ServerConfiguration configuration, + AppConfiguration appConfiguration, + string hostPath, + string containerName + ) { - var parameters = configuration.ToSharedCreateParameters(); + var parameters = configuration.ToSharedCreateParameters(appConfiguration); #region Security @@ -150,6 +155,7 @@ public static class ServerConfigurationExtensions public static CreateContainerParameters ToInstallationCreateParameters( this ServerConfiguration configuration, + AppConfiguration appConfiguration, string runtimeHostPath, string installationHostPath, string containerName, @@ -157,27 +163,27 @@ public static class ServerConfigurationExtensions string installShell ) { - var parameters = configuration.ToSharedCreateParameters(); + var parameters = configuration.ToSharedCreateParameters(appConfiguration); // - Name parameters.Name = containerName; parameters.Hostname = containerName; - + // - Image parameters.Image = installDockerImage; - + // - Env parameters.Env = configuration .ToEnvironmentVariables() .Select(x => $"{x.Key}={x.Value}") .ToList(); - + // -- Working directory parameters.WorkingDir = "/mnt/server"; - + // - User // Note: Some images might not work if we set a user here - + var userId = Syscall.getuid(); // If we are root, we are able to change owner permissions after the installation @@ -186,11 +192,11 @@ public static class ServerConfigurationExtensions if (userId == 0) parameters.User = "0:0"; else - parameters.User = $"{userId}:{userId}"; + parameters.User = $"{userId}:{userId}"; // -- Mounts parameters.HostConfig.Mounts = new List(); - + parameters.HostConfig.Mounts.Add(new() { Source = runtimeHostPath, @@ -198,7 +204,7 @@ public static class ServerConfigurationExtensions ReadOnly = false, Type = "bind" }); - + parameters.HostConfig.Mounts.Add(new() { Source = installationHostPath, @@ -212,7 +218,8 @@ public static class ServerConfigurationExtensions return parameters; } - private static CreateContainerParameters ToSharedCreateParameters(this ServerConfiguration configuration) + private static CreateContainerParameters ToSharedCreateParameters(this ServerConfiguration configuration, + AppConfiguration appConfiguration) { var parameters = new CreateContainerParameters() { @@ -242,7 +249,7 @@ public static class ServerConfigurationExtensions var memoryLimit = configuration.Memory; // The overhead multiplier gives the container a little bit more memory to prevent crashes - var memoryOverhead = memoryLimit + (memoryLimit * 0.05f); // TODO: Config + var memoryOverhead = memoryLimit + (memoryLimit * appConfiguration.Server.MemoryOverheadMultiplier); long swapLimit = -1; @@ -287,7 +294,7 @@ public static class ServerConfigurationExtensions parameters.HostConfig.Tmpfs = new Dictionary() { - { "/tmp", $"rw,exec,nosuid,size=100M" } // TODO: Config + { "/tmp", $"rw,exec,nosuid,size={appConfiguration.Server.TmpFsSize}M" } }; #endregion diff --git a/MoonlightServers.Daemon/Http/Controllers/Servers/UploadController.cs b/MoonlightServers.Daemon/Http/Controllers/Servers/UploadController.cs index e5e2a86..91296d0 100644 --- a/MoonlightServers.Daemon/Http/Controllers/Servers/UploadController.cs +++ b/MoonlightServers.Daemon/Http/Controllers/Servers/UploadController.cs @@ -16,8 +16,6 @@ public class UploadController : Controller private readonly AppConfiguration Configuration; private readonly ServerService ServerService; - private readonly long ChunkSize = ByteConverter.FromMegaBytes(20).Bytes; // TODO config - public UploadController( ServerService serverService, AppConfiguration configuration @@ -29,11 +27,14 @@ public class UploadController : Controller [HttpPost] public async Task Upload( - [FromQuery] long totalSize, // TODO: Add limit in config + [FromQuery] long totalSize, [FromQuery] int chunkId, [FromQuery] string path ) { + var chunkSize = ByteConverter.FromMegaBytes(Configuration.Files.UploadChunkSize).Bytes; + var uploadLimit = ByteConverter.FromMegaBytes(Configuration.Files.UploadSizeLimit).Bytes; + #region File validation if (Request.Form.Files.Count != 1) @@ -41,7 +42,7 @@ public class UploadController : Controller var file = Request.Form.Files[0]; - if (file.Length > ChunkSize) + if (file.Length > chunkSize) throw new HttpApiException("The provided data exceeds the chunk size limit", 400); #endregion @@ -49,14 +50,17 @@ public class UploadController : Controller var serverId = int.Parse(User.Claims.First(x => x.Type == "serverId").Value); #region Chunk calculation and validation + + if(totalSize > uploadLimit) + throw new HttpApiException("Invalid upload request: Exceeding upload limit", 400); - var chunks = totalSize / ChunkSize; - chunks += totalSize % ChunkSize > 0 ? 1 : 0; + var chunks = totalSize / chunkSize; + chunks += totalSize % chunkSize > 0 ? 1 : 0; if (chunkId > chunks) throw new HttpApiException("Invalid chunk id: Out of bounds", 400); - var positionToSkipTo = ChunkSize * chunkId; + var positionToSkipTo = chunkSize * chunkId; #endregion diff --git a/MoonlightServers.Daemon/Models/ServerConsole.cs b/MoonlightServers.Daemon/Models/ServerConsole.cs index 8e5e928..ec7f4d4 100644 --- a/MoonlightServers.Daemon/Models/ServerConsole.cs +++ b/MoonlightServers.Daemon/Models/ServerConsole.cs @@ -2,12 +2,17 @@ namespace MoonlightServers.Daemon.Models; public class ServerConsole { - public event Func OnOutput; - public event Func OnInput; + public event Func? OnOutput; + public event Func? OnInput; public string[] Messages => GetMessages(); private readonly Queue MessageCache = new(); - private const int MaxMessagesInCache = 250; //TODO: Config + private int MaxMessagesInCache; + + public ServerConsole(int maxMessagesInCache) + { + MaxMessagesInCache = maxMessagesInCache; + } public async Task WriteToOutput(string content) { diff --git a/MoonlightServers.Daemon/Services/ServerService.cs b/MoonlightServers.Daemon/Services/ServerService.cs index abdbadf..7f6316b 100644 --- a/MoonlightServers.Daemon/Services/ServerService.cs +++ b/MoonlightServers.Daemon/Services/ServerService.cs @@ -5,6 +5,7 @@ using MoonCore.Attributes; using MoonCore.Exceptions; using MoonCore.Models; using MoonlightServers.Daemon.Abstractions; +using MoonlightServers.Daemon.Configuration; using MoonlightServers.Daemon.Enums; using MoonlightServers.Daemon.Extensions; using MoonlightServers.Daemon.Http.Hubs; @@ -22,6 +23,7 @@ public class ServerService : IHostedLifecycleService private readonly IServiceProvider ServiceProvider; private readonly ILoggerFactory LoggerFactory; private readonly IHubContext WebSocketHub; + private readonly AppConfiguration Configuration; private CancellationTokenSource Cancellation = new(); private bool IsInitialized = false; @@ -30,7 +32,8 @@ public class ServerService : IHostedLifecycleService ILogger logger, IServiceProvider serviceProvider, ILoggerFactory loggerFactory, - IHubContext webSocketHub + IHubContext webSocketHub, + AppConfiguration configuration ) { RemoteService = remoteService; @@ -38,6 +41,7 @@ public class ServerService : IHostedLifecycleService ServiceProvider = serviceProvider; LoggerFactory = loggerFactory; WebSocketHub = webSocketHub; + Configuration = configuration; } public async Task Initialize() //TODO: Add initialize call from panel @@ -196,7 +200,8 @@ public class ServerService : IHostedLifecycleService LoggerFactory.CreateLogger($"Server {serverConfiguration.Id}"), ServiceProvider, serverConfiguration, - WebSocketHub + WebSocketHub, + Configuration ); await server.Initialize(existingContainers);