Commit ee30e02a4865

Vincent Demeester <vincent@sbr.pm>
2020-05-31 12:37:27
systems: migrate to modules/users/systems
This is a huge wip still... Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 1e52625
hardware/lenovo-p50.nix
@@ -7,6 +7,9 @@ in
     (sources.nixos-hardware + "/common/pc/ssd")
     ./thinkpad.nix
   ];
+  boot = {
+    initrd.availableKernelModules = [ "nvme" "rtsx_pci_sdmmc" ];
+  };
   hardware = {
     bluetooth = {
       enable = true;
machines/base.nix
@@ -1,11 +1,6 @@
 { pkgs, ... }:
 
 {
-  programs = {
-    home-manager = {
-      enable = true;
-    };
-  };
   home.file.".nix-channels".source = ../assets/nix-channels;
   home.packages = with pkgs; [
     enchive
modules/profiles/assets/git
@@ -0,0 +1,1 @@
+users/vincent/core/git
\ No newline at end of file
modules/profiles/assets/tmux
@@ -0,0 +1,1 @@
+users/vincent/core/tmux
\ No newline at end of file
modules/profiles/assets/zsh
@@ -0,0 +1,1 @@
+users/vincent/core/zsh
\ No newline at end of file
modules/profiles/aliases.shell.nix
@@ -1,16 +1,14 @@
 {
-  # auto create parent directories
-  mkdir = ''mkdir -pv'';
-  rm = ''rm -i'';
-  cp = ''cp -i'';
-  mv = ''mv -i'';
+  mkdir = ''mkdir --parents --verbose'';
+  rm = ''rm --interactive'';
+  cp = ''cp --interactive'';
+  mv = ''mv --interactive'';
   gcd = ''cd (git root)'';
   ls = ''exa'';
-  ll = ''exa -l'';
-  la = ''exa -a'';
-  l = ''exa -lah'';
-  t = ''exa --tree -L 2'';
+  ll = ''exa --long'';
+  la = ''exa --all'';
+  l = ''exa --long --all --header'';
+  t = ''exa --tree --level=2'';
   wget = ''wget -c'';
   map = ''xargs -n1'';
-  m = ''m'';
 }
modules/profiles/virtualization.nixos.nix
@@ -7,11 +7,7 @@ in
 {
   options = {
     profiles.virtualization = {
-      enable = mkOption {
-        default = false;
-        description = "Enable virtualization profile";
-        type = types.bool;
-      };
+      enable = mkOption { default = false; description = "Enable virtualization profile"; type = types.bool; };
       nested = mkOption {
         default = false;
         description = "Enable nested virtualization";
@@ -37,6 +33,7 @@ in
     }
     (
       mkIf cfg.nested {
+        boot.kernelParams = [ "kvm_intel.nested=1" ];
         environment.etc."modprobe.d/kvm.conf".text = ''
           options kvm_intel nested=1
         '';
modules/programs/crc.nix
@@ -0,0 +1,27 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.programs.crc;
+in
+{
+  options = {
+    programs.crc = {
+      enable = mkOption { default = false; description = "wether to enable crc"; type = types.bool; };
+      package = mkOption {
+        default = pkgs.crc;
+        description = "crc package to be used";
+        type = types.package;
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = with pkgs; [ cfg.package ];
+    networking.networkmanager.dns = "dnsmasq";
+    environment.etc."NetworkManager/dnsmasq.d/crc.conf".text = ''
+      server=/apps-crc.testing/192.168.130.11
+      server=/crc.testing/192.168.130.11
+    '';
+  };
+}
modules/programs/default.nix
@@ -1,5 +1,6 @@
 {
   imports = [
+    ./crc.nix
     # Remove "nixos" from here
     ./podman.nixos.nix
   ];
systems/hokkaido.nix
@@ -9,6 +9,9 @@ in
     ../hardware/thinkpad-x220.nix
     # modules
     ../modules
+    # users
+    (import ../users).vincent
+    (import ../users).root
   ];
 
   fileSystems."/" =
@@ -24,21 +27,6 @@ in
   swapDevices =
     [{ device = "/dev/disk/by-uuid/e1833693-77ac-4d52-bcc7-54d082788639"; }];
 
-  # FIXME move this away
-  home-manager.users.vincent = { pkgs, ... }: {
-    imports = [
-      # Default profile with default configuration
-      ../modules/module-list.nix
-      # Set the machine to home
-      ../machines/is-hm.nix
-      # Machine specific configuration files
-      ../machines/hokkaido.nix
-    ];
-  };
-  home-manager.users.root = { pkgs, ... }: {
-    home.packages = with pkgs; [ htop ];
-  };
-
   networking = {
     hostName = "hokkaido";
   };
@@ -48,6 +36,7 @@ in
     avahi.enable = true;
     git.enable = true;
     ssh.enable = true;
+    users.enable = false;
     users.withMachines = enableHome;
     mail.enable = enableHome;
   };
systems/wakasu.nix
@@ -1,82 +1,104 @@
 { lib, pkgs, ... }:
 let
-  dummyConfig = pkgs.writeText "configuration.nix" ''
-    # assert builtins.trace "This is a dummy config, use switch!" false;
-    {}
-  '';
   inCi = builtins.pathExists /home/build;
   enableHome = !inCi;
 in
 {
   imports = [
-    (import ../nix).home-manager
-    ../modules/module-list.nixos.nix
     # hardware
-    ../hardware/thinkpad-x220.nix
-    # FIXME: remove this
-    ../machines/home.nixos.nix
+    ../hardware/lenovo-p50.nix
+    # modules
+    ../modules
+    # users
+    (import ../users).vincent
+    (import ../users).root
   ];
 
-  profiles.home = enableHome;
-  profiles.users.withMachines = enableHome;
-
   networking = {
     hostName = "wakasu";
   };
 
-  # FIXME move this away
-  home-manager.users.vincent = { pkgs, ... }: {
-    imports = [
-      # Default profile with default configuration
-      ../modules/module-list.nix
-      # Set the machine to home
-      ../machines/is-hm.nix
-      # Machine specific configuration files
-      ../machines/wakasu.nix
-    ];
-  };
-  home-manager.users.root = { pkgs, ... }: {
-    home.packages = with pkgs; [ htop ];
+  boot.initrd.luks.devices = {
+    root = {
+      device = "/dev/disk/by-uuid/49167ed2-8411-4fa3-94cf-2f3cce05c940";
+      preLVM = true;
+      allowDiscards = true;
+      keyFile = "/dev/disk/by-id/usb-_USB_DISK_2.0_070D375D84327E87-0:0";
+      keyFileOffset = 30992883712;
+      keyFileSize = 4096;
+      fallbackToPassword = true;
+    };
   };
 
-  # FIXME: ain't true
   fileSystems."/" =
     {
-      device = "/dev/disk/by-uuid/884a3d57-f652-49b2-9c8b-f6eebd5edbeb";
+      device = "/dev/disk/by-uuid/c44cdfec-b567-4059-8e66-1be8fec6342a";
       fsType = "ext4";
+      options = [ "noatime" "discard" ];
     };
-  # FIXME: move this away
-  profiles.nix-config.enable = false;
-  home-manager.useGlobalPkgs = true;
-  nix.nixPath = [
-    "nixos-config=${dummyConfig}"
-    "nixpkgs=/run/current-system/nixpkgs"
-    "nixpkgs-overlays=/run/current-system/overlays/compat"
-  ];
 
-  nixpkgs = {
-    overlays = [
-      (import ../overlays/sbr.nix)
-      (import ../overlays/unstable.nix)
-      (import ../nix).emacs
+  fileSystems."/boot" =
+    {
+      device = "/dev/disk/by-uuid/E974-AB5D";
+      fsType = "vfat";
+    };
+
+  swapDevices =
+    [
+      { device = "/dev/disk/by-uuid/c8c3308a-6ca6-4669-bad3-37a225af4083"; }
     ];
-    config = {
-      allowUnfree = true;
-      packageOverrides = pkgs: {
-        nur = import (builtins.fetchTarball "https://github.com/nix-community/NUR/archive/master.tar.gz") {
-          inherit pkgs;
-        };
-      };
+
+  profiles = {
+    dev.enable = true;
+    desktop.autoLogin = true;
+    docker.enable = true;
+    laptop.enable = true;
+    ssh = { enable = true; forwardX11 = true; };
+    virtualization = { enable = true; nested = true; listenTCP = true; };
+    yubikey.enable = true;
+  };
+  programs = {
+    podman.enable = true;
+    crc.enable = true;
+  };
+  security = {
+    sudo.extraConfig = ''
+      %users ALL = (root) NOPASSWD: /home/vincent/.nix-profile/bin/kubernix
+    '';
+    pam.u2f.enable = true;
+  };
+  services = {
+    logind.extraConfig = ''
+      HandleLidSwitch=ignore
+      HandleLidSwitchExternalPower=ignore
+      HandleLidSwitchDocked=ignore
+    '';
+    #syncthing.guiAddress = "${wireguard.ips.wakasu}:8384";
+    syncthing.guiAddress = "0.0.0.0:8384";
+    smartd = {
+      enable = true;
+      devices = [{ device = "/dev/nvme0n1"; }];
+    };
+    # FIXME handle secrets
+    /*
+    wireguard = {
+      enable = true;
+      ips = [ "${wireguard.ips.wakasu}/24" ];
+      endpoint = wg.endpointIP;
+      endpointPort = wg.listenPort;
+      endpointPublicKey = wireguard.kerkouane.publicKey;
+    };
+    */
+    xserver = {
+      videoDrivers = [ "nvidia" ];
+      dpi = 96;
+      serverFlagsSection = ''
+        Option "BlankTime" "0"
+        Option "StandbyTime" "0"
+        Option "SuspendTime" "0"
+        Option "OffTime" "0"
+      '';
     };
   };
 
-  # FIXME: put this in a common
-  system = {
-    extraSystemBuilderCmds = ''
-      ln -sv ${pkgs.path} $out/nixpkgs
-      ln -sv ${../overlays} $out/overlays
-    '';
-
-    stateVersion = "20.03";
-  };
 }
users/houbeb/default.nix
@@ -0,0 +1,14 @@
+{ pkgs, ... }: {
+  users.users.houbeb = {
+    createHome = true;
+    description = "Houbeb Ben Othmene";
+    extraGroups = [ "wheel" ];
+    isNormalUser = true;
+    openssh.authorizedKeys.keys = [
+      "…"
+    ];
+  };
+  home-manager.users.houbeb = {
+    home.packages = with pkgs; [ hello ];
+  };
+}
users/root/default.nix
@@ -0,0 +1,7 @@
+{ config, lib, pkgs, ... }:
+
+{
+  home-manager.users.root = lib.mkMerge (
+    [ (import ../vincent/core) ]
+  );
+}
modules/profiles/assets/git/redhat.gitconfig → users/vincent/core/git/redhat.gitconfig
File renamed without changes
modules/profiles/assets/tmux/keybindings → users/vincent/core/tmux/keybindings
File renamed without changes
modules/profiles/assets/tmux/tmux.conf → users/vincent/core/tmux/tmux.conf
File renamed without changes
modules/profiles/assets/zsh/_kubectl → users/vincent/core/zsh/_kubectl
File renamed without changes
modules/profiles/assets/zsh/_rg → users/vincent/core/zsh/_rg
File renamed without changes
modules/profiles/assets/zsh/_tkn → users/vincent/core/zsh/_tkn
File renamed without changes
modules/profiles/assets/zsh/completion.zsh → users/vincent/core/zsh/completion.zsh
File renamed without changes
modules/profiles/assets/zsh/j → users/vincent/core/zsh/j
File renamed without changes
modules/profiles/assets/zsh/prompt.zsh → users/vincent/core/zsh/prompt.zsh
File renamed without changes
users/vincent/core/bash.nix
@@ -0,0 +1,14 @@
+{ config, lib, pkgs, ... }:
+let
+  shellConfig = import ./shell.nix { inherit config lib pkgs; };
+in
+{
+  programs.bash = {
+    enable = true;
+    historyControl = [ "erasedups" "ignorespace" ];
+    historyFile = "${config.xdg.dataHome}/bash_history";
+    historyFileSize = shellConfig.historySize;
+    historySize = shellConfig.historySize;
+    shellAliases = shellConfig.aliases;
+  };
+}
users/vincent/core/default.nix
@@ -0,0 +1,32 @@
+{ pkgs, ... }: {
+  imports = [
+    ./bash.nix
+    ./direnv.nix
+    ./fzf.nix
+    ./git.nix
+    ./gpg.nix
+    ./htop.nix
+    ./tmux.nix
+    ./xdg.nix
+    ./zsh.nix
+  ];
+
+  home = {
+    stateVersion = "20.03";
+    packages = with pkgs; [
+      enchive
+      entr
+      exa
+      fd
+      htop
+      mpw
+      mosh
+      ncurses
+      ripgrep
+      scripts
+      tree
+    ];
+  };
+
+  xdg.configFile."nixpkgs/config.nix".text = "{ allowUnfree = true; }";
+}
users/vincent/core/direnv.nix
@@ -0,0 +1,13 @@
+{ pkgs, ... }:
+
+{
+  programs.direnv = {
+    enable = true;
+    stdlib = ''
+      mkdir -p $HOME/.cache/direnv/layouts
+      pwd_hash=$(echo -n $PWD | shasum | cut -d ' ' -f 1)
+      direnv_layout_dir=$HOME/.cache/direnv/layouts/$pwd_hash
+      source ${pkgs.nix-direnv}/share/nix-direnv/direnvrc
+    '';
+  };
+}
users/vincent/core/fzf.nix
@@ -0,0 +1,7 @@
+{
+  programs.fzf = {
+    enable = true;
+    enableZshIntegration = true;
+    defaultOptions = [ "--bind=ctrl-j:accept" ];
+  };
+}
users/vincent/core/git.nix
@@ -0,0 +1,200 @@
+{ config, lib, pkgs, ... }:
+let
+  ca-bundle_crt = "/etc/ssl/certs/ca-bundle.crt";
+in
+{
+  home.packages = with pkgs; [
+    gist
+    git-lfs
+    gitAndTools.git-annex
+    gitAndTools.hub
+    gitAndTools.gh
+    mr
+    my.prm
+    my.ape
+  ];
+  programs.git = {
+    enable = true;
+    package = pkgs.gitAndTools.gitFull;
+
+    userName = "Vincent Demeester";
+    userEmail = "vincent@sbr.pm";
+
+    signing = {
+      key = "6EB699A3";
+      signByDefault = false;
+    };
+
+    aliases = {
+      b = "branch --color -v";
+      br = "branch";
+      ci = "commit --signoff";
+      co = "checkout";
+      conflicts = "!git ls-files --unmerged | cut -c51- | sort -u | xargs $EDITOR";
+      ca = "commit --amend";
+      wdiff = "diff --color-words";
+      unstage = "reset HEAD";
+      lg = "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative";
+      lga = "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative --branches --remotes";
+      lol = "log --pretty=oneline --abbrev-commit --graph --decorate";
+      ls-ignored = "ls-files --exclude-standard --ignored --others";
+      resolve = "!git ls-files --unmerged | cut -c51- | sort -u | xargs git add";
+      su = "submodule update --init --recursive";
+      st = "status";
+      w = "status -sb";
+    };
+    attributes = [
+      "*.org   diff=org"
+    ];
+    extraConfig = {
+      core = {
+        editor = "${pkgs.emacs}/bin/emacsclient -t";
+      };
+      color = {
+        status = "auto";
+        diff = "auto";
+        branch = "auto";
+        interactive = "auto";
+        ui = "auto";
+        sh = "auto";
+      };
+      "color.branch" = {
+        current = "cyan reverse";
+        local = "cyan";
+        remote = "green";
+      };
+      "color.diff" = {
+        current = "white reverse";
+        frag = "magenta reverse";
+        old = "red";
+        new = "green";
+      };
+      "color.status" = {
+        added = "green";
+        changed = "yellow";
+        untracked = "red";
+      };
+      "diff.org" = {
+        xfuncname = "\"^\\\\*+.*\"";
+      };
+      forge = {
+        remote = "upstream";
+      };
+      hub = {
+        protocol = true;
+      };
+      pull = {
+        rebase = true;
+      };
+      push = {
+        default = "upstream";
+        recurseSubmodules = "check";
+      };
+      rebase = {
+        autosquash = true;
+      };
+      advice = {
+        statusHints = false;
+        pushNonFastForward = false;
+      };
+      http = {
+        sslCAinfo = "${ca-bundle_crt}";
+        sslverify = true;
+      };
+      github.user = "vdemeester";
+      "filter \"lfs\"" = {
+        clean = "${pkgs.git-lfs}/bin/git-lfs clean -- %f";
+        smudge = "${pkgs.git-lfs}/bin/git-lfs smudge --skip -- %f";
+        required = true;
+      };
+      "url \"git@github.com:\"".insteadOf = "git://github.com/";
+    };
+
+    includes = [
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/github.com/kubernetes/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/k8s.io/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/github.com/knative/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/github.com/tektoncd/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir/i:${config.home.homeDirectory}/src/github.com/google**";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/k8s.io/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/github.com/minishift/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/github.com/operator-framework/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/github.com/openshift**";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/github.com/redhat**";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/github.com/containers/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/gitlab.cee.redhat.com/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/gitlab.corp.redhat.com/";
+      }
+      {
+        path = "${config.xdg.configHome}/git/config.d/redhat.gitconfig";
+        condition = "gitdir:${config.home.homeDirectory}/src/pkg.devel.redhat.com/";
+      }
+    ];
+    ignores = [
+      "*.elc"
+      "*.vo"
+      "*.aux"
+      "*.v.d"
+      "*.o"
+      "*.a"
+      "*.la"
+      "*.so"
+      "*.dylib"
+      "*.pyc"
+      "*.pyo"
+      ".idea"
+      "*.iml"
+      "*~"
+      "#*#"
+      ".makefile"
+      ".clean"
+    ];
+  };
+  xdg.configFile."git/config.d/redhat.gitconfig".source = ./git/redhat.gitconfig;
+  xdg.configFile."nr/git" = {
+    text = builtins.toJSON [
+      { cmd = "tig"; }
+      { cmd = "grv"; pkg = "gitAndTools.grv"; }
+      { cmd = "git-appraise"; pkg = "gitAndTools.git-appraise"; chan = "unstable"; }
+    ];
+    onChange = "${pkgs.my.nr}/bin/nr git";
+  };
+}
users/vincent/core/gpg.nix
@@ -0,0 +1,13 @@
+{ pkgs, ... }:
+
+{
+  home.packages = with pkgs; [ gnupg ];
+  services = {
+    gpg-agent = {
+      enable = true;
+      enableSshSupport = true;
+      defaultCacheTtlSsh = 7200;
+      # pinEntryFlavor = "gtk2";
+    };
+  };
+}
users/vincent/core/htop.nix
@@ -0,0 +1,10 @@
+{
+  programs.htop = {
+    enable = true;
+    delay = 10;
+    meters = {
+      left = [ "AllCPUs2" "Memory" "Swap" ];
+      right = [ "Clock" "Hostname" "Tasks" "LoadAverage" "Uptime" "Battery" ];
+    };
+  };
+}
users/vincent/core/shell.nix
@@ -0,0 +1,28 @@
+{ config, ... }: {
+  aliases = {
+    mkdir = ''mkdir --parents --verbose'';
+    rm = ''rm --interactive'';
+    cp = ''cp --interactive'';
+    mv = ''mv --interactive'';
+    gcd = ''cd (git root)'';
+    ls = ''exa'';
+    ll = ''exa --long'';
+    la = ''exa --all'';
+    l = ''exa --long --all --header'';
+    t = ''exa --tree --level=2'';
+    wget = ''wget -c'';
+    map = ''xargs -n1'';
+  };
+
+  env = ''
+    export LESSHISTFILE="${config.xdg.dataHome}/less_history"
+    export GOPATH=${config.home.homeDirectory}
+    export WEBKIT_DISABLE_COMPOSITING_MODE=1;
+    export PATH=$HOME/bin:$PATH
+    if [ -d $HOME/.krew/bin ]; then
+      export PATH=$HOME/.krew/bin:$PATH
+    fi
+  '';
+
+  historySize = 10000;
+}
users/vincent/core/tmux.nix
@@ -0,0 +1,22 @@
+{ config, pkgs, ... }:
+
+{
+  programs.tmux = {
+    enable = true;
+    #sensibleOnTop = true;
+    #aggressiveResize = true;
+    clock24 = true;
+    escapeTime = 0;
+    newSession = true;
+    #plugins = with pkgs.tmuxPlugins; [ prefix-highlight ];
+    #secureSocket = false;
+    terminal = "tmux-256color";
+    #historyLimit = 30000;
+    extraConfig = ''
+      source-file ${config.xdg.configHome}/tmux/commons/keybindings
+      source-file ${config.xdg.configHome}/tmux/tmux.conf
+    '';
+  };
+  xdg.configFile."tmux/tmux.conf".source = ./tmux/tmux.conf;
+  xdg.configFile."tmux/commons/keybindings".source = ./tmux/keybindings;
+}
users/vincent/core/xdg.nix
@@ -0,0 +1,16 @@
+{
+  xdg = {
+    enable = true;
+    userDirs = {
+      enable = true;
+      desktop = "$HOME/desktop";
+      documents = "$HOME/desktop/documents";
+      download = "$HOME/desktop/downloads";
+      music = "$HOME/desktop/music";
+      pictures = "$HOME/desktop/pictures";
+      publicShare = "$HOME/desktop/sites";
+      templates = "$HOME/desktop/documents/templates";
+      videos = "$HOME/desktop/videos";
+    };
+  };
+}
users/vincent/core/zsh.nix
@@ -0,0 +1,147 @@
+{ config, lib, pkgs, ... }:
+let
+  shellConfig = import ./shell.nix { inherit config lib pkgs; };
+in
+{
+  home.packages = with pkgs; [
+    zsh-syntax-highlighting
+    nix-zsh-completions
+  ];
+
+  home.file."${config.programs.zsh.dotDir}/completion.zsh".source = ./zsh/completion.zsh;
+  home.file."${config.programs.zsh.dotDir}/prompt.zsh".source = ./zsh/prompt.zsh;
+  home.file."${config.programs.zsh.dotDir}/functions/j".source = ./zsh/j;
+
+  programs = {
+    direnv.enableZshIntegration = true;
+  };
+
+  programs.zsh = {
+    enable = true;
+    enableAutosuggestions = true;
+    enableCompletion = true;
+    autocd = true;
+    dotDir = ".config/zsh";
+    defaultKeymap = "emacs";
+    history = {
+      expireDuplicatesFirst = true;
+      extended = true;
+      ignoreDups = true;
+      path = "${config.xdg.dataHome}/zsh_history";
+      save = shellConfig.historySize;
+      share = true;
+    };
+    envExtra = shellConfig.env;
+    initExtra = ''
+      # c.f. https://wiki.gnupg.org/AgentForwarding
+      gpgconf --create-socketdir &!
+      path+="$HOME/${config.programs.zsh.dotDir}/functions"
+      fpath+="$HOME/.nix-profile/share/zsh/site-functions"
+      fpath+="$HOME/${config.programs.zsh.dotDir}/functions"
+      for func ($HOME/${config.programs.zsh.dotDir}/functions) autoload -U $func/*(x:t)
+      autoload -Uz select-word-style; select-word-style bash
+      if [ -e /home/vincent/.nix-profile/etc/profile.d/nix.sh ]; then . /home/vincent/.nix-profile/etc/profile.d/nix.sh; fi
+      #if [ -n "$INSIDE_EMACS" ]; then
+      #  chpwd() { print -P "\033AnSiTc %d" }
+      #  print -P "\033AnSiTu %n"
+      #  print -P "\033AnSiTc %d"
+      #fi
+      if [[ "$TERM" == "dumb" || "$TERM" == "emacs" ]]
+      then
+        TERM=eterm-color
+        unsetopt zle
+        unsetopt prompt_cr
+        unsetopt prompt_subst
+        unfunction precmd
+        unfunction preexec
+        PS1='$ '
+        return
+      fi
+      # make sure navigation using emacs keybindings works on all non-alphanumerics
+      # syntax highlighting
+      source $HOME/${config.programs.zsh.dotDir}/plugins/zsh-nix-shell/nix-shell.plugin.zsh
+      source ${pkgs.zsh-syntax-highlighting}/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
+      ZSH_HIGHLIGHT_PATTERNS+=('rm -rf *' 'fg=white,bold,bg=red')
+      ZSH_HIGHLIGHT_PATTERNS+=('rm -fR *' 'fg=white,bold,bg=red')
+      ZSH_HIGHLIGHT_PATTERNS+=('rm -fr *' 'fg=white,bold,bg=red')
+      source $HOME/${config.programs.zsh.dotDir}/completion.zsh
+      source $HOME/${config.programs.zsh.dotDir}/plugins/powerlevel10k/powerlevel10k.zsh-theme
+      source $HOME/${config.programs.zsh.dotDir}/prompt.zsh
+      setopt hist_ignore_space
+      alias -g L="|less"
+      alias -g EEL=' 2>&1 | less'
+      alias -g GB='`git rev-parse --abbrev-ref HEAD`'
+      alias -g GR='`git rev-parse --show-toplevel`'
+      (( $+commands[jq] )) && alias -g MJ="| jq -C '.'"  || alias -g MJ="| ${pkgs.python3}/bin/python -mjson.tool"
+    '';
+    loginExtra = ''
+      export GOPATH=${config.home.homeDirectory}
+    '';
+    profileExtra = ''
+      if [ -e /home/vincent/.nix-profile/etc/profile.d/nix.sh ]; then . /home/vincent/.nix-profile/etc/profile.d/nix.sh; fi
+    '';
+    localVariables = {
+      EMOJI_CLI_KEYBIND = "^n";
+      EMOJI_CLI_USE_EMOJI = "yes";
+      ZSH_HIGHLIGHT_HIGHLIGHTERS = [ "main" "brackets" "pattern" ];
+    };
+    sessionVariables = { RPROMPT = ""; };
+    plugins = [
+      {
+        name = "emoji-cli";
+        src = pkgs.fetchFromGitHub {
+          owner = "b4b4r07";
+          repo = "emoji-cli";
+          rev = "26e2d67d566bfcc741891c8e063a00e0674abc92";
+          sha256 = "0n88w4k5vaz1iyikpmlzdrrkxmfn91x5s4q405k1fxargr1w6bmx";
+        };
+      }
+      {
+        name = "zsh-z";
+        src = pkgs.fetchFromGitHub {
+          owner = "agkozak";
+          repo = "zsh-z";
+          rev = "5b903f8f5489783ee2a4af668a941b7d9a02efc9";
+          sha256 = "07h6ksiqgqyf5m84hv5xf4jcqrl8q1cj8wd4z52cjmy82kk10fkn";
+        };
+      }
+      {
+        name = "async";
+        src = pkgs.fetchFromGitHub {
+          owner = "mafredri";
+          repo = "zsh-async";
+          rev = "v1.7.0";
+          sha256 = "1jbbypgn0r4pilhv2s2p11vbkkvlnf75wrhxfcvr7bfjpzyp9wbc";
+        };
+      }
+      {
+        name = "zsh-completions";
+        src = pkgs.fetchFromGitHub {
+          owner = "zsh-users";
+          repo = "zsh-completions";
+          rev = "922eee0706acb111e9678ac62ee77801941d6df2";
+          sha256 = "04skzxv8j06f1snsx62qnca5f2183w0wfs5kz78rs8hkcyd6g89w";
+        };
+      }
+      {
+        name = "powerlevel10k";
+        src = pkgs.fetchFromGitHub {
+          owner = "romkatv";
+          repo = "powerlevel10k";
+          rev = "700910cd0421a7d25d2800cefa76eb6d80dc62a8";
+          sha256 = "011ja4r3a8vbcs42js9nri4p8pi8z4ccqxl2qyf52pn3pfnidigj";
+        };
+      }
+      {
+        name = "zsh-nix-shell";
+        src = pkgs.fetchFromGitHub {
+          owner = "chisui";
+          repo = "zsh-nix-shell";
+          rev = "v0.1.0";
+          sha256 = "0snhch9hfy83d4amkyxx33izvkhbwmindy0zjjk28hih1a9l2jmx";
+        };
+      }
+    ];
+    shellAliases = shellConfig.aliases;
+  };
+}
users/vincent/default.nix
@@ -0,0 +1,37 @@
+{ config, lib, pkgs, ... }:
+with lib;
+{
+  users.users.vincent = {
+    createHome = true;
+    uid = 1000;
+    description = "Vincent Demeester";
+    extraGroups = [ "wheel" "input" ]
+      ++ optionals config.profiles.desktop.enable [ "audio" "video" "lp" "scanner" "networkmanager" ]
+      ++ optionals config.networking.networkmanager.enable [ "networkmanager" ]
+      ++ optionals config.profiles.docker.enable [ "docker" ]
+      ++ optionals config.profiles.buildkit.enable [ "buildkit" ]
+      ++ optionals config.profiles.virtualization.enable [ "libvirtd" ];
+    shell = mkIf config.programs.zsh.enable pkgs.zsh;
+    isNormalUser = true;
+    # FIXME handle this too
+    openssh.authorizedKeys.keys = [ ];
+    # FIXME change this ?
+    initialPassword = "changeMe";
+    # FIXME This might be handled differently by programs.podman, …
+    subUidRanges = [{ startUid = 100000; count = 65536; }];
+    subGidRanges = [{ startGid = 100000; count = 65536; }];
+  };
+
+  home-manager.users.vincent = lib.mkMerge (
+    [
+      (import ./core)
+    ]
+    ++ optionals config.profiles.dev.enable [
+      (import ./dev)
+    ]
+    ++ optionals config.profiles.laptop.enable [
+    ]
+    ++ optionals config.profiles.desktop.enable [
+    ]
+  );
+}
users/default.nix
@@ -0,0 +1,10 @@
+with builtins;
+let
+  lib = (import ../nix).lib;
+  userDirs = attrNames (lib.filterAttrs (_: v: v == "directory") (readDir ./.));
+  mkUser = u: import (./. + "/${u}");
+  users = lib.genAttrs userDirs mkUser;
+in
+{
+  family = with users; [ vincent houbeb ];
+} // users
tasks.org
@@ -382,7 +382,7 @@
 
 ** TODO [#B] home-manager on fedora situation
 
-How to make it self contained too.
+How to make it self contained too. I think =home.nix= will work just fine.
 
 ** TODO [#A] How to manage secrets