-
-
Save 0atman/1a5133b842f929ba4c1e195ee67599d5 to your computer and use it in GitHub Desktop.
{ | |
config, | |
pkgs, | |
options, | |
... | |
}: let | |
hostname = "oatman-pc"; # to alllow per-machine config | |
in { | |
networking.hostName = hostname; | |
imports = [ | |
/etc/nixos/hardware-configuration.nix | |
(/home/oatman/dotfiles/nixos + "/${hostname}.nix") | |
]; | |
} |
#!/usr/bin/env bash | |
# | |
# I believe there are a few ways to do this: | |
# | |
# 1. My current way, using a minimal /etc/nixos/configuration.nix that just imports my config from my home directory (see it in the gist) | |
# 2. Symlinking to your own configuration.nix in your home directory (I think I tried and abandoned this and links made relative paths weird) | |
# 3. My new favourite way: as @clot27 says, you can provide nixos-rebuild with a path to the config, allowing it to be entirely inside your dotfies, with zero bootstrapping of files required. | |
# `nixos-rebuild switch -I nixos-config=path/to/configuration.nix` | |
# 4. If you uses a flake as your primary config, you can specify a path to `configuration.nix` in it and then `nixos-rebuild switch —flake` path/to/directory | |
# As I hope was clear from the video, I am new to nixos, and there may be other, better, options, in which case I'd love to know them! (I'll update the gist if so) | |
# A rebuild script that commits on a successful build | |
set -e | |
# Edit your config | |
$EDITOR configuration.nix | |
# cd to your config dir | |
pushd ~/dotfiles/nixos/ | |
# Early return if no changes were detected (thanks @singiamtel!) | |
if git diff --quiet '*.nix'; then | |
echo "No changes detected, exiting." | |
popd | |
exit 0 | |
fi | |
# Autoformat your nix files | |
alejandra . &>/dev/null \ | |
|| ( alejandra . ; echo "formatting failed!" && exit 1) | |
# Shows your changes | |
git diff -U0 '*.nix' | |
echo "NixOS Rebuilding..." | |
# Rebuild, output simplified errors, log trackebacks | |
sudo nixos-rebuild switch &>nixos-switch.log || (cat nixos-switch.log | grep --color error && exit 1) | |
# Get current generation metadata | |
current=$(nixos-rebuild list-generations | grep current) | |
# Commit all changes witih the generation metadata | |
git commit -am "$current" | |
# Back to where you were | |
popd | |
# Notify all OK! | |
notify-send -e "NixOS Rebuilt OK!" --icon=software-update-available |
nixos-rebuild switch
will check the current working directory first
I didn't see this behavior documented anywhere and it didn't work either. After searching a bit, I found that one needs to specify the configuration.nix
file if its not the default one by -I
flag, like: nixos-rebuild switch -I nixos-config=path/to/configuration.nix
(I think one need to change the nixos-rebuild
in script to this, doing this worked for me). More info: https://nixos.wiki/wiki/Nixos-rebuild
I am also just a starter and maybe wrong :)
@clot27 that makes sense. I was having the same difficulty my config was only updating from the default location regardless of where I was running ti from. And I was very confused and frustrated. My solution was to delete the default files and make them symbolic links to the location where I have them managed in my git repo.
rm /etc/nixos/configuration.nix /etc/nixos/hardware-configuration.nix
ln -s ~/mynixos/configuration.nix /etc/nixos/configuration.nix
ln -s ~/mynixos/hardware-configuration.nix /etc/nixos/hardware-configuration.nix
This is probably bad practice for portability's sake, but it lets me progress with my learning journey right now.
I think your suggestion is better for any real system setups. I will keep it in mind. Thanks
Apologies for the lack of detail folks, I have added the options in as comments in the file, but I'll repeat it here so you get a notification:
I believe there are a few ways to do this:
- My current way, using a minimal
/etc/nixos/configuration.nix
that just imports my config from my home directory (added to this gist) - Symlinking to your own
configuration.nix
in your home directory (I think I tried and abandoned this and links made relative paths weird) - My new favourite way: as @clot27 says, you can provide
nixos-rebuild
with a path to the config, allowing it to be entirely inside your dotfies, with zero bootstrapping of files required.
nixos-rebuild switch -I nixos-config=path/to/configuration.nix
As I hope was clear from the video, I am new to nixos, and there may be other, better, options, in which case I'd love to know them! (I'll update the gist if so)
Just a little suggestion: check that the editor exited successfully. This allows to cancel your edits using :cq
in (neo)vim and kill-emacs 1
in emacs, like you would with git. Something simple like
if [ "$?" -ne 0 ]; then
echo Cancelling...
popd
exit 1
fi
EDIT: forgot to popd
Just to add a fourth option here, if you implement flakes in your nixos deployment that makes it a bit easier since the path to configuration.nix
is specified inside your flake.nix
then your rebuild can be run with nixos-rebuild switch —flake path/to/directory
where the directory contains your flake.nix
so for this script it would just be . since it cds to it.
I think that’s what I got wrong earlier, the normal nixos-rebuild doesn’t search your cwd but my install command does. I just added —flake .
to line 29 before the stdout redirect.
@0atman Hey Tris, thanks for providing this script and introducing me to NixOS, I'm loving it so far.
After using this script for a bit, I noticed that if there is a nix config syntax error, the script exits without printing anything.
Since set -e
is active, errors produced from alejandra
exit the script, and since alejandra
's output is being &>/dev/null
'ed, we can't see this output.
My suggestion is to change the alejandra
command.
Before
alejandra . &>/dev/null
freddy@nixos:~/nixos/ > ./nixos-rebuild.sh
~/nixos ~/nixos
After
alejandra . >/dev/null
freddy@nixos:~/nixos/ > ./nixos-rebuild.sh
~/nixos ~/nixos
Checking style in 4 files using 4 threads.
Failed! 1 error found at:
- ./hosts/default/configuration.nix: unexpected TOKEN_ASSIGN at 5215..5224, wanted any of [TOKEN_SEMICOLON]
Although the error message isn't particularly useful, it is useful to know something has gone wrong.
Thanks
@freddycansic perfect, I've updated the gist!
@NECooley nice, added that as a 4th option in the file!
Yeah, I agree with @NECooley , The flakes option is by far the cleanest way to go.
For me, I had a hell of a time figuring out the basics of flakes and almost gave up on trying to use them. That is, until I watched the linked video below that explained how flakes will ignore any files in a git repo that havent been staged, as if the file didnt exist. That missing bit of knowledge was resulting in file not found errors that frustrated me to no end. That one little tip made all the difference for me.
Creating this as a flake automatically solves the default pathing issue. In addition to all the other benefits they bring.
Recommend watching this video for a great demo on how to use them.
https://youtu.be/H_Qct7TVB6o?si=WHov4EddXUYqFcKO
Thanks, I'll check out the video! Luckily I was warned about the 'not staged files' problem with flakes early on. An absolutely insane design decision, and honestly put me off the whole thing.
I don't use things I can't recommend, and I can't - yet - recommend flakes, the wtf/min is too high! I imagine I'll revisit them when I get more into nixos, but I am yet to be impressed.
Just a little suggestion: check that the editor exited successfully. This allows to cancel your edits using
:cq
in (neo)vim andkill-emacs 1
in emacs, like you would with git. Something simple likeif [ "$?" -ne 0 ]; then echo Cancelling... popd exit 1 fiEDIT: forgot to popd
I'm doing this too but checking for file changes instead of return code, works better with my workflow
# Early return if no changes were detected
if git diff --quiet *.nix; then
echo "No changes detected, exiting."
popd
exit 0
fi
Very nice gist, thanks for providing it!
@singiamtel omg that's genius, I've added it to the gist, works great!
Thanks for sharing this script. Now, I won't ruin my system because I messed up my configuration.nix. One improvement that I made when I started using it was to handle the script itself the nix way by storing is a nixos-rebuild.nix file:
{
config,
pkgs,
...
}: {
environment.systemPackages = with pkgs; [
(writeShellScriptBin "nixos-rebuild.sh" ''
// Script without shebang
'')
];
}
And just importing it in my managed version of configuration.nix. This way, I don't need to think about shebang and my script is also versioned via NixOS using generations too.
my changes so far:
alejandra . &>/dev/null \
|| ( alejandra . ; echo "formatting failed!" && exit 1)
and:
SUDO="sudo"
if [ "$(id -u)" == "0" ]; then
SUDO="" # already root
fi
# $SUDO nixos-rebuild switch --flake .#${HOST} &> nixos-switch.log \
$SUDO nixos-rebuild switch &> nixos-switch.log \
|| (cat nixos-switch.log | grep --color error && false)
not sure why the git diff
check is above editing the configuration.nix
, I would put it below 🙃.
One improvement that I made when I started using it was to handle the script itself the nix way by storing is a nixos-rebuild.nix file:
@Lemm1
Very interesting idea! I have a clean division between my system (managed by nixos) and my home directory and dotfiles (managed by ME). So I don't think I'll do this just yet, but everyone else, take note!
@aikomastboom love the alejandra tweak - added.
Interesting sudo tweak - but on my machine root using sudo is a no-op and can safely run both normal and sudo
ed commands?
Yeah, I know.. I came across it when fiddling with a VM that only had root and no sudo
installed
I like the idea to nixify the script too ( to ensure those dependency commands are available)
Fellow NixOS noob here thanks to your video! thanks for sharing this script as well.
FYI, I had to surround the two references to '*.nix' in single quotes to prevent bash from expanding the glob which resulted in 'No changes detected' and no diff output. Probably because my configuration is mostly in subfolders.
@MvRens updated, well spotted!
Hi! First of all, great video and an amazing script!
A weird problem i got stuck with is the fact that the nixos-rebuild hashing would not rebuild if the git repo was dirty - this blog post helped but i realized that staging the files fixed it - git add ./*.nix
before the rebuild stage.
Aside from that, i found that using sudo nix-env -p /nix/var/nix/profiles/system --list-generations | grep "current"
gave a cleaner output then nixos-rebuild list-generations
I added a bit where if a rebuild fails it asks if you want to open the logs or not
# In my case I use flakes but here it checks whether it fails or not
if sudo nixos-rebuild switch --flake ".#$1" &>.nixos-switch.log; then
echo -e "Done\n"
else
echo ""
cat .nixos-switch.log | grep --color error
# this is needed otherwise the script would not start next time telling you "no changes detected"
# (The weird patter is to include all subdirectories)
sudo git restore --staged ./**/*.nix
if read -p "Open log? (y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]]; then
cat .nixos-switch.log | vim -
fi
# Clean stuff and exit
shopt -u globstar
popd > /dev/null
exit 1
fi
thx @0atman for the *hem inspiration ;)
Very cool!
Here's a version that's I edited to work with Home Manager and custom *.nix file locations, I've also added a segment to check for untracked *.nix files since these don't get picked up by git diff
Not sure if ether of those things are useful to anyone else but shrug
@TechT10n /etc/nixos is only the default location for the configuration files. Your .nix files can be stored anywhere.
nixos-rebuild switch
will check the current working directory first, before checking the default.Tris didnt mention it specifically, but the vimjoyer video he linked talks about it in more detail around the 13 minute mark. I'm also just getting my start in nixos through this video, haha. I'd be happy to swap notes with you, maybe we can help each other out.