Creating server daemon. Added system info (not host info) and data usage endpoints
This commit is contained in:
26
MoonlightServers.Daemon/Configuration/AppConfiguration.cs
Normal file
26
MoonlightServers.Daemon/Configuration/AppConfiguration.cs
Normal file
@@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
46
MoonlightServers.Daemon/Helpers/UnsafeDockerClient.cs
Normal file
46
MoonlightServers.Daemon/Helpers/UnsafeDockerClient.cs
Normal file
@@ -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<HttpClient> 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<DataUsageResponse> GetDataUsage()
|
||||||
|
{
|
||||||
|
using var client = await CreateHttpClient();
|
||||||
|
var responseJson = await client.GetStringAsync("http://some.random.domain/v1.47/system/df");
|
||||||
|
var response = JsonSerializer.Deserialize<DataUsageResponse>(responseJson)!;
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<SystemDataUsageResponse> 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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<SystemInfoResponse> 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()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
7
MoonlightServers.Daemon/Models/UnsafeDocker/UsageData.cs
Normal file
7
MoonlightServers.Daemon/Models/UnsafeDocker/UsageData.cs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
namespace MoonlightServers.Daemon.Models.UnsafeDocker;
|
||||||
|
|
||||||
|
public class UsageData
|
||||||
|
{
|
||||||
|
public long Used { get; set; }
|
||||||
|
public long Reclaimable { get; set; }
|
||||||
|
}
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
24
MoonlightServers.Daemon/MoonlightServers.Daemon.csproj
Normal file
24
MoonlightServers.Daemon/MoonlightServers.Daemon.csproj
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Docker.DotNet" Version="3.125.15" />
|
||||||
|
<PackageReference Include="MoonCore" Version="1.8.0" />
|
||||||
|
<PackageReference Include="MoonCore.Extended" Version="1.2.4" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Http\Middleware\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\MoonlightServers.DaemonShared\MoonlightServers.DaemonShared.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
5
MoonlightServers.Daemon/Program.cs
Normal file
5
MoonlightServers.Daemon/Program.cs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
using MoonlightServers.Daemon;
|
||||||
|
|
||||||
|
var startup = new Startup();
|
||||||
|
|
||||||
|
await startup.Run(args);
|
||||||
15
MoonlightServers.Daemon/Properties/launchSettings.json
Normal file
15
MoonlightServers.Daemon/Properties/launchSettings.json
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
52
MoonlightServers.Daemon/Services/DockerInfoService.cs
Normal file
52
MoonlightServers.Daemon/Services/DockerInfoService.cs
Normal file
@@ -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<string> GetDockerVersion()
|
||||||
|
{
|
||||||
|
var version = await DockerClient.System.GetVersionAsync();
|
||||||
|
|
||||||
|
return $"{version.Version} commit {version.GitCommit} ({version.APIVersion})";
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UsageDataReport> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
101
MoonlightServers.Daemon/Services/SystemInfoService.cs
Normal file
101
MoonlightServers.Daemon/Services/SystemInfoService.cs
Normal file
@@ -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<SystemInfoService> Logger;
|
||||||
|
private readonly IHost Host;
|
||||||
|
|
||||||
|
public SystemInfoService(
|
||||||
|
ILogger<SystemInfoService> logger,
|
||||||
|
IHost host
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Logger = logger;
|
||||||
|
Host = host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<string> 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<long> GetMemoryUsage()
|
||||||
|
{
|
||||||
|
var process = Process.GetCurrentProcess();
|
||||||
|
var bytes = process.PrivateMemorySize64;
|
||||||
|
return Task.FromResult(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<TimeSpan> GetUptime()
|
||||||
|
{
|
||||||
|
var process = Process.GetCurrentProcess();
|
||||||
|
var uptime = DateTime.Now - process.StartTime;
|
||||||
|
return Task.FromResult(uptime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
241
MoonlightServers.Daemon/Startup.cs
Normal file
241
MoonlightServers.Daemon/Startup.cs
Normal file
@@ -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<Startup> 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<Startup>();
|
||||||
|
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<AppConfiguration>("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<ConfigurationService>();
|
||||||
|
|
||||||
|
// Retrieve configuration
|
||||||
|
Configuration = ConfigurationService.GetConfiguration<AppConfiguration>(
|
||||||
|
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<Startup>();
|
||||||
|
|
||||||
|
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<string, string>
|
||||||
|
{
|
||||||
|
{ "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
|
||||||
|
}
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Http\Requests\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -6,6 +6,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoonlightServers.Frontend",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoonlightServers.Shared", "MoonlightServers.Shared\MoonlightServers.Shared.csproj", "{70FAFFFB-9EA6-4BB7-B4C0-A6BEF9684B32}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MoonlightServers.Shared", "MoonlightServers.Shared\MoonlightServers.Shared.csproj", "{70FAFFFB-9EA6-4BB7-B4C0-A6BEF9684B32}"
|
||||||
EndProject
|
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
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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}.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.ActiveCfg = Release|Any CPU
|
||||||
{70FAFFFB-9EA6-4BB7-B4C0-A6BEF9684B32}.Release|Any CPU.Build.0 = 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
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
Reference in New Issue
Block a user