Reformat all Nix files
This commit is contained in:
parent
9e0c1102a9
commit
355b63cf73
81 changed files with 2293 additions and 1153 deletions
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
boot.loader = {
|
||||
grub = {
|
||||
|
@ -10,4 +15,3 @@
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
eap=TTLS
|
||||
identity="37C3"
|
||||
password="37C3"
|
||||
ca_cert="${builtins.fetchurl {
|
||||
url = "https://letsencrypt.org/certs/isrgrootx1.pem";
|
||||
sha256 = "sha256:1la36n2f31j9s03v847ig6ny9lr875q3g7smnq33dcsmf2i5gd92";
|
||||
}}"
|
||||
ca_cert="${
|
||||
builtins.fetchurl {
|
||||
url = "https://letsencrypt.org/certs/isrgrootx1.pem";
|
||||
sha256 = "sha256:1la36n2f31j9s03v847ig6ny9lr875q3g7smnq33dcsmf2i5gd92";
|
||||
}
|
||||
}"
|
||||
altsubject_match="DNS:radius.c3noc.net"
|
||||
phase2="auth=PAP"
|
||||
'';
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
networking = {
|
||||
hostName = config.frogeye.name;
|
||||
|
@ -16,13 +21,17 @@
|
|||
|
||||
# Enable passwordless sudo
|
||||
# TODO execWheelOnly? sudo-rs?
|
||||
security.sudo.extraRules = [{
|
||||
groups = [ "wheel" ];
|
||||
commands = [{
|
||||
command = "ALL";
|
||||
options = [ "NOPASSWD" ];
|
||||
}];
|
||||
}];
|
||||
security.sudo.extraRules = [
|
||||
{
|
||||
groups = [ "wheel" ];
|
||||
commands = [
|
||||
{
|
||||
command = "ALL";
|
||||
options = [ "NOPASSWD" ];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
# UPST disko --root-mountpoint doesn't work when using flake, workaround:
|
||||
disko.rootMountPoint = "/mnt/nixos";
|
||||
|
@ -44,7 +53,10 @@
|
|||
nix = {
|
||||
package = pkgs.lix;
|
||||
settings = {
|
||||
experimental-features = [ "nix-command" "flakes" ];
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
warn-dirty = false;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# Need nvidia proprietary drivers to work
|
||||
{ pkgs, nixpkgs, config, lib, ... }:
|
||||
{
|
||||
pkgs,
|
||||
nixpkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config = lib.mkIf config.frogeye.cuda {
|
||||
nix.settings = {
|
||||
|
@ -11,7 +17,8 @@
|
|||
];
|
||||
};
|
||||
nixpkgs.overlays = [
|
||||
(self: super:
|
||||
(
|
||||
self: super:
|
||||
let
|
||||
pkgs_uf = import nixpkgs {
|
||||
inherit (super) system;
|
||||
|
@ -19,11 +26,14 @@
|
|||
};
|
||||
in
|
||||
{
|
||||
ctranslate2 = (pkgs_uf.ctranslate2.override {
|
||||
withCUDA = true;
|
||||
withCuDNN = true;
|
||||
});
|
||||
})
|
||||
ctranslate2 = (
|
||||
pkgs_uf.ctranslate2.override {
|
||||
withCUDA = true;
|
||||
withCuDNN = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
setupScript = "${pkgs.writeShellApplication {
|
||||
name = "greeter-setup-script";
|
||||
runtimeInputs = [ pkgs.autorandr ];
|
||||
text = ''
|
||||
autorandr --change
|
||||
'';
|
||||
}}/bin/greeter-setup-script";
|
||||
setupScript = "${
|
||||
pkgs.writeShellApplication {
|
||||
name = "greeter-setup-script";
|
||||
runtimeInputs = [ pkgs.autorandr ];
|
||||
text = ''
|
||||
autorandr --change
|
||||
'';
|
||||
}
|
||||
}/bin/greeter-setup-script";
|
||||
in
|
||||
{
|
||||
config = {
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config = lib.mkIf config.frogeye.desktop.xorg {
|
||||
boot.kernelModules = [ "i2c-dev" ]; # Allows using ddcutil
|
||||
|
@ -19,7 +24,7 @@
|
|||
# https://wiki.archlinux.org/title/PipeWire#Noticeable_audio_delay_or_audible_pop/crack_when_starting_playback
|
||||
preventGetTogetherDuoFromShuttingDown."monitor.bluez.rules" = [
|
||||
{
|
||||
matches = [{ "node.name" = "~bluez_output.41_42_D2_B5_13_72.*"; }];
|
||||
matches = [ { "node.name" = "~bluez_output.41_42_D2_B5_13_72.*"; } ];
|
||||
actions.update-props = {
|
||||
"session.suspend-timeout-seconds" = 0;
|
||||
"dither.method" = "wannamaker3";
|
||||
|
@ -39,23 +44,25 @@
|
|||
extraLayouts.qwerty-fr = {
|
||||
description = "QWERTY-fr";
|
||||
languages = [ "fr" ];
|
||||
symbolsFile = "${pkgs.stdenv.mkDerivation {
|
||||
name = "qwerty-fr-keypad";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "qwerty-fr";
|
||||
repo = "qwerty-fr";
|
||||
rev = "3a4d13089e8ef016aa20baf6b2bf3ea53de674b8";
|
||||
sha256 = "sha256-wn5n6jJVDrQWJze8xYF2nEY8a7mHI3hVO4xsT4LMo9c=";
|
||||
};
|
||||
patches = [ ./qwerty-fr-keypad.diff ];
|
||||
# TODO This doesn't seem to be applied... it's the whole point of the derivation :(
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/linux
|
||||
cp $src/linux/us_qwerty-fr $out/linux
|
||||
runHook postInstall
|
||||
'';
|
||||
}}/linux/us_qwerty-fr";
|
||||
symbolsFile = "${
|
||||
pkgs.stdenv.mkDerivation {
|
||||
name = "qwerty-fr-keypad";
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "qwerty-fr";
|
||||
repo = "qwerty-fr";
|
||||
rev = "3a4d13089e8ef016aa20baf6b2bf3ea53de674b8";
|
||||
sha256 = "sha256-wn5n6jJVDrQWJze8xYF2nEY8a7mHI3hVO4xsT4LMo9c=";
|
||||
};
|
||||
patches = [ ./qwerty-fr-keypad.diff ];
|
||||
# TODO This doesn't seem to be applied... it's the whole point of the derivation :(
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir -p $out/linux
|
||||
cp $src/linux/us_qwerty-fr $out/linux
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
||||
}/linux/us_qwerty-fr";
|
||||
};
|
||||
layout = "qwerty-fr";
|
||||
};
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf config.frogeye.dev.docker {
|
||||
|
|
|
@ -1,29 +1,33 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
config = lib.mkIf config.frogeye.gaming
|
||||
{
|
||||
programs.steam.enable = true;
|
||||
hardware.graphics.enable32Bit = true; # Needed by Steam
|
||||
services = {
|
||||
udev.packages = [ pkgs.python3Packages.ds4drv ];
|
||||
xserver.config = ''
|
||||
# Disable mouse support for joypad
|
||||
Section "InputClass"
|
||||
Identifier "joystick catchall"
|
||||
MatchIsJoystick "on"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "joystick"
|
||||
Option "StartKeysEnabled" "False"
|
||||
Option "StartMouseEnabled" "False"
|
||||
EndSection
|
||||
# Same thing for DualShock 4 touchpad
|
||||
Section "InputClass"
|
||||
Identifier "ds4-touchpad"
|
||||
Driver "libinput"
|
||||
MatchProduct "Wireless Controller Touchpad"
|
||||
Option "Ignore" "True"
|
||||
EndSection
|
||||
'';
|
||||
};
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config = lib.mkIf config.frogeye.gaming {
|
||||
programs.steam.enable = true;
|
||||
hardware.graphics.enable32Bit = true; # Needed by Steam
|
||||
services = {
|
||||
udev.packages = [ pkgs.python3Packages.ds4drv ];
|
||||
xserver.config = ''
|
||||
# Disable mouse support for joypad
|
||||
Section "InputClass"
|
||||
Identifier "joystick catchall"
|
||||
MatchIsJoystick "on"
|
||||
MatchDevicePath "/dev/input/event*"
|
||||
Driver "joystick"
|
||||
Option "StartKeysEnabled" "False"
|
||||
Option "StartMouseEnabled" "False"
|
||||
EndSection
|
||||
# Same thing for DualShock 4 touchpad
|
||||
Section "InputClass"
|
||||
Identifier "ds4-touchpad"
|
||||
Driver "libinput"
|
||||
MatchProduct "Wireless Controller Touchpad"
|
||||
Option "Ignore" "True"
|
||||
EndSection
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,20 @@
|
|||
{ pkgs, lib, config, home-manager, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
home-manager,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config = {
|
||||
users.users.root.initialHashedPassword = "$y$j9T$e64bjL7iyVlniEKwKbM9g0$cCn74za0r6L9QMO20Fdxz3/SX0yvhz3Xd6.2BhtbRL1"; # Not a real password
|
||||
|
||||
users.users.geoffrey = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "adbusers" "wheel" ];
|
||||
extraGroups = [
|
||||
"adbusers"
|
||||
"wheel"
|
||||
];
|
||||
shell = pkgs.zsh;
|
||||
|
||||
initialHashedPassword = "$y$j9T$e64bjL7iyVlniEKwKbM9g0$cCn74za0r6L9QMO20Fdxz3/SX0yvhz3Xd6.2BhtbRL1"; # Not a real password
|
||||
|
@ -21,11 +30,13 @@
|
|||
nix.settings.trusted-users = [ "geoffrey" ];
|
||||
|
||||
home-manager = {
|
||||
users.geoffrey = { pkgs, ... }: {
|
||||
frogeye = lib.mkDefault config.frogeye;
|
||||
# Propagating options that way doesn't seem to conserve priority info,
|
||||
# this is not great. Hopefully mkDefault resolve conflicts.
|
||||
};
|
||||
users.geoffrey =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
frogeye = lib.mkDefault config.frogeye;
|
||||
# Propagating options that way doesn't seem to conserve priority info,
|
||||
# this is not great. Hopefully mkDefault resolve conflicts.
|
||||
};
|
||||
# Makes VMs able to re-run
|
||||
useUserPackages = true;
|
||||
# Adds consistency
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
passwordStoreDir = "/etc/passwords";
|
||||
passwordHash = password: builtins.hashString "sha256" "${password.path}\n${builtins.toString password.selector}\n${builtins.toString password.transform}";
|
||||
passwordHash =
|
||||
password:
|
||||
builtins.hashString "sha256" "${password.path}\n${builtins.toString password.selector}\n${builtins.toString password.transform}";
|
||||
passwordStorePath = password: "${passwordStoreDir}/${passwordHash password}";
|
||||
describePassword = password: password.path
|
||||
describePassword =
|
||||
password:
|
||||
password.path
|
||||
+ (if password.selector != null then " -> ${password.selector}" else "")
|
||||
+ (if password.transform != null then " | (${password.transform})" else "");
|
||||
passwordFiles = builtins.attrValues config.vivarium.passwordFiles;
|
||||
|
@ -12,16 +21,23 @@ in
|
|||
config = {
|
||||
system = {
|
||||
activationScripts.secrets = {
|
||||
deps = [ "users" "groups" ];
|
||||
deps = [
|
||||
"users"
|
||||
"groups"
|
||||
];
|
||||
supportsDryActivation = false; # TODO
|
||||
text =
|
||||
let
|
||||
readPassword = password: "cat ${lib.strings.escapeShellArg (passwordStorePath password)}";
|
||||
# Using awk's ENVIRON so it should resist any input?
|
||||
pipeSubstitute = k: v: ''K=${lib.strings.escapeShellArg k} V="$(${v})" awk '{ gsub (ENVIRON["K"], ENVIRON["V"]); print }' '';
|
||||
pipeSubstitute =
|
||||
k: v:
|
||||
''K=${lib.strings.escapeShellArg k} V="$(${v})" awk '{ gsub (ENVIRON["K"], ENVIRON["V"]); print }' '';
|
||||
subsitutePassword = variable: password: pipeSubstitute variable (readPassword password);
|
||||
subsitutePasswordFile = passwordFile: lib.mapAttrsToList subsitutePassword passwordFile.passwords;
|
||||
renderPasswordFile = passwordFile: "${lib.strings.concatStringsSep "| " (subsitutePasswordFile passwordFile)} < ${passwordFile.template}";
|
||||
renderPasswordFile =
|
||||
passwordFile:
|
||||
"${lib.strings.concatStringsSep "| " (subsitutePasswordFile passwordFile)} < ${passwordFile.template}";
|
||||
installPasswordFile = passwordFile: ''
|
||||
install -C -o ${passwordFile.owner} -g ${passwordFile.group} -m ${passwordFile.mode} -d ${builtins.dirOf passwordFile.path}
|
||||
temp="$(mktemp)"
|
||||
|
@ -31,12 +47,15 @@ in
|
|||
rm "$temp"
|
||||
trap - ERR
|
||||
'';
|
||||
installPasswordFileApp = passwordFile: pkgs.writeShellApplication {
|
||||
name = builtins.replaceStrings ["/"] ["_"] passwordFile.path;
|
||||
runtimeInputs = with pkgs; [ gawk ];
|
||||
text = installPasswordFile passwordFile;
|
||||
};
|
||||
installPasswordFileSandboxed = passwordFile:
|
||||
installPasswordFileApp =
|
||||
passwordFile:
|
||||
pkgs.writeShellApplication {
|
||||
name = builtins.replaceStrings [ "/" ] [ "_" ] passwordFile.path;
|
||||
runtimeInputs = with pkgs; [ gawk ];
|
||||
text = installPasswordFile passwordFile;
|
||||
};
|
||||
installPasswordFileSandboxed =
|
||||
passwordFile:
|
||||
''${lib.getExe (installPasswordFileApp passwordFile)} || echo Failed to install ${lib.strings.escapeShellArg passwordFile.path}'';
|
||||
in
|
||||
''
|
||||
|
@ -47,22 +66,38 @@ in
|
|||
extraSystemBuilderCmds =
|
||||
let
|
||||
passwords = builtins.attrValues config.vivarium.passwords;
|
||||
readPasswordClear = password: "pass show ${lib.strings.escapeShellArg password.path}" + (
|
||||
if password.selector == null
|
||||
then " | head -n1"
|
||||
else
|
||||
(if password.selector == "@"
|
||||
then ""
|
||||
else " | tail -n +2 | yq -r '.${password.selector}'")
|
||||
);
|
||||
readPassword = password: (readPasswordClear password) + (lib.strings.optionalString (password.transform != null) " | ${password.transform}");
|
||||
readPasswordClear =
|
||||
password:
|
||||
"pass show ${lib.strings.escapeShellArg password.path}"
|
||||
+ (
|
||||
if password.selector == null then
|
||||
" | head -n1"
|
||||
else
|
||||
(if password.selector == "@" then "" else " | tail -n +2 | yq -r '.${password.selector}'")
|
||||
);
|
||||
readPassword =
|
||||
password:
|
||||
(readPasswordClear password)
|
||||
+ (lib.strings.optionalString (password.transform != null) " | ${password.transform}");
|
||||
gitPath = password: ''"$PASSWORD_STORE_DIR"/${lib.strings.escapeShellArg password.path}.gpg'';
|
||||
isGeneratedPassword = password: ''test -f ${gitPath password}'';
|
||||
dateGit = password: " " + ''(cd "$(dirname ${gitPath password})"; git log -n1 --format='format:%ct' "$(basename ${gitPath password})")'' + " ";
|
||||
dateGit =
|
||||
password:
|
||||
" "
|
||||
+ ''(cd "$(dirname ${gitPath password})"; git log -n1 --format='format:%ct' "$(basename ${gitPath password})")''
|
||||
+ " ";
|
||||
dateStore = password: ''sudo stat -c '%Y' ${passwordStorePath password}'';
|
||||
isInStore = password: ''sudo test -f ${passwordStorePath password}'';
|
||||
testCanGenerate = password: lib.asserts.assertMsg (builtins.elem password.selector [ "@" null ]) "Unimplemented: generator + selector ${describePassword password}";
|
||||
generatePassword = password: assert testCanGenerate password; ''${password.generator} | pass insert -m ${lib.strings.escapeShellArg password.path}'';
|
||||
testCanGenerate =
|
||||
password:
|
||||
lib.asserts.assertMsg (builtins.elem password.selector [
|
||||
"@"
|
||||
null
|
||||
]) "Unimplemented: generator + selector ${describePassword password}";
|
||||
generatePassword =
|
||||
password:
|
||||
assert testCanGenerate password;
|
||||
''${password.generator} | pass insert -m ${lib.strings.escapeShellArg password.path}'';
|
||||
raiseCantGenerate = password: ''echo "Error: no generator" ; exit 1'';
|
||||
syncPasswordStore = password: ''
|
||||
# ${describePassword password}
|
||||
|
@ -112,23 +147,27 @@ in
|
|||
allFilenames = builtins.map (password: "${passwordStoreDir}/${passwordHash password}") passwords;
|
||||
in
|
||||
''
|
||||
ln -s ${lib.getExe (pkgs.writeShellApplication {
|
||||
name = "update-password-store";
|
||||
text = ''
|
||||
test -d "$PASSWORD_STORE_DIR"
|
||||
sudo install -C -o root -g root -m u=rwx -d "${passwordStoreDir}"
|
||||
ln -s ${
|
||||
lib.getExe (
|
||||
pkgs.writeShellApplication {
|
||||
name = "update-password-store";
|
||||
text = ''
|
||||
test -d "$PASSWORD_STORE_DIR"
|
||||
sudo install -C -o root -g root -m u=rwx -d "${passwordStoreDir}"
|
||||
|
||||
${lib.strings.concatLines (builtins.map syncPasswordStore passwords)}
|
||||
${lib.strings.concatLines (builtins.map syncPasswordStore passwords)}
|
||||
|
||||
comm -23 <(sudo find ${passwordStoreDir} -type f -ctime +60 | sort) <(echo ${lib.strings.escapeShellArg (lib.strings.concatLines allFilenames)} | sort) | while read -r file
|
||||
do
|
||||
echo Removing "$file" from password store
|
||||
sudo rm "$file"
|
||||
done
|
||||
'';
|
||||
# -ctime +60 is so it is possible to boot from previous nixpkgs without missing transform hashes
|
||||
# TODO Find a better mechanism, maybe à la bootspec, or something compatible with cross-arch
|
||||
})} $out/bin/
|
||||
comm -23 <(sudo find ${passwordStoreDir} -type f -ctime +60 | sort) <(echo ${lib.strings.escapeShellArg (lib.strings.concatLines allFilenames)} | sort) | while read -r file
|
||||
do
|
||||
echo Removing "$file" from password store
|
||||
sudo rm "$file"
|
||||
done
|
||||
'';
|
||||
# -ctime +60 is so it is possible to boot from previous nixpkgs without missing transform hashes
|
||||
# TODO Find a better mechanism, maybe à la bootspec, or something compatible with cross-arch
|
||||
}
|
||||
)
|
||||
} $out/bin/
|
||||
'';
|
||||
};
|
||||
vivarium.passwords =
|
||||
|
@ -144,82 +183,89 @@ in
|
|||
vivarium =
|
||||
let
|
||||
defaultvar = "@PASSWORD@";
|
||||
passwordSubmodule = lib.types.submodule ({ ... }: {
|
||||
options = {
|
||||
path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Path to the password store entry";
|
||||
passwordSubmodule = lib.types.submodule (
|
||||
{ ... }:
|
||||
{
|
||||
options = {
|
||||
path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Path to the password store entry";
|
||||
};
|
||||
selector = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "If unset, selects the first line. If '@', select everything. If any other value, will parse the password metadata as YML and use selector (yq).";
|
||||
};
|
||||
generator = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "${lib.getExe pkgs.pwgen} -s 32";
|
||||
description = "Command to generate the password. Won't work when selector is set to read metadata.";
|
||||
};
|
||||
transform = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "Shell command to transform the password with before substitution";
|
||||
};
|
||||
};
|
||||
selector = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "If unset, selects the first line. If '@', select everything. If any other value, will parse the password metadata as YML and use selector (yq).";
|
||||
};
|
||||
generator = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = "${lib.getExe pkgs.pwgen} -s 32";
|
||||
description = "Command to generate the password. Won't work when selector is set to read metadata.";
|
||||
};
|
||||
transform = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "Shell command to transform the password with before substitution";
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
in
|
||||
{
|
||||
passwords = lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrsOf passwordSubmodule;
|
||||
};
|
||||
passwordFiles =
|
||||
lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrsOf (lib.types.submodule ({ name, config, ... }: {
|
||||
options = {
|
||||
path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Where to place the file.";
|
||||
passwordFiles = lib.mkOption {
|
||||
default = { };
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, config, ... }:
|
||||
{
|
||||
options = {
|
||||
path = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
description = "Where to place the file.";
|
||||
};
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0400";
|
||||
description = "Unix permission";
|
||||
};
|
||||
owner = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "root";
|
||||
description = "Owner of the secret file";
|
||||
};
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "root";
|
||||
description = "Group of the secret file";
|
||||
};
|
||||
text = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultvar;
|
||||
description = "Content of the template used to make the file. Exclusive with `template`.";
|
||||
};
|
||||
template = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = pkgs.writeText "password-template" config.text;
|
||||
description = "Content of the template used to make the file. Exclusive with `text`.";
|
||||
};
|
||||
passwords = lib.mkOption {
|
||||
default = lib.optionalAttrs (config.password != null) { ${defaultvar} = config.password; };
|
||||
type = lib.types.attrsOf passwordSubmodule;
|
||||
description = "Paths to passwords that will substitute the variables in the template. Exclusive with `password`";
|
||||
};
|
||||
password = lib.mkOption {
|
||||
type = passwordSubmodule;
|
||||
description = "Path to password that will substitute '@PASSWORD@' in the template. Exclusive with `passwords`.";
|
||||
};
|
||||
};
|
||||
mode = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "0400";
|
||||
description = "Unix permission";
|
||||
};
|
||||
owner = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "root";
|
||||
description = "Owner of the secret file";
|
||||
};
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "root";
|
||||
description = "Group of the secret file";
|
||||
};
|
||||
text = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = defaultvar;
|
||||
description = "Content of the template used to make the file. Exclusive with `template`.";
|
||||
};
|
||||
template = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = pkgs.writeText "password-template" config.text;
|
||||
description = "Content of the template used to make the file. Exclusive with `text`.";
|
||||
};
|
||||
passwords = lib.mkOption {
|
||||
default = lib.optionalAttrs (config.password != null) { ${defaultvar} = config.password; };
|
||||
type = lib.types.attrsOf passwordSubmodule;
|
||||
description = "Paths to passwords that will substitute the variables in the template. Exclusive with `password`";
|
||||
};
|
||||
password = lib.mkOption {
|
||||
type = passwordSubmodule;
|
||||
description = "Path to password that will substitute '@PASSWORD@' in the template. Exclusive with `passwords`.";
|
||||
};
|
||||
};
|
||||
}));
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
vivariumBuilderDefault = {
|
||||
systems = [ "x86_64-linux" "aarch64-linux" ];
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
];
|
||||
protocol = "ssh-ng";
|
||||
sshUser = "nixremote";
|
||||
# sshKey doesn't work
|
||||
|
@ -11,7 +19,12 @@ let
|
|||
{
|
||||
hostName = "abavorana.frogeye.fr";
|
||||
publicHostKey = "c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSU5iNzcrS01tRHI0MVhZdmZITXQvK3NHMkJCSEIzYUl4M045WDNVejhFaUogZ2VvZmZyZXlAY3VyYWNhbwo=";
|
||||
supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
|
||||
supportedFeatures = [
|
||||
"nixos-test"
|
||||
"benchmark"
|
||||
"big-parallel"
|
||||
"kvm"
|
||||
];
|
||||
maxJobs = 8;
|
||||
}
|
||||
{
|
||||
|
@ -32,21 +45,31 @@ in
|
|||
supportsDryActivation = true;
|
||||
text = ''
|
||||
mkdir -p /root/.ssh
|
||||
cat ${pkgs.writeText "root-ssh-config" (lib.strings.concatLines (builtins.map (builder: ''
|
||||
Host ${builder.hostName}
|
||||
ControlMaster auto
|
||||
ControlPath ~/.ssh/master-%r@%n:%p
|
||||
ControlPersist 60s
|
||||
'') vivariumBuilders)) } > /root/.ssh/config
|
||||
cat ${
|
||||
pkgs.writeText "root-ssh-config" (
|
||||
lib.strings.concatLines (
|
||||
builtins.map (builder: ''
|
||||
Host ${builder.hostName}
|
||||
ControlMaster auto
|
||||
ControlPath ~/.ssh/master-%r@%n:%p
|
||||
ControlPersist 60s
|
||||
'') vivariumBuilders
|
||||
)
|
||||
)
|
||||
} > /root/.ssh/config
|
||||
'';
|
||||
};
|
||||
nix = {
|
||||
buildMachines = builtins.map (vivariumBuilder: vivariumBuilderDefault // vivariumBuilder) vivariumBuilders;
|
||||
buildMachines = builtins.map (
|
||||
vivariumBuilder: vivariumBuilderDefault // vivariumBuilder
|
||||
) vivariumBuilders;
|
||||
distributedBuilds = false;
|
||||
settings = {
|
||||
builders-use-substitutes = true;
|
||||
trusted-public-keys = publicKeys;
|
||||
trusted-substituters = builtins.map (builder: "${builder.protocol}://${builder.sshUser}@${builder.hostName}") config.nix.buildMachines;
|
||||
trusted-substituters = builtins.map (
|
||||
builder: "${builder.protocol}://${builder.sshUser}@${builder.hostName}"
|
||||
) config.nix.buildMachines;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
{ pkgs, lib, config, stylix, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
stylix,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config = {
|
||||
boot = {
|
||||
|
@ -6,13 +12,17 @@
|
|||
initrd.systemd.enable = true;
|
||||
};
|
||||
stylix = {
|
||||
enable = true;
|
||||
enable = true;
|
||||
homeManagerIntegration.autoImport = false; # Makes config reuse easier
|
||||
polarity = "dark";
|
||||
targets.plymouth.logo = pkgs.runCommand "flower.png" { } "${pkgs.inkscape}/bin/inkscape ${pkgs.substituteAll {
|
||||
src = ./flower.svg;
|
||||
color = config.lib.stylix.colors.withHashtag.base07;
|
||||
}} -w 256 -o $out";
|
||||
targets.plymouth.logo =
|
||||
pkgs.runCommand "flower.png" { }
|
||||
"${pkgs.inkscape}/bin/inkscape ${
|
||||
pkgs.substituteAll {
|
||||
src = ./flower.svg;
|
||||
color = config.lib.stylix.colors.withHashtag.base07;
|
||||
}
|
||||
} -w 256 -o $out";
|
||||
# UPST Default grub font is sansSerif, which doesn't work.
|
||||
# Maybe because people patch mono with nerdfonts and that isn't compatible?
|
||||
};
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.syncthing;
|
||||
service = "syncthing";
|
||||
|
@ -9,9 +14,14 @@ let
|
|||
generator = ''(t="$(mktemp -d)" && ${lib.getExe pkgs.syncthing} generate --home="$t" &> /dev/null && cat "$t"/{cert,key}.pem && rm -rf "$t")'';
|
||||
};
|
||||
|
||||
capitalizeFirstLetter = str: (lib.strings.toUpper (builtins.substring 0 1 str)) + (builtins.substring 1 (builtins.stringLength str) str);
|
||||
capitalizeFirstLetter =
|
||||
str:
|
||||
(lib.strings.toUpper (builtins.substring 0 1 str))
|
||||
+ (builtins.substring 1 (builtins.stringLength str) str);
|
||||
|
||||
nixosDevices = builtins.map (system: system.config.frogeye) (builtins.attrValues config.frogeye.toplevel.nixosConfigurations);
|
||||
nixosDevices = builtins.map (system: system.config.frogeye) (
|
||||
builtins.attrValues config.frogeye.toplevel.nixosConfigurations
|
||||
);
|
||||
allDevices = nixosDevices;
|
||||
syncingDevices = builtins.filter (device: device.syncthing.id != null) allDevices;
|
||||
peerDevices = builtins.filter (device: device.name != config.frogeye.name) syncingDevices;
|
||||
|
@ -20,7 +30,10 @@ let
|
|||
allFolders = builtins.attrValues config.frogeye.folders;
|
||||
syncedFolders = builtins.filter (folder: folder.syncthing.enable) allFolders;
|
||||
|
||||
folderShouldSyncWith = folder: device: (lib.hasAttrByPath [ folder.name ] device.folders) && device.folders.${folder.name}.syncthing.enable;
|
||||
folderShouldSyncWith =
|
||||
folder: device:
|
||||
(lib.hasAttrByPath [ folder.name ] device.folders)
|
||||
&& device.folders.${folder.name}.syncthing.enable;
|
||||
folderDeviceEntry = folder: device: { deviceID = device.syncthing.id; };
|
||||
|
||||
enable = (builtins.length syncedFolders) > 0;
|
||||
|
@ -38,29 +51,38 @@ in
|
|||
cert = "${secretsDir}/cert.pem";
|
||||
|
||||
settings = {
|
||||
devices = builtins.listToAttrs (builtins.map (device: { inherit (device) name; value = device.syncthing; }) syncingDevices);
|
||||
folders = builtins.listToAttrs (builtins.map
|
||||
(folder: {
|
||||
devices = builtins.listToAttrs (
|
||||
builtins.map (device: {
|
||||
inherit (device) name;
|
||||
value = device.syncthing;
|
||||
}) syncingDevices
|
||||
);
|
||||
folders = builtins.listToAttrs (
|
||||
builtins.map (folder: {
|
||||
inherit (folder) name;
|
||||
value =
|
||||
{
|
||||
label = "${capitalizeFirstLetter folder.user} ${folder.label}";
|
||||
path = "${config.users.users.${folder.user}.home}/${folder.path}";
|
||||
# Despite further in the code indicating this is possible, it is, actually not
|
||||
# devices = builtins.map (folderDeviceEntry folder) (builtins.filter (folderShouldSyncWith folder) peerDevices);
|
||||
devices = builtins.map (device: device.name) (builtins.filter (folderShouldSyncWith folder) peerDevices);
|
||||
versioning =
|
||||
if (config.frogeye.storageSize == "big" && folder.versionsMaxDays != null) then {
|
||||
value = {
|
||||
label = "${capitalizeFirstLetter folder.user} ${folder.label}";
|
||||
path = "${config.users.users.${folder.user}.home}/${folder.path}";
|
||||
# Despite further in the code indicating this is possible, it is, actually not
|
||||
# devices = builtins.map (folderDeviceEntry folder) (builtins.filter (folderShouldSyncWith folder) peerDevices);
|
||||
devices = builtins.map (device: device.name) (
|
||||
builtins.filter (folderShouldSyncWith folder) peerDevices
|
||||
);
|
||||
versioning =
|
||||
if (config.frogeye.storageSize == "big" && folder.versionsMaxDays != null) then
|
||||
{
|
||||
type = "staggered";
|
||||
params.maxAge = builtins.toString (folder.versionsMaxDays * 24 * 3600);
|
||||
# TODO Increase cleanupIntervalS to 1 day or so
|
||||
} else null;
|
||||
rescanIntervalS = 10 * 3600; # Using watcher, should be good enough
|
||||
copyRangeMethod = "all"; # Prevents duplication
|
||||
copyOwnershipFromParent = true;
|
||||
} // folder.syncthing;
|
||||
})
|
||||
syncedFolders);
|
||||
}
|
||||
else
|
||||
null;
|
||||
rescanIntervalS = 10 * 3600; # Using watcher, should be good enough
|
||||
copyRangeMethod = "all"; # Prevents duplication
|
||||
copyOwnershipFromParent = true;
|
||||
} // folder.syncthing;
|
||||
}) syncedFolders
|
||||
);
|
||||
options = rec {
|
||||
urAccepted = 3;
|
||||
urSeen = urAccepted;
|
||||
|
@ -75,7 +97,11 @@ in
|
|||
''}"
|
||||
];
|
||||
PrivateUsers = lib.mkForce false;
|
||||
AmbientCapabilities = ["CAP_CHOWN" "CAP_DAC_OVERRIDE" "CAP_FOWNER"];
|
||||
AmbientCapabilities = [
|
||||
"CAP_CHOWN"
|
||||
"CAP_DAC_OVERRIDE"
|
||||
"CAP_FOWNER"
|
||||
];
|
||||
};
|
||||
vivarium.passwordFiles = {
|
||||
${cfg.key}.password = password // {
|
||||
|
|
|
@ -1,17 +1,23 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
importScript = pkgs.writers.writePython3 "install-wifi-import"
|
||||
{
|
||||
libraries = [ pkgs.python3Packages.pyaml ];
|
||||
}
|
||||
(builtins.readFile ./import.py);
|
||||
importScript = pkgs.writers.writePython3 "install-wifi-import" {
|
||||
libraries = [ pkgs.python3Packages.pyaml ];
|
||||
} (builtins.readFile ./import.py);
|
||||
applyScript = pkgs.writers.writePython3 "install-wifi-apply" { } (builtins.readFile ./apply.py);
|
||||
in
|
||||
{
|
||||
environment.systemPackages = [
|
||||
(pkgs.writeShellApplication {
|
||||
name = "install-wifi";
|
||||
runtimeInputs = with pkgs; [ wpa_supplicant diffutils ];
|
||||
runtimeInputs = with pkgs; [
|
||||
wpa_supplicant
|
||||
diffutils
|
||||
];
|
||||
text = ''
|
||||
temp="$(mktemp --directory --suffix="-install-wifi")"
|
||||
cd "$temp"
|
||||
|
@ -61,8 +67,7 @@ in
|
|||
"WiFi in de trein"
|
||||
"_WIFI_LYRIA"
|
||||
"WIFIonICE"
|
||||
]
|
||||
(ssid: { });
|
||||
] (ssid: { });
|
||||
userControlled.enable = true; # Allow some control with wpa_cli
|
||||
};
|
||||
services.chrony.serverOption = "offline";
|
||||
|
@ -71,8 +76,8 @@ in
|
|||
wantedBy = [ "wpa_supplicant.service" ];
|
||||
path = with pkgs; [ wpa_supplicant ];
|
||||
script = ''
|
||||
for i in {1..50}; do wpa_cli status &> /dev/null && break; sleep 0.1; done
|
||||
${applyScript}
|
||||
for i in {1..50}; do wpa_cli status &> /dev/null && break; sleep 0.1; done
|
||||
${applyScript}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue