summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--config.nix3
-rw-r--r--env/acme/default.nix44
-rw-r--r--env/acme/domains.nix12
-rw-r--r--env/default.nix8
-rw-r--r--env/dhe.nix6
-rw-r--r--env/users/default.nix126
-rw-r--r--env/users/mailbox.nix163
-rw-r--r--env/users/users.nix1
-rw-r--r--env/users/virtual.nix1
-rw-r--r--flake.nix109
-rw-r--r--home/default.nix19
-rw-r--r--home/environ.nix20
-rw-r--r--home/i3-config.nix3
-rw-r--r--home/mail/.gitignore1
-rw-r--r--home/mail/default.nix72
-rw-r--r--home/mail/sieve/mail.sieve1
-rw-r--r--home/path.nix98
-rw-r--r--pkgs/config/default.nix4
-rw-r--r--pkgs/config/unfree.nix1
-rw-r--r--pkgs/default.nix47
-rw-r--r--pkgs/mssql-tools.nix30
-rw-r--r--pkgs/oregano/default.nix34
-rw-r--r--pkgs/rqlite.nix3
-rw-r--r--pkgs/rv8.nix50
-rw-r--r--pkgs/scripts/clip.nix27
-rw-r--r--pkgs/scripts/default.nix2
-rw-r--r--pkgs/st.nix2
-rw-r--r--pkgs/tmux-lift/default.nix4
-rw-r--r--sys/auth.nix3
-rw-r--r--sys/boot.nix105
-rw-r--r--sys/default.nix14
-rw-r--r--sys/fs/btrfs.nix157
-rw-r--r--sys/fs/default.nix3
-rw-r--r--sys/fs/layout.nix57
-rw-r--r--sys/net.nix3
-rw-r--r--sys/nspawn.nix130
-rw-r--r--sys/options.nix5
-rw-r--r--sys/users.nix33
-rw-r--r--util/importAll.nix6
40 files changed, 1019 insertions, 389 deletions
diff --git a/.gitignore b/.gitignore
index 58fb194..f094862 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
!**/.keep
+result
diff --git a/config.nix b/config.nix
deleted file mode 100644
index 8d78534..0000000
--- a/config.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- android_sdk.accept_license = true;
-}
diff --git a/env/acme/default.nix b/env/acme/default.nix
new file mode 100644
index 0000000..779b4e2
--- /dev/null
+++ b/env/acme/default.nix
@@ -0,0 +1,44 @@
+{ config, lib, ... }:
+with lib; let
+ cfg = config.local;
+in
+{
+ options.local = with types; {
+ domains = mkOption {
+ type = attrsOf (attrsOf str);
+ };
+
+ certs = mapAttrs
+ (_: _: {
+ enable = mkEnableOption "TLS cert for ${name}";
+ })
+ cfg.domains;
+ };
+
+ config = {
+ security.acme = {
+ acceptTerms = true;
+
+ defaults = {
+ email = "security@${config.networking.domain}";
+ renewInterval = "weekly";
+ };
+
+ certs =
+ let
+ domainSort = sort (a: b: splitString "." a < splitString "." b);
+
+ certConfig = domains: {
+ domain = domains.main;
+ extraDomainNames = domainSort (attrValues (filterAttrs (k: _: k != "main") domains));
+ webroot = "/var/lib/acme/acme-challenge";
+ };
+ in
+ mapAttrs'
+ (_: value: nameValuePair value.main (certConfig value))
+ (filterAttrs (name: _: cfg.certs.${name}.enable) cfg.domains);
+ };
+
+ local.domains = import ./domains.nix;
+ };
+}
diff --git a/env/acme/domains.nix b/env/acme/domains.nix
new file mode 100644
index 0000000..0412391
--- /dev/null
+++ b/env/acme/domains.nix
@@ -0,0 +1,12 @@
+{
+ host = {
+ main = "34project.org";
+ www = "www.34project.org";
+ mail = "mail.34project.org";
+ };
+
+ smtp.main = "smtp.34project.org";
+ imap.main = "imap.34project.org";
+
+ git.main = "git.cluster451.org";
+}
diff --git a/env/default.nix b/env/default.nix
new file mode 100644
index 0000000..d9b85ab
--- /dev/null
+++ b/env/default.nix
@@ -0,0 +1,8 @@
+{ lib, ... }:
+with lib; {
+ imports = [
+ ./acme
+ ./dhe.nix
+ ./users
+ ];
+}
diff --git a/env/dhe.nix b/env/dhe.nix
new file mode 100644
index 0000000..7a95f2d
--- /dev/null
+++ b/env/dhe.nix
@@ -0,0 +1,6 @@
+{ ... }: {
+ config.security.dhparams = {
+ enable = true;
+ defaultBitSize = 2048;
+ };
+}
diff --git a/env/users/default.nix b/env/users/default.nix
new file mode 100644
index 0000000..3602630
--- /dev/null
+++ b/env/users/default.nix
@@ -0,0 +1,126 @@
+{ config, lib, ... }:
+with lib; let
+ cfg = config.local;
+ inherit (config.networking) domain;
+in
+{
+ imports = [
+ ./mailbox.nix
+ ];
+
+ options.local = with types; {
+ sysadmin = mkOption {
+ type = str;
+ };
+
+ users = mkOption {
+ default = { };
+
+ type = attrsOf (submodule ({ config, ... }: {
+ options = {
+ uid = mkOption {
+ type = int;
+ };
+
+ gid = mkOption {
+ type = int;
+ };
+
+ gecos = mkOption {
+ type = str;
+ default = "";
+ };
+
+ sysadmin = mkOption {
+ type = bool;
+ default = false;
+ };
+
+ groups = mkOption {
+ type = listOf str;
+ default = [ ];
+ };
+
+ allowLogin = mkOption {
+ type = bool;
+ default = true;
+ };
+
+ hardAliases = mkOption {
+ type = listOf str;
+ default = [ ];
+ };
+ };
+
+ config.groups = mkBefore (optional config.sysadmin "wheel");
+ }));
+ };
+
+ virtual = mkOption {
+ default = { };
+
+ type = attrsOf (submodule ({ name, ... }: {
+ options = {
+ aliases = mkOption {
+ type = attrsOf (listOf str);
+ default = { };
+ };
+
+ rules = mkOption {
+ default = [ ];
+
+ type = listOf (submodule {
+ options = {
+ pattern = mkOption {
+ type = str;
+ };
+
+ targets = mkOption {
+ type = listOf str;
+ };
+ };
+ });
+ };
+
+ users = mkOption {
+ type = attrsOf (submodule { });
+ default = { };
+ };
+ };
+
+ config.aliases =
+ let
+ sysadmin = mkDefault [ "sysadmin@${name}" ];
+ in
+ {
+ abuse = sysadmin;
+ security = sysadmin;
+ webmaster = sysadmin;
+ hostmaster = sysadmin;
+ postmaster = sysadmin;
+
+ sysadmin = mkDefault [ "sysadmin@${domain}" ];
+ };
+ }));
+ };
+ };
+
+ config.local = mkMerge [
+ {
+ users = import ./users.nix;
+ virtual = import ./virtual.nix;
+
+ sysadmin =
+ (findSingle
+ (user: user.value.sysadmin)
+ (throw "no user is declared as sysadmin")
+ (throw "more than one user is declared as sysadmin")
+ (mapAttrsToList nameValuePair cfg.users)
+ ).name;
+ }
+
+ {
+ virtual.${domain}.aliases.sysadmin = [ cfg.sysadmin ];
+ }
+ ];
+}
diff --git a/env/users/mailbox.nix b/env/users/mailbox.nix
new file mode 100644
index 0000000..e603214
--- /dev/null
+++ b/env/users/mailbox.nix
@@ -0,0 +1,163 @@
+{ config, lib, pkgs, ... }:
+with lib; let
+ cfg = config.local;
+in
+{
+ options.local.mailHost = with types; {
+ enable = mkEnableOption "mailbox host service";
+
+ mdaListen = mkOption {
+ type = str;
+ };
+
+ saslPort = mkOption {
+ type = port;
+ };
+
+ lmtpPort = mkOption {
+ type = port;
+ };
+ };
+
+ config =
+ let
+ imapHostname = cfg.domains.imap.main;
+ in
+ mkIf cfg.mailHost.enable {
+ services.dovecot2 =
+ let
+ cert = config.security.acme.certs.${imapHostname}.directory;
+ in
+ {
+ enable = true;
+ enablePAM = false;
+ enableLmtp = true;
+
+ #sslServerKey = "${cert}/key.pem";
+ #sslServerCert = "${cert}/fullchain.pem";
+
+ modules = [ pkgs.dovecot_pigeonhole ];
+
+ mailUser = "vmail";
+ mailGroup = "vmail";
+ mailLocation = "maildir:~/mail";
+ mailPlugins.perProtocol.lmtp.enable = [ "sieve" ];
+
+ extraConfig =
+ let
+ inherit (config.networking) domain;
+
+ # https://dovecot.org/list/dovecot/2019-March/115250.html
+ # Otra solución posible (https://serverfault.com/a/1062274/980378):
+ # auth_username_format = %{if;%d;eq;${domain};%Ln;%Lu}
+ localEntry = canonical: username: ''
+ ${username}:::::::user=${canonical} nopassword userdb_user=${canonical}
+ '';
+
+ localEntries = concatStrings
+ (flatten (mapAttrsToList
+ (canonical: user:
+ map (localEntry canonical) ([ canonical ] ++ user.hardAliases))
+ cfg.users));
+
+ localMailboxes = pkgs.writeText "local-mailboxes" localEntries;
+
+ vmailPath = "/var/lib/vmail/%{if;%d;ne;;%Ld;${domain}}";
+ in
+ ''
+ auth_mechanisms = plain login external
+
+ # TODO: los defaults de nixpkgs dejan los sockets bajo
+ # /run/dovecot2 con demasiados permisos rwx, arreglar
+
+ service auth {
+ inet_listener mta-sasl {
+ port = ${toString cfg.mailHost.saslPort}
+ address = ${cfg.mailHost.mdaListen}
+ }
+ }
+
+ service lmtp {
+ inet_listener mta-lmtp {
+ port = ${toString cfg.mailHost.lmtpPort}
+ address = ${cfg.mailHost.mdaListen}
+ }
+ }
+
+ # Esto enfuerza user@domain.tld
+ auth_username_format = %{if;%Ld;eq;${domain};%Ln;%{if;%d;ne;;%Lu;%Ln@invalid}}
+
+ # FIXME: Esta cadena de passdbs hace que 'doveadm user lookup'
+ # falle para usuarios locales, pero todo lo demás sirve. Parece
+ # ser debido a que pam no puede enumerar.
+
+ passdb {
+ driver = passwd-file
+ args = username_format=%Ln ${vmailPath}/passwd
+ }
+
+ passdb {
+ driver = passwd-file
+ args = ${localMailboxes}
+
+ # Esta es una forma de determinar si se encontró el usuario en
+ # el passwd-file por medio de nopassword sin realmente
+ # autenticarlo. Cuidado con result_success, porque si eso se
+ # configura mal se permite inicio de sesión con cualquier
+ # contraseña (!!!).
+ result_success = continue
+ result_failure = return-fail
+ result_internalfail = return-fail
+
+ username_filter = !*@*
+ }
+
+ passdb {
+ driver = pam
+ args = dovecot2
+ username_filter = !*@*
+ #TODO: algo como 'override_fields = allow_nets=...'
+ }
+
+ userdb {
+ driver = passwd-file
+ args = username_format=%Ln ${vmailPath}/passwd
+ override_fields = uid=vmail gid=vmail home=${vmailPath}/home/%Ln
+ }
+
+ userdb {
+ driver = passwd-file
+ args = ${localMailboxes}
+
+ result_success = continue-ok
+ result_internalfail = return-fail
+ skip = found
+ }
+
+ userdb {
+ driver = passwd
+ args = blocking=no
+ skip = notfound
+ }
+ '';
+ };
+
+ security = {
+ # Necesario debido a 'enablePAM = false'
+ pam.services.dovecot2 = { };
+
+ #acme.certs.${imapHostname} = {
+ # inherit (config.services.dovecot2) group;
+ #};
+ };
+
+ users = {
+ users.${config.services.dovecot2.mailUser}.uid = 995;
+ groups.${config.services.dovecot2.mailGroup}.gid = 993;
+ };
+
+ #networking.firewall.allowedTCPPorts = [ 143 993 ];
+
+ #local.certs.imap.enable = true;
+ };
+}
diff --git a/env/users/users.nix b/env/users/users.nix
new file mode 100644
index 0000000..1bb3788
--- /dev/null
+++ b/env/users/users.nix
@@ -0,0 +1 @@
+# This file has been lustrated.
diff --git a/env/users/virtual.nix b/env/users/virtual.nix
new file mode 100644
index 0000000..1bb3788
--- /dev/null
+++ b/env/users/virtual.nix
@@ -0,0 +1 @@
+# This file has been lustrated.
diff --git a/flake.nix b/flake.nix
index 5fdeb7e..99e0c70 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,10 +1,10 @@
{
inputs = {
- nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05";
- nixpkgsUnstable.url = "github:nixos/nixpkgs";
+ nixpkgs.url = "github:nixos/nixpkgs/nixos-22.11";
+ unstable.url = "github:nixos/nixpkgs";
home-manager = {
- url = "github:nix-community/home-manager/release-22.05";
+ url = "github:nix-community/home-manager/release-22.11";
inputs.nixpkgs.follows = "nixpkgs";
};
@@ -14,58 +14,79 @@
};
outputs =
- { self, nixpkgs, nixpkgsUnstable, home-manager
- , nur, impermanence, hm-isolation, ... }:
- with nixpkgs.lib; let
- util = import ./util;
- inherit (util nixpkgs.lib) importAll;
+ { self, nixpkgs, unstable, home-manager, nur, impermanence, hm-isolation, ... }:
+ let
+ system = "x86_64-linux";
+
+ pkgs = pkgsNoLocal.extend self.overlays.default;
+ pkgsNoLocal = importPkgs nixpkgs;
- pkgSet = pkgs: import ./pkgs pkgs;
- in {
- packages."x86_64-linux" = pkgSet nixpkgs.legacyPackages."x86_64-linux";
+ importPkgs = flake: import flake {
+ inherit system;
- overlay = self: super: {
- local = pkgSet super;
- unstable = import nixpkgsUnstable { inherit (super) config system; };
+ config = import ./pkgs/config nixpkgs.lib;
+ overlays = [ nur.overlay ];
};
- nixosConfigurations = let
- hostConfig = host: (makeOverridable nixosSystem) {
- system = "x86_64-linux";
- modules = [ (import ./sys { inherit self impermanence; }) host ];
- };
- in mapAttrs (_: hostConfig) (importAll { root = ./sys/platform; });
+ util = import ./util;
+ inherit (util pkgs.lib) importAll;
- homeConfigurations = let
- configuration = import ./home {
- inherit self nixpkgs nixpkgsUnstable nur hm-isolation;
- };
+ local = import ./pkgs;
+ in
+ with pkgs.lib; {
+ formatter.${system} = pkgs.nixpkgs-fmt;
+ packages.${system} = local pkgs pkgsNoLocal;
- username = "ale";
+ overlays.default = final: prev: {
+ local = local final prev;
+ unstable = (importPkgs unstable).extend self.overlays.default;
+ };
- home = platform: home-manager.lib.homeManagerConfiguration {
- system = "x86_64-linux";
+ nixosConfigurations =
+ let
+ hostConfig = host: (makeOverridable nixpkgs.lib.nixosSystem) {
+ inherit pkgs system;
- inherit configuration;
- extraModules = [ platform ];
+ modules = [
+ ./sys
+ host
+ nixpkgs.nixosModules.notDetected
+ impermanence.nixosModule
+ ];
+ };
+ in
+ mapAttrs (_: hostConfig) (importAll { root = ./sys/platform; });
- inherit username;
- homeDirectory = "/home/${username}";
+ homeConfigurations =
+ let
+ registry = { ... }: {
+ config.nix.registry = {
+ "nixpkgs".flake = nixpkgs;
+ "unstable".flake = unstable;
+ "nur".flake = nur;
+ };
+ };
- # Update the state version as needed.
- # See the changelog here:
- # https://nix-community.github.io/home-manager/release-notes.html#sec-release-21.05
- stateVersion = "21.11";
+ home = platform: home-manager.lib.homeManagerConfiguration {
+ inherit pkgs;
- # Optionally use extraSpecialArgs
- # to pass through arguments to home.nix
- extraSpecialArgs = {};
- };
+ modules = [
+ ./home
+ platform
+ registry
+ hm-isolation.homeManagerModule
+ ];
+ };
- platformHome = name: platform: {
- name = "${username}@${name}";
- value = home platform;
- };
- in mapAttrs' platformHome (importAll { root = ./home/platform; });
+ platformHome = name: platform:
+ let
+ value = home platform;
+ in
+ {
+ inherit value;
+ name = "${value.config.home.username}@${name}";
+ };
+ in
+ mapAttrs' platformHome (importAll { root = ./home/platform; });
};
}
diff --git a/home/default.nix b/home/default.nix
index d6e8a81..0afdc7c 100644
--- a/home/default.nix
+++ b/home/default.nix
@@ -1,12 +1,11 @@
-{ self, nixpkgs, nixpkgsUnstable, nur, hm-isolation }:
{ lib, config, pkgs, ... }:
with lib; {
imports = [
- hm-isolation.homeManagerModule
./desktop.nix
./environ.nix
./graphics.nix
./isolation.nix
+ ./mail
./path.nix
];
@@ -15,17 +14,9 @@ with lib; {
};
config = {
- nixpkgs.overlays = [ nur.overlay self.overlay ];
-
- nix.registry = {
- "nixpkgs".flake = nixpkgs;
- "nixpkgsUnstable".flake = nixpkgsUnstable;
- "nur".flake = nur;
-
- "system".to = {
- type = "path";
- path = "/home/ale/nix";
- };
+ nix.registry."system".to = {
+ type = "path";
+ path = "${config.home.homeDirectory}/nix";
};
home = {
@@ -40,7 +31,7 @@ with lib; {
stateVersion = "21.11";
username = "ale";
- homeDirectory = "/home/ale";
+ homeDirectory = "/home/${config.home.username}";
sessionVariables = {
EDITOR = "nvim";
diff --git a/home/environ.nix b/home/environ.nix
index 5b20f51..b12093e 100644
--- a/home/environ.nix
+++ b/home/environ.nix
@@ -7,15 +7,17 @@ with lib; {
"d %t/vtmp 0700"
];
- home.file = let
- symlink = path: { source = config.lib.file.mkOutOfStoreSymlink path; };
- #TODO: No sirve, creo que por readline
- devNull = symlink "/dev/null";
- in {
- "vtmp" = symlink "/run/user/1000/vtmp";
- ".calc_history" = devNull;
- ".units_history" = devNull;
- };
+ home.file =
+ let
+ symlink = path: { source = config.lib.file.mkOutOfStoreSymlink path; };
+ #TODO: No sirve, creo que por readline
+ devNull = symlink "/dev/null";
+ in
+ {
+ "vtmp" = symlink "/run/user/1000/vtmp";
+ ".units_history" = devNull;
+ #TODO: .calc_history
+ };
programs = {
zsh = {
diff --git a/home/i3-config.nix b/home/i3-config.nix
index 18e94ce..999745b 100644
--- a/home/i3-config.nix
+++ b/home/i3-config.nix
@@ -171,6 +171,9 @@
# (No) Title Bars
for_window [class="^.*"] border pixel 5
+ # i3-msg exec --no-startup-id --class floating
+ for_window [class="floating"] floating enabled
+
exec --no-startup-id ${xautolock}/bin/xautolock -time 10 -locker '${i3lock-color}/bin/i3lock-color -fe -c222222'
#exec --no-startup-id /usr/local/bin/platform-graphical-login.sh
''
diff --git a/home/mail/.gitignore b/home/mail/.gitignore
new file mode 100644
index 0000000..1d9a3a0
--- /dev/null
+++ b/home/mail/.gitignore
@@ -0,0 +1 @@
+*.svbin
diff --git a/home/mail/default.nix b/home/mail/default.nix
new file mode 100644
index 0000000..a6fe8ff
--- /dev/null
+++ b/home/mail/default.nix
@@ -0,0 +1,72 @@
+{ config, lib, pkgs, ... }:
+with lib; {
+ config = mkIf (!config.home.isolation.active) {
+ accounts.email = {
+ maildirBasePath = "mail";
+
+ accounts.local = {
+ address = "alejandro@34project.org";
+ userName = "alejandro@34project.org";
+ realName = "Alejandro Soto";
+
+ primary = true;
+
+ # ${maildirBasePath}/${maildir.path}
+ maildir.path = "";
+ folders.inbox = "";
+
+ msmtp.enable = true;
+ neomutt.enable = true;
+
+ smtp = {
+ host = "smtp.34project.org";
+
+ tls = {
+ enable = true;
+ useStartTls = true;
+ };
+ };
+ };
+ };
+
+ programs = {
+ msmtp.enable = true;
+
+ neomutt = {
+ enable = true;
+ vimKeys = true;
+
+ settings = {
+ record = "+.Sent";
+ postponed = "+.Drafts";
+
+ use_threads = "flat";
+ index_format = "'%4C %Z %<[y?%<[m?%<[d?%[%H:%M ]&%[%a %d]>&%[%b %d]>&%[%m/%y ]> %-15.15L (%?l?%4l&%4c?) %s'";
+ };
+ };
+ };
+
+ # .dovecot.sieve tiene que ser un symlink tal que el readlink -f de su
+ # dirname (no del symlink en sí) sea la misma cadena que el readlink -f
+ # de ~/sieve. Dovecot verifica eso y tira "Invalid/unknown path to
+ # storage" si este check frágil falla. Ni siquiera
+ # mkOutOfStoreSymlink funciona. Ver código fuente de Dovecot:
+ # pigeonhole/src/lib-sieve/storage/file/sieve-file-storage-active.c
+ home =
+ let
+ sieve = pkgs.runCommandNoCCLocal "sieve" { src = ./sieve; } ''
+ cp -r $src $out
+ chmod -R u+w $out
+ find $out -name '*.sieve' -exec ${pkgs.dovecot_pigeonhole}/bin/sievec -c /dev/null {} \;
+ '';
+ in
+ {
+ file."sieve".source = sieve;
+
+ activation.sieve = hm.dag.entryBetween [ "linkGeneration" ] [ "writeBoundary" ] ''
+ $DRY_RUN_CMD ln -Tsf ${sieve}/mail.sieve .dovecot.sieve
+ $DRY_RUN_CMD ln -Tsf ${sieve}/mail.svbin .dovecot.svbin
+ '';
+ };
+ };
+}
diff --git a/home/mail/sieve/mail.sieve b/home/mail/sieve/mail.sieve
new file mode 100644
index 0000000..1bb3788
--- /dev/null
+++ b/home/mail/sieve/mail.sieve
@@ -0,0 +1 @@
+# This file has been lustrated.
diff --git a/home/path.nix b/home/path.nix
index 56678bb..2199b3e 100644
--- a/home/path.nix
+++ b/home/path.nix
@@ -1,53 +1,51 @@
{ config, lib, pkgs, ... }:
with lib; {
- home.packages = let
- py = pkgs.python39Packages;
- in [
- pkgs.file
- pkgs.killall
- pkgs.man-pages
- pkgs.man-pages-posix
- pkgs.tree
- pkgs.unzip
- pkgs.wget
- pkgs.zip
- ] ++ optionals (!config.home.isolation.active) [
- pkgs.calc
- pkgs.cloc
- pkgs.gcc
- pkgs.gnome.gnome-screenshot
- pkgs.gpicview
- pkgs.gruvbox-dark-icons-gtk
- pkgs.hack-font
- pkgs.i3-gaps
- py.ipython
- pkgs.jq
- pkgs.keepassxc
- pkgs.libreoffice-fresh
- pkgs.mosh
- pkgs.mpv
- pkgs.nmap
- pkgs.libsForQt5.okular
- pkgs.pavucontrol
- pkgs.pciutils
- py.python
- pkgs.rustup
- pkgs.local.scripts
- pkgs.socat
- pkgs.local.st
- pkgs.local.tmux-lift
- pkgs.units
- pkgs.usbutils
- pkgs.xclip # keepassxc-cli clip
- pkgs.xsel
- pkgs.xournalpp
- ];
-
- nixpkgs.config.allowUnfreePredicate = pkg: elem (getName pkg) [
- "anydesk"
- "mssql-tools"
- "quartus-prime-lite-unwrapped"
- "teams"
- "zoom"
- ];
+ home.packages =
+ let
+ py = pkgs.python39Packages;
+ in
+ [
+ pkgs.file
+ pkgs.killall
+ pkgs.man-pages
+ pkgs.man-pages-posix
+ pkgs.tree
+ pkgs.unzip
+ pkgs.wget
+ pkgs.zip
+ ] ++ optionals (!config.home.isolation.active) [
+ pkgs.calc
+ pkgs.cloc
+ pkgs.gcc
+ pkgs.gnome.gnome-screenshot
+ pkgs.gpicview
+ pkgs.gruvbox-dark-icons-gtk
+ pkgs.hack-font
+ pkgs.i3-gaps
+ py.ipython
+ pkgs.jq
+ pkgs.keepassxc
+ pkgs.libreoffice-fresh
+ pkgs.mosh
+ pkgs.mpv
+ pkgs.nmap
+ pkgs.libsForQt5.okular
+ pkgs.pavucontrol
+ pkgs.pciutils
+ py.python
+ pkgs.rustup
+ pkgs.local.scripts
+ pkgs.signal-desktop
+ pkgs.socat
+ pkgs.local.st
+ pkgs.tdesktop
+ pkgs.local.tmux-lift
+ pkgs.teams
+ pkgs.units
+ pkgs.usbutils
+ pkgs.xclip # keepassxc-cli clip
+ pkgs.xsel
+ pkgs.xournalpp
+ pkgs.zoom-us
+ ];
}
diff --git a/pkgs/config/default.nix b/pkgs/config/default.nix
new file mode 100644
index 0000000..6787b5e
--- /dev/null
+++ b/pkgs/config/default.nix
@@ -0,0 +1,4 @@
+lib: with lib; {
+ android_sdk.accept_license = true;
+ allowUnfreePredicate = pkg: import ./unfree.nix lib (getName pkg);
+}
diff --git a/pkgs/config/unfree.nix b/pkgs/config/unfree.nix
new file mode 100644
index 0000000..1bb3788
--- /dev/null
+++ b/pkgs/config/unfree.nix
@@ -0,0 +1 @@
+# This file has been lustrated.
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 21d9686..a0fc1c7 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,28 +1,25 @@
-pkgs:
-with pkgs.lib; let
- inherit (pkgs) buildEnv callPackage writeTextDir;
+final: prev:
+let
+ inherit (final) callPackage fetchpatch;
+in
+{
+ btclone = callPackage ./btclone { };
+ git-aliases = callPackage ./git-aliases.nix { };
+ mssql-tools = callPackage ./mssql-tools.nix { };
+ oregano = callPackage ./oregano { };
+ rqlite = callPackage ./rqlite.nix { };
+ rv8 = callPackage ./rv8.nix { };
+ scripts = callPackage ./scripts { };
+ tmux-lift = callPackage ./tmux-lift { };
- combined = pkgs // { inherit local; };
+ st = prev.st.override {
+ conf = import ./st.nix { };
- local = {
- btclone = callPackage ./btclone {};
- git-aliases = callPackage ./git-aliases.nix {};
- mssql-tools = callPackage ./mssql-tools.nix {};
- oregano = callPackage ./oregano {};
- rqlite = callPackage ./rqlite.nix {};
- rv8 = callPackage ./rv8.nix {};
- scripts = callPackage ./scripts {};
- tmux-lift = callPackage ./tmux-lift {};
-
- st = pkgs.st.override {
- conf = import ./st.nix {};
-
- patches = [
- (pkgs.fetchpatch {
- url = "https://st.suckless.org/patches/clipboard/st-clipboard-0.8.3.diff";
- sha256 = "cbb37675e9b4986836c19aadacc616a006df81c9bf394e9e3573e164fa1867cf";
- })
- ];
- };
+ patches = [
+ (fetchpatch {
+ url = "https://st.suckless.org/patches/clipboard/st-clipboard-0.8.3.diff";
+ sha256 = "cbb37675e9b4986836c19aadacc616a006df81c9bf394e9e3573e164fa1867cf";
+ })
+ ];
};
-in local
+}
diff --git a/pkgs/mssql-tools.nix b/pkgs/mssql-tools.nix
index a2de629..9213c16 100644
--- a/pkgs/mssql-tools.nix
+++ b/pkgs/mssql-tools.nix
@@ -5,7 +5,8 @@
let
version = "17.9.1.1-1";
ubuntuRelease = "21.10";
-in stdenv.mkDerivation {
+in
+stdenv.mkDerivation {
pname = "mssql-tools";
inherit version;
@@ -13,10 +14,11 @@ in stdenv.mkDerivation {
src =
if stdenv.hostPlatform.system == "x86_64-linux" then
- fetchurl {
- url = "https://packages.microsoft.com/ubuntu/${ubuntuRelease}/prod/pool/main/m/mssql-tools/mssql-tools_${version}_amd64.deb";
- sha256 = "0ya9643assr80yh6g0nd3i6iw819frhbb1m421khwplk9iq793kk";
- }
+ fetchurl
+ {
+ url = "https://packages.microsoft.com/ubuntu/${ubuntuRelease}/prod/pool/main/m/mssql-tools/mssql-tools_${version}_amd64.deb";
+ sha256 = "0ya9643assr80yh6g0nd3i6iw819frhbb1m421khwplk9iq793kk";
+ }
else
throw "mssql-tools is not supported on ${stdenv.hostPlatform.system}";
@@ -32,14 +34,16 @@ in stdenv.mkDerivation {
rm -r $out/opt $out/usr
'';
- postFixup = let
- rpath = lib.makeLibraryPath [ glibc stdenv.cc.cc unixODBC ];
- in ''
- for file in $(find $out/bin -type f); do
- patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$file"
- patchelf --set-rpath ${rpath} $file
- done
- '';
+ postFixup =
+ let
+ rpath = lib.makeLibraryPath [ glibc stdenv.cc.cc unixODBC ];
+ in
+ ''
+ for file in $(find $out/bin -type f); do
+ patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" "$file"
+ patchelf --set-rpath ${rpath} $file
+ done
+ '';
meta = with lib; {
license = licenses.unfree;
diff --git a/pkgs/oregano/default.nix b/pkgs/oregano/default.nix
index e85dded..82303f4 100644
--- a/pkgs/oregano/default.nix
+++ b/pkgs/oregano/default.nix
@@ -1,9 +1,23 @@
-{ lib, fetchFromGitHub, glib, goocanvas2, groff
-, gtk3, gtksourceview, intltool, libxml2, perl
-, pkg-config, python, stdenv, wafHook, wrapGAppsHook }:
+{ lib
+, fetchFromGitHub
+, glib
+, goocanvas2
+, groff
+, gtk3
+, gtksourceview
+, intltool
+, libxml2
+, perl
+, pkg-config
+, python
+, stdenv
+, wafHook
+, wrapGAppsHook
+}:
let
version = "0.84.43";
-in stdenv.mkDerivation {
+in
+stdenv.mkDerivation {
pname = "oregano";
inherit version;
@@ -18,7 +32,15 @@ in stdenv.mkDerivation {
patches = [ ./gio-unix.patch ];
buildInputs = [
- intltool glib goocanvas2 groff gtk3 gtksourceview
- libxml2 perl pkg-config python
+ intltool
+ glib
+ goocanvas2
+ groff
+ gtk3
+ gtksourceview
+ libxml2
+ perl
+ pkg-config
+ python
];
}
diff --git a/pkgs/rqlite.nix b/pkgs/rqlite.nix
index a56d288..19d0fa3 100644
--- a/pkgs/rqlite.nix
+++ b/pkgs/rqlite.nix
@@ -1,7 +1,8 @@
{ lib, buildGoModule, fetchFromGitHub }:
let
version = "7.5.0";
-in buildGoModule {
+in
+buildGoModule {
pname = "rqlite";
inherit version;
diff --git a/pkgs/rv8.nix b/pkgs/rv8.nix
index 61cb91f..8527601 100644
--- a/pkgs/rv8.nix
+++ b/pkgs/rv8.nix
@@ -17,30 +17,32 @@ stdenv.mkDerivation {
mkdir -p $out/bin $out/lib
'';
- patches = [ (writeText "rv8-include-limits.patch" ''
- diff --git a/src/gen/gen-cc.cc b/src/gen/gen-cc.cc
- index fd9f948..44c8bf7 100644
- --- a/src/gen/gen-cc.cc
- +++ b/src/gen/gen-cc.cc
- @@ -12,6 +12,7 @@
- #include <deque>
- #include <map>
- #include <set>
- +#include <limits>
+ patches = [
+ (writeText "rv8-include-limits.patch" ''
+ diff --git a/src/gen/gen-cc.cc b/src/gen/gen-cc.cc
+ index fd9f948..44c8bf7 100644
+ --- a/src/gen/gen-cc.cc
+ +++ b/src/gen/gen-cc.cc
+ @@ -12,6 +12,7 @@
+ #include <deque>
+ #include <map>
+ #include <set>
+ +#include <limits>
- #include "util.h"
- #include "cmdline.h"
- diff --git a/src/gen/gen-fpu-test.cc b/src/gen/gen-fpu-test.cc
- index f1b8f84..d0a2f32 100644
- --- a/src/gen/gen-fpu-test.cc
- +++ b/src/gen/gen-fpu-test.cc
- @@ -12,6 +12,7 @@
- #include <deque>
- #include <map>
- #include <set>
- +#include <limits>
+ #include "util.h"
+ #include "cmdline.h"
+ diff --git a/src/gen/gen-fpu-test.cc b/src/gen/gen-fpu-test.cc
+ index f1b8f84..d0a2f32 100644
+ --- a/src/gen/gen-fpu-test.cc
+ +++ b/src/gen/gen-fpu-test.cc
+ @@ -12,6 +12,7 @@
+ #include <deque>
+ #include <map>
+ #include <set>
+ +#include <limits>
- #include "util.h"
- #include "cmdline.h"
- '') ];
+ #include "util.h"
+ #include "cmdline.h"
+ '')
+ ];
}
diff --git a/pkgs/scripts/clip.nix b/pkgs/scripts/clip.nix
index 862d82e..501bb3b 100644
--- a/pkgs/scripts/clip.nix
+++ b/pkgs/scripts/clip.nix
@@ -1,5 +1,12 @@
-{ lib ,writeShellScriptBin, gnome, xclip
-, file, imagemagick, toPDF, ... }:
+{ lib
+, writeShellScriptBin
+, gnome
+, xclip
+, file
+, imagemagick
+, toPDF
+, ...
+}:
with lib; let
name = if toPDF then "clip-pdf" else "clip";
@@ -13,13 +20,15 @@ with lib; let
shift
'';
- copyOut = if toPDF then ''
- ${imagemagick}/bin/convert "$CLIP" "$OUT"
- '' else ''
- ${xclip}/bin/xclip -selection clipboard \
- -t $(${file}/bin/file -b --mime-type $CLIP) <"$CLIP"
- '';
-in writeShellScriptBin name ''
+ copyOut =
+ if toPDF then ''
+ ${imagemagick}/bin/convert "$CLIP" "$OUT"
+ '' else ''
+ ${xclip}/bin/xclip -selection clipboard \
+ -t $(${file}/bin/file -b --mime-type $CLIP) <"$CLIP"
+ '';
+in
+writeShellScriptBin name ''
${pdfCmdline}
OPTIONS=-a
diff --git a/pkgs/scripts/default.nix b/pkgs/scripts/default.nix
index 18900f6..43eae89 100644
--- a/pkgs/scripts/default.nix
+++ b/pkgs/scripts/default.nix
@@ -4,6 +4,6 @@ symlinkJoin {
paths = [
(callPackage ./clip.nix { toPDF = false; })
(callPackage ./clip.nix { toPDF = true; })
- (callPackage ./merge-pdfs.nix {})
+ (callPackage ./merge-pdfs.nix { })
];
}
diff --git a/pkgs/st.nix b/pkgs/st.nix
index a19bcea..117b94c 100644
--- a/pkgs/st.nix
+++ b/pkgs/st.nix
@@ -1,4 +1,4 @@
-{ }:
+{}:
''
/* See LICENSE file for copyright and license details. */
diff --git a/pkgs/tmux-lift/default.nix b/pkgs/tmux-lift/default.nix
index 9d1adf2..e353494 100644
--- a/pkgs/tmux-lift/default.nix
+++ b/pkgs/tmux-lift/default.nix
@@ -5,7 +5,7 @@
src = ./.;
installPhase = ''
- mkdir -p $out/bin
- cp lift unlift $out/bin
+ mkdir -p $out/bin
+ cp lift unlift $out/bin
'';
}
diff --git a/sys/auth.nix b/sys/auth.nix
index e6e156d..e85543e 100644
--- a/sys/auth.nix
+++ b/sys/auth.nix
@@ -1,7 +1,8 @@
{ lib, config, ... }:
with lib; let
cfg = config.local;
-in {
+in
+{
config = {
security.pam = {
oath = {
diff --git a/sys/boot.nix b/sys/boot.nix
index 9e1ef85..5d37b25 100644
--- a/sys/boot.nix
+++ b/sys/boot.nix
@@ -1,7 +1,8 @@
{ lib, config, ... }:
with lib; let
cfg = config.local;
-in {
+in
+{
options.local = with lib.types; {
loader = mkOption {
type = enum [ "grub" "systemd-boot" ];
@@ -40,64 +41,70 @@ in {
};
};
- initrd = let
- crypt = cfg.crypt.toplevel;
- headerPathEscaped = escapeShellArg "/initrd-boot/${crypt.headerFromBoot}";
- in {
- availableKernelModules = cfg.initrdModules;
- supportedFilesystems = [ "vfat" ];
+ initrd =
+ let
+ crypt = cfg.crypt.toplevel;
+ headerPathEscaped = escapeShellArg "/initrd-boot/${crypt.headerFromBoot}";
+ in
+ {
+ availableKernelModules = cfg.initrdModules;
+ supportedFilesystems = [ "vfat" ];
- preDeviceCommands = optionalString (crypt != null) ''
- mkdir -p `dirname ${headerPathEscaped}`
- touch ${headerPathEscaped}
- '';
-
- preLVMCommands = optionalString cfg.portable ''
- sleep 2 #TODO
- '';
+ preDeviceCommands = optionalString (crypt != null) ''
+ mkdir -p `dirname ${headerPathEscaped}`
+ touch ${headerPathEscaped}
+ '';
- postMountCommands = let
- fromRoot = path: escapeShellArg "/mnt-root/${path}";
- auxOpen = aux: ''
- cryptsetup -v open \
- --header ${fromRoot aux.header} \
- --key-file ${fromRoot aux.keyfile} \
- ${aux.device} ${aux.target}
+ preLVMCommands = optionalString cfg.portable ''
+ sleep 2 #TODO
'';
- in concatStringsSep "\n" (map auxOpen cfg.crypt.aux);
- luks.devices = mkIf (crypt != null) {
- "${crypt.target}" = {
- inherit (crypt) device;
- header = "/initrd-boot/${crypt.headerFromBoot}";
- preLVM = false;
+ postMountCommands =
+ let
+ fromRoot = path: escapeShellArg "/mnt-root/${path}";
+ auxOpen = aux: ''
+ cryptsetup -v open \
+ --header ${fromRoot aux.header} \
+ --key-file ${fromRoot aux.keyfile} \
+ ${aux.device} ${aux.target}
+ '';
+ in
+ concatStringsSep "\n" (map auxOpen cfg.crypt.aux);
+
+ luks.devices = mkIf (crypt != null) {
+ "${crypt.target}" = {
+ inherit (crypt) device;
+ header = "/initrd-boot/${crypt.headerFromBoot}";
+ preLVM = false;
- preOpenCommands = ''
- mount -o ro -t vfat ${escapeShellArg cfg.fs.boot.device} /initrd-boot
- '';
+ preOpenCommands = ''
+ mount -o ro -t vfat ${escapeShellArg cfg.fs.boot.device} /initrd-boot
+ '';
- postOpenCommands = ''
- umount /initrd-boot
- '';
+ postOpenCommands = ''
+ umount /initrd-boot
+ '';
+ };
};
- };
- #network = {
- # enable = true;
+ #network = {
+ # enable = true;
- # ssh = {
- # enable = true;
- # port = 2234;
- # };
- #};
- };
+ # ssh = {
+ # enable = true;
+ # port = 2234;
+ # };
+ #};
+ };
};
- hardware.cpu = let
- ucode.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
- in {
- amd = mkIf (cfg.cpuVendor == "amd") ucode;
- intel = mkIf (cfg.cpuVendor == "intel") ucode;
- };
+ hardware.cpu =
+ let
+ ucode.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
+ in
+ {
+ amd = mkIf (cfg.cpuVendor == "amd") ucode;
+ intel = mkIf (cfg.cpuVendor == "intel") ucode;
+ };
};
}
diff --git a/sys/default.nix b/sys/default.nix
index ef60f43..f19bc0a 100644
--- a/sys/default.nix
+++ b/sys/default.nix
@@ -1,21 +1,17 @@
-{ self, impermanence }:
-{ lib, config, pkgs, modulesPath, ... }:
+{ lib, config, pkgs, ... }:
with lib; {
imports = [
- "${modulesPath}/installer/scan/not-detected.nix"
- impermanence.nixosModule
-
+ ../env
./auth.nix
./boot.nix
./fs
./net.nix
+ ./nspawn.nix
./options.nix
./users.nix
];
config = {
- nixpkgs.overlays = [ self.overlay ];
-
# This value determines the NixOS release from which the default
# settings for stateful data, like file locations and database versions
# on your system were taken. It‘s perfectly fine and recommended to leave
@@ -27,11 +23,11 @@ with lib; {
nix = {
package = pkgs.nixFlakes;
extraOptions = ''
- experimental-features = nix-command flakes
+ experimental-features = nix-command flakes repl-flake
'';
};
- # shenvs necesita systemd 251
+ # hm-isolation necesita systemd 251
systemd = mkIf (config.system.nixos.release == "22.05") {
package = pkgs.unstable.systemd;
};
diff --git a/sys/fs/btrfs.nix b/sys/fs/btrfs.nix
index 87c9fca..809d35e 100644
--- a/sys/fs/btrfs.nix
+++ b/sys/fs/btrfs.nix
@@ -1,15 +1,16 @@
{ lib, config, pkgs, ... }:
with lib; let
cfg = config.local;
-in {
+in
+{
options.local = with lib.types; {
snapperSubvols = mkOption {
type = attrsOf str;
- default = {};
+ default = { };
};
fs.btrfs = mkOption {
- default = [];
+ default = [ ];
type = attrsOf (submodule {
options = {
@@ -35,77 +36,83 @@ in {
};
config = {
- environment.systemPackages = optional (cfg.snapperSubvols != {}) pkgs.local.btclone;
-
- fileSystems = let
- inherit (cfg) fs;
- btrfs = { device, subvol, ssd, ... }: {
- inherit device;
- fsType = "btrfs";
- options = [ "noatime" "compress=zstd" "subvol=${subvol}" ] ++ optional ssd "ssd";
- };
- in mapAttrs (_: btrfs) cfg.fs.btrfs;
-
- local.snapperSubvols = let
- snapperEntry = path: opts: { name = opts.snapper; value = path; };
- validEntry = _: opts: opts.snapper != null;
- in mapAttrs' snapperEntry (filterAttrs validEntry cfg.fs.btrfs);
-
- services.snapper.configs = let
- snapperConfig = _: subvolume: {
- inherit subvolume;
-
- extraConfig = ''
- # btrfs qgroup for space aware cleanup algorithms
- QGROUP=""
-
- # fraction of the filesystems space the snapshots may use
- SPACE_LIMIT="0.5"
-
- # fraction of the filesystems space that should be free
- FREE_LIMIT="0.2"
-
- # users and groups allowed to work with config
- ALLOW_USERS=""
- ALLOW_GROUPS=""
-
- # sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots
- # directory
- SYNC_ACL="no"
-
- # start comparing pre- and post-snapshot in background after creating
- # post-snapshot
- BACKGROUND_COMPARISON="yes"
-
- # run daily number cleanup
- NUMBER_CLEANUP="yes"
-
- # limit for number cleanup
- NUMBER_MIN_AGE="1800"
- NUMBER_LIMIT="100"
- NUMBER_LIMIT_IMPORTANT="10"
-
- # create hourly snapshots
- TIMELINE_CREATE="yes"
-
- # cleanup hourly snapshots after some time
- TIMELINE_CLEANUP="yes"
-
- # limits for timeline cleanup
- TIMELINE_MIN_AGE="1800"
- TIMELINE_LIMIT_HOURLY="24"
- TIMELINE_LIMIT_DAILY="7"
- TIMELINE_LIMIT_WEEKLY="4"
- TIMELINE_LIMIT_MONTHLY="12"
- TIMELINE_LIMIT_YEARLY="10"
-
- # cleanup empty pre-post-pairs
- EMPTY_PRE_POST_CLEANUP="yes"
-
- # limits for empty pre-post-pair cleanup
- EMPTY_PRE_POST_MIN_AGE="1800"
- '';
- };
- in mapAttrs snapperConfig cfg.snapperSubvols;
+ environment.systemPackages = optional (cfg.snapperSubvols != { }) pkgs.local.btclone;
+
+ fileSystems =
+ let
+ inherit (cfg) fs;
+ btrfs = { device, subvol, ssd, ... }: {
+ inherit device;
+ fsType = "btrfs";
+ options = [ "noatime" "compress=zstd" "subvol=${subvol}" ] ++ optional ssd "ssd";
+ };
+ in
+ mapAttrs (_: btrfs) cfg.fs.btrfs;
+
+ local.snapperSubvols =
+ let
+ snapperEntry = path: opts: { name = opts.snapper; value = path; };
+ validEntry = _: opts: opts.snapper != null;
+ in
+ mapAttrs' snapperEntry (filterAttrs validEntry cfg.fs.btrfs);
+
+ services.snapper.configs =
+ let
+ snapperConfig = _: subvolume: {
+ inherit subvolume;
+
+ extraConfig = ''
+ # btrfs qgroup for space aware cleanup algorithms
+ QGROUP=""
+
+ # fraction of the filesystems space the snapshots may use
+ SPACE_LIMIT="0.5"
+
+ # fraction of the filesystems space that should be free
+ FREE_LIMIT="0.2"
+
+ # users and groups allowed to work with config
+ ALLOW_USERS=""
+ ALLOW_GROUPS=""
+
+ # sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots
+ # directory
+ SYNC_ACL="no"
+
+ # start comparing pre- and post-snapshot in background after creating
+ # post-snapshot
+ BACKGROUND_COMPARISON="yes"
+
+ # run daily number cleanup
+ NUMBER_CLEANUP="yes"
+
+ # limit for number cleanup
+ NUMBER_MIN_AGE="1800"
+ NUMBER_LIMIT="100"
+ NUMBER_LIMIT_IMPORTANT="10"
+
+ # create hourly snapshots
+ TIMELINE_CREATE="yes"
+
+ # cleanup hourly snapshots after some time
+ TIMELINE_CLEANUP="yes"
+
+ # limits for timeline cleanup
+ TIMELINE_MIN_AGE="1800"
+ TIMELINE_LIMIT_HOURLY="24"
+ TIMELINE_LIMIT_DAILY="7"
+ TIMELINE_LIMIT_WEEKLY="4"
+ TIMELINE_LIMIT_MONTHLY="12"
+ TIMELINE_LIMIT_YEARLY="10"
+
+ # cleanup empty pre-post-pairs
+ EMPTY_PRE_POST_CLEANUP="yes"
+
+ # limits for empty pre-post-pair cleanup
+ EMPTY_PRE_POST_MIN_AGE="1800"
+ '';
+ };
+ in
+ mapAttrs snapperConfig cfg.snapperSubvols;
};
}
diff --git a/sys/fs/default.nix b/sys/fs/default.nix
index d24e357..04b8acb 100644
--- a/sys/fs/default.nix
+++ b/sys/fs/default.nix
@@ -1,7 +1,8 @@
{ lib, config, ... }:
with lib; let
cfg = config.local.fs;
-in {
+in
+{
imports = [ ./btrfs.nix ./layout.nix ];
options.local.fs = with lib.types; {
diff --git a/sys/fs/layout.nix b/sys/fs/layout.nix
index 897cffe..7e1ac2e 100644
--- a/sys/fs/layout.nix
+++ b/sys/fs/layout.nix
@@ -1,7 +1,8 @@
{ lib, config, ... }:
with lib; let
cfg = config.local;
-in {
+in
+{
options.local.fs.layout = with lib.types; {
sysHddBtrfs = mkOption {
default = null;
@@ -41,38 +42,40 @@ in {
};
config = {
- local.fs.btrfs = let
- sysHddBtrfs = layout: {
- "/" = {
- inherit (layout.sys) device ssd;
- subvol = layout.sys.root;
- };
+ local.fs.btrfs =
+ let
+ sysHddBtrfs = layout: {
+ "/" = {
+ inherit (layout.sys) device ssd;
+ subvol = layout.sys.root;
+ };
- "/toplevel" = {
- inherit (layout.sys) device ssd;
- subvol = layout.sys.toplevel;
- };
+ "/toplevel" = {
+ inherit (layout.sys) device ssd;
+ subvol = layout.sys.toplevel;
+ };
- "/hdd" = {
- inherit (layout.hdd) device;
- subvol = "/";
- ssd = false;
- };
+ "/hdd" = {
+ inherit (layout.hdd) device;
+ subvol = "/";
+ ssd = false;
+ };
- "/home" = {
- inherit (layout.hdd) device;
- subvol = layout.hdd.home;
- ssd = false;
- snapper = "home";
+ "/home" = {
+ inherit (layout.hdd) device;
+ subvol = layout.hdd.home;
+ ssd = false;
+ snapper = "home";
+ };
};
- };
- inherit (cfg.fs) layout;
+ inherit (cfg.fs) layout;
- layoutMaps = [ sysHddBtrfs ];
- layoutOpts = [ layout.sysHddBtrfs ];
- valid = filter ({ snd, ... }: snd != null) (zipLists layoutMaps layoutOpts);
- in optionalAttrs (valid != []) ((head valid).fst (head valid).snd);
+ layoutMaps = [ sysHddBtrfs ];
+ layoutOpts = [ layout.sysHddBtrfs ];
+ valid = filter ({ snd, ... }: snd != null) (zipLists layoutMaps layoutOpts);
+ in
+ optionalAttrs (valid != [ ]) ((head valid).fst (head valid).snd);
assertions = [
{
diff --git a/sys/net.nix b/sys/net.nix
index 30675e0..4075a12 100644
--- a/sys/net.nix
+++ b/sys/net.nix
@@ -1,7 +1,8 @@
{ lib, config, pkgs, ... }:
with lib; let
cfg = config.local;
-in {
+in
+{
options.local = with lib.types; {
hostname = mkOption {
type = str;
diff --git a/sys/nspawn.nix b/sys/nspawn.nix
new file mode 100644
index 0000000..6f1558c
--- /dev/null
+++ b/sys/nspawn.nix
@@ -0,0 +1,130 @@
+{ lib, config, pkgs, ... }:
+with lib; let
+ cfg = config.local;
+in
+{
+ options.local.nspawn.dmz = with types; {
+ enable = mkEnableOption "DMZ services in a container";
+
+ net = mkOption {
+ type = str;
+ };
+
+ netBits = mkOption {
+ type = int;
+ };
+
+ hostAddr = mkOption {
+ type = str;
+ };
+
+ system = mkOption {
+ type = attrs;
+ };
+ };
+
+ # Situación con os-release
+ #
+ # La idea aquí es poder hacer 'btrfs subvol create /var/lib/machines/foo' y
+ # dejar que systemd-nspawn y el activation script creen todo lo demás. Esto
+ # no sirve bien debido a la prueba barata que hace systemd para revisar si el
+ # árbol parece contener una imagen de sistema operativo. Esta prueba falla en
+ # dos momentos distintos:
+ #
+ # 1. Inmediatamente tras crear un árbol vacío, puesto que os-release no existe.
+ # La solución naive es 'mkdir rootfs/etc && touch rootfs/etc/os-release'.
+ #
+ # 2. Luego de reiniciar el contenedor una vez que NixOS ha preparado /etc, ya que
+ # systemd espera un archivo regular y no telera el symlink a la store.
+ #
+ # Resulta ser que systemd revisa tanto /etc/os-release como /usr/lib/os-release.
+ # NixOS evidentemente no usa la segunda ruta por ser FHS, así que la duct tape
+ # final es 'mkdir rootfs/usr/lib && touch rootfs/usr/lib/os-release'.
+
+ config = mkIf cfg.nspawn.dmz.enable {
+ local = {
+ mailHost = {
+ mdaListen = cfg.nspawn.dmz.hostAddr;
+ saslPort = 11000;
+ lmtpPort = 11001;
+ };
+
+ nspawn.dmz = {
+ system =
+ let
+ containerModule = { ... }: {
+ #TODO: urgente: bloquear puertos de dovecot a non-postfix con iptables
+ config = {
+ boot.isContainer = true;
+
+ local.mta = {
+ mdaAddr = cfg.mailHost.mdaListen;
+ inherit (cfg.mailHost) saslPort lmtpPort;
+ };
+ };
+ };
+ in
+ pkgs.nixos [ ../dmz containerModule ];
+
+ net = "10.34.3.0";
+ netBits = 28;
+ hostAddr = "10.34.3.1";
+ };
+ };
+
+ systemd = {
+ nspawn.dmz = {
+ execConfig.PrivateUsers = "pick";
+
+ filesConfig.BindReadOnly = [
+ # idmap porque algunos hacks en nixpkgs (postfix-setup.service)
+ # asumen que la store es de root
+ "/nix/store:/nix/store:idmap"
+ "${cfg.nspawn.dmz.system.toplevel}/init:/sbin/init"
+ ];
+
+ networkConfig.Port = [ "tcp:25" "tcp:80" "tcp:443" "tcp:587" ];
+ };
+
+ network.networks."40-ve-dmz" = {
+ matchConfig = {
+ Name = "ve-dmz";
+ Driver = "veth";
+ };
+
+ networkConfig = {
+ Address = "${cfg.nspawn.dmz.hostAddr}/${toString cfg.nspawn.dmz.netBits}";
+ LinkLocalAddressing = "yes";
+ DHCPServer = "yes";
+ IPMasquerade = "both";
+ LLDP = "yes";
+ EmitLLDP = "customer-bridge";
+ IPv6SendRA = "yes";
+ };
+
+ # IP de contenedor fijada en hostAddr + 1
+ dhcpServerConfig = {
+ PoolOffset = 2;
+ PoolSize = 1;
+ };
+ };
+
+ services = {
+ dovecot2.after = [ "systemd-nspawn@dmz.service" ];
+
+ "systemd-nspawn@dmz" = {
+ overrideStrategy = "asDropin";
+
+ after = [ "network-online.target" ];
+ wants = [ "network-online.target" ];
+ wantedBy = [ "machines.target" ];
+ };
+ };
+ };
+
+ networking.firewall.interfaces.ve-dmz = {
+ allowedTCPPorts = [ cfg.mailHost.saslPort cfg.mailHost.lmtpPort ];
+ allowedUDPPorts = [ 67 ]; # DHCP
+ };
+ };
+}
diff --git a/sys/options.nix b/sys/options.nix
index f719522..cfb2827 100644
--- a/sys/options.nix
+++ b/sys/options.nix
@@ -1,7 +1,8 @@
{ lib, ... }:
with lib.types; let
inherit (lib) mkOption;
-in {
+in
+{
options.local = {
portable = mkOption {
type = bool;
@@ -29,7 +30,7 @@ in {
};
aux = mkOption {
- default = [];
+ default = [ ];
type = listOf (submodule {
options = {
device = mkOption {
diff --git a/sys/users.nix b/sys/users.nix
index 8c8be6b..b84d1c0 100644
--- a/sys/users.nix
+++ b/sys/users.nix
@@ -1,7 +1,8 @@
{ lib, config, pkgs, ... }:
with lib; let
cfg = config.local;
-in {
+in
+{
config = {
sound.enable = true;
hardware.pulseaudio.enable = true;
@@ -24,27 +25,21 @@ in {
environment.pathsToLink = [ "/share/zsh" ];
- users.users = {
- ale = {
+ users.users = mapAttrs
+ (username: user: {
isNormalUser = true;
- uid = 1000;
- group = "ale";
- extraGroups = [ "users" "wheel" "adbusers" ];
- shell = pkgs.zsh;
- };
- tutorias = {
- isNormalUser = true;
- uid = 1004;
- group = "tutorias";
- extraGroups = [ "users" ];
- shell = pkgs.zsh;
- };
- };
+ inherit (user) uid;
+ description = user.gecos;
+
+ group = username;
+ extraGroups = [ "users" ] ++ user.groups;
+
+ shell = if user.allowLogin then pkgs.zsh else null;
+ })
+ cfg.users;
- users.groups = {
- ale.gid = 1001;
- tutorias.gid = 1007;
+ users.groups = mapAttrs (_: user: { inherit (user) gid; }) cfg.users // {
adbusers.gid = 1008;
};
};
diff --git a/util/importAll.nix b/util/importAll.nix
index 678cf06..cc18640 100644
--- a/util/importAll.nix
+++ b/util/importAll.nix
@@ -1,5 +1,5 @@
lib:
-{ root, exclude ? [] }:
+{ root, exclude ? [ ] }:
with builtins; with lib;
# http://chriswarbo.net/projects/nixos/useful_hacks.html
@@ -7,11 +7,11 @@ let
basename = removeSuffix ".nix";
isMatch = name: type: (hasSuffix ".nix" name || type == "directory")
- && ! elem name (map basename exclude);
+ && ! elem name (map basename exclude);
entry = name: _: {
name = basename name;
value = import (root + "/${name}");
};
in
- mapAttrs' entry (filterAttrs isMatch (readDir root))
+mapAttrs' entry (filterAttrs isMatch (readDir root))