I should commit more frequently 🫣
This commit is contained in:
parent
d7e82621c8
commit
f1483e45f0
70 changed files with 2344 additions and 599 deletions
11
modules/adguard-home/default.nix
Normal file
11
modules/adguard-home/default.nix
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
services.adguardhome = {
|
||||
enable = true;
|
||||
settings = {
|
||||
bind_port = 3000;
|
||||
openFirewall = true;
|
||||
};
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [3000 53];
|
||||
networking.firewall.allowedUDPPorts = [53];
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
pkgs,
|
||||
...
|
||||
}: {
|
||||
boot.binfmt.emulatedSystems = ["aarch64-linux" "i686-linux"];
|
||||
boot.binfmt.emulatedSystems = ["aarch64-linux" "i686-linux" "riscv64-linux"];
|
||||
nix.extraOptions = ''
|
||||
extra-platforms = aarch64-linux arm-linux i686-linux
|
||||
'';
|
||||
|
|
|
@ -52,10 +52,12 @@
|
|||
description = "Andrea Ciceri";
|
||||
isNormalUser = true;
|
||||
inherit (config.ccr) extraGroups;
|
||||
shell = pkgs.nushell;
|
||||
shell = pkgs.zsh;
|
||||
openssh.authorizedKeys.keys = config.ccr.authorizedKeys;
|
||||
};
|
||||
|
||||
programs.zsh.enable = true;
|
||||
|
||||
services.getty.autologinUser =
|
||||
if config.ccr.autologin
|
||||
then "ccr"
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
...
|
||||
}: {
|
||||
virtualisation.docker.enable = true;
|
||||
virtualisation.podman.enable = true;
|
||||
users.users.ccr.extraGroups = ["docker"];
|
||||
environment.systemPackages = with pkgs; [
|
||||
docker-compose
|
||||
podman-compose
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{pkgs, ...}: {
|
||||
fonts = {
|
||||
fonts = with pkgs; [powerline-fonts dejavu_fonts fira-code fira-code-symbols emacs-all-the-icons-fonts nerdfonts joypixels etBook];
|
||||
fonts = with pkgs; [powerline-fonts dejavu_fonts fira-code fira-code-symbols iosevka iosevka-comfy.comfy emacs-all-the-icons-fonts nerdfonts joypixels etBook];
|
||||
fontconfig.defaultFonts = {
|
||||
monospace = ["DejaVu Sans Mono for Powerline"];
|
||||
sansSerif = ["DejaVu Sans"];
|
||||
|
|
3
modules/gnome-keyring/default.nix
Normal file
3
modules/gnome-keyring/default.nix
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
}
|
45
modules/grocy/default.nix
Normal file
45
modules/grocy/default.nix
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
grocy = super.grocy.overrideAttrs (old: {
|
||||
meta.broken = false;
|
||||
version = "4.0.1";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "grocy";
|
||||
repo = "grocy";
|
||||
rev = "v4.0.1";
|
||||
hash = "sha256-bCUH2dRCSNkpWyUxGdTdjgVsagbBghcHsBX01+NuHGc=";
|
||||
};
|
||||
});
|
||||
})
|
||||
];
|
||||
services.grocy = {
|
||||
enable = true;
|
||||
hostName = "grocy.aciceri.dev";
|
||||
nginx.enableSSL = false;
|
||||
settings = {
|
||||
culture = "it";
|
||||
currency = "EUR";
|
||||
calendar = {
|
||||
firstDayOfWeek = 1;
|
||||
showWeekNumber = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
services.nginx.virtualHosts.${config.services.grocy.hostName}.listen = [
|
||||
{
|
||||
addr = "0.0.0.0";
|
||||
port = 6789;
|
||||
ssl = false;
|
||||
}
|
||||
];
|
||||
networking.firewall.interfaces."wg0" = {
|
||||
allowedTCPPorts = [
|
||||
6789
|
||||
];
|
||||
};
|
||||
}
|
174
modules/home-assistant/default.nix
Normal file
174
modules/home-assistant/default.nix
Normal file
|
@ -0,0 +1,174 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
smartthings-fork = pkgs.fetchFromGitHub {
|
||||
owner = "veista";
|
||||
repo = "smartthings";
|
||||
rev = "ba1a6f33c6ac37d81f4263073571628803e79697";
|
||||
sha256 = "sha256-X3SYkg0B5pzEich7/4iUmlADJneVuT8HTVnIiC7odRE=";
|
||||
};
|
||||
pun_sensor = pkgs.fetchFromGitHub {
|
||||
owner = "virtualdj";
|
||||
repo = "pun_sensor";
|
||||
rev = "19f270b353594ab536f9dc42adf31427e7a81562";
|
||||
hash = "sha256-3pL+8CXzjmR54Ff9qLhHzC/C+uns0qWEgJFHv+K4MFs=";
|
||||
};
|
||||
cozy_life = pkgs.fetchFromGitHub {
|
||||
owner = "yangqian";
|
||||
repo = "hass-cozylife";
|
||||
rev = "9a40a2fa09b0f74aee0b278e2858f5600b3487a9";
|
||||
hash = "sha256-i+82EUamV1Fhwhb1vhRqn9aA9dJ0FxSSMD734domyhw=";
|
||||
};
|
||||
localtuya = pkgs.fetchFromGitHub {
|
||||
owner = "rospogrigio";
|
||||
repo = "localtuya";
|
||||
rev = "f06e4848e67997edfa696aa9a89372fb17077bd0";
|
||||
hash = "sha256-hA/1FxH0wfM0jz9VqGCT95rXlrWjxV5oIkSiBf0G0ac=";
|
||||
};
|
||||
in {
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
package = pkgs.home-assistant.overrideAttrs (old: {
|
||||
doInstallCheck = false;
|
||||
prePatch =
|
||||
''
|
||||
rm -rf homeassistant/components/smartthings
|
||||
cp -r ${smartthings-fork}/custom_components/smartthings homeassistant/components/smartthings
|
||||
''
|
||||
+ old.prePatch;
|
||||
});
|
||||
extraComponents = [
|
||||
# components required to complete the onboarding
|
||||
# "esphome"
|
||||
"met"
|
||||
"radio_browser"
|
||||
"frontend"
|
||||
"cloud"
|
||||
"google_translate"
|
||||
"smartthings" # samsung devices
|
||||
"tuya"
|
||||
"timer"
|
||||
"cast"
|
||||
"weather"
|
||||
"backup"
|
||||
"brother"
|
||||
"webostv"
|
||||
"media_player"
|
||||
"wyoming"
|
||||
];
|
||||
extraPackages = python3Packages:
|
||||
with python3Packages; [
|
||||
# used by pun_sensor
|
||||
holidays
|
||||
beautifulsoup4
|
||||
];
|
||||
config = {
|
||||
default_config = {};
|
||||
http = {
|
||||
use_x_forwarded_for = true;
|
||||
trusted_proxies = ["10.100.0.1"];
|
||||
};
|
||||
# ffmpeg = {};
|
||||
# camera = [
|
||||
# {
|
||||
# name = "EyeToy";
|
||||
# platform = "ffmpeg";
|
||||
# input = "/dev/video1";
|
||||
# extra_arguments = "-vcodec h264";
|
||||
# }
|
||||
# ];
|
||||
homeassistant = {
|
||||
unit_system = "metric";
|
||||
time_zone = "Europe/Rome";
|
||||
temperature_unit = "C";
|
||||
external_url = "https://home.aciceri.dev";
|
||||
internal_url = "http://rock5b.fleet:8123";
|
||||
};
|
||||
logger.default = "WARNING";
|
||||
# backup = {};
|
||||
# media_player = [{
|
||||
# platform = "webostv";
|
||||
# host = "10.1.1.213";
|
||||
# name = "TV";
|
||||
# timeout = "5";
|
||||
# turn_on_action = {
|
||||
# service = "wake_on_lan.send_magic_packet";
|
||||
# data.mac = "20:28:bc:74:14:c2";
|
||||
# };
|
||||
# }];
|
||||
};
|
||||
};
|
||||
|
||||
# services.avahi.enable = true;
|
||||
# services.avahi.nssmdns = true;
|
||||
|
||||
# systemd.services.home-assistant.serviceConfig = {
|
||||
# SupplementaryGroups = ["video"];
|
||||
# DeviceAllow = ["/dev/video1"];
|
||||
# };
|
||||
# users.users.hass.extraGroups = ["video"];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.home-assistant.configDir}/custom_components 770 hass hass"
|
||||
"L+ ${config.services.home-assistant.configDir}/custom_components/pun_sensor - - - - ${pun_sensor}/custom_components/pun_sensor"
|
||||
"L+ ${config.services.home-assistant.configDir}/custom_components/cozy_life - - - - ${cozy_life}/custom_components/cozylife"
|
||||
"L+ ${config.services.home-assistant.configDir}/custom_components/localtuya - - - - ${localtuya}/custom_components/localtuya"
|
||||
"d ${config.services.home-assistant.configDir}/www 770 hass hass"
|
||||
"C ${config.services.home-assistant.configDir}/www/home.png - - - - ${config.age.secrets.home-planimetry.path}"
|
||||
];
|
||||
|
||||
networking.firewall.interfaces."wg0" = {
|
||||
allowedTCPPorts = [
|
||||
config.services.home-assistant.config.http.server_port
|
||||
56000
|
||||
];
|
||||
};
|
||||
|
||||
# virtualisation.oci-containers.containers = {
|
||||
# cam2ip = {
|
||||
# image = "gen2brain/cam2ip:arm";
|
||||
# ports = ["56000:56000"];
|
||||
# extraOptions = [ "--device=/dev/video1:/dev/video1"];
|
||||
# environment.CAM2IP_INDEX = "1";
|
||||
# };
|
||||
# };
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
containers = {
|
||||
whisper = {
|
||||
image = "rhasspy/wyoming-whisper:latest";
|
||||
ports = ["10300:10300"];
|
||||
cmd = [
|
||||
"--model"
|
||||
"medium-int8"
|
||||
"--language"
|
||||
"it"
|
||||
];
|
||||
};
|
||||
piper = {
|
||||
image = "rhasspy/wyoming-piper:latest";
|
||||
ports = ["10200:10200"];
|
||||
cmd = [
|
||||
"--voice"
|
||||
"it_IT-riccardo-x_low"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# virtualisation.oci-containers = {
|
||||
# backend = "podman";
|
||||
# containers.homeassistant = {
|
||||
# volumes = [ "home-assistant:/config" ];
|
||||
# environment.TZ = "Europe/Rome";
|
||||
# image = "ghcr.io/home-assistant/home-assistant:stable"; # Warning: if the tag does not change, the image will not be updated
|
||||
# extraOptions = [
|
||||
# "--network=host"
|
||||
# "--device=/dev/ttyACM0:/dev/ttyACM0" # Example, change this to match your own hardware
|
||||
# ];
|
||||
# };
|
||||
# };s
|
||||
}
|
BIN
modules/home-assistant/home.png
Normal file
BIN
modules/home-assistant/home.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 550 KiB |
81
modules/immich/default.nix
Normal file
81
modules/immich/default.nix
Normal file
|
@ -0,0 +1,81 @@
|
|||
{
|
||||
config,
|
||||
fleetFlake,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
typesenseApiKeyFile = pkgs.writeText "typesense-api-key" "12318551487654187654"; # api key not ime, stolen from upstram PR
|
||||
pkgsImmich = fleetFlake.inputs.nixpkgsImmich.legacyPackages.${pkgs.system}.extend (final: prev: {
|
||||
python = prev.python.override {
|
||||
packageOverrides = final: prev: {
|
||||
insightface = prev.insightface.overrideAttrs (_: {
|
||||
pythonCatchConflictsPhase = "";
|
||||
});
|
||||
};
|
||||
};
|
||||
});
|
||||
in {
|
||||
imports = ["${fleetFlake.inputs.nixpkgsImmich}/nixos/modules/services/web-apps/immich.nix"];
|
||||
|
||||
services.immich = {
|
||||
package = pkgsImmich.immich;
|
||||
enable = true;
|
||||
server.mediaDir = "/mnt/hd/immich";
|
||||
server.typesense.apiKeyFile = typesenseApiKeyFile;
|
||||
};
|
||||
|
||||
services.typesense = {
|
||||
enable = true;
|
||||
# In a real setup you should generate an api key for immich
|
||||
# and not use the admin key!
|
||||
apiKeyFile = typesenseApiKeyFile;
|
||||
settings.server.api-address = "127.0.0.1";
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /mnt/hd/immich 770 immich immich"
|
||||
];
|
||||
|
||||
# networking.firewall.allowedTCPPorts = [8080];
|
||||
# virtualisation.oci-containers.containers.immich = {
|
||||
# image = "ghcr.io/imagegenius/immich:latest";
|
||||
# extraOptions = ["--network=host"];
|
||||
# volumes = [
|
||||
# "/mnt/immich/photos:/photos"
|
||||
# "/mnt/immich/config:/config"
|
||||
# ];
|
||||
# environment = {
|
||||
# PUID=builtins.toString config.users.users.ccr.uid;
|
||||
# PGID=builtins.toString config.users.groups.wheel.gid;
|
||||
# TZ="Europe/Rome";
|
||||
# DB_HOSTNAME="localhost";
|
||||
# DB_USERNAME="postgres";
|
||||
# DB_PASSWORD="postgres";
|
||||
# DB_DATABASE_NAME="immich";
|
||||
# DB_PORT="54320";
|
||||
# REDIS_HOSTNAME="localhost";
|
||||
# DISABLE_MACHINE_LEARNING="false";
|
||||
# DISABLE_TYPESENSE="false";
|
||||
# };
|
||||
# };
|
||||
|
||||
# virtualisation.oci-containers.containers.immich-redis = {
|
||||
# image = "redis";
|
||||
# extraOptions = ["--network=host"];
|
||||
# };
|
||||
|
||||
# virtualisation.oci-containers.containers.immich-postgres = {
|
||||
# image = "postgres:14";
|
||||
# extraOptions = ["--network=host"];
|
||||
# environment = {
|
||||
# POSTGRES_USER = "postgres";
|
||||
# POSTGRES_PASSWORD = "postgres";
|
||||
# POSTGRES_DB = "immich";
|
||||
# PGPORT = "54320";
|
||||
# };
|
||||
# volumes = [
|
||||
# "/mnt/immich/postgres:/var/lib/postgresql/data"
|
||||
# ];
|
||||
# };
|
||||
}
|
608
modules/immich/module.nix
Normal file
608
modules/immich/module.nix
Normal file
|
@ -0,0 +1,608 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(lib)
|
||||
hasAttr
|
||||
hasPrefix
|
||||
maintainers
|
||||
mapAttrs
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkMerge
|
||||
mkOption
|
||||
mkPackageOption
|
||||
optional
|
||||
optionalAttrs
|
||||
optionalString
|
||||
types
|
||||
;
|
||||
|
||||
cfg = config.services.immich;
|
||||
serverCfg = config.services.immich.server;
|
||||
backendCfg = serverCfg.backend;
|
||||
microservicesCfg = serverCfg.microservices;
|
||||
webCfg = cfg.web;
|
||||
mlCfg = cfg.machineLearning;
|
||||
|
||||
isServerPostgresUnix = hasPrefix "/" serverCfg.postgres.host;
|
||||
postgresEnv =
|
||||
if isServerPostgresUnix
|
||||
then {
|
||||
# If passwordFile is given, this will be overwritten in ExecStart
|
||||
DB_URL = "socket://${serverCfg.postgres.host}?dbname=${serverCfg.postgres.database}";
|
||||
}
|
||||
else {
|
||||
DB_HOSTNAME = serverCfg.postgres.host;
|
||||
DB_PORT = toString serverCfg.postgres.port;
|
||||
DB_DATABASE_NAME = serverCfg.postgres.database;
|
||||
DB_USERNAME = serverCfg.postgres.username;
|
||||
};
|
||||
|
||||
typesenseEnv =
|
||||
{
|
||||
TYPESENSE_ENABLED = toString serverCfg.typesense.enable;
|
||||
}
|
||||
// optionalAttrs serverCfg.typesense.enable {
|
||||
TYPESENSE_HOST = serverCfg.typesense.host;
|
||||
TYPESENSE_PORT = toString serverCfg.typesense.port;
|
||||
TYPESENSE_PROTOCOL = serverCfg.typesense.protocol;
|
||||
};
|
||||
|
||||
# Don't start a redis instance if the user sets a custom redis connection
|
||||
enableRedis = !hasAttr "REDIS_URL" serverCfg.extraConfig && !hasAttr "REDIS_SOCKET" serverCfg.extraConfig;
|
||||
redisServerCfg = config.services.redis.servers.immich;
|
||||
redisEnv = optionalAttrs enableRedis {
|
||||
REDIS_SOCKET = redisServerCfg.unixSocket;
|
||||
};
|
||||
|
||||
serverEnv =
|
||||
postgresEnv
|
||||
// typesenseEnv
|
||||
// redisEnv
|
||||
// {
|
||||
NODE_ENV = "production";
|
||||
|
||||
IMMICH_MEDIA_LOCATION = serverCfg.mediaDir;
|
||||
IMMICH_MACHINE_LEARNING_URL =
|
||||
if serverCfg.machineLearningUrl != null
|
||||
then serverCfg.machineLearningUrl
|
||||
else "false";
|
||||
};
|
||||
|
||||
serverStartWrapper = program: ''
|
||||
set -euo pipefail
|
||||
mkdir -p ${serverCfg.mediaDir}
|
||||
|
||||
${optionalString (serverCfg.postgres.passwordFile != null) (
|
||||
if isServerPostgresUnix
|
||||
then ''export DB_URL="socket://${serverCfg.postgres.username}:$(cat ${serverCfg.postgres.passwordFile})@${serverCfg.postgres.host}?dbname=${serverCfg.postgres.database}"''
|
||||
else "export DB_PASSWORD=$(cat ${serverCfg.postgres.passwordFile})"
|
||||
)}
|
||||
|
||||
${optionalString serverCfg.typesense.enable ''
|
||||
export TYPESENSE_API_KEY=$(cat ${serverCfg.typesense.apiKeyFile})
|
||||
''}
|
||||
|
||||
exec ${program}
|
||||
'';
|
||||
|
||||
commonServiceConfig = {
|
||||
Restart = "on-failure";
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = "";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateUsers = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
PrivateMounts = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
# Would re-mount paths ignored by temporary root
|
||||
# TODO ProtectSystem = "strict";
|
||||
RemoveIPC = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged"
|
||||
"@pkey"
|
||||
];
|
||||
UMask = "0077";
|
||||
};
|
||||
|
||||
serverServiceConfig = {
|
||||
DynamicUser = true;
|
||||
User = "immich";
|
||||
Group = "immich";
|
||||
SupplementaryGroups = optional enableRedis redisServerCfg.user;
|
||||
|
||||
StateDirectory = "immich";
|
||||
StateDirectoryMode = "0750";
|
||||
WorkingDirectory = "/var/lib/immich";
|
||||
|
||||
MemoryDenyWriteExecute = false; # nodejs requires this.
|
||||
EnvironmentFile = mkIf (serverCfg.environmentFile != null) serverCfg.environmentFile;
|
||||
|
||||
TemporaryFileSystem = "/:ro";
|
||||
BindReadOnlyPaths =
|
||||
[
|
||||
"/nix/store"
|
||||
"-/etc/resolv.conf"
|
||||
"-/etc/nsswitch.conf"
|
||||
"-/etc/hosts"
|
||||
"-/etc/localtime"
|
||||
"-/run/postgresql"
|
||||
]
|
||||
++ optional enableRedis redisServerCfg.unixSocket;
|
||||
};
|
||||
in {
|
||||
options.services.immich = {
|
||||
enable =
|
||||
mkEnableOption "immich"
|
||||
// {
|
||||
description = ''
|
||||
Enables immich which consists of a backend server, microservices,
|
||||
machine-learning and web ui. You can disable or reconfigure components
|
||||
individually using the subsections.
|
||||
'';
|
||||
};
|
||||
|
||||
package = mkPackageOption pkgs "immich" {};
|
||||
|
||||
server = {
|
||||
mediaDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/immich/media";
|
||||
description = "Directory used to store media files.";
|
||||
};
|
||||
|
||||
backend = {
|
||||
enable =
|
||||
mkEnableOption "immich backend server"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3001;
|
||||
description = "Port to bind to.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Whether to open the firewall for the specified port.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = {
|
||||
LOG_LEVEL = "debug";
|
||||
};
|
||||
description = ''
|
||||
Extra configuration options (environment variables).
|
||||
Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'server' for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Environment file as defined in systemd.exec(5). May be used to provide
|
||||
additional secret variables to the service without adding them to the
|
||||
world-readable Nix store.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
microservices = {
|
||||
enable =
|
||||
mkEnableOption "immich microservices"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3002;
|
||||
description = "Port to bind to.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Whether to open the firewall for the specified port.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = {
|
||||
REVERSE_GEOCODING_PRECISION = 1;
|
||||
};
|
||||
description = ''
|
||||
Extra configuration options (environment variables).
|
||||
Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'microservices' for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Environment file as defined in systemd.exec(5). May be used to provide
|
||||
additional secret variables to the service without adding them to the
|
||||
world-readable Nix store.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
typesense = {
|
||||
enable =
|
||||
mkEnableOption "typesense"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "127.0.0.1";
|
||||
example = "typesense.example.com";
|
||||
description = "Hostname/address of the typesense server to use.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 8108;
|
||||
description = "The port of the typesense server to use.";
|
||||
};
|
||||
|
||||
protocol = mkOption {
|
||||
type = types.str;
|
||||
default = "http";
|
||||
description = "The protocol to use when connecting to the typesense server.";
|
||||
};
|
||||
|
||||
apiKeyFile = mkOption {
|
||||
type = types.path;
|
||||
description = "Sets the api key for authentication with typesense.";
|
||||
};
|
||||
};
|
||||
|
||||
postgres = {
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "/run/postgresql";
|
||||
description = "Hostname/address of the postgres server to use. If an absolute path is given here, it will be interpreted as a unix socket path.";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 5432;
|
||||
description = "The port of the postgres server to use.";
|
||||
};
|
||||
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
default = "immich";
|
||||
description = "The postgres username to use.";
|
||||
};
|
||||
|
||||
passwordFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Sets the password for authentication with postgres.
|
||||
May be unset when using socket authentication.
|
||||
'';
|
||||
};
|
||||
|
||||
database = mkOption {
|
||||
type = types.str;
|
||||
default = "immich";
|
||||
description = "The postgres database to use.";
|
||||
};
|
||||
};
|
||||
|
||||
useMachineLearning = mkOption {
|
||||
description = "Use the given machine learning server endpoint to enable ML functionality in immich.";
|
||||
default = true;
|
||||
type = types.bool;
|
||||
};
|
||||
|
||||
machineLearningUrl = mkOption {
|
||||
type = types.str;
|
||||
default = "http://127.0.0.1:3003";
|
||||
example = "https://immich-ml.internal.example.com";
|
||||
description = "The machine learning server endpoint to use.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = {
|
||||
REDIS_SOCKET = "/run/custom-redis";
|
||||
};
|
||||
description = ''
|
||||
Extra configuration options (environment variables) for both backend and microservices.
|
||||
Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with both 'server' and 'microservices' for available options.
|
||||
'';
|
||||
};
|
||||
|
||||
environmentFile = mkOption {
|
||||
type = types.nullOr types.path;
|
||||
default = null;
|
||||
description = ''
|
||||
Environment file as defined in systemd.exec(5). May be used to provide
|
||||
additional secret variables to the backend and microservices servers without
|
||||
adding them to the world-readable Nix store.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
web = {
|
||||
enable =
|
||||
mkEnableOption "immich web frontend"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3000;
|
||||
description = "Port to bind to.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Whether to open the firewall for the specified port.";
|
||||
};
|
||||
|
||||
serverUrl = mkOption {
|
||||
type = types.str;
|
||||
default = "http://127.0.0.1:3001";
|
||||
example = "https://immich-backend.internal.example.com";
|
||||
description = "The backend server url to use.";
|
||||
};
|
||||
|
||||
apiUrlExternal = mkOption {
|
||||
type = types.str;
|
||||
default = "/web";
|
||||
description = "The api url to use for external requests.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = {
|
||||
PUBLIC_LOGIN_PAGE_MESSAGE = "My awesome Immich instance!";
|
||||
};
|
||||
description = ''
|
||||
Extra configuration options (environment variables).
|
||||
Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'web' for available options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
machineLearning = {
|
||||
enable =
|
||||
mkEnableOption "immich machine-learning server"
|
||||
// {
|
||||
default = true;
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 3003;
|
||||
description = "Port to bind to.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
default = false;
|
||||
type = types.bool;
|
||||
description = "Whether to open the firewall for the specified port.";
|
||||
};
|
||||
|
||||
extraConfig = mkOption {
|
||||
type = types.attrs;
|
||||
default = {};
|
||||
example = {
|
||||
MACHINE_LEARNING_MODEL_TTL = 600;
|
||||
};
|
||||
description = ''
|
||||
Extra configuration options (environment variables).
|
||||
Refer to [the documented variables](https://documentation.immich.app/docs/install/environment-variables) tagged with 'machine learning' for available options.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = !isServerPostgresUnix -> serverCfg.postgres.passwordFile != null;
|
||||
message = "A database password must be provided when unix sockets are not used.";
|
||||
}
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = mkMerge [
|
||||
(mkIf (backendCfg.enable && backendCfg.openFirewall) [backendCfg.port])
|
||||
(mkIf (microservicesCfg.enable && microservicesCfg.openFirewall) [microservicesCfg.port])
|
||||
(mkIf (webCfg.enable && webCfg.openFirewall) [webCfg.port])
|
||||
(mkIf (mlCfg.enable && mlCfg.openFirewall) [mlCfg.port])
|
||||
];
|
||||
|
||||
services.redis.servers.immich.enable = mkIf enableRedis true;
|
||||
services.redis.vmOverCommit = mkIf enableRedis (mkDefault true);
|
||||
|
||||
systemd.services.immich-server = mkIf backendCfg.enable {
|
||||
description = "Immich backend server (Self-hosted photo and video backup solution)";
|
||||
after =
|
||||
[
|
||||
"network.target"
|
||||
"typesense.service"
|
||||
"postgresql.service"
|
||||
"immich-machine-learning.service"
|
||||
]
|
||||
++ optional enableRedis "redis-immich.service";
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
environment =
|
||||
serverEnv
|
||||
// {
|
||||
SERVER_PORT = toString backendCfg.port;
|
||||
}
|
||||
// mapAttrs (_: toString) serverCfg.extraConfig
|
||||
// mapAttrs (_: toString) backendCfg.extraConfig;
|
||||
|
||||
script = serverStartWrapper "${cfg.package}/bin/server";
|
||||
serviceConfig = mkMerge [
|
||||
(commonServiceConfig // serverServiceConfig)
|
||||
{
|
||||
EnvironmentFile = mkIf (backendCfg.environmentFile != null) backendCfg.environmentFile;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services.immich-microservices = mkIf microservicesCfg.enable {
|
||||
description = "Immich microservices (Self-hosted photo and video backup solution)";
|
||||
after =
|
||||
[
|
||||
"network.target"
|
||||
"typesense.service"
|
||||
"postgresql.service"
|
||||
"immich-machine-learning.service"
|
||||
]
|
||||
++ optional enableRedis "redis-immich.service";
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
environment =
|
||||
serverEnv
|
||||
// {
|
||||
MICROSERVICES_PORT = toString microservicesCfg.port;
|
||||
}
|
||||
// mapAttrs (_: toString) serverCfg.extraConfig
|
||||
// mapAttrs (_: toString) microservicesCfg.extraConfig;
|
||||
|
||||
script = serverStartWrapper "${cfg.package}/bin/microservices";
|
||||
serviceConfig = mkMerge [
|
||||
(commonServiceConfig // serverServiceConfig)
|
||||
{
|
||||
EnvironmentFile = mkIf (microservicesCfg.environmentFile != null) microservicesCfg.environmentFile;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services.immich-web = mkIf webCfg.enable {
|
||||
description = "Immich web (Self-hosted photo and video backup solution)";
|
||||
after = [
|
||||
"network.target"
|
||||
"immich-server.service"
|
||||
];
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
environment =
|
||||
{
|
||||
NODE_ENV = "production";
|
||||
PORT = toString webCfg.port;
|
||||
IMMICH_SERVER_URL = webCfg.serverUrl;
|
||||
IMMICH_API_URL_EXTERNAL = webCfg.apiUrlExternal;
|
||||
}
|
||||
// mapAttrs (_: toString) webCfg.extraConfig;
|
||||
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
export PUBLIC_IMMICH_SERVER_URL=$IMMICH_SERVER_URL
|
||||
export PUBLIC_IMMICH_API_URL_EXTERNAL=$IMMICH_API_URL_EXTERNAL
|
||||
exec ${cfg.package.web}/bin/web
|
||||
'';
|
||||
serviceConfig =
|
||||
commonServiceConfig
|
||||
// {
|
||||
DynamicUser = true;
|
||||
User = "immich-web";
|
||||
Group = "immich-web";
|
||||
|
||||
MemoryDenyWriteExecute = false; # nodejs requires this.
|
||||
|
||||
TemporaryFileSystem = "/:ro";
|
||||
BindReadOnlyPaths = [
|
||||
"/nix/store"
|
||||
"-/etc/resolv.conf"
|
||||
"-/etc/nsswitch.conf"
|
||||
"-/etc/hosts"
|
||||
"-/etc/localtime"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.immich-machine-learning = mkIf mlCfg.enable {
|
||||
description = "Immich machine learning (Self-hosted photo and video backup solution)";
|
||||
after = ["network.target"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
environment =
|
||||
{
|
||||
NODE_ENV = "production";
|
||||
MACHINE_LEARNING_PORT = toString mlCfg.port;
|
||||
|
||||
MACHINE_LEARNING_CACHE_FOLDER = "/var/cache/immich-ml";
|
||||
TRANSFORMERS_CACHE = "/var/cache/immich-ml";
|
||||
}
|
||||
// mapAttrs (_: toString) mlCfg.extraConfig;
|
||||
|
||||
serviceConfig =
|
||||
commonServiceConfig
|
||||
// {
|
||||
ExecStart = "${cfg.package.machine-learning}/bin/machine-learning";
|
||||
DynamicUser = true;
|
||||
User = "immich-ml";
|
||||
Group = "immich-ml";
|
||||
|
||||
MemoryDenyWriteExecute = false; # onnxruntime_pybind11 requires this.
|
||||
ProcSubset = "all"; # Needs /proc/cpuinfo
|
||||
|
||||
CacheDirectory = "immich-ml";
|
||||
CacheDirectoryMode = "0700";
|
||||
|
||||
# TODO gpu access
|
||||
|
||||
TemporaryFileSystem = "/:ro";
|
||||
BindReadOnlyPaths = [
|
||||
"/nix/store"
|
||||
"-/etc/resolv.conf"
|
||||
"-/etc/nsswitch.conf"
|
||||
"-/etc/hosts"
|
||||
"-/etc/localtime"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with maintainers; [oddlama];
|
||||
};
|
||||
}
|
15
modules/mediatomb/default.nix
Normal file
15
modules/mediatomb/default.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
services.mediatomb = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
serverName = "Rock 5B";
|
||||
mediaDirectories = [
|
||||
{
|
||||
path = "/mnt/hd/torrent";
|
||||
recursive = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
users.users.mediatomb.extraGroups = ["transmission"];
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
friendly_name = config.networking.hostName;
|
||||
inotify = "yes";
|
||||
media_dir = [
|
||||
"/mnt/raid/torrent"
|
||||
"/mnt/torrent"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
|
27
modules/nextcloud/default.nix
Normal file
27
modules/nextcloud/default.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
cfg = config.services.nextcloud;
|
||||
in {
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /mnt/raid/nextcloud 770 nextcloud nextcloud"
|
||||
];
|
||||
|
||||
ccr.extraGroups = ["nextcloud"];
|
||||
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
package = pkgs.nextcloud26;
|
||||
database.createLocally = true;
|
||||
home = "/mnt/raid/nextcloud";
|
||||
hostName = "nextcloud.aciceri.dev";
|
||||
config = {
|
||||
adminpassFile = config.age.secrets.nextcloud-admin-pass.path;
|
||||
overwriteProtocol = "https";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [80];
|
||||
}
|
|
@ -15,8 +15,8 @@ in {
|
|||
config = {
|
||||
services.nix-serve = {
|
||||
enable = true;
|
||||
secretKeyFile = config.age.secrets.cache-private-key.path;
|
||||
# Public key: cache.aciceri.dev-1:aNP6f+rRTuDHi/45L1VBzlGchuj54/mI2N/22qTWgzE=
|
||||
# secretKeyFile = config.age.secrets.cache-private-key.path;
|
||||
# Public key: cache.aciceri.dev-1B:aNP6f+BrRTuDHi/45L1VBzlGchuj54/mI2N/22qTWgzE=
|
||||
};
|
||||
services.nginx.virtualHosts."${cfg.domain}" = {
|
||||
forceSSL = true;
|
||||
|
|
20
modules/org-roam-ui/default.nix
Normal file
20
modules/org-roam-ui/default.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
{...}: {
|
||||
networking.firewall.interfaces."wg0" = {
|
||||
allowedTCPPorts = [
|
||||
35901
|
||||
];
|
||||
};
|
||||
imports = [../nginx-base];
|
||||
services.nginx.virtualHosts = {
|
||||
"roam.aciceri.dev" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:35901";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# TODO use oauth2 proxy
|
||||
}
|
|
@ -8,5 +8,17 @@
|
|||
# Important to resolve .local domains of printers, otherwise you get an error
|
||||
# like "Impossible to connect to XXX.local: Name or service not known"
|
||||
services.avahi.nssmdns = true;
|
||||
services.printing.enable = true;
|
||||
hardware.sane.enable = true;
|
||||
|
||||
services.paperless = {
|
||||
enable = true;
|
||||
passwordFile = builtins.toFile "password" "admin";
|
||||
};
|
||||
|
||||
services.printing = {
|
||||
enable = true;
|
||||
drivers = [
|
||||
(pkgs.callPackage ./driver.nix {})
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
86
modules/printing/driver.nix
Normal file
86
modules/printing/driver.nix
Normal file
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
lib,
|
||||
stdenv,
|
||||
fetchurl,
|
||||
dpkg,
|
||||
autoPatchelfHook,
|
||||
makeWrapper,
|
||||
perl,
|
||||
gnused,
|
||||
ghostscript,
|
||||
file,
|
||||
coreutils,
|
||||
gnugrep,
|
||||
which,
|
||||
}: let
|
||||
arches = ["x86_64" "i686" "armv7l"];
|
||||
|
||||
runtimeDeps = [
|
||||
ghostscript
|
||||
file
|
||||
gnused
|
||||
gnugrep
|
||||
coreutils
|
||||
which
|
||||
];
|
||||
in
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "cups-brother-mfcl2710dw";
|
||||
version = "4.0.0-1";
|
||||
|
||||
nativeBuildInputs = [dpkg makeWrapper autoPatchelfHook];
|
||||
buildInputs = [perl];
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://download.brother.com/welcome/dlf103526/mfcl2710dwpdrv-${version}.i386.deb";
|
||||
hash = "sha256-OOTvbCuyxw4k01CTMuBqG2boMN13q5xC7LacaweGmyw=";
|
||||
};
|
||||
|
||||
installPhase =
|
||||
''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out
|
||||
dpkg-deb -x $src $out
|
||||
|
||||
# delete unnecessary files for the current architecture
|
||||
''
|
||||
+ lib.concatMapStrings (arch: ''
|
||||
echo Deleting files for ${arch}
|
||||
rm -r "$out/opt/brother/Printers/MFCL2710DW/lpd/${arch}"
|
||||
'') (builtins.filter (arch: arch != stdenv.hostPlatform.linuxArch) arches)
|
||||
+ ''
|
||||
|
||||
# bundled scripts don't understand the arch subdirectories for some reason
|
||||
ln -s \
|
||||
"$out/opt/brother/Printers/MFCL2710DW/lpd/${stdenv.hostPlatform.linuxArch}/"* \
|
||||
"$out/opt/brother/Printers/MFCL2710DW/lpd/"
|
||||
|
||||
# Fix global references and replace auto discovery mechanism with hardcoded values
|
||||
substituteInPlace $out/opt/brother/Printers/MFCL2710DW/lpd/lpdfilter \
|
||||
--replace /opt "$out/opt" \
|
||||
--replace "my \$BR_PRT_PATH =" "my \$BR_PRT_PATH = \"$out/opt/brother/Printers/MFCL2710DW\"; #" \
|
||||
--replace "PRINTER =~" "PRINTER = \"MFCL2710DW\"; #"
|
||||
|
||||
# Make sure all executables have the necessary runtime dependencies available
|
||||
find "$out" -executable -and -type f | while read file; do
|
||||
wrapProgram "$file" --prefix PATH : "${lib.makeBinPath runtimeDeps}"
|
||||
done
|
||||
|
||||
# Symlink filter and ppd into a location where CUPS will discover it
|
||||
mkdir -p $out/lib/cups/filter
|
||||
mkdir -p $out/share/cups/model
|
||||
|
||||
ln -s \
|
||||
$out/opt/brother/Printers/MFCL2710DW/lpd/lpdfilter \
|
||||
$out/lib/cups/filter/brother_lpdwrapper_MFCL2710DW
|
||||
|
||||
ln -s \
|
||||
$out/opt/brother/Printers/MFCL2710DW/cupswrapper/brother-MFCL2710DW-cups-en.ppd \
|
||||
$out/share/cups/model/
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
{config, ...}: {
|
||||
imports = [../nginx-base];
|
||||
services.nginx.virtualHosts = {
|
||||
"bubbleupnp.mothership.aciceri.dev" = {
|
||||
|
@ -8,6 +8,18 @@
|
|||
proxyPass = "http://rock5b.fleet:58050";
|
||||
};
|
||||
};
|
||||
"home.aciceri.dev" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://rock5b.fleet:8123";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
extraConfig = ''
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
'';
|
||||
};
|
||||
"transmission.mothership.aciceri.dev" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
|
@ -15,5 +27,13 @@
|
|||
proxyPass = "http://rock5b.fleet:9091";
|
||||
};
|
||||
};
|
||||
"photos.aciceri.dev" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:8080";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
openRPCPort = true;
|
||||
openPeerPorts = true;
|
||||
settings = {
|
||||
download-dir = "/mnt/raid/torrent";
|
||||
incomplete-dir = "/mnt/raid/torrent/.incomplete";
|
||||
download-dir = "/mnt/hd/torrent";
|
||||
incomplete-dir = "/mnt/hd/torrent/.incomplete";
|
||||
|
||||
rpc-bind-address = "0.0.0.0";
|
||||
peer-port = 51413; # Forward both TCP and UDP on router traffic from router
|
||||
|
@ -36,8 +36,8 @@
|
|||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d /mnt/raid/torrent 770 transmission transmission"
|
||||
"d /mnt/raid/torrent/.incomplete 770 transmission transmission"
|
||||
"d /mnt/hd/torrent 770 transmission transmission"
|
||||
"d /mnt/hd/torrent/.incomplete 770 transmission transmission"
|
||||
];
|
||||
|
||||
ccr.extraGroups = ["transmission"];
|
||||
|
|
BIN
modules/vm-mara/adls_dmc_ver2_01.bin
Normal file
BIN
modules/vm-mara/adls_dmc_ver2_01.bin
Normal file
Binary file not shown.
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
# config,
|
||||
config,
|
||||
pkgs,
|
||||
# lib,
|
||||
# fleetFlake,
|
||||
|
@ -29,12 +29,27 @@
|
|||
];
|
||||
};
|
||||
|
||||
# boot.kernelParams = [
|
||||
# "intel_iommu=on"
|
||||
# # "iommu=pt"
|
||||
# "i915.enable_guc=3"
|
||||
# "i915.max_vfs=7"
|
||||
# ];
|
||||
hardware.opengl.enable = true;
|
||||
virtualisation.spiceUSBRedirection.enable = true;
|
||||
|
||||
boot = {
|
||||
initrd.kernelModules = [
|
||||
"vfio_pci"
|
||||
"vfio"
|
||||
"vfio_iommu_type1"
|
||||
"vfio_virqfd"
|
||||
|
||||
# "i915"
|
||||
];
|
||||
};
|
||||
|
||||
boot.kernelParams = [
|
||||
"intel_iommu=on"
|
||||
"vfio-pci.ids=8086:4680"
|
||||
# "iommu=pt"
|
||||
"i915.enable_guc=3"
|
||||
"i915.max_vfs=7"
|
||||
];
|
||||
|
||||
# boot.blacklistedKernelModules = ["i915"];
|
||||
|
||||
|
@ -47,9 +62,9 @@
|
|||
# (config.boot.kernelPackages.callPackage ./i915-sriov-dkms.nix {} )
|
||||
# ];
|
||||
|
||||
# boot.initrd.availableKernelModules = [
|
||||
# "i915"
|
||||
# ];
|
||||
boot.initrd.availableKernelModules = [
|
||||
# "i915"
|
||||
];
|
||||
|
||||
# boot.initrd.kernelModules = [
|
||||
# "i915"
|
||||
|
@ -94,9 +109,9 @@
|
|||
# }
|
||||
];
|
||||
|
||||
# boot.kernel.sysctl = {
|
||||
# "devices/pci0000:00/0000:00:02.0/sriov_numvfs" = 7;
|
||||
# };
|
||||
boot.kernel.sysctl = {
|
||||
"devices/pci0000:00/0000:00:02.0/sriov_numvfs" = 7;
|
||||
};
|
||||
|
||||
# -vnc :0 \
|
||||
# -audiodev alsa,id=snd0,out.try-poll=off -device ich9-intel-hda -device hda-output,audiodev=snd0 \
|
||||
|
@ -112,7 +127,7 @@
|
|||
|
||||
qemu-system-x86_64 \
|
||||
-enable-kvm \
|
||||
-cpu host,kvm=on,hv-vendor_id="GenuineIntel" \
|
||||
-cpu host,kvm=off,hv-spinlocks=819,hv-vapic=on,hv-relaxed=on,hv-vendor-id="IrisXE" \
|
||||
-smp 4 \
|
||||
-m 8192 \
|
||||
-nic user,model=virtio-net-pci,hostfwd=tcp::3389-:3389,hostfwd=tcp::47989-:47989,hostfwd=tcp::47990-:47990,hostfwd=tcp::47984-:47984,hostfwd=tcp::48010-:48010,hostfwd=udp::47998-:47988,hostfwd=udp::47999-:47999,hostfwd=udp::48000-:48000,hostfwd=udp::48002-:48002,hostfwd=udp::48003-:48003,hostfwd=udp::48004-:48004,hostfwd=udp::48005-:48005,hostfwd=udp::48006-:48006,hostfwd=udp::48007-:48007,hostfwd=udp::48008-:48008,hostfwd=udp::48009-:48009,hostfwd=udp::48010-:48010 \
|
||||
|
@ -121,7 +136,9 @@
|
|||
-device usb-tablet \
|
||||
-vnc :0 \
|
||||
-nographic \
|
||||
-drive file=/var/lib/vm-mara/w10.qcow2
|
||||
-vga none \
|
||||
-drive file=/var/lib/vm-mara/w10.qcow2 \
|
||||
-device vfio-pci,host=00:02.0,addr=03.0,x-vga=on,multifunction=on,romfile=${./adls_dmc_ver2_01.bin}
|
||||
'';
|
||||
};
|
||||
in {
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
src = fetchFromGitHub {
|
||||
owner = "strongtz";
|
||||
repo = "i915-sriov-dkms";
|
||||
rev = version;
|
||||
sha256 = "sha256-LNKDNi7oEhO3FY47oKYbg8wt+268GlBVxQpHdNLNrwM=";
|
||||
rev = "db4e8ccd9bd31fad79361e27afc032487426fe6a";
|
||||
hash = "sha256-WCDwy39jpnc2wkM/883gFwChVD7wAP2nCR8Aw+CfDw8=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = kernel.moduleBuildDependencies;
|
||||
|
|
34
modules/vm-ubuntu/default.nix
Normal file
34
modules/vm-ubuntu/default.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{pkgs, ...}: {
|
||||
virtualisation.libvirtd.enable = true;
|
||||
|
||||
networking.firewall.interfaces."wg0" = {
|
||||
allowedTCPPorts = [
|
||||
5900 # vnc by QEMU
|
||||
2233
|
||||
60022
|
||||
8545
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services.vm-ubuntu = let
|
||||
start-vm = pkgs.writeShellApplication {
|
||||
name = "start-vm";
|
||||
runtimeInputs = with pkgs; [qemu];
|
||||
text = ''
|
||||
qemu-system-x86_64 \
|
||||
-enable-kvm \
|
||||
-cpu host,kvm=on,hv-vendor_id="GenuineIntel" \
|
||||
-smp 4 \
|
||||
-m 8192 \
|
||||
-nic user,model=virtio-net-pci,hostfwd=tcp::60022-:22,hostfwd=tcp::8545-:8545 \
|
||||
-drive file=/var/lib/vm-ubuntu/ubuntu.qcow2
|
||||
'';
|
||||
};
|
||||
in {
|
||||
wantedBy = ["multi-user.target"];
|
||||
after = ["network.target"];
|
||||
serviceConfig = {
|
||||
ExecStart = "${start-vm}/bin/start-vm";
|
||||
};
|
||||
};
|
||||
}
|
3
modules/waydroid/default.nix
Normal file
3
modules/waydroid/default.nix
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
virtualisation.waydroid.enable = true;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue