Skip to content

Instantly share code, notes, and snippets.

@damhiya
Last active July 15, 2023 13:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save damhiya/458bc9107c48ba5d6ac4c59a0c228a5c to your computer and use it in GitHub Desktop.
Save damhiya/458bc9107c48ba5d6ac4c59a0c228a5c to your computer and use it in GitHub Desktop.
nixos profile management
#!/usr/bin/env bash
PROFILE_PATH=/nix/var/nix/profiles
get_list() {
find $PROFILE_PATH -type l \
| awk "match(\$0, /^${PROFILE_PATH//\//\\\/}\/system-([0-9]*)-link\$/, res) { print res[1] }" \
| sort
}
get_current() {
readlink "$PROFILE_PATH/system" \
| awk 'match($0, /^system-([0-9]*)-link$/, res) { print res[1] }'
}
# list
list() {
if [ $# -ne 0 ] ; then
echo "nixos-profile ls : wrong argument"
exit
fi
nums=$(get_list)
current=$(get_current)
for num in $nums; do
link="$PROFILE_PATH/system-$num-link"
date=$(date -d "@$(stat --printf "%W" "$link")" "+%F %T")
if [ -e "$link/boot.json" ] ; then
info=$(jq -r '."org.nixos.bootspec.v1"."label"' <"$link/boot.json")
else
# Some old profiles may have no boot.json
nixosVersion=$(cat "$link/nixos-version")
kernelVersion=$( readlink "$link/kernel" \
| awk 'match($0, /^.*-linux-([0-9.]*)\/.*/, res) { print res[1] }' \
)
info="NixOS $nixosVersion (Linux $kernelVersion)"
fi
if [ "$num" = "$current" ] ; then
cur="*"
else
cur=" "
fi
echo "$cur $num $date $info"
done
}
# remove
remove_single() {
num=$1
nums=$(get_list)
current=$(get_current)
if [ "$num" = "$current" ] ; then
echo "You should not remove current profile $current"
exit
elif [ ! -e "$PROFILE_PATH/system-$num-link" ] ; then
echo "No such profile exists : $num"
exit
fi
echo "remove $num"
sudo rm "$PROFILE_PATH/system-$num-link"
}
remove_range() {
min=$1
max=$2
nums=$(get_list)
current=$(get_current)
if [ "$min" -le "$current" ] && [ "$current" -le "$max" ] ; then
echo "You should not remove current profile $current : $current is included in the range [$min-$max]"
exit
fi
for num in $nums ; do
if [ "$min" -le "$num" ] && [ "$num" -le "$max" ] ; then
echo "remove $num"
sudo rm "$PROFILE_PATH/system-$num-link"
fi
done
}
remove() {
if [ $# -ne 1 ] ; then
echo "nixos-profile rm : wrong argument"
exit
fi
if (echo "$1" | awk -v r=1 '/^[0-9]+$/{r=0} END{exit r}'); then
remove_single "$1"
elif range=$(echo "$1" | awk -v r=1 'match($0, /^\[([0-9]+)-([0-9]+)\]$/, res) {r=0; print res[1], res[2]} END{exit r}'); then
read -r min max <<< "$range"
remove_range "$min" "$max"
else
echo "rm: no parse"
fi
}
# main
if [ $# = 0 ] ; then
echo "Usage: nixos-profile ls"
echo "Usage: nixos-profile rm num"
echo "Usage: nixos-profile rm [min-max]"
elif [ "$1" = "ls" ] ; then
list "${@:2}"
elif [ "$1" = "rm" ] ; then
remove "${@:2}"
else
echo "no parse"
fi
@damhiya
Copy link
Author

damhiya commented Jul 15, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment