Compare commits

..

No commits in common. "c7c87ec8b259c49b52ac0c88979e3336d82a50ec" and "89988727c3e51c7fafcf4d7c55a380ac6871c221" have entirely different histories.

17 changed files with 198 additions and 260 deletions

14
flake.lock generated
View file

@ -452,16 +452,16 @@
"nixpkgs-regression": "nixpkgs-regression" "nixpkgs-regression": "nixpkgs-regression"
}, },
"locked": { "locked": {
"lastModified": 1740601978, "lastModified": 1736798728,
"narHash": "sha256-b70oopwDPaHiddorJIvI8H50yTXOd04noGZVp3YPHbM=", "narHash": "sha256-Em+CXWHBgLG2m106Hs11FmVlsCr3ZQedTosJvRF2gnE=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nix", "repo": "nix",
"rev": "31923aaac0358336442244ec6baf8f6517463afd", "rev": "2cb0ddfe4eb216fab6d826c1056743c152722720",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "NixOS", "owner": "NixOS",
"ref": "31923aaac0358336442244ec6baf8f6517463afd", "ref": "2cb0ddfe4eb216fab6d826c1056743c152722720",
"repo": "nix", "repo": "nix",
"type": "github" "type": "github"
} }
@ -647,11 +647,11 @@
"systems": "systems" "systems": "systems"
}, },
"locked": { "locked": {
"lastModified": 1740960270, "lastModified": 1740880178,
"narHash": "sha256-JsNqwyqD2I/5h0KJ5ntrvULJpFgJdJb9jHNFucCLXJw=", "narHash": "sha256-NBPrFkKsTB/C8L6JDeC6p5Dxek/NMtcCRWYkafsyL38=",
"owner": "Gerg-L", "owner": "Gerg-L",
"repo": "nvim-flake", "repo": "nvim-flake",
"rev": "57f3e79cf0330cb4db3c1c612307dddd84c05a42", "rev": "b7488d039a8c63b7015c67f026da0564ae54b833",
"type": "github" "type": "github"
}, },
"original": { "original": {

View file

@ -24,7 +24,7 @@
type = "github"; type = "github";
owner = "NixOS"; owner = "NixOS";
repo = "nix"; repo = "nix";
ref = "31923aaac0358336442244ec6baf8f6517463afd"; ref = "2cb0ddfe4eb216fab6d826c1056743c152722720";
inputs.nixpkgs.follows = "stable"; inputs.nixpkgs.follows = "stable";
}; };
#other #other

View file

