How do you compose your configuration files?
Firstly, I am a big fan of large files, I like growing them and looking for repetition, break off into an abstraction in another file perhaps and tidy up (this is my general approach with code).
However, with NixOS I am unsure what the best approach to follow.
E.g. if I wanted “child” configuration files which utilise specific environment packages or tmpfile rules, somehow I need to combine together on a “parent” level (?).
With Terraform for example I don’t need to do this… Perhaps I am missing something, or perhaps the problem is different in both cases (Terraform resources are more independent?).
Grateful for any words of advice.
2 Likes
How do you compose your configuration files?
E.g. if I wanted “child” configuration files which utilize specific environment packages or tmpfile rules, somehow I need to combine together on a “parent” level (?).
In the case of environment.systemPackages
option - you can define it in as many configuration files as you like, these arrays get merged and that’s basically it
If you find a case where you’d like to separate some logic into a separate file - you can just import ./xyz.nix { arg = 123; }
4 Likes
Ahh, I see the merging idea here . Nice!
I organize my modules the same way NixOS does: all module files are imported always and turned on with enable
options.
Here’s my directory structure:
$ tree
.
├── flake.lock
├── flake.nix
├── modules
│ ├── bluetooth.nix
│ ├── common.nix
│ ├── default.nix
│ ├── dosbox.nix
│ ├── efi.nix
│ ├── graphical.nix
│ ├── laptop.nix
│ ├── mount-data.nix
│ ├── printing.nix
│ ├── run-or-raise.patch
│ ├── security.nix
│ ├── server.nix
│ ├── ssh.nix
│ └── user.nix
├── secrets
│ ├── redacted.age
│ └── secrets.nix
└── systems
├── home1.nix
├── home2.nix
├── laptop1.nix
├── laptop3.nix
└── mail1.nix
modules/default.nix
is a list of all my modules. All my modules have configuration options prefixed by ‘our’ to avoid collisions. For example, ‘our.graphical.enable’. Each system file enables the modules that make sense for it.
5 Likes
I also use a module system with enable options. Almost all are disabled by default (eg. the programs/), cli/ is the other way and enabled by default. I use ‘ncfg’ as my prefix. I’m not happy about some of the layout, I’m still looking for a better finetuning
ncfg = {
nix.enableDirenv = true;
network = {
enable = true;
wireless-interface = "wlp4s0";
wired-interfaces."enp0s25" = { macAddress = "redacted"; };
};
hardware = {
laptop.thinkpad.enable = true;
cpu.intel.enable = true;
gpu.primaryGPU = "intel";
ssd.enable = true;
printer-scanner.enable = true;
};
theme.additionalFonts = true;
sway = {
background = "${./wallpapers/redacted.jpg} fill";
gammastep.enable = true;
waybar.backlightModule = true;
waybar.batteryModule = true;
waybar.bluetoothModule = false;
waybar.clockUtcModule = true;
waybar.position = "top";
waybar.pulseAudioModule = true;
waybar.temperatureModulePath = "/sys/class/thermal/thermal_zone0/temp";
extraConfig = ''
assign [app_id="w1"] workspace 1
assign [app_id="w2"] workspace 2
assign [app_id="w3"] workspace 3
assign [app_id="w4"] workspace 4
assign [app_id="w5"] workspace 5
assign [app_id="w6"] workspace 6
assign [app_id="thunderbird"] workspace 7
assign [app_id="w8"] workspace 8
assign [app_id="w9"] workspace 9
exec swaymsg "exec ${packages.${system}.thunderbird}/bin/thunderbird;"
'';
};
programs = {
browsers.firefox.enable = true;
browsers.google-chrome.enable = true;
editors.android-studio.enable = true;
editors.kolourpaint.enable = true;
editors.libreoffice.enable = true;
editors.meld.enable = true;
editors.lightburn.enable = true;
editors.sublime.enable = true;
editors.exiftool.enable = true;
editors.ffmpeg.enable = true;
editors.imagemagick.enable = true;
editors.poppler_utils.enable = true;
image-viewers.eog.enable = true;
image-viewers.feh.enable = true;
image-viewers.imv.enable = true;
image-viewers.sxiv.enable = true;
media-players.mpv.enable = true;
obs.enable = true;
element.enable = true;
evince.enable = true;
nautilus.enable = true;
terminal.enable = true;
thunderbird.enable = true;
xeyes.enable = true;
yt-dlp.enable = true;
};
services = {
vnstat.enable = true;
};
scripts.group.desktop.enable = true;
};
λ tree
├── flake.lock
├── flake.nix
├── hosts
│ ├── my-laptop
│ │ ├── boot-loader.nix
│ │ └── hardware-configuration.nix
│ ├── my-desktop
│ │ ├── boot-loader.nix
│ │ └── hardware-configuration.nix
├── iso.nix
├── modules
│ ├── base-system.nix
│ ├── cli
│ │ ├── autojump.nix
│ │ ├── bat.nix
│ │ ├── default.nix
│ │ ├── dircolors.nix
│ │ ├── exa.nix
│ │ ├── fish.nix
│ │ ├── fzf.nix
│ │ ├── git.nix
│ │ ├── gpg.nix
│ │ ├── neofetch.nix
│ │ ├── neovim
│ │ │ ├── default.nix
│ │ │ ├── lsp.nix
│ │ │ ├── syntax.nix
│ │ │ ├── theme.nix
│ │ │ └── ui.nix
│ │ ├── neovim.nix
│ │ ├── nix-index.nix
│ │ ├── nnn-colemak.h
│ │ ├── nnn.nix
│ │ ├── screen.nix
│ │ ├── shellAliases.nix
│ │ ├── speedtest.nix
│ │ ├── starship.nix
│ │ ├── tmux.nix
│ │ └── zsh.nix
│ ├── common-system
│ │ ├── default.nix
│ │ ├── knowledgebase.nix
│ │ ├── mail.nix
│ │ ├── network.nix
│ │ ├── nix.nix
│ │ ├── smartd.nix
│ │ ├── sshd.nix
│ │ ├── sudo-doas.nix
│ │ ├── tools.nix
│ │ ├── user.nix
│ │ └── zfs.nix
│ ├── containers
│ │ ├── default.nix
│ │ ├── gui-firefox
│ ├── development
│ │ ├── android
│ │ ├── default.nix
│ │ └── docker
│ ├── graphical
│ │ ├── gnome
│ │ │ └── default.nix
│ │ └── sway
│ │ ├── default.nix
│ │ ├── gammastep.nix
│ │ ├── ipcamera-viewer
│ │ │ ├── bg.png
│ │ │ └── default.nix
│ │ ├── mako.nix
│ │ ├── waybar.nix
│ │ ├── waybar-style.css
│ │ ├── waybar-style-horizontal.css
│ │ ├── waybar-style-vertical.css
│ │ ├── wayrecorder.nix
│ │ ├── xdg-desktop-portal.nix
│ │ └── ydotool.nix
│ ├── hardware
│ │ ├── bluetooth
│ │ ├── cpu
│ │ │ ├── amd
│ │ │ ├── arm
│ │ │ ├── default.nix
│ │ │ └── intel
│ │ ├── default.nix
│ │ ├── gpu
│ │ ├── laptop
│ │ │ ├── default.nix
│ │ │ └── thinkpad
│ │ ├── printer-scanner
│ │ ├── rpi4
│ │ └── ssd
│ ├── nixcfg-link-in-home.nix
│ ├── programs
│ │ ├── _browsers
│ │ │ ├── brave
│ │ │ ├── chromium
│ │ │ ├── default.nix
│ │ │ ├── firefox
│ │ │ ├── google-chrome
│ │ │ ├── qutebrowser
│ │ │ └── ungoogled-chromium
│ │ ├── calibre
│ │ ├── default.nix
│ │ ├── dropbox
│ │ ├── _editors
│ │ │ ├── android-studio
│ │ │ ├── default.nix
│ │ │ ├── gimp
│ │ │ ├── idea
│ │ │ ├── inkscape
│ │ │ ├── kolourpaint
│ │ │ ├── libreoffice
│ │ │ ├── lightburn
│ │ │ ├── meld
│ │ │ ├── sublime
│ │ │ └── vscodium
│ │ ├── eid
│ │ ├── element
│ │ ├── evince
│ │ ├── _games
│ │ │ ├── steam
│ │ ├── gnupg
│ │ ├── _image-viewers
│ │ │ ├── default.nix
│ │ │ ├── eog
│ │ │ ├── feh
│ │ │ ├── imv
│ │ │ └── sxiv
│ │ ├── latex
│ │ ├── _media-players
│ │ │ ├── celluloid
│ │ │ ├── deadbeef
│ │ │ ├── default.nix
│ │ │ ├── mpv
│ │ │ └── vlc
│ │ ├── motioneye
│ │ ├── nautilus
│ │ ├── obs
│ │ ├── okular
│ │ ├── pass
│ │ ├── syncthing
│ │ ├── terminal
│ │ ├── thunderbird
│ │ ├── xeyes
│ │ ├── yt-dlp
│ │ └── zathura
│ ├── scripts
│ ├── services
│ │ ├── auto-reboot
│ │ ├── containers
│ │ ├── default.nix
│ │ ├── iphone
│ │ ├── matrix
│ │ ├── nextcloud
│ │ ├── nginx
│ │ ├── numlock-on-tty.nix
│ │ ├── opensnitch
│ │ ├── syncthing
│ │ └── vnstat
│ ├── sound.nix
│ ├── ssh.nix
│ ├── theme.nix
│ └── xdg.nix
├── overlay
├── packages
│ ├── default.nix
│ ├── locksway
│ ├── motioneye
│ ├── systemd-lock-handler
├── README.md
├── scripts
│ ├── create-zfs-storage-pool.sh
│ ├── drvi.sh
│ ├── nixcfg.sh
│ ├── setup-nixos-native-encrypted-zfs-boot.sh
├── secrets
├── secrets.nix
└── wallpapers
edit: home-manager and nixos are both inside these files. It can be specific configs, user groups, …
example: modules/programs/_media-players/mpv/default.nix
{ config
, lib
, pkgs
, primaryUserName
, ...
}:
with lib; let
cfg = config.ncfg.programs.media-players.mpv;
dftApp = [ "mpv.desktop" ];
in
{
options.ncfg.programs.media-players.mpv.enable = lib.mkEnableOption "Enable mpv";
config = lib.mkIf cfg.enable {
programs.firejail = {
enable = true;
wrappedBinaries = {
mpv = "${lib.getBin pkgs.mpv}/bin/mpv";
};
};
home-manager.users.${primaryUserName} = { pkgs, ... }: {
home.packages = with pkgs; [
yt-dlp
# streamlink
# jellyfin-mpv-shim
];
programs.mpv = {
enable = true;
scripts = with pkgs.mpvScripts; [
# autoload
# mpris # Allows control of the player using standard media keys
# mpv-playlistmanager
# thumbnail # performance-intensive
];
config = {
## Video
# profile = "gpu-hq";
vo = "gpu";
scale = "bicubic_fast";
cscale = "bicubic_fast";
dscale = "bilinear";
# tscale="robidouxsharp";
scale-antiring = 1;
cscale-antiring = 1;
sigmoid-upscaling = "yes";
# tscale-clamp;
scaler-resizes-only = "yes";
dither-depth = "auto";
dither-size-fruit = 6;
temporal-dither = "yes";
gamma-factor = "0.9338";
deband = "no"; # performance-intensive
gpu-context = "wayland";
hwdec = "auto-safe"; # "auto-safe" , "vdpau"
hwdec-codecs = "all";
target-prim = "bt.709";
video-output-levels = "full";
video-sync = "display-resample";
# interpolation;
# vd-lavc-skiploopfilter = "bidir";
sws-scaler = "x";
screenshot-directory = "~/pictures/mpv-screenshots/";
screenshot-format = "png";
screenshot-png-compression = 0;
screenshot-png-filter = 0;
screenshot-tag-colorspace = "yes";
screenshot-high-bit-depth = "yes";
geometry = "50%:50%";
autofit = "90%x90%";
autofit-larger = "90%x90%";
# vo-vaapi-deint-mode = "bob";
vd-lavc-threads = 4;
## Audio
ao = "pulse";
audio-channels = "auto";
volume = 50;
volume-max = 200;
alang = "en,eng,english,us";
ad = "lavc:libdcadec";
## Subtitles
sub-ass-vsfilter-color-compat = "full";
sub-ass-force-style = "Kerning=yes";
demuxer-mkv-subtitle-preroll = "yes";
slang = "en,eng,english";
sub-auto = "all";
# osd-font = "Bitstream Vera Sans";
ytdl-format = "(bestvideo[fps=60][height<=1080]/bestvideo[height<=1080])[vcodec!=vp9]+(bestaudio[acodec=opus]/bestaudio[ext=webm]/bestaudio)/best";
# ytdl-format = "bestvideo[height<=?1080][vcodec!=?vp9]+bestaudio/best";
# ytdl-format = "ytdl-format=bestvideo[height<=?1920][fps<=?30][vcodec!=?vp9]+bestaudio/best";
# ytdl-format = "(bestvideo[vcodec=vp9]/bestvideo)+(bestaudio[acodec=opus]/bestaudio)/best"; # Prefer VP9 and Opus codecs for streams.
# ytdl=yes
# ytdl-format = "(bestvideo[ext=webm]/bestvideo[height>720]/bestvideo[fps=60])[tbr<13000]+(bestaudio[acodec=opus]/bestaudio[ext=webm]/bestaudio)/best"; # Always use 1080p+ or 60 fps where available. Prefer VP9 over AVC and VP8 for high-resolution streams.
## Script options
script-opts = "osc-seekbarstyle=bar,osc-valign=-1,osc-hidetimeout=1000,osc-vidscale=no,osc-layout=topbar,osc-scalewindowed=2.0,osc-scalefullscreen=2.0,osc-minmousemove=1,ytdl_hook-ytdl_path=${pkgs.yt-dlp}/bin/yt-dlp";
## Other
fullscreen = "yes";
keep-open = "no"; # Keep mpv open after playback is finished.
save-position-on-quit = true;
# watch-later-directory = "${config.xdg.cacheHome}/mpv-watch-later/";
cache = "auto";
# cache-pause-initial = "yes";
cache-pause-wait = "3";
cache-on-disk = "yes";
cache-dir = "~/.cache/mpv";
demuxer-readahead-secs = 125;
demuxer-max-bytes = "10GiB";
};
# bindings = {
# # Basics
# SPACE = "cycle pause";
# "Alt+ENTER" = "cycle fullscreen";
# "Alt+x" = "quit-watch-later";
# "1" = "cycle border";
# "Ctrl+a" = "cycle ontop";
# n = ''show-text ''${media-title}'';
# MBTN_LEFT = "cycle pause";
# MBTN_LEFT_DBL = "cycle fullscreen";
# MBTN_RIGHT = "ignore";
# z = "script-binding Blackbox";
# # Video
# v = "cycle sub-visibility";
# "Ctrl+LEFT" = "sub-seek -1";
# "Ctrl+RIGHT" = "sub-seek 1";
# PGUP = "playlist-next; write-watch-later-config";
# PGDWN = "playlist-prev; write-watch-later-config";
# "Alt+1" = "set window-scale 0.5";
# "Alt+2" = "set window-scale 1.0";
# "Alt+3" = "set window-scale 2.0";
# "Alt+i" = "screenshot";
# s = "ignore";
# # Audio
# UP = "add volume +5";
# DOWN = "add volume -5";
# WHEEL_UP = "add volume +5";
# WHEEL_DOWN = "add volume -5";
# "+" = "add audio-delay 0.100";
# "-" = "add audio-delay -0.100";
# a = "cycle audio";
# "Shift+a" = "cycle audio down";
# "Ctrl+M" = "cycle mute";
# "=" = ''af toggle "lavfi=[pan=1c|c0=0.5*c0+0.5*c1]" ; show-text "Audio mix set to Mono"'';
# # Frame-step
# ">" = "frame-step";
# "<" = "frame-back-step";
# };
};
xdg = lib.mkIf config.ncfg.xdg.enable {
configFile = {
## Add scripts distributed with mpv
## Commented out autocrop because it shows a text overlay the first 3 seconds of starting mpv
# "autocrop.lua" = {
# source = "${pkgs.mpv-unwrapped.src.outPath}/TOOLS/lua/autocrop.lua";
# target = "mpv/scripts/autocrop.lua";
# };
"autodeint.lua" = {
source = "${pkgs.mpv-unwrapped.src.outPath}/TOOLS/lua/autodeint.lua";
target = "mpv/scripts/autodeint.lua";
};
};
mimeApps.defaultApplications = {
"application/mxf" = mkForce dftApp;
"application/ogg" = mkForce dftApp;
"application/sdp" = mkForce dftApp;
"application/smil" = mkForce dftApp;
"application/streamingmedia" = mkForce dftApp;
"application/vnd.apple.mpegurl" = mkForce dftApp;
"application/vnd.ms-asf" = mkForce dftApp;
"application/vnd.rn-realmedia" = mkForce dftApp;
"application/vnd.rn-realmedia-vbr" = mkForce dftApp;
"application/x-cue" = mkForce dftApp;
"application/x-extension-m4a" = mkForce dftApp;
"application/x-extension-mp4" = mkForce dftApp;
"application/x-matroska" = mkForce dftApp;
"application/x-mpegurl" = mkForce dftApp;
"application/x-ogg" = mkForce dftApp;
"application/x-ogm" = mkForce dftApp;
"application/x-ogm-audio" = mkForce dftApp;
"application/x-ogm-video" = mkForce dftApp;
"application/x-shorten" = mkForce dftApp;
"application/x-smil" = mkForce dftApp;
"application/x-streamingmedia" = mkForce dftApp;
"audio/3gpp" = mkForce dftApp;
"audio/3gpp2" = mkForce dftApp;
"audio/aac" = mkForce dftApp;
"audio/ac3" = mkForce dftApp;
"audio/aiff" = mkForce dftApp;
"audio/AMR" = mkForce dftApp;
"audio/amr-wb" = mkForce dftApp;
"audio/dv" = mkForce dftApp;
"audio/eac3" = mkForce dftApp;
"audio/flac" = mkForce dftApp;
"audio/m3u" = mkForce dftApp;
"audio/m4a" = mkForce dftApp;
"audio/mp1" = mkForce dftApp;
"audio/mp2" = mkForce dftApp;
"audio/mp3" = mkForce dftApp;
"audio/mp4" = mkForce dftApp;
"audio/mpeg" = mkForce dftApp;
"audio/mpeg2" = mkForce dftApp;
"audio/mpeg3" = mkForce dftApp;
"audio/mpegurl" = mkForce dftApp;
"audio/mpg" = mkForce dftApp;
"audio/musepack" = mkForce dftApp;
"audio/ogg" = mkForce dftApp;
"audio/opus" = mkForce dftApp;
"audio/rn-mpeg" = mkForce dftApp;
"audio/scpls" = mkForce dftApp;
"audio/vnd.dolby.heaac.1" = mkForce dftApp;
"audio/vnd.dolby.heaac.2" = mkForce dftApp;
"audio/vnd.dts" = mkForce dftApp;
"audio/vnd.dts.hd" = mkForce dftApp;
"audio/vnd.rn-realaudio" = mkForce dftApp;
"audio/vorbis" = mkForce dftApp;
"audio/wav" = mkForce dftApp;
"audio/webm" = mkForce dftApp;
"audio/x-aac" = mkForce dftApp;
"audio/x-adpcm" = mkForce dftApp;
"audio/x-aiff" = mkForce dftApp;
"audio/x-ape" = mkForce dftApp;
"audio/x-m4a" = mkForce dftApp;
"audio/x-matroska" = mkForce dftApp;
"audio/x-mp1" = mkForce dftApp;
"audio/x-mp2" = mkForce dftApp;
"audio/x-mp3" = mkForce dftApp;
"audio/x-mpegurl" = mkForce dftApp;
"audio/x-mpg" = mkForce dftApp;
"audio/x-ms-asf" = mkForce dftApp;
"audio/x-ms-wma" = mkForce dftApp;
"audio/x-musepack" = mkForce dftApp;
"audio/x-pls" = mkForce dftApp;
"audio/x-pn-au" = mkForce dftApp;
"audio/x-pn-realaudio" = mkForce dftApp;
"audio/x-pn-wav" = mkForce dftApp;
"audio/x-pn-windows-pcm" = mkForce dftApp;
"audio/x-realaudio" = mkForce dftApp;
"audio/x-scpls" = mkForce dftApp;
"audio/x-shorten" = mkForce dftApp;
"audio/x-tta" = mkForce dftApp;
"audio/x-vorbis" = mkForce dftApp;
"audio/x-vorbis+ogg" = mkForce dftApp;
"audio/x-wav" = mkForce dftApp;
"audio/x-wavpack" = mkForce dftApp;
"video/3gp" = mkForce dftApp;
"video/3gpp" = mkForce dftApp;
"video/3gpp2" = mkForce dftApp;
"video/avi" = mkForce dftApp;
"video/divx" = mkForce dftApp;
"video/dv" = mkForce dftApp;
"video/fli" = mkForce dftApp;
"video/flv" = mkForce dftApp;
"video/mkv" = mkForce dftApp;
"video/mp2t" = mkForce dftApp;
"video/mp4" = mkForce dftApp;
"video/mp4v-es" = mkForce dftApp;
"video/mpeg" = mkForce dftApp;
"video/msvideo" = mkForce dftApp;
"video/ogg" = mkForce dftApp;
"video/quicktime" = mkForce dftApp;
"video/vnd.divx" = mkForce dftApp;
"video/vnd.mpegurl" = mkForce dftApp;
"video/vnd.rn-realvideo" = mkForce dftApp;
"video/webm" = mkForce dftApp;
"video/x-avi" = mkForce dftApp;
"video/x-flc" = mkForce dftApp;
"video/x-flic" = mkForce dftApp;
"video/x-flv" = mkForce dftApp;
"video/x-m4v" = mkForce dftApp;
"video/x-matroska" = mkForce dftApp;
"video/x-mpeg2" = mkForce dftApp;
"video/x-mpeg3" = mkForce dftApp;
"video/x-ms-afs" = mkForce dftApp;
"video/x-ms-asf" = mkForce dftApp;
"video/x-ms-wmv" = mkForce dftApp;
"video/x-ms-wmx" = mkForce dftApp;
"video/x-ms-wvxvideo" = mkForce dftApp;
"video/x-msvideo" = mkForce dftApp;
"video/x-ogm" = mkForce dftApp;
"video/x-ogm+ogg" = mkForce dftApp;
"video/x-theora" = mkForce dftApp;
"video/x-theora+ogg" = mkForce dftApp;
};
};
};
};
}
3 Likes
Sandro
June 9, 2022, 12:46am
6
I have one file per host and one shared. I also have a small collections of functions to make nginx and systemd services less boilerplate.
3 Likes
Atemu
June 9, 2022, 2:25am
7
I do the same but slightly different and less organised. Seemed like the most sensible to me.
How do you import the custom modules in the system configs? I do the equivalent of putting ../../modules
into every config but I kinda don’t like the boilerplate.
2 Likes
I organise mine as well with modules and I have some configuration which the define roles for a system. E.g. desktop or headless for servers.
nixos
2 Likes
rehno
June 9, 2022, 7:41pm
9
For myself I religiously mirror the canonical output schema that flakes provides in my directory structure.
(Because it’s the only “obvious” and complete, agreed upon schema that everyone needs to follow anyway. Closest thing we have to a “universal language”, so to speak.)
E.g. suppose the flake outputs looks like this
outputs = { self, ... }: {
apps = { ... };
bundlers = { ... };
devShells = { ... };
formatters = { ... };
lib = { ... };
nixosConfigurations = { ... };
nixosModules = { ... };
packages = { ... };
}
Then I’ll either do it directly in the root if it’s a nix-only project:
.
├── flake.lock
├── flake.nix
├── apps
│ └── ...
├── bundlers
│ └── ...
├── dev-shells
│ └── ...
├── formatters
│ └── ...
├── lib
│ └── ...
├── nixos-configurations
│ └── ...
├── nixos-modules
│ └── ...
└── packages
└── ...
Or I’ll nest it under ./nix
if it’s a broader project that is not specific to nix (e.g. there’s a src
with a different language)
.
├── flake.lock
├── flake.nix
├── src
└── nix
├── apps
│ └── ...
├── bundlers
│ └── ...
├── dev-shells
│ └── ...
├── formatters
│ └── ...
├── lib
│ └── ...
├── nixos-configurations
│ └── ...
├── nixos-modules
│ └── ...
└── packages
└── ...
If I feel like I really need to group some things together more, then I tend to create a new flake because I think it’s a strong signal that this could potentially be broken out as new a standalone git repository.
Unfortunately sub-flakes has some practical problems at the moment, but I put up with it and organize things this way:
.
├── flake.lock
├── flake.nix
├── sub-flake1
| ├── flake.nix
| ├── flake.lock
| ├── nixos-configurations
| │ └── ...
| └── nixos-modules
| └── ...
├── sub-flake2
| ├── flake.nix
| ├── flake.lock
| ├── nixos-configurations
| │ └── ...
| └── nixos-modules
| └── ...
└── dev-shells
└── ...
(This is what it looks like in practice: GitHub - rehno-lindeque/wip: A work-in-progress, into perpetuity ❤ )
4 Likes
ryantm
June 10, 2022, 3:59pm
10
I have a function like this that generates nixosConfigurations flake outputs:
defaultSystem = systemModules:
nixpkgs.lib.nixosSystem {
inherit pkgs system;
modules = systemModules ++ [
(
{modulesPath, ...}: {
imports = (import ./modules) ++ ["${modulesPath}/installer/scan/not-detected.nix"];
}
)
];
};
and modules/default.nix looks like this:
[
./bluetooth.nix
./common.nix
./dosbox.nix
./efi.nix
./graphical.nix
./laptop.nix
./mount-data.nix
./printing.nix
./security.nix
./server.nix
./ssh.nix
./user.nix
]
2 Likes