Files
dashcaddy/desktop/Services/TemplateRegistry.cs
T
Hermes 86e4c9fc81 wip: Windows desktop app scaffold (WinUI 3/.NET 8) + NSIS installer + docs
Owner decision pending (STATE.md DC-100 tick): adopt/ship/park.
Preserved from fragile git stash to named branch 2026-08-23.
NOTE: requires a Windows build machine (WinUI XAML compiler + MSIX do not
cross-build on Linux) — see WINDOWS_APP_BUILD.md in this tree.
Secret-scanned clean 2026-08-23 (no keys/tokens/PEM in tree).
2026-08-22 23:50:34 -07:00

284 lines
9.1 KiB
C#

using System.Text.Json;
using System.Text.Json.Nodes;
using DashCaddy.Desktop.Models;
namespace DashCaddy.Desktop.Services;
public static class ComposeParser
{
public static List<ServiceModel> Parse(string yamlContent)
{
var services = new List<ServiceModel>();
// Simple YAML parsing - in production use YamlDotNet
// For now, we'll do a basic JSON-based approach assuming compose is converted
try
{
var json = JsonSerializer.Deserialize<JsonNode>(yamlContent); // This won't work for YAML directly
// Real implementation would use YamlDotNet
}
catch
{
// Fallback
}
return services;
}
public static List<ServiceModel> ParseJson(string jsonContent)
{
var compose = JsonSerializer.Deserialize<ComposeFile>(jsonContent, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
var services = new List<ServiceModel>();
if (compose?.Services != null)
{
foreach (var (name, svc) in compose.Services)
{
var port = ExtractPort(svc);
var env = svc.Environment ?? new Dictionary<string, string>();
services.Add(new ServiceModel
{
Id = Guid.NewGuid().ToString("N")[..8],
Name = name,
Type = "docker-compose",
Image = svc.Image ?? "",
Host = "localhost",
Port = port,
Environment = env,
Volumes = svc.Volumes ?? new List<string>(),
Labels = svc.Labels ?? new Dictionary<string, string>(),
ComposeFile = jsonContent
});
}
}
return services;
}
private static int ExtractPort(ComposeService svc)
{
if (svc.Ports != null)
{
foreach (var (key, value) in svc.Ports)
{
if (int.TryParse(key.Split(':')[0], out var hostPort))
return hostPort;
if (int.TryParse(key, out var containerPort))
return containerPort;
}
}
return 80;
}
}
public static class TemplateRegistry
{
private static readonly Dictionary<string, ServiceTemplate> Templates = new()
{
["plex"] = new ServiceTemplate
{
Id = "plex",
Name = "Plex Media Server",
Description = "Media server for movies, TV shows, and music",
Icon = "📺",
DefaultPort = 32400,
Image = "plexinc/pms-docker:latest",
Environment = new Dictionary<string, string>
{
["PLEX_CLAIM"] = "",
["TZ"] = "America/Los_Angeles"
},
Volumes = new List<string>
{
"E:/dockerdata/plex/config:/config",
"E:/dockerdata/plex/transcode:/transcode",
"E:/media:/data"
},
RequiredVariables = new[] { "PLEX_CLAIM" }
},
["homeassistant"] = new ServiceTemplate
{
Id = "homeassistant",
Name = "Home Assistant",
Description = "Open source home automation platform",
Icon = "🏠",
DefaultPort = 8123,
Image = "ghcr.io/home-assistant/home-assistant:stable",
Environment = new Dictionary<string, string>
{
["TZ"] = "America/Los_Angeles"
},
Volumes = new List<string>
{
"E:/dockerdata/homeassistant:/config"
},
NetworkMode = "host"
},
["jellyfin"] = new ServiceTemplate
{
Id = "jellyfin",
Name = "Jellyfin",
Description = "Free software media system",
Icon = "🎬",
DefaultPort = 8096,
Image = "jellyfin/jellyfin:latest",
Environment = new Dictionary<string, string>
{
["TZ"] = "America/Los_Angeles"
},
Volumes = new List<string>
{
"E:/dockerdata/jellyfin/config:/config",
"E:/dockerdata/jellyfin/cache:/cache",
"E:/media:/media"
}
},
["portainer"] = new ServiceTemplate
{
Id = "portainer",
Name = "Portainer",
Description = "Docker container management UI",
Icon = "🐳",
DefaultPort = 9443,
Image = "portainer/portainer-ce:latest",
Volumes = new List<string>
{
"E:/dockerdata/portainer:/data",
"//./pipe/docker_engine:/var/run/docker.sock"
}
},
["adguard"] = new ServiceTemplate
{
Id = "adguard",
Name = "AdGuard Home",
Description = "Network-wide ad blocking & DNS",
Icon = "🛡️",
DefaultPort = 3000,
Image = "adguard/adguardhome:latest",
Volumes = new List<string>
{
"E:/dockerdata/adguard/work:/opt/adguardhome/work",
"E:/dockerdata/adguard/conf:/opt/adguardhome/conf"
},
Ports = new Dictionary<int, int> { [53] = 53, [3000] = 3000 }
},
["uptime-kuma"] = new ServiceTemplate
{
Id = "uptime-kuma",
Name = "Uptime Kuma",
Description = "Self-hosted monitoring tool",
Icon = "📊",
DefaultPort = 3001,
Image = "louislam/uptime-kuma:1",
Volumes = new List<string>
{
"E:/dockerdata/uptime-kuma:/app/data"
}
},
["vaultwarden"] = new ServiceTemplate
{
Id = "vaultwarden",
Name = "Vaultwarden (Bitwarden)",
Description = "Self-hosted password manager",
Icon = "🔐",
DefaultPort = 8080,
Image = "vaultwarden/server:latest",
Environment = new Dictionary<string, string>
{
["SIGNUPS_ALLOWED"] = "true",
["INVITATIONS_ALLOWED"] = "true"
},
Volumes = new List<string>
{
"E:/dockerdata/vaultwarden:/data"
}
},
["paperless"] = new ServiceTemplate
{
Id = "paperless",
Name = "Paperless-ngx",
Description = "Document management system",
Icon = "📄",
DefaultPort = 8000,
Image = "ghcr.io/paperless-ngx/paperless-ngx:latest",
Environment = new Dictionary<string, string>
{
["PAPERLESS_REDIS"] = "redis://localhost:6379",
["PAPERLESS_DBHOST"] = "localhost",
["PAPERLESS_DBNAME"] = "paperless",
["PAPERLESS_DBUSER"] = "paperless",
["PAPERLESS_DBPASS"] = "paperless"
},
Volumes = new List<string>
{
"E:/dockerdata/paperless/data:/usr/src/paperless/data",
"E:/dockerdata/paperless/media:/usr/src/paperless/media",
"E:/dockerdata/paperless/export:/usr/src/paperless/export",
"E:/dockerdata/paperless/consume:/usr/src/paperless/consume"
}
}
};
public static ServiceTemplate Get(string id)
{
return Templates.TryGetValue(id, out var template) ? template : null;
}
public static IEnumerable<ServiceTemplate> GetAll()
{
return Templates.Values;
}
}
public class ServiceTemplate
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Icon { get; set; }
public int DefaultPort { get; set; }
public string Image { get; set; }
public Dictionary<string, string> Environment { get; set; } = new();
public List<string> Volumes { get; set; } = new();
public Dictionary<int, int> Ports { get; set; } = new();
public string NetworkMode { get; set; }
public string[] RequiredVariables { get; set; } = Array.Empty<string>();
public ServiceModel Instantiate(Dictionary<string, string> variables)
{
var env = new Dictionary<string, string>(Environment);
foreach (var (key, value) in variables)
{
env[key] = value;
}
var port = DefaultPort;
if (Ports.Count > 0)
{
port = Ports.Keys.First();
}
return new ServiceModel
{
Id = Guid.NewGuid().ToString("N")[..8],
Name = Name,
Type = "template",
Image = Image,
Host = "localhost",
Port = port,
Environment = env,
Volumes = Volumes,
Labels = new Dictionary<string, string>
{
["dashcaddy.template"] = Id,
["dashcaddy.managed"] = "true"
}
};
}
}