@ -1,4 +1,5 @@
cloudflare: ENC[AES256_GCM,data:RZ+Smjn1nvnkxYAF56fEcBsFvO3YY+FWJ8wb0c72sxQleRjy9tVp7yDr9gRfUg3G,iv:mGaFxKFLrIouNhyqq/nBKaKub1WfekcCeHVLASQpBCs=,tag:xKl5EHR9g7d4pJkt49BLyw==,type:str] cloudflare: ENC[AES256_GCM,data:RZ+Smjn1nvnkxYAF56fEcBsFvO3YY+FWJ8wb0c72sxQleRjy9tVp7yDr9gRfUg3G,iv:mGaFxKFLrIouNhyqq/nBKaKub1WfekcCeHVLASQpBCs=,tag:xKl5EHR9g7d4pJkt49BLyw==,type:str]
discordenv: ENC[AES256_GCM,data:GQVGLVlIutSEyCZYiGfc2ON4yOfCtKEApRYLHn98xKaflEQtgbhF62vwzKCc9hYEoqHH8L5wF1shqD0qJqVjJSwpVqiMJnWg7UMhxJ+sf+6QKkcrcy9W3oZx3YPd2PrbjaZTBpM1fq+Ccs/6zrs3WIZhR6At7qwnuSm+XjOFHsFwamqgrikhzgWzdrPXysiYMYglQ4IxjuJbgMbW+v/9qvfzf1DUIVpbFYHpUgOko1pR362YBe8yxv1arWJzejzxX/6TG3TLoyaa3H0lA+ch9LMp0cy9x2A2E1WufuC+tbXITNiHVWPlUUf233g=,iv:HWY/PXuVOyMNAiPdv1G0ysGcbdbk3YgCVp3eNkkdTl4=,tag:RhSH0KsppNCX0TcjZFttLQ==,type:str]
reboot_token: ENC[AES256_GCM,data:/3QP30OUZsFaagj9Ljde1jz5nxZA6jp6/B6pmlponepRy3uZJ2jlaYQ3EBDiv5L413ecfWePAeWlX07eZ08JIRdoO5Ky52LM1+nPHMJFXzQ0h2onz4RVQAM=,iv:qiRk93LM7+3QmW27ItoWYGo7PLlu/hpprcPdnOaCBdw=,tag:X9kEov2FOrsIqkkStLegPw==,type:str] reboot_token: ENC[AES256_GCM,data:/3QP30OUZsFaagj9Ljde1jz5nxZA6jp6/B6pmlponepRy3uZJ2jlaYQ3EBDiv5L413ecfWePAeWlX07eZ08JIRdoO5Ky52LM1+nPHMJFXzQ0h2onz4RVQAM=,iv:qiRk93LM7+3QmW27ItoWYGo7PLlu/hpprcPdnOaCBdw=,tag:X9kEov2FOrsIqkkStLegPw==,type:str]
searxngenv: ENC[AES256_GCM,data:HtH4KxXWoQEJp88Bgfhfj5Y4Up+inHu8mnVtay64XvCRpVKHF/kceC3XwT9C3IdXpQ==,iv:iXK8hOFoEnM5wFUZhC8IOdHzPhwPDHtTL8MmS5FSlns=,tag:TZHTB7ia5Qq2f2fETJOpEA==,type:str] searxngenv: ENC[AES256_GCM,data:HtH4KxXWoQEJp88Bgfhfj5Y4Up+inHu8mnVtay64XvCRpVKHF/kceC3XwT9C3IdXpQ==,iv:iXK8hOFoEnM5wFUZhC8IOdHzPhwPDHtTL8MmS5FSlns=,tag:TZHTB7ia5Qq2f2fETJOpEA==,type:str]
minifluxenv: ENC[AES256_GCM,data:wgz6sxSbbjXrgBAak0Q0TlvG78+JHPpiPtcbqGo9HpSF3qY78edECCDB3qqIaynxdhI4,iv:mbsr+OG8fE5MggmC+TNkLmhhDNGvJo+uelNRo/rMLoo=,tag:xN+FbNHZIVCruQh23aMt5g==,type:str] minifluxenv: ENC[AES256_GCM,data:wgz6sxSbbjXrgBAak0Q0TlvG78+JHPpiPtcbqGo9HpSF3qY78edECCDB3qqIaynxdhI4,iv:mbsr+OG8fE5MggmC+TNkLmhhDNGvJo+uelNRo/rMLoo=,tag:xN+FbNHZIVCruQh23aMt5g==,type:str]
@ -22,8 +23,8 @@ sops:
dGhDRXRTWE9xSGtxQU80RVpuL1A5MkEKxAxC/wDkq+6hM8eXkWd/RBDNIUtGYnPy dGhDRXRTWE9xSGtxQU80RVpuL1A5MkEKxAxC/wDkq+6hM8eXkWd/RBDNIUtGYnPy
MvVxB6dkj+S11oRcMpdFqiM9jSzz/gYecB2tfuDgj+UX/VAzSkvPxA== MvVxB6dkj+S11oRcMpdFqiM9jSzz/gYecB2tfuDgj+UX/VAzSkvPxA==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-02-26T23:23:36Z" lastmodified: "2025-02-25T22:55:01Z"
mac: ENC[AES256_GCM,data:rUuzMNzXf2rgmT7t4eNXnVDtA4izwbc+8wvMztu5gvymJNBGf2B+uvFzEZMqMA+gmdqwX4B51K2oTYe7GU3EAgjp+7709hy4Dzs0vILebJn6ijO3AVHLEWLE7ia0cao6wAzKv6qtlyvAb1TvyTgtJpM+LCsuOkEItPJxoEDGlzc=,iv:rYlkNXaz/mk7WBYm27y/+eqJAThZ/pcjW6bMuTjTIZ4=,tag:end6/klu3sW9PuTIbWxZmw==,type:str] mac: ENC[AES256_GCM,data:/TumMnTtiarcoWQmqXMJ1tJ8TBIJ37+E3V+aAQkGVGmOHcA1HaG8cf2LC2yDaDMD8H+mLXqNgw9iU22ZiXopIAmzP+wRRkkVnE61RpI8BFnW25guUE1h3j109rKV94j9fem/ejzqAIh3d1CcewULokOTD6TtS2QCMKZLhSVShp0=,iv:UvAZDLzrA+HGTFdNwZoB5K30tNwJDXBDJN/ZP/tllcA=,tag:2H5EST0cPEMXCIwz4i0Aag==,type:str]
pgp: [] pgp: []
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.9.4 version: 3.9.4

View file

@ -1,9 +1,5 @@
{ config }: { config }:
let
link = config.local.links.forgejo;
in
{ {
local.links.forgejo = { };
users = { users = {
groups.${config.services.forgejo.group} = { }; groups.${config.services.forgejo.group} = { };
users = { users = {
@ -14,6 +10,7 @@ in
openssh.authorizedKeys.keys = [ config.local.keys.gerg_gerg-desktop ]; openssh.authorizedKeys.keys = [ config.local.keys.gerg_gerg-desktop ];
}; };
${config.services.nginx.user}.extraGroups = [ config.services.forgejo.group ];
}; };
}; };
services.forgejo = { services.forgejo = {
@ -25,8 +22,9 @@ in
DOMAIN = "git.gerg-l.com"; DOMAIN = "git.gerg-l.com";
ROOT_URL = "https://git.gerg-l.com/"; ROOT_URL = "https://git.gerg-l.com/";
LANDING_PAGE = "/explore/repos"; LANDING_PAGE = "/explore/repos";
HTTP_ADDR = link.ipv4; HTTP_ADDR = "/run/forgejo/forgejo.sock";
HTTP_PORT = link.port; PROTOCOL = "http+unix";
UNIX_SOCKET_PERMISSION = "660";
}; };
ui.DEFAULT_THEME = "forgejo-dark"; ui.DEFAULT_THEME = "forgejo-dark";
service.DISABLE_REGISTRATION = true; service.DISABLE_REGISTRATION = true;
@ -37,5 +35,6 @@ in
}; };
}; };
local.nginx.proxyVhosts."git.gerg-l.com" = link.url; local.nginx.proxyVhosts."git.gerg-l.com" =
"http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}";
} }

View file

@ -1,11 +1,11 @@
{ config, ... }: { config, ... }:
let let
cfg = config.services.immich; cfg = config.services.immich;
link = config.local.links.immich;
in in
{ {
local.links.immich = { }; systemd.tmpfiles.rules =
systemd.tmpfiles.rules = [ "d ${cfg.mediaLocation} - ${cfg.user} ${cfg.group} - -" ];
[ "d ${cfg.mediaLocation} - ${cfg.user} ${cfg.group} - -" ];
users.users.${cfg.user}.extraGroups = [ "postgres" ]; users.users.${cfg.user}.extraGroups = [ "postgres" ];
services.immich = { services.immich = {
@ -18,9 +18,9 @@ in
mediaLocation = "/persist/services/immich"; mediaLocation = "/persist/services/immich";
machine-learning.enable = true; machine-learning.enable = true;
settings = null; settings = null;
inherit (link) port; port = 2283;
host = link.ipv4; host = "0.0.0.0";
}; };
local.nginx.proxyVhosts."photos.gerg-l.com" = link.url; local.nginx.proxyVhosts."photos.gerg-l.com" = "http://localhost:${toString cfg.port}";
} }

View file

@ -1,19 +1,15 @@
{ {
config, config,
lib,
}: }:
let
link = config.local.links.miniflux;
in
{ {
local.links.miniflux = { };
sops.secrets.minifluxenv = { }; sops.secrets.minifluxenv = { };
services.miniflux = { services.miniflux = {
enable = true; enable = true;
config = { config = {
BASE_URL = "https://flux.gerg-l.com"; BASE_URL = "https://flux.gerg-l.com";
LISTEN_ADDR = link.tuple; LISTEN_ADDR = "/run/miniflux/miniflux.sock";
}; };
adminCredentialsFile = config.sops.secrets.minifluxenv.path; adminCredentialsFile = config.sops.secrets.minifluxenv.path;
createDatabaseLocally = true; createDatabaseLocally = true;
@ -32,5 +28,11 @@ in
}; };
}; };
local.nginx.proxyVhosts."flux.gerg-l.com" = link.url; systemd.services.miniflux.serviceConfig = {
RuntimeDirectoryMode = lib.mkForce "0770";
DynamicUser = lib.mkForce false;
};
local.nginx.proxyVhosts."flux.gerg-l.com" =
"http://unix:${config.services.miniflux.config.LISTEN_ADDR}";
} }

View file

@ -1,23 +1,29 @@
{ {
config, config,
pkgs, pkgs,
lib,
}: }:
let
link = config.local.links.nix-serve;
in
{ {
local.links.nix-serve = { }; sops.secrets.store_key.owner = "nix-serve";
sops.secrets.store_key = { };
users = { users = {
groups.builder = { }; groups = {
users.builder = { builder = { };
nix-serve = { };
};
users = {
${config.services.nginx.user}.extraGroups = [ "nix-serve" ];
builder = {
isSystemUser = true; isSystemUser = true;
openssh.authorizedKeys.keys = [ config.local.keys.root_media-laptop ]; openssh.authorizedKeys.keys = [ config.local.keys.root_media-laptop ];
group = "builder"; group = "builder";
shell = pkgs.bashInteractive; shell = pkgs.bashInteractive;
}; };
nix-serve = {
isSystemUser = true;
group = "nix-serve";
};
};
}; };
services.openssh.extraConfig = '' services.openssh.extraConfig = ''
@ -32,18 +38,37 @@ in
nix.settings = { nix.settings = {
trusted-users = [ "builder" ]; trusted-users = [ "builder" ];
allowed-users = [ "nix-serve" ];
keep-outputs = true; keep-outputs = true;
keep-derivations = true; keep-derivations = true;
secret-key-files = config.sops.secrets.store_key.path; secret-key-files = config.sops.secrets.store_key.path;
}; };
services.nix-serve = { systemd.services.nix-serve = {
enable = true; description = "nix-serve binary cache server";
inherit (link) port; after = [ "network.target" ];
package = pkgs.nix-serve-ng; wantedBy = [ "multi-user.target" ];
bindAddress = link.ipv4;
secretKeyFile = config.sops.secrets.store_key.path; path = [
config.nix.package
pkgs.bzip2
];
serviceConfig = {
ExecStart = "${lib.getExe pkgs.nix-serve-ng} --socket /run/nix-serve/nix-serve.sock";
Restart = "always";
RestartSec = "5s";
User = "nix-serve";
Group = "nix-serve";
RuntimeDirectory = "nix-serve";
UMask = "0117";
}; };
local.nginx.proxyVhosts."cache.gerg-l.com" = link.url; environment = {
NIX_REMOTE = "daemon";
NIX_SECRET_KEY_FILE = config.sops.secrets.store_key.path;
};
};
local.nginx.proxyVhosts."cache.gerg-l.com" = "http://unix:/run/nix-serve/nix-serve.sock";
} }

