From 3c88b60e8dc91df4b3c75a6f54a15065d14b0ab9 Mon Sep 17 00:00:00 2001 From: ChiaraBm Date: Thu, 12 Dec 2024 23:04:39 +0100 Subject: [PATCH] Creating server daemon. Added system info (not host info) and data usage endpoints --- .../Configuration/AppConfiguration.cs | 26 ++ .../Helpers/UnsafeDockerClient.cs | 46 ++++ .../Sys/SystemDataUsageController.cs | 33 +++ .../Controllers/Sys/SystemInfoController.cs | 33 +++ .../Models/UnsafeDocker/DataUsageResponse.cs | 75 ++++++ .../Models/UnsafeDocker/UsageData.cs | 7 + .../Models/UnsafeDocker/UsageDataReport.cs | 8 + .../MoonlightServers.Daemon.csproj | 24 ++ MoonlightServers.Daemon/Program.cs | 5 + .../Properties/launchSettings.json | 15 ++ .../Services/DockerInfoService.cs | 52 ++++ .../Services/SystemInfoService.cs | 101 ++++++++ MoonlightServers.Daemon/Startup.cs | 241 ++++++++++++++++++ .../Responses/Sys/SystemDataUsageResponse.cs | 11 + .../Http/Responses/Sys/SystemInfoResponse.cs | 11 + .../MoonlightServers.DaemonShared.csproj | 13 + MoonlightServers.sln | 12 + 17 files changed, 713 insertions(+) create mode 100644 MoonlightServers.Daemon/Configuration/AppConfiguration.cs create mode 100644 MoonlightServers.Daemon/Helpers/UnsafeDockerClient.cs create mode 100644 MoonlightServers.Daemon/Http/Controllers/Sys/SystemDataUsageController.cs create mode 100644 MoonlightServers.Daemon/Http/Controllers/Sys/SystemInfoController.cs create mode 100644 MoonlightServers.Daemon/Models/UnsafeDocker/DataUsageResponse.cs create mode 100644 MoonlightServers.Daemon/Models/UnsafeDocker/UsageData.cs create mode 100644 MoonlightServers.Daemon/Models/UnsafeDocker/UsageDataReport.cs create mode 100644 MoonlightServers.Daemon/MoonlightServers.Daemon.csproj create mode 100644 MoonlightServers.Daemon/Program.cs create mode 100644 MoonlightServers.Daemon/Properties/launchSettings.json create mode 100644 MoonlightServers.Daemon/Services/DockerInfoService.cs create mode 100644 MoonlightServers.Daemon/Services/SystemInfoService.cs create mode 100644 MoonlightServers.Daemon/Startup.cs create mode 100644 MoonlightServers.DaemonShared/Http/Responses/Sys/SystemDataUsageResponse.cs create mode 100644 MoonlightServers.DaemonShared/Http/Responses/Sys/SystemInfoResponse.cs create mode 100644 MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj diff --git a/MoonlightServers.Daemon/Configuration/AppConfiguration.cs b/MoonlightServers.Daemon/Configuration/AppConfiguration.cs new file mode 100644 index 0000000..f60e255 --- /dev/null +++ b/MoonlightServers.Daemon/Configuration/AppConfiguration.cs @@ -0,0 +1,26 @@ +namespace MoonlightServers.Daemon.Configuration; + +public class AppConfiguration +{ + public DockerData Docker { get; set; } = new(); + public StorageData Storage { get; set; } = new(); + public SecurityData Security { get; set; } = new(); + + public class DockerData + { + public string Uri { get; set; } = "unix:///var/run/docker.sock"; + } + + public class SecurityData + { + public string Token { get; set; } + } + + public class StorageData + { + public string Volumes { get; set; } + public string VirtualDisks { get; set; } + public string Backups { get; set; } + public string Install { get; set; } + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/Helpers/UnsafeDockerClient.cs b/MoonlightServers.Daemon/Helpers/UnsafeDockerClient.cs new file mode 100644 index 0000000..8178929 --- /dev/null +++ b/MoonlightServers.Daemon/Helpers/UnsafeDockerClient.cs @@ -0,0 +1,46 @@ +using System.Net.Sockets; +using System.Text.Json; +using MoonCore.Attributes; +using MoonCore.Helpers; +using MoonlightServers.Daemon.Configuration; +using MoonlightServers.Daemon.Models.UnsafeDocker; + +namespace MoonlightServers.Daemon.Helpers; + +[Singleton] +public class UnsafeDockerClient +{ + private readonly AppConfiguration Configuration; + + public UnsafeDockerClient(AppConfiguration configuration) + { + Configuration = configuration; + } + + public Task CreateHttpClient() + { + var client = new HttpClient(new SocketsHttpHandler() + { + ConnectCallback = async (context, token) => + { + var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP); + var endpoint = new UnixDomainSocketEndPoint( + Formatter.ReplaceStart(Configuration.Docker.Uri, "unix://", "") + ); + await socket.ConnectAsync(endpoint, token); + return new NetworkStream(socket, ownsSocket: true); + } + }); + + return Task.FromResult(client); + } + + public async Task GetDataUsage() + { + using var client = await CreateHttpClient(); + var responseJson = await client.GetStringAsync("http://some.random.domain/v1.47/system/df"); + var response = JsonSerializer.Deserialize(responseJson)!; + + return response; + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/Http/Controllers/Sys/SystemDataUsageController.cs b/MoonlightServers.Daemon/Http/Controllers/Sys/SystemDataUsageController.cs new file mode 100644 index 0000000..d8e9efa --- /dev/null +++ b/MoonlightServers.Daemon/Http/Controllers/Sys/SystemDataUsageController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; +using MoonlightServers.Daemon.Services; +using MoonlightServers.DaemonShared.Http.Responses.Sys; + +namespace MoonlightServers.Daemon.Http.Controllers.Sys; + +[ApiController] +[Route("api/system/dataUsage")] +public class SystemDataUsageController : Controller +{ + private readonly DockerInfoService DockerInfoService; + + public SystemDataUsageController(DockerInfoService dockerInfoService) + { + DockerInfoService = dockerInfoService; + } + + [HttpGet] + public async Task Get() + { + var report = await DockerInfoService.GetDataUsage(); + + return new SystemDataUsageResponse() + { + ImagesReclaimable = report.Images.Reclaimable, + ImagesUsed = report.Images.Used, + ContainersReclaimable = report.Containers.Reclaimable, + ContainersUsed = report.Containers.Used, + BuildCacheReclaimable = report.BuildCache.Reclaimable, + BuildCacheUsed = report.BuildCache.Used + }; + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/Http/Controllers/Sys/SystemInfoController.cs b/MoonlightServers.Daemon/Http/Controllers/Sys/SystemInfoController.cs new file mode 100644 index 0000000..69bdb30 --- /dev/null +++ b/MoonlightServers.Daemon/Http/Controllers/Sys/SystemInfoController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; +using MoonlightServers.Daemon.Services; +using MoonlightServers.DaemonShared.Http.Responses.Sys; + +namespace MoonlightServers.Daemon.Http.Controllers.Sys; + +[ApiController] +[Route("api/system/info")] +public class SystemInfoController : Controller +{ + private readonly SystemInfoService SystemInfoService; + private readonly DockerInfoService DockerInfoService; + + public SystemInfoController(SystemInfoService systemInfoService, DockerInfoService dockerInfoService) + { + SystemInfoService = systemInfoService; + DockerInfoService = dockerInfoService; + } + + [HttpGet] + public async Task GetInfo() + { + return new SystemInfoResponse() + { + Uptime = await SystemInfoService.GetUptime(), + Version = "2.1.0", + CpuUsage = await SystemInfoService.GetCpuUsage(), + DockerVersion = await DockerInfoService.GetDockerVersion(), + MemoryUsage = await SystemInfoService.GetMemoryUsage(), + OsName = await SystemInfoService.GetOsName() + }; + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/Models/UnsafeDocker/DataUsageResponse.cs b/MoonlightServers.Daemon/Models/UnsafeDocker/DataUsageResponse.cs new file mode 100644 index 0000000..332a1c4 --- /dev/null +++ b/MoonlightServers.Daemon/Models/UnsafeDocker/DataUsageResponse.cs @@ -0,0 +1,75 @@ +using System.Text.Json.Serialization; + +namespace MoonlightServers.Daemon.Models.UnsafeDocker; + +public class DataUsageResponse +{ + [JsonPropertyName("BuildCache")] + public BuildCacheData[] BuildCache { get; set; } + + [JsonPropertyName("LayersSize")] + public long LayersSize { get; set; } + + [JsonPropertyName("Images")] + public ImageData[] Images { get; set; } + + [JsonPropertyName("Containers")] + public ContainerData[] Containers { get; set; } + + [JsonPropertyName("Volumes")] + public VolumeData[] Volumes { get; set; } + + public class BuildCacheData + { + [JsonPropertyName("Size")] + public long Size { get; set; } + + [JsonPropertyName("InUse")] + public bool InUse { get; set; } + } + + public class ContainerData + { + [JsonPropertyName("Id")] + public string Id { get; set; } + + [JsonPropertyName("SizeRw")] + public long SizeRw { get; set; } + + [JsonPropertyName("SizeRootFs")] + public long SizeRootFs { get; set; } + } + + public class ImageData + { + [JsonPropertyName("Containers")] + public long Containers { get; set; } + + [JsonPropertyName("Id")] + public string Id { get; set; } + + [JsonPropertyName("SharedSize")] + public long SharedSize { get; set; } + + [JsonPropertyName("Size")] + public long Size { get; set; } + } + + public class VolumeData + { + [JsonPropertyName("Name")] + public string Name { get; set; } + + [JsonPropertyName("UsageData")] + public VolumeUsageData UsageData { get; set; } + } + + public class VolumeUsageData + { + [JsonPropertyName("RefCount")] + public long RefCount { get; set; } + + [JsonPropertyName("Size")] + public long Size { get; set; } + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/Models/UnsafeDocker/UsageData.cs b/MoonlightServers.Daemon/Models/UnsafeDocker/UsageData.cs new file mode 100644 index 0000000..d427ff1 --- /dev/null +++ b/MoonlightServers.Daemon/Models/UnsafeDocker/UsageData.cs @@ -0,0 +1,7 @@ +namespace MoonlightServers.Daemon.Models.UnsafeDocker; + +public class UsageData +{ + public long Used { get; set; } + public long Reclaimable { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/Models/UnsafeDocker/UsageDataReport.cs b/MoonlightServers.Daemon/Models/UnsafeDocker/UsageDataReport.cs new file mode 100644 index 0000000..d8677c2 --- /dev/null +++ b/MoonlightServers.Daemon/Models/UnsafeDocker/UsageDataReport.cs @@ -0,0 +1,8 @@ +namespace MoonlightServers.Daemon.Models.UnsafeDocker; + +public class UsageDataReport +{ + public UsageData Containers { get; set; } + public UsageData Images { get; set; } + public UsageData BuildCache { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj b/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj new file mode 100644 index 0000000..8b513fe --- /dev/null +++ b/MoonlightServers.Daemon/MoonlightServers.Daemon.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + diff --git a/MoonlightServers.Daemon/Program.cs b/MoonlightServers.Daemon/Program.cs new file mode 100644 index 0000000..ea1b72f --- /dev/null +++ b/MoonlightServers.Daemon/Program.cs @@ -0,0 +1,5 @@ +using MoonlightServers.Daemon; + +var startup = new Startup(); + +await startup.Run(args); \ No newline at end of file diff --git a/MoonlightServers.Daemon/Properties/launchSettings.json b/MoonlightServers.Daemon/Properties/launchSettings.json new file mode 100644 index 0000000..b3b3329 --- /dev/null +++ b/MoonlightServers.Daemon/Properties/launchSettings.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5275", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/MoonlightServers.Daemon/Services/DockerInfoService.cs b/MoonlightServers.Daemon/Services/DockerInfoService.cs new file mode 100644 index 0000000..3a49639 --- /dev/null +++ b/MoonlightServers.Daemon/Services/DockerInfoService.cs @@ -0,0 +1,52 @@ +using Docker.DotNet; +using MoonCore.Attributes; +using MoonlightServers.Daemon.Helpers; +using MoonlightServers.Daemon.Models.UnsafeDocker; + +namespace MoonlightServers.Daemon.Services; + +[Singleton] +public class DockerInfoService +{ + private readonly DockerClient DockerClient; + private readonly UnsafeDockerClient UnsafeDockerClient; + + public DockerInfoService(DockerClient dockerClient, UnsafeDockerClient unsafeDockerClient) + { + DockerClient = dockerClient; + UnsafeDockerClient = unsafeDockerClient; + } + + public async Task GetDockerVersion() + { + var version = await DockerClient.System.GetVersionAsync(); + + return $"{version.Version} commit {version.GitCommit} ({version.APIVersion})"; + } + + public async Task GetDataUsage() + { + var response = await UnsafeDockerClient.GetDataUsage(); + + var report = new UsageDataReport() + { + Containers = new UsageData() + { + Used = response.Containers.Sum(x => x.SizeRw), + Reclaimable = 0 + }, + Images = new UsageData() + { + Used = response.Images.Sum(x => x.Size), + Reclaimable = response.Images.Where(x => x.Containers == 0).Sum(x => x.Size) + }, + BuildCache = new UsageData() + { + Used = response.BuildCache.Sum(x => x.Size), + Reclaimable = response.BuildCache.Where(x => !x.InUse).Sum(x => x.Size) + } + }; + + return report; + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/Services/SystemInfoService.cs b/MoonlightServers.Daemon/Services/SystemInfoService.cs new file mode 100644 index 0000000..77587e5 --- /dev/null +++ b/MoonlightServers.Daemon/Services/SystemInfoService.cs @@ -0,0 +1,101 @@ +using System.Diagnostics; +using System.Runtime.InteropServices; +using Docker.DotNet; +using MoonCore.Attributes; +using MoonlightServers.Daemon.Helpers; + +namespace MoonlightServers.Daemon.Services; + +[Singleton] +public class SystemInfoService +{ + private readonly ILogger Logger; + private readonly IHost Host; + + public SystemInfoService( + ILogger logger, + IHost host + ) + { + Logger = logger; + Host = host; + } + + public Task GetOsName() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // Windows platform detected + var osVersion = Environment.OSVersion.Version; + return Task.FromResult($"Windows {osVersion.Major}.{osVersion.Minor}.{osVersion.Build}"); + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + var releaseRaw = File + .ReadAllLines("/etc/os-release") + .FirstOrDefault(x => x.StartsWith("PRETTY_NAME=")); + + if (string.IsNullOrEmpty(releaseRaw)) + return Task.FromResult("Linux (unknown release)"); + + var release = releaseRaw + .Replace("PRETTY_NAME=", "") + .Replace("\"", ""); + + if (string.IsNullOrEmpty(release)) + return Task.FromResult("Linux (unknown release)"); + + return Task.FromResult(release); + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // macOS platform detected + var osVersion = Environment.OSVersion.Version; + return Task.FromResult($"macOS {osVersion.Major}.{osVersion.Minor}.{osVersion.Build}"); + } + + // Unknown platform + return Task.FromResult("N/A"); + } + + public Task GetMemoryUsage() + { + var process = Process.GetCurrentProcess(); + var bytes = process.PrivateMemorySize64; + return Task.FromResult(bytes); + } + + public Task GetUptime() + { + var process = Process.GetCurrentProcess(); + var uptime = DateTime.Now - process.StartTime; + return Task.FromResult(uptime); + } + + public Task GetCpuUsage() + { + var process = Process.GetCurrentProcess(); + var cpuTime = process.TotalProcessorTime; + var wallClockTime = DateTime.UtcNow - process.StartTime.ToUniversalTime(); + + var cpuUsage = (int)(100.0 * cpuTime.TotalMilliseconds / wallClockTime.TotalMilliseconds / + Environment.ProcessorCount); + + return Task.FromResult(cpuUsage); + } + + public Task Shutdown() + { + Logger.LogCritical("Restart of daemon has been requested"); + + Task.Run(async () => + { + await Task.Delay(TimeSpan.FromSeconds(1)); + await Host.StopAsync(CancellationToken.None); + }); + + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/MoonlightServers.Daemon/Startup.cs b/MoonlightServers.Daemon/Startup.cs new file mode 100644 index 0000000..cfb1029 --- /dev/null +++ b/MoonlightServers.Daemon/Startup.cs @@ -0,0 +1,241 @@ +using System.Text.Json; +using Docker.DotNet; +using MoonCore.Configuration; +using MoonCore.Extended.Extensions; +using MoonCore.Extensions; +using MoonCore.Helpers; +using MoonCore.Services; +using MoonlightServers.Daemon.Configuration; + +namespace MoonlightServers.Daemon; + +public class Startup +{ + private string[] Args; + + // Configuration + private AppConfiguration Configuration; + private ConfigurationService ConfigurationService; + private ConfigurationOptions ConfigurationOptions; + + // Logging + private ILoggerProvider[] LoggerProviders; + private ILoggerFactory LoggerFactory; + private ILogger Logger; + + // WebApplication Stuff + private WebApplication WebApplication; + private WebApplicationBuilder WebApplicationBuilder; + + public async Task Run(string[] args) + { + Args = args; + + await SetupStorage(); + await SetupAppConfiguration(); + await SetupLogging(); + + await CreateWebApplicationBuilder(); + + await RegisterAppConfiguration(); + await RegisterLogging(); + await RegisterBase(); + await RegisterDocker(); + + await BuildWebApplication(); + + await UseBase(); + await UseBaseMiddleware(); + + await MapBase(); + + await WebApplication.RunAsync(); + } + + private Task SetupStorage() + { + Directory.CreateDirectory("storage"); + Directory.CreateDirectory(PathBuilder.Dir("storage", "logs")); + Directory.CreateDirectory(PathBuilder.Dir("storage", "plugins")); + + return Task.CompletedTask; + } + + #region Base + + private Task RegisterBase() + { + WebApplicationBuilder.Services.AutoAddServices(); + WebApplicationBuilder.Services.AddControllers(); + + WebApplicationBuilder.Services.AddApiExceptionHandler(); + WebApplicationBuilder.Services.AddSignalR(); + + return Task.CompletedTask; + } + + private Task UseBase() + { + WebApplication.UseRouting(); + WebApplication.UseApiExceptionHandler(); + + return Task.CompletedTask; + } + + private Task UseBaseMiddleware() + { + return Task.CompletedTask; + } + + private Task MapBase() + { + WebApplication.MapControllers(); + + return Task.CompletedTask; + } + + #endregion + + #region Docker + + private Task RegisterDocker() + { + var dockerClient = new DockerClientConfiguration( + new Uri(Configuration.Docker.Uri) + ).CreateClient(); + + WebApplicationBuilder.Services.AddSingleton(dockerClient); + + return Task.CompletedTask; + } + + #endregion + + #region Configurations + + private Task SetupAppConfiguration() + { + ConfigurationService = new ConfigurationService(); + + // Setup options + ConfigurationOptions = new ConfigurationOptions(); + + ConfigurationOptions.AddConfiguration("app"); + ConfigurationOptions.Path = PathBuilder.Dir("storage"); + ConfigurationOptions.EnvironmentPrefix = "WebAppTemplate".ToUpper(); + + // Create minimal logger + var loggerFactory = new LoggerFactory(); + + loggerFactory.AddMoonCore(configuration => + { + configuration.Console.Enable = true; + configuration.Console.EnableAnsiMode = true; + configuration.FileLogging.Enable = false; + }); + + var logger = loggerFactory.CreateLogger(); + + // Retrieve configuration + Configuration = ConfigurationService.GetConfiguration( + ConfigurationOptions, + logger + ); + + return Task.CompletedTask; + } + + private Task RegisterAppConfiguration() + { + ConfigurationService.RegisterInDi(ConfigurationOptions, WebApplicationBuilder.Services); + WebApplicationBuilder.Services.AddSingleton(ConfigurationService); + + return Task.CompletedTask; + } + + #endregion + + #region Web Application + + private Task CreateWebApplicationBuilder() + { + WebApplicationBuilder = WebApplication.CreateBuilder(Args); + return Task.CompletedTask; + } + + private Task BuildWebApplication() + { + WebApplication = WebApplicationBuilder.Build(); + return Task.CompletedTask; + } + + #endregion + + #region Logging + + private Task SetupLogging() + { + LoggerProviders = LoggerBuildHelper.BuildFromConfiguration(configuration => + { + configuration.Console.Enable = true; + configuration.Console.EnableAnsiMode = true; + + configuration.FileLogging.Enable = true; + configuration.FileLogging.EnableLogRotation = true; + configuration.FileLogging.Path = PathBuilder.File("storage", "logs", "WebAppTemplate.log"); + configuration.FileLogging.RotateLogNameTemplate = + PathBuilder.File("storage", "logs", "WebAppTemplate.log.{0}"); + }); + + LoggerFactory = new LoggerFactory(); + LoggerFactory.AddProviders(LoggerProviders); + + Logger = LoggerFactory.CreateLogger(); + + return Task.CompletedTask; + } + + private async Task RegisterLogging() + { + // Configure application logging + WebApplicationBuilder.Logging.ClearProviders(); + WebApplicationBuilder.Logging.AddProviders(LoggerProviders); + + // Logging levels + var logConfigPath = PathBuilder.File("storage", "logConfig.json"); + + // Ensure logging config, add a default one is missing + if (!File.Exists(logConfigPath)) + { + var logLevels = new Dictionary + { + { "Default", "Information" }, + { "Microsoft.AspNetCore", "Warning" }, + { "System.Net.Http.HttpClient", "Warning" } + }; + + var logLevelsJson = JsonSerializer.Serialize(logLevels); + var logConfig = "{\"LogLevel\":" + logLevelsJson + "}"; + await File.WriteAllTextAsync(logConfigPath, logConfig); + } + + // Configure logging configuration + WebApplicationBuilder.Logging.AddConfiguration( + await File.ReadAllTextAsync(logConfigPath) + ); + + // Mute exception handler middleware + // https://github.com/dotnet/aspnetcore/issues/19740 + WebApplicationBuilder.Logging.AddFilter( + "Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware", + LogLevel.Critical + ); + + WebApplicationBuilder.Logging.AddFilter( + "Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware", + LogLevel.Critical + ); + } + + #endregion +} \ No newline at end of file diff --git a/MoonlightServers.DaemonShared/Http/Responses/Sys/SystemDataUsageResponse.cs b/MoonlightServers.DaemonShared/Http/Responses/Sys/SystemDataUsageResponse.cs new file mode 100644 index 0000000..9b721fb --- /dev/null +++ b/MoonlightServers.DaemonShared/Http/Responses/Sys/SystemDataUsageResponse.cs @@ -0,0 +1,11 @@ +namespace MoonlightServers.DaemonShared.Http.Responses.Sys; + +public class SystemDataUsageResponse +{ + public long ImagesUsed { get; set; } + public long ImagesReclaimable { get; set; } + public long ContainersUsed { get; set; } + public long ContainersReclaimable { get; set; } + public long BuildCacheUsed { get; set; } + public long BuildCacheReclaimable { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.DaemonShared/Http/Responses/Sys/SystemInfoResponse.cs b/MoonlightServers.DaemonShared/Http/Responses/Sys/SystemInfoResponse.cs new file mode 100644 index 0000000..b9b1ef5 --- /dev/null +++ b/MoonlightServers.DaemonShared/Http/Responses/Sys/SystemInfoResponse.cs @@ -0,0 +1,11 @@ +namespace MoonlightServers.DaemonShared.Http.Responses.Sys; + +public class SystemInfoResponse +{ + public string DockerVersion { get; set; } + public string Version { get; set; } + public string OsName { get; set; } + public long MemoryUsage { get; set; } + public TimeSpan Uptime { get; set; } + public int CpuUsage { get; set; } +} \ No newline at end of file diff --git a/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj b/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj new file mode 100644 index 0000000..f217468 --- /dev/null +++ b/MoonlightServers.DaemonShared/MoonlightServers.DaemonShared.csproj @@ -0,0 +1,13 @@ + + + + net8.0 + enable + enable + + + + + + + diff --git a/MoonlightServers.sln b/MoonlightServers.sln index d95a8f0..1eadb0a 100644 --- a/MoonlightServers.sln +++ b/MoonlightServers.sln @@ -6,6 +6,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoonlightServers.Frontend", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoonlightServers.Shared", "MoonlightServers.Shared\MoonlightServers.Shared.csproj", "{70FAFFFB-9EA6-4BB7-B4C0-A6BEF9684B32}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoonlightServers.Daemon", "MoonlightServers.Daemon\MoonlightServers.Daemon.csproj", "{5EAFCB32-500B-477C-937A-3DAD63C5BB1A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoonlightServers.DaemonShared", "MoonlightServers.DaemonShared\MoonlightServers.DaemonShared.csproj", "{15EBCC5D-2440-4B5B-A046-F8327E0C1CB8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -24,5 +28,13 @@ Global {70FAFFFB-9EA6-4BB7-B4C0-A6BEF9684B32}.Debug|Any CPU.Build.0 = Debug|Any CPU {70FAFFFB-9EA6-4BB7-B4C0-A6BEF9684B32}.Release|Any CPU.ActiveCfg = Release|Any CPU {70FAFFFB-9EA6-4BB7-B4C0-A6BEF9684B32}.Release|Any CPU.Build.0 = Release|Any CPU + {5EAFCB32-500B-477C-937A-3DAD63C5BB1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5EAFCB32-500B-477C-937A-3DAD63C5BB1A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5EAFCB32-500B-477C-937A-3DAD63C5BB1A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5EAFCB32-500B-477C-937A-3DAD63C5BB1A}.Release|Any CPU.Build.0 = Release|Any CPU + {15EBCC5D-2440-4B5B-A046-F8327E0C1CB8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15EBCC5D-2440-4B5B-A046-F8327E0C1CB8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15EBCC5D-2440-4B5B-A046-F8327E0C1CB8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15EBCC5D-2440-4B5B-A046-F8327E0C1CB8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal