Recreated plugin with new project template. Started implementing server system daemon
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
using System.ComponentModel;
|
||||
using Docker.DotNet.Models;
|
||||
using MoonlightServers.Daemon.Models;
|
||||
|
||||
namespace MoonlightServers.Daemon.ServerSystem.Implementations.Docker;
|
||||
|
||||
public static class ConfigMapper
|
||||
{
|
||||
public static CreateContainerParameters GetRuntimeConfig(
|
||||
string uuid,
|
||||
string name,
|
||||
RuntimeConfiguration configuration,
|
||||
string runtimeStoragePath
|
||||
)
|
||||
{
|
||||
var parameters = new CreateContainerParameters()
|
||||
{
|
||||
HostConfig = new()
|
||||
};
|
||||
|
||||
ApplySharedOptions(parameters, configuration);
|
||||
|
||||
// Limits
|
||||
|
||||
if (configuration.Limits.CpuPercent.HasValue)
|
||||
{
|
||||
parameters.HostConfig.CPUQuota = configuration.Limits.CpuPercent.Value * 1000;
|
||||
parameters.HostConfig.CPUPeriod = 100000;
|
||||
parameters.HostConfig.CPUShares = 1024;
|
||||
}
|
||||
|
||||
if (configuration.Limits.MemoryMb.HasValue)
|
||||
{
|
||||
var memoryLimit = configuration.Limits.MemoryMb.Value;
|
||||
|
||||
// The overhead multiplier gives the container a little bit more memory to prevent crashes
|
||||
var memoryOverhead = memoryLimit + memoryLimit * 0.05f;
|
||||
|
||||
parameters.HostConfig.Memory = (long)memoryOverhead * 1024L * 1024L;
|
||||
parameters.HostConfig.MemoryReservation = (long)memoryLimit * 1024L * 1024L;
|
||||
|
||||
if (configuration.Limits.SwapMb.HasValue)
|
||||
{
|
||||
var rawSwap = configuration.Limits.SwapMb.Value * 1024L * 1024L;
|
||||
parameters.HostConfig.MemorySwap = rawSwap + (long)memoryOverhead;
|
||||
}
|
||||
}
|
||||
|
||||
parameters.HostConfig.BlkioWeight = 100;
|
||||
parameters.HostConfig.OomKillDisable = true;
|
||||
|
||||
// Storage
|
||||
|
||||
parameters.HostConfig.Tmpfs = new Dictionary<string, string>()
|
||||
{
|
||||
{ "/tmp", "rw,exec,nosuid,size=100M" } // TODO: Config
|
||||
};
|
||||
|
||||
parameters.WorkingDir = "/home/container";
|
||||
|
||||
parameters.HostConfig.Mounts = new List<Mount>();
|
||||
parameters.HostConfig.Mounts.Add(new Mount()
|
||||
{
|
||||
Source = runtimeStoragePath,
|
||||
Target = "/home/container",
|
||||
Type = "bind",
|
||||
ReadOnly = false
|
||||
});
|
||||
|
||||
// Labels
|
||||
parameters.Labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "dev.moonlightpanel", "true" },
|
||||
{ "dev.moonlightpanel.id", uuid }
|
||||
};
|
||||
|
||||
foreach (var label in configuration.Environment.Labels)
|
||||
parameters.Labels.Add(label.Key, label.Value);
|
||||
|
||||
// Security
|
||||
|
||||
parameters.HostConfig.CapDrop = new List<string>()
|
||||
{
|
||||
"setpcap", "mknod", "audit_write", "net_raw", "dac_override",
|
||||
"fowner", "fsetid", "net_bind_service", "sys_chroot", "setfcap"
|
||||
};
|
||||
|
||||
parameters.HostConfig.ReadonlyRootfs = true;
|
||||
parameters.HostConfig.SecurityOpt = new List<string>()
|
||||
{
|
||||
"no-new-privileges"
|
||||
};
|
||||
|
||||
// Name
|
||||
|
||||
parameters.Name = name;
|
||||
|
||||
// Docker Image
|
||||
parameters.Image = configuration.Template.DockerImage;
|
||||
|
||||
// Networking
|
||||
|
||||
if (configuration.Network.Ports.Length > 0 && !string.IsNullOrWhiteSpace(configuration.Network.FriendlyName))
|
||||
parameters.Hostname = configuration.Network.FriendlyName;
|
||||
|
||||
parameters.ExposedPorts = new Dictionary<string, EmptyStruct>();
|
||||
parameters.HostConfig.PortBindings = new Dictionary<string, IList<PortBinding>>();
|
||||
|
||||
foreach (var port in configuration.Network.Ports)
|
||||
{
|
||||
parameters.ExposedPorts.Add($"{port.Port}/tcp", new());
|
||||
parameters.ExposedPorts.Add($"{port.Port}/udp", new());
|
||||
|
||||
parameters.HostConfig.PortBindings.Add($"{port.Port}/tcp", new List<PortBinding>
|
||||
{
|
||||
new()
|
||||
{
|
||||
HostPort = port.Port.ToString(),
|
||||
HostIP = port.IpAddress
|
||||
}
|
||||
});
|
||||
|
||||
parameters.HostConfig.PortBindings.Add($"{port.Port}/udp", new List<PortBinding>
|
||||
{
|
||||
new()
|
||||
{
|
||||
HostPort = port.Port.ToString(),
|
||||
HostIP = port.IpAddress
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Force outgoing ip stuff
|
||||
|
||||
// User
|
||||
parameters.User = "1000:1000";
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public static CreateContainerParameters GetInstallConfig(
|
||||
string uuid,
|
||||
string name,
|
||||
RuntimeConfiguration runtimeConfiguration,
|
||||
InstallConfiguration installConfiguration,
|
||||
string runtimeStoragePath,
|
||||
string installStoragePath
|
||||
)
|
||||
{
|
||||
var parameters = new CreateContainerParameters()
|
||||
{
|
||||
HostConfig = new()
|
||||
};
|
||||
|
||||
ApplySharedOptions(parameters, runtimeConfiguration);
|
||||
|
||||
// Labels
|
||||
parameters.Labels = new Dictionary<string, string>()
|
||||
{
|
||||
{ "dev.moonlightpanel", "true" },
|
||||
{ "dev.moonlightpanel.id", uuid }
|
||||
};
|
||||
|
||||
foreach (var label in runtimeConfiguration.Environment.Labels)
|
||||
parameters.Labels.Add(label.Key, label.Value);
|
||||
|
||||
// Name
|
||||
|
||||
parameters.Name = name;
|
||||
|
||||
// Docker Image
|
||||
parameters.Image = installConfiguration.DockerImage;
|
||||
|
||||
// User
|
||||
parameters.User = "1000:1000";
|
||||
|
||||
// Storage
|
||||
parameters.WorkingDir = "/mnt/server";
|
||||
|
||||
parameters.HostConfig.Mounts = new List<Mount>();
|
||||
|
||||
parameters.HostConfig.Mounts.Add(new Mount()
|
||||
{
|
||||
Source = runtimeStoragePath,
|
||||
Target = "/mnt/server",
|
||||
ReadOnly = false,
|
||||
Type = "bind"
|
||||
});
|
||||
|
||||
parameters.HostConfig.Mounts.Add(new Mount()
|
||||
{
|
||||
Source = installStoragePath,
|
||||
Target = "/mnt/install",
|
||||
ReadOnly = false,
|
||||
Type = "bind"
|
||||
});
|
||||
|
||||
// Command
|
||||
parameters.Cmd = [installConfiguration.Shell, "/mnt/install/install.sh"];
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private static void ApplySharedOptions(
|
||||
CreateContainerParameters parameters,
|
||||
RuntimeConfiguration configuration
|
||||
)
|
||||
{
|
||||
// Input, output & error streams and TTY
|
||||
|
||||
parameters.Tty = true;
|
||||
parameters.AttachStderr = true;
|
||||
parameters.AttachStdin = true;
|
||||
parameters.AttachStdout = true;
|
||||
parameters.OpenStdin = true;
|
||||
|
||||
// Logging
|
||||
|
||||
parameters.HostConfig.LogConfig = new()
|
||||
{
|
||||
Type = "json-file", // We need to use this provider, as the GetLogs endpoint needs it
|
||||
Config = new Dictionary<string, string>()
|
||||
};
|
||||
|
||||
// Environment variables
|
||||
|
||||
parameters.Env = new List<string>()
|
||||
{
|
||||
$"STARTUP={configuration.Template.StartupCommand}",
|
||||
//TODO: Add timezone, add server ip
|
||||
};
|
||||
|
||||
if (configuration.Limits.MemoryMb.HasValue)
|
||||
parameters.Env.Add($"SERVER_MEMORY={configuration.Limits.MemoryMb.Value}");
|
||||
|
||||
if (configuration.Network.MainPort != null)
|
||||
{
|
||||
parameters.Env.Add($"SERVER_IP={configuration.Network.MainPort.IpAddress}");
|
||||
parameters.Env.Add($"SERVER_PORT={configuration.Network.MainPort.Port}");
|
||||
}
|
||||
|
||||
// Handle port variables
|
||||
var i = 1;
|
||||
foreach (var port in configuration.Network.Ports)
|
||||
{
|
||||
parameters.Env.Add($"ML_PORT_{i}={port.Port}");
|
||||
i++;
|
||||
}
|
||||
|
||||
// Copy variables as env vars
|
||||
foreach (var variable in configuration.Environment.Variables)
|
||||
parameters.Env.Add($"{variable.Key}={variable.Value}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user