View file

@ -1,10 +1,5 @@
{ config, pkgs }: { config, pkgs }:
let
link = config.local.links.searx;
in
{ {
local.links.searx = { };
sops.secrets.searxngenv = { }; sops.secrets.searxngenv = { };
users.users.${config.services.nginx.user}.extraGroups = [ "searx" ]; users.users.${config.services.nginx.user}.extraGroups = [ "searx" ];
services.searx = { services.searx = {
@ -12,7 +7,8 @@ in
package = pkgs.searxng; package = pkgs.searxng;
runInUwsgi = true; runInUwsgi = true;
uwsgiConfig = { uwsgiConfig = {
http = link.tuple; socket = "/run/searx/searx.sock";
chmod-socket = "660";
disable-logging = true; disable-logging = true;
}; };
environmentFile = config.sops.secrets.searxngenv.path; environmentFile = config.sops.secrets.searxngenv.path;
@ -41,7 +37,7 @@ in
}; };
local.nginx.defaultVhosts."search.gerg-l.com" = { local.nginx.defaultVhosts."search.gerg-l.com" = {
locations."/".proxyPass = link.url; locations."/".extraConfig = "uwsgi_pass unix:${config.services.searx.uwsgiConfig.socket};";
extraConfig = "access_log off;"; extraConfig = "access_log off;";
}; };
} }

View file

@ -12,32 +12,41 @@ plugins:
# The clients to use for track loading. See below for a list of valid clients. # The clients to use for track loading. See below for a list of valid clients.
# Clients are queried in the order they are given (so the first client is queried first and so on...) # Clients are queried in the order they are given (so the first client is queried first and so on...)
clients: clients:
- MUSIC
- TVHTML5EMBEDDED - TVHTML5EMBEDDED
- TV
- ANDROID_VR
- WEB
- WEBEMBEDDED
oauth: oauth:
enabled: true enabled: true
# Set with env vars refreshToken: "@refresh_token@"
#refreshToken: "" # name: # Name of the plugin
# some_key: some_value # Some key-value pair for the plugin
# another_key: another_value
lavalink: lavalink:
plugins: plugins:
- dependency: "dev.lavalink.youtube:youtube-plugin:1.11.5" - dependency: "dev.lavalink.youtube:youtube-plugin:1.11.5"
snapshot: false snapshot: false
# setting "enabled: true" is the bare minimum to get OAuth working. # setting "enabled: true" is the bare minimum to get OAuth working.
enabled: true enabled: true
# - dependency: "com.github.example:example-plugin:1.0.0" # required, the coordinates of your plugin
# Set with env vars # repository: "https://maven.example.com/releases" # optional, defaults to the Lavalink releases repository by default
#pluginsDir: "" # snapshot: false # optional, defaults to false, used to tell Lavalink to use the snapshot repository instead of the release repository
# pluginsDir: "./plugins" # optional, defaults to "./plugins"
# defaultPluginRepository: "https://maven.lavalink.dev/releases" # optional, defaults to the Lavalink release repository
# defaultPluginSnapshotRepository: "https://maven.lavalink.dev/snapshots" # optional, defaults to the Lavalink snapshot repository
server: server:
password: "@password@"
# Set with env vars
#password: ""
sources: sources:
# The default Youtube source is now deprecated and won't receive further updates. Please use https://github.com/lavalink-devs/youtube-source#plugin instead.
youtube: false youtube: false
bandcamp: true bandcamp: true
soundcloud: true soundcloud: true
twitch: true twitch: true
vimeo: true vimeo: true
nico: true nico: true
http: true http: true # warning: keeping HTTP enabled without a proxy configured could expose your server's IP address.
local: false local: false
filters: # All filters are enabled by default filters: # All filters are enabled by default
volume: true volume: true
@ -86,10 +95,14 @@ metrics:
sentry: sentry:
dsn: "" dsn: ""
environment: "" environment: ""
# tags:
# some_key: some_value
# another_key: another_value
logging: logging:
file: file:
path: null path: ./logs/
level: level:
root: INFO root: INFO
lavalink: INFO lavalink: INFO
@ -103,6 +116,7 @@ logging:
includePayload: true includePayload: true
maxPayloadLength: 10000 maxPayloadLength: 10000
logback: logback:
rollingpolicy: rollingpolicy:
max-file-size: 1GB max-file-size: 1GB

