manual_inherit
This commit is contained in:
@@ -16,11 +16,11 @@ let
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
services.actual = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
settings = {
|
||||
inherit (cfg) port;
|
||||
trustedProxies = [ config.${namespace}.network.ipv4.address ];
|
||||
port = cfg.port;
|
||||
serverFiles = "${cfg.configDir}/${name}/server-files";
|
||||
userFiles = "${cfg.configDir}/${name}/user-files";
|
||||
dataDir = "${cfg.configDir}/${name}";
|
||||
|
||||
@@ -39,23 +39,23 @@ let
|
||||
moduleConfig = {
|
||||
services = {
|
||||
ollama = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
package = pkgs.ollama-rocm;
|
||||
port = 11434;
|
||||
host = "0.0.0.0";
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
openFirewall = cfg.openFirewall;
|
||||
rocmOverrideGfx = "11.0.2";
|
||||
loadModels = [ ];
|
||||
home = "${cfg.configDir}/ollama";
|
||||
};
|
||||
|
||||
llama-cpp = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
port = 8127;
|
||||
host = "0.0.0.0";
|
||||
openFirewall = cfg.openFirewall;
|
||||
model = "${cfg.configDir}/llama-cpp/models/${cfg.llama-cpp.model}.gguf";
|
||||
package = inputs.llama-cpp.packages.${system}.rocm;
|
||||
extraFlags = [
|
||||
@@ -87,11 +87,11 @@ let
|
||||
};
|
||||
|
||||
open-webui = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
package = pkgs.open-webui;
|
||||
host = "0.0.0.0";
|
||||
port = 8888;
|
||||
openFirewall = cfg.openFirewall;
|
||||
environmentFile = config.sops.secrets."jallen-nas/open-webui".path;
|
||||
environment = {
|
||||
OPENID_PROVIDER_URL = "https://authentik.mjallen.dev/application/o/chat/.well-known/openid-configuration";
|
||||
|
||||
@@ -56,8 +56,8 @@ let
|
||||
# Enable radarr service
|
||||
services = {
|
||||
radarr = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
dataDir = "${cfg.configDir}/radarr";
|
||||
@@ -65,8 +65,8 @@ let
|
||||
|
||||
# Enable Sonarr service
|
||||
sonarr = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
dataDir = "${cfg.configDir}/sonarr";
|
||||
@@ -74,8 +74,8 @@ let
|
||||
};
|
||||
|
||||
lidarr = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
dataDir = "${cfg.configDir}/lidarr";
|
||||
@@ -172,23 +172,22 @@ let
|
||||
};
|
||||
|
||||
deluge = {
|
||||
inherit (cfg) openFirewall dataDir;
|
||||
enable = false;
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
openFirewall = cfg.openFirewall;
|
||||
dataDir = cfg.dataDir;
|
||||
web = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
port = 8112;
|
||||
openFirewall = cfg.openFirewall;
|
||||
};
|
||||
};
|
||||
|
||||
jackett = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = false;
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
openFirewall = cfg.openFirewall;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -27,8 +27,8 @@ let
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
services.atticd = {
|
||||
inherit (cfg) environmentFile;
|
||||
enable = true;
|
||||
environmentFile = cfg.environmentFile;
|
||||
settings = {
|
||||
listen = "${cfg.listenAddress}:${toString cfg.port}";
|
||||
storage = {
|
||||
|
||||
@@ -18,9 +18,11 @@ let
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
services.authentik = {
|
||||
inherit (cfg) environmentFile;
|
||||
enable = true;
|
||||
environmentFile = cfg.environmentFile;
|
||||
settings.port = cfg.port;
|
||||
settings = {
|
||||
inherit (cfg) port;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -6,55 +6,24 @@
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.services.caddy;
|
||||
|
||||
caddySecret = {
|
||||
inherit (config.users.users.caddy) name group;
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
sops = {
|
||||
secrets = {
|
||||
"jallen-nas/traefik/crowdsec/lapi-key" = {
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
owner = config.users.users.caddy.name;
|
||||
group = config.users.users.caddy.group;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
|
||||
"jallen-nas/traefik/crowdsec/capi-machine-id" = {
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
owner = config.users.users.caddy.name;
|
||||
group = config.users.users.caddy.group;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
|
||||
"jallen-nas/traefik/crowdsec/capi-password" = {
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
owner = config.users.users.caddy.name;
|
||||
group = config.users.users.caddy.group;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
"jallen-nas/traefik/cloudflare-dns-api-token" = {
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
owner = config.users.users.caddy.name;
|
||||
group = config.users.users.caddy.group;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
"jallen-nas/traefik/cloudflare-zone-api-token" = {
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
owner = config.users.users.caddy.name;
|
||||
group = config.users.users.caddy.group;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
"jallen-nas/traefik/cloudflare-api-key" = {
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
owner = config.users.users.caddy.name;
|
||||
group = config.users.users.caddy.group;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
"jallen-nas/traefik/cloudflare-email" = {
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
owner = config.users.users.caddy.name;
|
||||
group = config.users.users.caddy.group;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
"jallen-nas/traefik/crowdsec/lapi-key" = caddySecret;
|
||||
"jallen-nas/traefik/crowdsec/capi-machine-id" = caddySecret;
|
||||
"jallen-nas/traefik/crowdsec/capi-password" = caddySecret;
|
||||
"jallen-nas/traefik/cloudflare-dns-api-token" = caddySecret;
|
||||
"jallen-nas/traefik/cloudflare-zone-api-token" = caddySecret;
|
||||
"jallen-nas/traefik/cloudflare-api-key" = caddySecret;
|
||||
"jallen-nas/traefik/cloudflare-email" = caddySecret;
|
||||
};
|
||||
templates = {
|
||||
"caddy.env" = {
|
||||
@@ -64,8 +33,7 @@ in
|
||||
CLOUDFLARE_API_KEY=${config.sops.placeholder."jallen-nas/traefik/cloudflare-api-key"}
|
||||
CLOUDFLARE_EMAIL=${config.sops.placeholder."jallen-nas/traefik/cloudflare-email"}
|
||||
'';
|
||||
owner = config.users.users.caddy.name;
|
||||
group = config.users.users.caddy.group;
|
||||
inherit (config.users.users.caddy) name group;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
};
|
||||
|
||||
@@ -17,9 +17,9 @@ let
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
services.calibre-server = {
|
||||
inherit (cfg) port;
|
||||
enable = false;
|
||||
openFirewall = true;
|
||||
port = cfg.port;
|
||||
libraries = [ "${cfg.dataDir}/books" ];
|
||||
};
|
||||
};
|
||||
@@ -37,8 +37,8 @@ let
|
||||
package = pkgs.stable.calibre-web;
|
||||
dataDir = "${cfgWeb.configDir}/calibre-web";
|
||||
listen = {
|
||||
inherit (cfgWeb) port;
|
||||
ip = "0.0.0.0";
|
||||
port = cfgWeb.port;
|
||||
};
|
||||
options = {
|
||||
enableBookUploading = true;
|
||||
|
||||
@@ -15,9 +15,8 @@ let
|
||||
description = "Cockpit web-based server management UI";
|
||||
moduleConfig = {
|
||||
services.cockpit = {
|
||||
inherit (cfg) port openFirewall;
|
||||
enable = true;
|
||||
port = cfg.port;
|
||||
openFirewall = cfg.openFirewall;
|
||||
allowed-origins = [
|
||||
"https://${net.hosts.nas.lan}:${toString cfg.port}"
|
||||
"https://${net.hosts.nas.hostname}:${toString cfg.port}"
|
||||
|
||||
@@ -16,22 +16,21 @@ let
|
||||
moduleConfig = {
|
||||
# Configure the standard NixOS code-server service
|
||||
services.code-server = {
|
||||
inherit (cfg) port extraEnvironment;
|
||||
enable = true;
|
||||
port = cfg.port;
|
||||
user = "admin";
|
||||
group = "jallen-nas";
|
||||
host = cfg.listenAddress;
|
||||
auth = "none"; # "password"
|
||||
disableTelemetry = true;
|
||||
disableUpdateCheck = true;
|
||||
extraEnvironment = cfg.extraEnvironment;
|
||||
extraGroups = [
|
||||
"admin"
|
||||
"wheel"
|
||||
];
|
||||
}
|
||||
// optionalAttrs (cfg.hashedPassword != null) {
|
||||
hashedPassword = cfg.hashedPassword;
|
||||
inherit (cfg) hashedPassword;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -17,7 +17,7 @@ let
|
||||
moduleConfig = {
|
||||
services.collabora-online = {
|
||||
enable = true;
|
||||
port = cfg.port;
|
||||
inherit (cfg) port;
|
||||
settings = {
|
||||
# Rely on reverse proxy for SSL
|
||||
ssl = {
|
||||
|
||||
@@ -39,7 +39,7 @@ let
|
||||
services = {
|
||||
crowdsec = {
|
||||
enable = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
inherit (cfg) openFirewall;
|
||||
hub = {
|
||||
appSecConfigs = [
|
||||
"crowdsecurity/appsec-default"
|
||||
|
||||
@@ -22,8 +22,8 @@ let
|
||||
stateDir = "${cfg.configDir}/gitea";
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
mailerPasswordFile = mailerPasswordFile;
|
||||
metricsTokenFile = metricsTokenFile;
|
||||
inherit mailerPasswordFile;
|
||||
inherit metricsTokenFile;
|
||||
settings = {
|
||||
server = {
|
||||
DOMAIN = "jallen-nas";
|
||||
|
||||
@@ -12,9 +12,9 @@ let
|
||||
hostedServiceSites =
|
||||
let
|
||||
servicesCfg = config.${namespace}.services;
|
||||
serviceNames = builtins.attrNames servicesCfg;
|
||||
serviceNames = attrNames servicesCfg;
|
||||
in
|
||||
builtins.concatMap (
|
||||
concatMap (
|
||||
serviceName:
|
||||
let
|
||||
serviceCfg = servicesCfg.${serviceName};
|
||||
@@ -24,9 +24,7 @@ let
|
||||
[
|
||||
(
|
||||
{
|
||||
title = hosted.title;
|
||||
url = hosted.url;
|
||||
icon = hosted.icon;
|
||||
inherit (hosted) title url icon;
|
||||
}
|
||||
// optionalAttrs hosted.basicAuth {
|
||||
basic-auth = {
|
||||
@@ -40,9 +38,9 @@ let
|
||||
[ ]
|
||||
) serviceNames;
|
||||
|
||||
hostedServicesByGroup = builtins.groupBy (svc: svc.hostedService.group) (
|
||||
builtins.filter (svc: svc.hostedService != null && svc.hostedService.enable) (
|
||||
builtins.map (
|
||||
hostedServicesByGroup = groupBy (svc: svc.hostedService.group) (
|
||||
filter (svc: svc.hostedService != null && svc.hostedService.enable) (
|
||||
map (
|
||||
serviceName:
|
||||
let
|
||||
serviceCfg = config.${namespace}.services.${serviceName};
|
||||
@@ -50,7 +48,7 @@ let
|
||||
{
|
||||
hostedService = serviceCfg.hostedService or null;
|
||||
}
|
||||
) (builtins.attrNames config.${namespace}.services)
|
||||
) (attrNames config.${namespace}.services)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -332,7 +330,7 @@ let
|
||||
settings = {
|
||||
server = {
|
||||
host = "0.0.0.0";
|
||||
port = cfg.port;
|
||||
inherit (cfg) port;
|
||||
};
|
||||
pages = [
|
||||
{
|
||||
@@ -371,31 +369,27 @@ let
|
||||
}
|
||||
]
|
||||
++ lib.optionals cfg.hostedServiceGroups (
|
||||
builtins.map (
|
||||
map (
|
||||
groupName:
|
||||
makeMonitorWidget groupName (
|
||||
builtins.map (svc: {
|
||||
title = svc.hostedService.title;
|
||||
url = svc.hostedService.url;
|
||||
icon = svc.hostedService.icon;
|
||||
map (svc: {
|
||||
inherit (svc.hostedService) title url icon;
|
||||
}) (hostedServicesByGroup.${groupName} or [ ])
|
||||
)
|
||||
) (builtins.attrNames hostedServicesByGroup)
|
||||
) (attrNames hostedServicesByGroup)
|
||||
)
|
||||
++ lib.optionals (!cfg.hostedServiceGroups && cfg.enableHostedServices) [
|
||||
(makeMonitorWidget "Services" hostedServiceSites)
|
||||
]
|
||||
++ lib.optionals (cfg.extraSites != [ ]) (
|
||||
builtins.map (site: {
|
||||
map (site: {
|
||||
type = "monitor";
|
||||
cache = "1m";
|
||||
title = site.title;
|
||||
inherit (site) title;
|
||||
sites = [
|
||||
(
|
||||
{
|
||||
title = site.title;
|
||||
url = site.url;
|
||||
icon = site.icon;
|
||||
inherit (site) title url icon;
|
||||
}
|
||||
// optionalAttrs site.allow-insecure { allow-insecure = true; }
|
||||
)
|
||||
@@ -407,7 +401,7 @@ let
|
||||
groups = cfg.bookmarks;
|
||||
}
|
||||
++ lib.optionals (cfg.reddit != [ ]) (
|
||||
builtins.map (subreddit: {
|
||||
map (subreddit: {
|
||||
type = "reddit";
|
||||
inherit subreddit;
|
||||
}) cfg.reddit
|
||||
|
||||
@@ -17,7 +17,7 @@ let
|
||||
services.headscale = {
|
||||
enable = true;
|
||||
address = cfg.listenAddress;
|
||||
port = cfg.port;
|
||||
inherit (cfg) port;
|
||||
settings = {
|
||||
server_url = "https://headscale.mjallen.dev:443";
|
||||
database.sqlite.path = "${cfg.configDir}/headscale/db.sqlite";
|
||||
|
||||
@@ -19,9 +19,8 @@ let
|
||||
moduleConfig = {
|
||||
# Enable immich service
|
||||
services.immich = {
|
||||
inherit (cfg) port openFirewall;
|
||||
enable = true;
|
||||
port = cfg.port;
|
||||
openFirewall = true;
|
||||
secretsFile = dbPassword;
|
||||
mediaLocation = "${cfg.dataDir}/photos";
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ let
|
||||
moduleConfig = {
|
||||
services.jellyfin = {
|
||||
enable = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
inherit (cfg) openFirewall;
|
||||
user = "nix-apps";
|
||||
group = "jallen-nas";
|
||||
dataDir = "${cfg.configDir}/jellyfin";
|
||||
|
||||
@@ -16,9 +16,8 @@ let
|
||||
moduleConfig = {
|
||||
# Enable seerr service
|
||||
services.seerr = {
|
||||
inherit (cfg) port openFirewall;
|
||||
enable = true;
|
||||
port = cfg.port;
|
||||
openFirewall = cfg.openFirewall;
|
||||
configDir = "${cfg.configDir}/jellyseerr";
|
||||
};
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ let
|
||||
"jallen-nas/kavita/token" = {
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nas-secrets.yaml";
|
||||
owner = config.users.users.kavita.name;
|
||||
group = config.users.users.kavita.group;
|
||||
inherit (config.users.users.kavita) group;
|
||||
restartUnits = [ "kavita.service" ];
|
||||
};
|
||||
};
|
||||
@@ -28,7 +28,7 @@ let
|
||||
dataDir = "${cfg.configDir}/kavita";
|
||||
tokenKeyFile = config.sops.secrets."jallen-nas/kavita/token".path;
|
||||
settings = {
|
||||
Port = cfg.port;
|
||||
inherit (cfg) port;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -14,10 +14,10 @@ let
|
||||
options = { };
|
||||
moduleConfig = {
|
||||
services.minecraft-server = {
|
||||
inherit (cfg) openFirewall;
|
||||
enable = true;
|
||||
eula = true;
|
||||
declarative = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
dataDir = "${cfg.configDir}/minecraft"; # todo
|
||||
serverProperties = {
|
||||
enforce-whitelist = true;
|
||||
|
||||
@@ -115,20 +115,21 @@ let
|
||||
'';
|
||||
|
||||
services.nebula.networks.${cfg.networkName} = {
|
||||
inherit (cfg)
|
||||
isLighthouse
|
||||
isRelay
|
||||
lighthouses
|
||||
staticHostMap
|
||||
;
|
||||
enable = true;
|
||||
enableReload = true;
|
||||
isLighthouse = cfg.isLighthouse;
|
||||
isRelay = cfg.isRelay;
|
||||
inherit ca cert key;
|
||||
|
||||
lighthouses = cfg.lighthouses;
|
||||
staticHostMap = cfg.staticHostMap;
|
||||
|
||||
tun.device = if cfg.tunDevice != null then cfg.tunDevice else "nebula0";
|
||||
|
||||
listen = {
|
||||
host = cfg.listenAddress;
|
||||
port = cfg.port;
|
||||
inherit (cfg) port;
|
||||
};
|
||||
|
||||
settings.firewall = {
|
||||
|
||||
@@ -115,8 +115,8 @@ let
|
||||
virtualHosts.${config.services.nextcloud.hostName} = {
|
||||
listen = [
|
||||
{
|
||||
inherit (cfg) port;
|
||||
addr = "0.0.0.0";
|
||||
port = cfg.port;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
|
||||
@@ -17,7 +17,7 @@ let
|
||||
moduleConfig = {
|
||||
services.onlyoffice = {
|
||||
enable = true;
|
||||
port = cfg.port;
|
||||
inherit (cfg) port;
|
||||
wopi = true;
|
||||
hostname = "office.mjallen.dev";
|
||||
jwtSecretFile = jwtSecretFile;
|
||||
|
||||
@@ -21,7 +21,7 @@ let
|
||||
enable = true;
|
||||
url = "https://cloud.mjallen.dev";
|
||||
address = cfg.listenAddress;
|
||||
port = cfg.port;
|
||||
inherit (cfg) port;
|
||||
stateDir = "${cfg.configDir}/opencloud";
|
||||
environment = {
|
||||
PROXY_TLS = "false"; # disable https when behind reverse-proxy
|
||||
|
||||
@@ -61,8 +61,7 @@ in
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
virtualisation.oci-containers.containers."${cfg.name}" = {
|
||||
autoStart = cfg.autoStart;
|
||||
image = cfg.image;
|
||||
inherit (cfg) autoStart image;
|
||||
ports = [ "${cfg.httpPort}:9200" ];
|
||||
volumes = [
|
||||
"${cfg.configPath}:/etc/ocis"
|
||||
|
||||
@@ -18,9 +18,9 @@ let
|
||||
moduleConfig = {
|
||||
# Enable paperless service
|
||||
services.paperless = {
|
||||
inherit (cfg) port;
|
||||
enable = true;
|
||||
package = pkgs.paperless-ngx;
|
||||
port = cfg.port;
|
||||
# user = "nix-apps";
|
||||
address = cfg.listenAddress;
|
||||
dataDir = "${cfg.configDir}/paperless";
|
||||
|
||||
@@ -202,14 +202,16 @@ in
|
||||
services.restic.backups = mapAttrs (
|
||||
_name: jobCfg:
|
||||
{
|
||||
initialize = jobCfg.initialize;
|
||||
createWrapper = jobCfg.createWrapper;
|
||||
inhibitsSleep = jobCfg.inhibitsSleep;
|
||||
paths = jobCfg.paths;
|
||||
inherit (jobCfg)
|
||||
initialize
|
||||
createWrapper
|
||||
inhibitsSleep
|
||||
paths
|
||||
timerConfig
|
||||
pruneOpts
|
||||
extraBackupArgs
|
||||
;
|
||||
exclude = jobCfg.exclude ++ cfg.defaultExcludes;
|
||||
timerConfig = jobCfg.timerConfig;
|
||||
pruneOpts = jobCfg.pruneOpts;
|
||||
extraBackupArgs = jobCfg.extraBackupArgs;
|
||||
}
|
||||
// optionalAttrs (jobCfg.passwordFile != null) { inherit (jobCfg) passwordFile; }
|
||||
// optionalAttrs (jobCfg.repository != null) { inherit (jobCfg) repository; }
|
||||
|
||||
@@ -17,7 +17,7 @@ let
|
||||
moduleConfig = {
|
||||
services.sunshine = {
|
||||
enable = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
inherit (cfg) openFirewall;
|
||||
autoStart = true;
|
||||
capSysAdmin = true;
|
||||
applications.apps = with pkgs; [
|
||||
|
||||
Reference in New Issue
Block a user