server: add scanservjs, nixmsi: refix boot

This commit is contained in:
chayleaf 2023-08-24 18:27:05 +07:00
parent c0cc98e541
commit 9e70d53ee5
12 changed files with 375 additions and 44 deletions

View file

@ -131,6 +131,7 @@
nixos-mailserver.nixosModules.default
./system/devices/hp-probook-g0-server.nix
(if devMaubot then import /${devPath}/maubot.nix/module else maubot.nixosModules.default)
./system/modules/scanservjs.nix
];
};
nixserver-cross = crossConfig nixserver;

View file

@ -178,9 +178,8 @@
]);
plugins = let ps = pkgs.vimPlugins; in map (x: if x?config && x?plugin then { type = "lua"; } // x else x) [
ps.vim-svelte
# TODO remove on next nvim update (0.8.3/0.9? whenever they add builtin nix syntax)
# testing the removal
# ps.vim-nix
# vim-nix isn't necessary for syntax highlighting, but it improves overall editing experience
ps.vim-nix
{ plugin = pkgs.vimUtils.buildVimPluginFrom2Nix {
pname = "vscode-nvim";
version = "2023-02-10";

View file

@ -5,7 +5,7 @@
, pkgs' ? pkgs
, ... }:
let
inherit (pkgs) callPackage;
inherit (pkgs') callPackage;
sources = import ./_sources/generated.nix {
inherit (pkgs) fetchgit fetchurl fetchFromGitHub dockerTools;
};
@ -13,21 +13,6 @@ let
in
{
linux-firmware = if pkgs.system == "x86_64-linux" then pkgs.stdenvNoCC.mkDerivation {
inherit (pkgs.linux-firmware) pname version src meta;
dontFixup = true;
passthru = { inherit (pkgs.linux-firmware) version; };
installFlags = [ "DESTDIR=$(out)" ];
# revert microcode updates which break boot for me
patches = [ ./revert-amd-ucode-update.patch ];
postPatch = ''
cp ${pkgs.fetchurl {
url = "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/amd-ucode/microcode_amd_fam17h.bin?id=b250b32ab1d044953af2dc5e790819a7703b7ee6";
hash = "sha256-HnKjEb2di7BiKB09JYUjIUuZNCVgXlwRSbjijnuYBcM=";
}} amd-ucode/microcode_amd_fam17h.bin
'';
} else pkgs.linux-firmware;
inherit (nix-gaming) faf-client osu-lazer-bin;
inherit nixForNixPlugins;
nix = nixForNixPlugins;
@ -100,6 +85,7 @@ in
'';
};
rofi-steam-game-list = callPackage ./rofi-steam-game-list { };
scanservjs = callPackage ./scanservjs.nix { };
searxng = pkgs'.python3.pkgs.toPythonModule (pkgs.searxng.overrideAttrs (old: {
inherit (sources.searxng) src;
version = "unstable-" + sources.searxng.date;

91
pkgs/scanservjs.nix Normal file
View file

@ -0,0 +1,91 @@
{ lib
, fetchFromGitHub
, buildNpmPackage
, fetchNpmDeps
, nodejs
}:
let
version = "2.27.0";
src = fetchFromGitHub {
owner = "sbs20";
repo = "scanservjs";
rev = "v${version}";
hash = "sha256-GFpfH7YSXFRNRmx8F2bUJsGdPW1ECT7AQquJRxiRJEU=";
};
depsHashes = {
server = "sha256-V4w4euMl67eS4WNIFM8j06/JAEudaq+4zY9pFVgTmlY=";
client = "sha256-r/uYaXpQnlI90Yn6mo2KViKDMHE8zaCAxNFnEZslnaY=";
};
serverDepsForClient = fetchNpmDeps {
inherit src nodejs;
sourceRoot = "${src.name}/packages/server";
name = "scanservjs-server";
hash = depsHashes.server or lib.fakeHash;
};
# static client files
client = buildNpmPackage ({
pname = "scanservjs-static";
inherit version src nodejs;
sourceRoot = "${src.name}/packages/client";
npmDepsHash = depsHashes.client or lib.fakeHash;
preBuild = ''
cd ../server
chmod +w package-lock.json . /build/source/
npmDeps=${serverDepsForClient} npmConfigHook
cd ../client
'';
env.NODE_OPTIONS = "--openssl-legacy-provider";
dontNpmInstall = true;
installPhase = ''
mv /build/source/dist/client $out
'';
});
in buildNpmPackage {
pname = "scanservjs";
inherit version src nodejs;
sourceRoot = "${src.name}/packages/server";
npmDepsHash = depsHashes.server or lib.fakeHash;
preBuild = ''
chmod +w /build/source
substituteInPlace src/server.js --replace "express.static('client')" "express.static('${client}')"
substituteInPlace src/api.js --replace \
'`''${config.previewDirectory}/default.jpg`' \
"'$out/lib/node_modules/scanservjs-api/data/preview/default.jpg'"
substituteInPlace src/application.js --replace \
"'../../config/config.local.js'" \
"process.env.NIX_SCANSERVJS_CONFIG_PATH"
substituteInPlace src/classes/user-options.js --replace \
"const localPath = path.join(__dirname, localConfigPath);" \
"const localPath = localConfigPath;"
substituteInPlace src/configure.js --replace \
"fs.mkdirSync(config.outputDirectory, { recursive: true });" \
"fs.mkdirSync(config.outputDirectory, { recursive: true }); fs.mkdirSync(config.previewDirectory, { recursive: true });"
'';
postInstall = ''
mkdir -p $out/bin
makeWrapper ${nodejs}/bin/node $out/bin/scanservjs \
--set NODE_ENV production \
--add-flags "'$out/lib/node_modules/scanservjs-api/src/server.js'"
'';
meta = with lib; {
description = "SANE scanner nodejs web ui";
longDescription = "scanservjs is a simple web-based UI for SANE which allows you to share a scanner on a network without the need for drivers or complicated installation.";
homepage = "https://github.com/sbs20/scanservjs";
license = licenses.gpl2Only;
mainProgram = "scanservjs";
maintainers = with maintainers; [ chayleaf ];
};
}

View file

@ -11,7 +11,7 @@ let
dataroot = "/dev/disk/by-uuid/${datarootUuid}";
in {
imports = [
../hardware/msi-delta-15.nix
../hardware/msi-delta-15
../hosts/nixmsi.nix
];

View file

@ -1,24 +0,0 @@
{ hardware
, ... }:
{
imports = with hardware; [
common-pc-ssd # enables fstrim
common-cpu-amd # microcode
common-cpu-amd-pstate # amd-pstate
common-gpu-amd # configures drivers
common-pc-laptop # enables tlp
];
common.resolution = "1920x1080";
vfio.pciIDs = [ "1002:73df" "1002:ab28" ];
boot = {
initrd.availableKernelModules = [ "nvme" "xhci_pci" ];
kernelParams = [
# disable PSR to *hopefully* avoid random hangs
# this one didnt help
"amdgpu.dcdebugmask=0x10"
# maybe this one will?
"amdgpu.noretry=0"
];
};
}

View file

@ -0,0 +1,54 @@
{ hardware
, ... }:
{
imports = with hardware; [
common-pc-ssd # enables fstrim
common-cpu-amd # microcode
common-cpu-amd-pstate # amd-pstate
common-gpu-amd # configures drivers
common-pc-laptop # enables tlp
];
common.resolution = "1920x1080";
vfio.pciIDs = [ "1002:73df" "1002:ab28" ];
boot = {
initrd.availableKernelModules = [ "nvme" "xhci_pci" ];
kernelParams = [
# disable PSR to *hopefully* avoid random hangs
# this one didnt help
"amdgpu.dcdebugmask=0x10"
# maybe this one will?
"amdgpu.noretry=0"
];
};
# TODO: really, really, please, I want latest firmware to work...
nixpkgs.overlays = [
(final: prev: {
amd-ucode = prev.amd-ucode.override { inherit (final) linux-firmware; };
linux-firmware = prev.stdenvNoCC.mkDerivation {
inherit (prev.linux-firmware) pname version meta src;
dontFixup = true;
passthru = { inherit (prev.linux-firmware) version; };
installFlags = [ "DESTDIR=$(out)" ];
# revert microcode updates which break boot for me
patches = [
./revert-amd-ucode-update-fam17h.patch
./revert-amd-ucode-update-fam19h.patch
];
postPatch = ''
cp ${final.fetchurl {
name = "microcode_amd_fam17h.bin";
url = "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/amd-ucode/microcode_amd_fam17h.bin?id=b250b32ab1d044953af2dc5e790819a7703b7ee6";
hash = "sha256-HnKjEb2di7BiKB09JYUjIUuZNCVgXlwRSbjijnuYBcM=";
}} amd-ucode/microcode_amd_fam17h.bin
cp ${final.fetchurl {
name = "microcode_amd_fam19h.bin";
url = "https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/amd-ucode/microcode_amd_fam19h.bin?id=0ab353f8d8aa96d68690911cea22ec538f3095c4";
hash = "sha256-LlA+E4EVQpfjD3/cg6Y52BsCGW/5ZfY0J2UnCUI/3MQ";
}} amd-ucode/microcode_amd_fam19h.bin
'';
};
})
];
}

View file

@ -0,0 +1,61 @@
diff --git a/WHENCE b/WHENCE
index 54aadb0..99cee97 100644
--- a/WHENCE
+++ b/WHENCE
@@ -3924,7 +3924,7 @@ Raw: amd-ucode/microcode_amd_fam17h.bin
Version: 2023-07-19
File: amd-ucode/microcode_amd_fam19h.bin
Raw: amd-ucode/microcode_amd_fam19h.bin
-Version: 2023-08-08
+Version: 2023-07-18
File: amd-ucode/README
License: Redistributable. See LICENSE.amd-ucode for details
diff --git a/amd-ucode/README b/amd-ucode/README
index fac1152..1d39da3 100644
--- a/amd-ucode/README
+++ b/amd-ucode/README
@@ -37,19 +37,6 @@ Microcode patches in microcode_amd_fam17h.bin:
Family=0x17 Model=0x01 Stepping=0x02: Patch=0x0800126e Length=3200 bytes
Microcode patches in microcode_amd_fam19h.bin:
- Family=0x19 Model=0x11 Stepping=0x01: Patch=0x0a10113e Length=5568 bytes
- Family=0x19 Model=0x11 Stepping=0x02: Patch=0x0a10123e Length=5568 bytes
- Family=0x19 Model=0xa0 Stepping=0x02: Patch=0x0aa00212 Length=5568 bytes
Family=0x19 Model=0x01 Stepping=0x01: Patch=0x0a0011d1 Length=5568 bytes
Family=0x19 Model=0x01 Stepping=0x00: Patch=0x0a001079 Length=5568 bytes
Family=0x19 Model=0x01 Stepping=0x02: Patch=0x0a001234 Length=5568 bytes
- Family=0x19 Model=0xa0 Stepping=0x01: Patch=0x0aa00116 Length=5568 bytes
-
-NOTE: For Genoa (Family=0x19 Model=0x11) and Bergamo (Family=0x19 Model=0xa0),
-either AGESA version >= 1.0.0.8 OR a kernel with the following commit is
-required:
-a32b0f0db3f3 ("x86/microcode/AMD: Load late on both threads too")
-
-When late loading the patches for Genoa or Bergamo, there may be one spurious
-NMI observed per physical core. These NMIs are benign and don't cause any
-functional issue but will result in kernel messages being logged.
diff --git a/amd-ucode/microcode_amd_fam19h.bin.asc b/amd-ucode/microcode_amd_fam19h.bin.asc
index 8cff901..a32b4d6 100644
--- a/amd-ucode/microcode_amd_fam19h.bin.asc
+++ b/amd-ucode/microcode_amd_fam19h.bin.asc
@@ -1,11 +1,11 @@
-----BEGIN PGP SIGNATURE-----
-iQEzBAABCgAdFiEE/HxsUF2vzBRxg1fK5L5TOfMornMFAmTEYrcACgkQ5L5TOfMo
-rnN4IQf/QKbOezXZ4OYzaPANvsZQEAzLNfuylC/aQMwrPaO7daz5/zmCN4HU5XkH
-dDT8DYfPg+fQHIgxAw0/L24xPOm5Op/QuLVDyDqVr4qvL8+65eeI+JqxD/wXMXYN
-V34kkLM2p8iuyY1Nc8IDLXu4X75KGNPbKZlMRKMU3Pr7ai5O4ihmiAM+N6qv1KEJ
-YToNN6vrg0qt1cv0SLM8sa4e7L1+oblUrg/o0FViYE8pxsU3ZRRVSJMUg+lKjvl/
-1ZPGKOdD80fcNJ+ItYGHNNs3eCc3WgW7Kc/E668eH75Yu9Zt7ewWZX8Sg/mygleY
-OzMwhbPJg4bF4zm7C/Pku7i1T2Omcg==
-=km2X
+iQEzBAABCgAdFiEE/HxsUF2vzBRxg1fK5L5TOfMornMFAmS3F00ACgkQ5L5TOfMo
+rnNEhQgAizSV8IFpvaYNytaJKLA4uevrZneGPV4czjCXnnj1yHpfQmCTyZQnoLnx
+7gyzf7K5271zO51FBQ5z2Nm48a3XPUhMbQLNP4BZdekLiA3bRpMtSyHct6zD0ULm
+xaFaOQ7MR1tGADhlon1bDvtnOuixUhwrZhEIlR9MzQAzERKDMOAVTbxn9ZhMfYiT
+LhA791Blyyi+6Z9uh7BpaA8l8uvoxt+uuvlBTjQMR3ER/TEjgcsoy+XhhK4QKS0V
+wJCtcDle/3pF+N6SAFWiXbNZ+P8p19afhcYddDl97xtpzA6/8b20a2eHkrqnu/Ds
+jTozF9kmhiifYMYpXtXgSOwI3GRZbQ==
+=t+j1
-----END PGP SIGNATURE-----

View file

@ -120,6 +120,7 @@
# programs.wireshark.enable = true;
# users.groups.wireshark.members = [ config.common.mainUsername ];
services.printing.enable = true;
services.printing.drivers = [ pkgs.hplip ];
services.pipewire = {
enable = true;
alsa.enable = true;
@ -171,6 +172,8 @@
services.udev.packages = [
pkgs.android-udev-rules
];
services.avahi.enable = true;
services.avahi.nssmdns = true;
environment.systemPackages = with pkgs; [
comma
neovim

View file

@ -47,6 +47,7 @@ in {
'';
# locations."/.well-known/acme-challenge".extraConfig = "auth_basic off;";
locations."/".root = "/var/www/home.${cfg.domainName}/";
locations."/scan/".proxyPass = "http://${lib.quoteListenAddr config.services.scanservjs.settings.host}:${toString config.services.scanservjs.settings.port}/";
locations."/grafana/" = {
proxyPass = "http://grafana/";
proxyWebsockets = true;
@ -383,4 +384,12 @@ in {
publish.addresses = true;
publish.userServices = true;
};
hardware.sane = {
enable = true;
extraBackends = with pkgs; [ hplipWithPlugin ];
};
nixpkgs.config.allowUnfreePredicate = pkg: lib.getName pkg == "hplip";
services.scanservjs.enable = true;
services.scanservjs.settings.host = "127.0.0.1";
services.scanservjs.settings.port = 3952;
}

View file

@ -0,0 +1,151 @@
{ config
, lib
, pkgs
, ...}:
let
cfg = config.services.scanservjs;
/*
substituteInPlace src/classes/config.js \
--replace '/usr/bin/scanimage' '${sane-backends}/bin/scanimage' \
--replace '/usr/bin/convert' '${imagemagick}/bin/convert' \
--replace '/usr/bin/tesseract' '${tesseract}/bin/tesseract'
*/
settings = {
scanimage = "${pkgs.sane-backends}/bin/scanimage";
convert = "${pkgs.imagemagick}/bin/convert";
tesseract = "${pkgs.tesseract}/bin/tesseract";
# it defaults to config/devices.json, but "config" dir doesn't exist and scanservjs doesn't create it
devicesPath = "devices.json";
} // cfg.settings;
settingsFormat = pkgs.formats.json { };
leafs = attrs:
builtins.concatLists
(lib.mapAttrsToList
(k: v: if builtins.isAttrs v then leafs v else [v])
attrs);
package = pkgs.scanservjs;
# config.host = '127.0.0.1';
# config.port = 8080;
# config.devices = [];
# config.ocrLanguage = 'eng';
# config.log.level = 'DEBUG';
# config.scanimage = '/usr/bin/scanimage';
# config.convert = '/usr/bin/convert';
# config.tesseract = '/usr/bin/tesseract';
# config.previewResolution = 100;
configFile = pkgs.writeText "config.local.js" ''
/* eslint-disable no-unused-vars */
module.exports = {
afterConfig(config) {
${builtins.concatStringsSep ""
(leafs
(lib.mapAttrsRecursive (path: val: ''
${builtins.concatStringsSep "." path} = ${builtins.toJSON val};
'') { config = settings; }))}
${cfg.extraConfig}
},
afterDevices(devices) {
${cfg.extraDevicesConfig}
},
async afterScan(fileInfo) {
${cfg.runAfterScan}
},
actions: [
${builtins.concatStringsSep ",\n" cfg.extraActions}
],
};
'';
in {
options.services.scanservjs = {
enable = lib.mkEnableOption (lib.mdDoc "scanservjs");
stateDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/scanservjs";
description = lib.mdDoc ''
State directory for scanservjs
'';
};
settings = lib.mkOption {
default = {};
description = lib.mdDoc ''
Config to set in config.local.js's `afterConfig`
'';
type = lib.types.submodule {
freeformType = settingsFormat.type;
options.host = lib.mkOption {
type = lib.types.str;
description = "The IP to listen on";
default = "127.0.0.1";
};
options.port = lib.mkOption {
type = lib.types.port;
description = "The port to listen on";
default = 8080;
};
};
};
extraConfig = lib.mkOption {
default = "";
type = lib.types.lines;
description = lib.mdDoc ''
Extra code to add to config.local.js's `afterConfig`
'';
};
extraDevicesConfig = lib.mkOption {
default = "";
type = lib.types.lines;
description = lib.mdDoc ''
Extra code to add to config.local.js's `afterDevices`
'';
};
runAfterScan = lib.mkOption {
default = "";
type = lib.types.lines;
description = lib.mdDoc ''
Extra code to add to config.local.js's `afterScan`
'';
};
extraActions = lib.mkOption {
default = [];
type = lib.types.listOf lib.types.lines;
description = "Actions to add to config.local.js's `actions`";
};
};
config = lib.mkIf cfg.enable {
hardware.sane.enable = true;
users.users.scanservjs = {
group = "scanservjs";
extraGroups = [ "scanner" "lp" ];
home = cfg.stateDir;
isSystemUser = true;
createHome = true;
};
users.groups.scanservjs = {};
systemd.services.scanservjs = {
description = "scanservjs";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
# yes, those paths are configurable, but the config option isn't always used...
path = with pkgs; [ coreutils sane-backends imagemagick tesseract ];
environment.NIX_SCANSERVJS_CONFIG_PATH = configFile;
environment.SANE_CONFIG_DIR = "/etc/sane-config";
environment.LD_LIBRARY_PATH = "/etc/sane-libs";
serviceConfig = {
ExecStart = "${package}/bin/scanservjs";
Restart = "always";
User = "scanservjs";
Group = "scanservjs";
WorkingDirectory = cfg.stateDir;
};
};
};
}