View file

@ -1,10 +1,11 @@
vocard: vocard:
token: ENC[AES256_GCM,data:aNRKBA94pqMCsRypIiVEmNMQK6cKCWa7pHC8dNpYSYGrn58i5PF+ByoR0k6AgGagBCtp//1fb9JzDHHLBKEbx5DH8J3B/D+F,iv:65zw7RZbFPvvBxz09OTnAci/dugbEvNj48ObxpYcmLE=,tag:Kcx0X+6mtm50S51c06oJ8g==,type:str] token: ENC[AES256_GCM,data:CCu4yOw4Fvwyx0KkYIikiz3VY2xTPbBx1q92W7FBTp+5fU+UP7yuAwZMWWZtzKdEyypzlk5uJ4tJRwUHqq62EnJqYj4wCVcr,iv:/Nxr9QPjEa67Xxn+tz3TRrcNG+cqEPVsqdjjxLp7R+k=,tag:LcVRrGorxvljJqpgs2bSoA==,type:str]
client_id: ENC[AES256_GCM,data:E490VeSSfy4q7Ztc+7mng3LcAg==,iv:iLLhg7/okFFFGNSOPH7JmOGeMjcjzk1AdtkhgZbGx9Y=,tag:gWKPUjlqVTKqOzzdFHP+FQ==,type:str] client_id: ENC[AES256_GCM,data:yd9vcUVxMpAKiPzl1hDI9EJhzA==,iv:dzB8ls0k5kWd+qtbSAkSfAXO0dxIUwdjppGYMkc+OHg=,tag:l1M4XTs79fszfNcFXSzVVg==,type:str]
spotify_client_id: ENC[AES256_GCM,data:uwqtWL7JZnN6FsPfTxtBjEgjE7qwGcKbDnloO6SNWs4=,iv:HMZ42J2oXavE4NZCmP1MUVZ+s9Px4XBDRWIbCcl6dYs=,tag:iO8hn8mlNGS1dcLBwwl/AQ==,type:str] spotify_client_id: ENC[AES256_GCM,data:uwqtWL7JZnN6FsPfTxtBjEgjE7qwGcKbDnloO6SNWs4=,iv:HMZ42J2oXavE4NZCmP1MUVZ+s9Px4XBDRWIbCcl6dYs=,tag:iO8hn8mlNGS1dcLBwwl/AQ==,type:str]
spotify_client_secret: ENC[AES256_GCM,data:YnfLj7RPTaucpZCqnel2gStd8oBcbWnL4/+KnkyT4u0=,iv:W6gXch7jH5jFp0PJy0LZ7vq1yCtO1NLbCTR3N6r47nQ=,tag:ct5Y786N6qVkZCts6pZniQ==,type:str] spotify_client_secret: ENC[AES256_GCM,data:YnfLj7RPTaucpZCqnel2gStd8oBcbWnL4/+KnkyT4u0=,iv:W6gXch7jH5jFp0PJy0LZ7vq1yCtO1NLbCTR3N6r47nQ=,tag:ct5Y786N6qVkZCts6pZniQ==,type:str]
password: ENC[AES256_GCM,data:7yGTh6LPtoZvJgSvLvbZQ5Gx0Xw=,iv:UKy14fJZhn5EwtMxd6vZ5X55Tk3iOW7UUF9GVXyhup8=,tag:bKoNLltZQPgmT2mv7kDSQw==,type:str] lavalink:
lavalink: ENC[AES256_GCM,data:Ub5baoxk8fOtchrOKR1YRwgrv/ja8e/9BY1Qaf+njDnvATSrRTcsvNZYU+YZb7OnJjfGRC5qytZo7T0ZBqHSFEdqvZToBHj0nVDTrXnbCm5o+NLKegCkofMG0c3D7JOB6lsc/0zBh8DF+i2M/Z5PNfmeE5Woe8Ev4gZEKyXQmFswULC5tsUqtnf7itQinf+FPDYqKA8Fi90JRWADt/XM1xRRZ4k5QthJ3kIQjYLa4+EOiSTAwIGxAvljl8c=,iv:cdpyakU0/eolOnamevITA4CKpNkU8lRYsOYFOUW8mO8=,tag:dT5lGvsUZDO5Esjyrn77Dg==,type:str] refresh_token: ENC[AES256_GCM,data:xiPmWhJTQ4OBIeB98t8qtDVQ7e/KVcThTmw5KE0VCIPfm6g7sOzXt7f91nSXX3wBvmy3tX+xii9/rp4dAg3b3/NYL4uHnLsKjM1wGTSH+KuCkbmJZDNYEk2OMSOlAK2x0yAMvpFB,iv:IdITL9x+yfVzf9yqDgJPUBok0Zn/CtN0CVF4AGIcgj8=,tag:DvQChj3Mng47LvNBYd6NAg==,type:str]
password: ENC[AES256_GCM,data:boIoVKGcXWAaKx6rOH1w1awTGfc=,iv:mX8WaaeeQXqyVuM5oA5tUUG7h7C0rV9QAVoHW/InyPc=,tag:Q/P3T5o1CMlbxe+UWyOP3A==,type:str]
sops: sops:
kms: [] kms: []
gcp_kms: [] gcp_kms: []
@ -20,8 +21,8 @@ sops:
WC9NVmdtWjlWSWN6dUwwMFdPRmpxWG8Ka0i27kBbA4p835RWsEPIghFTwxo4elOz WC9NVmdtWjlWSWN6dUwwMFdPRmpxWG8Ka0i27kBbA4p835RWsEPIghFTwxo4elOz
PL0TnuMNnl66TJiD0x6oRMn8tb6wQIAqGxBt9Jb2lj24eXCtzfGbEg== PL0TnuMNnl66TJiD0x6oRMn8tb6wQIAqGxBt9Jb2lj24eXCtzfGbEg==
-----END AGE ENCRYPTED FILE----- -----END AGE ENCRYPTED FILE-----
lastmodified: "2025-03-03T00:10:49Z" lastmodified: "2025-02-26T22:57:12Z"
mac: ENC[AES256_GCM,data:41um/6Fa0HqCVO/qj7/geUXWWOlXFZFt552W/T/hlsiUoebyPa4RgGVPcs332vuP+bgb4ELeJ0bsVqUFTtEbkfjaij9HT+BZIhImu8ZGKs/ZNkofw1s6h+kIVH4uf/sXYqMEATfHhSFqEoWsGsuL57i4llKzPBqsSyhdB4FeXDs=,iv:T3mt5lZmIT208gaCywsiuZ+Le/3BSDLL2UDxLExsEwE=,tag:jfpFXmcRNzJZCSAdZB4K7g==,type:str] mac: ENC[AES256_GCM,data:mb/kTo9zPyLbDJlvh6+P9GTzTVzVt7RMBnzS/qMDUvUR9OAP+zSt1Vf80oXnO3WqRncgRrIi1k3oKeipKHdTxmzXae+jefh7oOMGCeXI51IlnOhkA0MBgrN/jSMwEinYmqDGemzB7ff9quATtm8N/SoxepkR1ddikgEX6Zfr0mw=,iv:yTm2at3lgb1uWCsETw/XpDdrfKv5/8b1oxU2Eq89tbk=,tag:AP8vrUHejq2gsnkSBWHKyA==,type:str]
pgp: [] pgp: []
unencrypted_suffix: _unencrypted unencrypted_suffix: _unencrypted
version: 3.9.4 version: 3.9.4

View file

@ -6,32 +6,26 @@
{ {
sops = { sops = {
secrets = secrets =
{ builtins.mapAttrs
lavalink = { (
_: v:
v
// {
sopsFile = ./secrets.yaml; sopsFile = ./secrets.yaml;
restartUnits = [
"vocard.service"
"lavalink.service"
];
};
} }
// builtins.listToAttrs ( )
map {
(x: { "vocard/token" = { };
name = "vocard/${x}"; "vocard/client_id" = { };
value.sopsFile = ./secrets.yaml; "vocard/spotify_client_id" = { };
}) "vocard/spotify_client_secret" = { };
[ "lavalink/refresh_token" = { };
"token" "lavalink/password" = { };
"client_id"
"spotify_client_id"
"spotify_client_secret"
"password"
]
);
templates.vocard = { };
templates = {
vocard = {
path = "/persist/services/vocard/settings.json";
restartUnits = [ restartUnits = [
"vocard.service" "vocard.service"
"lavalink.service" "lavalink.service"
@ -45,25 +39,49 @@
"@spotify_client_secret@" "@spotify_client_secret@"
"@password@" "@password@"
] ]
(map (x: config.sops.placeholder.${x}) [ [
"vocard/token" config.sops.placeholder."vocard/token"
"vocard/client_id" config.sops.placeholder."vocard/client_id"
"vocard/spotify_client_id" config.sops.placeholder."vocard/spotify_client_id"
"vocard/spotify_client_secret" config.sops.placeholder."vocard/spotify_client_secret"
"vocard/password" config.sops.placeholder."lavalink/password"
])
]
(builtins.readFile ./settings.json); (builtins.readFile ./settings.json);
}; };
lavalink = {
path = "/persist/services/lavalink/application.yml";
restartUnits = [
"vocard.service"
"lavalink.service"
];
content =
builtins.replaceStrings
[
"@refresh_token@"
"@password@"
]
[
config.sops.placeholder."lavalink/refresh_token"
config.sops.placeholder."lavalink/password"
]
(builtins.readFile ./application.yml);
}; };
};
};
systemd.tmpfiles.rules = [
"d /persist/services/vocard - - - - -"
"d /persist/services/lavalink - - - - -"
];
systemd.services = { systemd.services = {
vocard = { vocard = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
wants = [
bindsTo = [ "lavalink.service" ];
requires = [
"network-online.target" "network-online.target"
"lavalink.service"
"ferretdb.service" "ferretdb.service"
]; ];
after = [ after = [
@ -74,8 +92,7 @@
]; ];
serviceConfig = { serviceConfig = {
ExecStart = lib.getExe self'.packages.vocard; ExecStart = lib.getExe self'.packages.vocard;
DynamicUser = true; WorkingDirectory = "/persist/services/vocard";
LoadCredential = "settings.json:${config.sops.templates.vocard.path}";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "30s"; RestartSec = "30s";
}; };
@ -87,13 +104,9 @@
"syslog.target" "syslog.target"
"network-online.target" "network-online.target"
]; ];
environment.LAVALINK_PLUGINS_DIR = self'.packages.lavalinkPlugins;
serviceConfig = { serviceConfig = {
ExecStart = "${lib.getExe self'.packages.lavalink} --spring.config.location='file:${./application.yml}'"; ExecStart = lib.getExe self'.packages.lavalink;
DynamicUser = true; WorkingDirectory = "/persist/services/lavalink";
EnvironmentFile = config.sops.secrets.lavalink.path;
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "30s"; RestartSec = "30s";
}; };
@ -101,15 +114,4 @@
}; };
services.ferretdb.enable = true; services.ferretdb.enable = true;
systemd.mounts = [
{
what = "/persist/services/ferretdb";
where = "/var/lib/private/ferretdb";
wantedBy = [ "ferretdb.service" ];
bindsTo = [ "ferretdb.service" ];
type = "none";
options = "bind";
}
];
} }

View file

@ -59,6 +59,7 @@
# #
#allow-import-from-derivation = false; #allow-import-from-derivation = false;
trusted-users = [ "root" ]; trusted-users = [ "root" ];
allowed-users = [ "@wheel" ];
use-xdg-base-directories = true; use-xdg-base-directories = true;
auto-allocate-uids = true; auto-allocate-uids = true;
}; };

View file

@ -1,94 +0,0 @@
{ lib, ... }:
{
options.local.links = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule (
{
config,
name,
...
}:
let
portHash = lib.flip lib.pipe [
(builtins.hashString "md5")
(builtins.substring 0 7)
(hash: (fromTOML "v=0x${hash}").v)
(lib.flip lib.mod config.reservedPorts.amount)
(builtins.add config.reservedPorts.start)
];
in
{
options = {
ipv4 = lib.mkOption {
type = lib.types.str;
default = "127.0.0.1";
description = "The IPv4 address.";
};
hostname = lib.mkOption {
type = lib.types.str;
description = "The hostname.";
};
port = lib.mkOption {
type = lib.types.int;
description = "The TCP or UDP port.";
};
portStr = lib.mkOption {
type = lib.types.str;
description = "The TCP or UDP port, as a string.";
};
reservedPorts = {
amount = lib.mkOption {
type = lib.types.int;
default = 10000;
description = "Amount of ports to reserve at most.";
};
start = lib.mkOption {
type = lib.types.int;
default = 30000;
description = "Starting point for reserved ports.";
};
};
protocol = lib.mkOption {
type = lib.types.str;
default = "http";
description = "The protocol in URL scheme name format.";
};
path = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "The resource path.";
};
url = lib.mkOption {
type = lib.types.str;
description = "The URL.";
};
tuple = lib.mkOption {
type = lib.types.str;
description = "The hostname:port tuple.";
};
extra = lib.mkOption {
type = lib.types.attrs;
description = "Arbitrary extra data.";
};
};
config = lib.mkIf true {
hostname = lib.mkDefault config.ipv4;
port = lib.mkDefault (portHash "${config.hostname}:${name}");
portStr = toString config.port;
tuple = "${config.hostname}:${config.portStr}";
url = "${config.protocol}://${config.hostname}:${config.portStr}${
if config.path == null then "" else config.path
}";
};
}
)
);
description = "Port Magic links.";
default = { };
};
}

View file

@ -14,17 +14,24 @@ stdenvNoCC.mkDerivation (finalAttrs: {
hash = "sha256-G4a9ltPq/L0vcazTQjStTlOOtwrBi37bYUNQHy5CV9Y="; hash = "sha256-G4a9ltPq/L0vcazTQjStTlOOtwrBi37bYUNQHy5CV9Y=";
}; };
plugin = fetchurl {
url = "https://github.com/lavalink-devs/youtube-source/releases/download/1.11.5/youtube-plugin-1.11.5.jar";
hash = "sha256-Zz4S5mWcsVFWGmN41L34GqZeCOswt/CAn+1PN1XJtbk=";
};
dontUnpack = true; dontUnpack = true;
nativeBuildInputs = [ makeBinaryWrapper ]; nativeBuildInputs = [ makeBinaryWrapper ];
buildCommand = '' buildCommand = ''
install -Dm644 "$src" "$out/lib/Lavalink.jar" install -Dm644 "$src" "$out/lib/Lavalink.jar"
install -Dm644 "$plugin" "$out/plugins/youtube-plugin.jar"
mkdir -p "$out/bin" mkdir -p $out/bin
makeWrapper '${lib.getExe zulu17}' "$out/bin/lavalink" \ makeWrapper ${lib.getExe zulu17} $out/bin/lavalink \
--add-flags "-jar $out/lib/Lavalink.jar" --add-flags "-jar -Xmx4G $out/lib/Lavalink.jar"
''; '';
meta.mainProgram = "lavalink"; meta.mainProgram = "lavalink";
}) })

View file

@ -1,13 +0,0 @@
{
fetchurl,
linkFarm,
}:
linkFarm "lavalinkPlugins" [
{
name = "youtube-plugin-1.11.5.jar";
path = fetchurl {
url = "https://github.com/lavalink-devs/youtube-source/releases/download/1.11.5/youtube-plugin-1.11.5.jar";
hash = "sha256-Zz4S5mWcsVFWGmN41L34GqZeCOswt/CAn+1PN1XJtbk=";
};
}
]

View file

@ -38,7 +38,7 @@ stdenv.mkDerivation {
runHook postBuild runHook postBuild
''; '';
patches = [ ./useLoadCredential.patch ]; patches = [ ./use_cwd.patch ];
nativeBuildInputs = [ nativeBuildInputs = [
makeBinaryWrapper makeBinaryWrapper

View file

@ -1,6 +1,5 @@
diff --git a/function.py b/function.py diff --git a/function.py b/function.py
index 6e09f5e..0c8bfa4 100644 index 6e09f5e..f0f6a11 100644
--- a/function.py --- a/function.py
+++ b/function.py +++ b/function.py
@@ -18,7 +18,7 @@ from motor.motor_asyncio import ( @@ -18,7 +18,7 @@ from motor.motor_asyncio import (
@ -8,7 +7,7 @@ index 6e09f5e..0c8bfa4 100644
ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
-if not os.path.exists(os.path.join(ROOT_DIR, "settings.json")): -if not os.path.exists(os.path.join(ROOT_DIR, "settings.json")):
+if not os.path.exists(os.path.join(os.getenv("CREDENTIALS_DIRECTORY"), "settings.json")): +if not os.path.exists(os.path.join(os.getcwd(), "settings.json")):
raise Exception("Settings file not set!") raise Exception("Settings file not set!")
#--------------- Cache Var --------------- #--------------- Cache Var ---------------
@ -58,21 +57,19 @@ index 6e09f5e..0c8bfa4 100644
if len(keys) == 1: if len(keys) == 1:
return LANGS.get(lang, {}).get(keys[0], "Language pack not found!") return LANGS.get(lang, {}).get(keys[0], "Language pack not found!")
diff --git a/main.py b/main.py diff --git a/main.py b/main.py
index e2c6b9e..98dc34b 100644 index e2c6b9e..4ff7de6 100644
--- a/main.py --- a/main.py
+++ b/main.py +++ b/main.py
@@ -80,13 +80,7 @@ class Vocard(commands.Bot): @@ -81,12 +81,6 @@ class Vocard(commands.Bot):
await self.ipc.connect()
except Exception as e: except Exception as e:
func.logger.error(f"Cannot connected to dashboard! - Reason: {e}") func.logger.error(f"Cannot connected to dashboard! - Reason: {e}")
-
- if not func.settings.version or func.settings.version != update.__version__: - if not func.settings.version or func.settings.version != update.__version__:
- func.update_json("settings.json", new_data={"version": update.__version__}) - func.update_json("settings.json", new_data={"version": update.__version__})
- -
- await self.tree.set_translator(Translator()) - await self.tree.set_translator(Translator())
- await self.tree.sync() - await self.tree.sync()
- -
+ await self.tree.sync()
async def on_ready(self): async def on_ready(self):
func.logger.info("------------------") func.logger.info("------------------")
func.logger.info(f"Logging As {self.user}") func.logger.info(f"Logging As {self.user}")
@ -81,7 +78,7 @@ index e2c6b9e..98dc34b 100644
# Loading settings and logger # Loading settings and logger
-func.settings = Settings(func.open_json("settings.json")) -func.settings = Settings(func.open_json("settings.json"))
+func.settings = Settings(func.open_json(os.path.join(os.getenv("CREDENTIALS_DIRECTORY"),"settings.json"))) +func.settings = Settings(func.open_json(os.path.join(os.getcwd(),"settings.json")))
LOG_SETTINGS = func.settings.logging LOG_SETTINGS = func.settings.logging
if (LOG_FILE := LOG_SETTINGS.get("file", {})).get("enable", True): if (LOG_FILE := LOG_SETTINGS.get("file", {})).get("enable", True):