mirror of
https://github.com/tomasriveral/nixos.git
synced 2026-08-11 18:18:37 +02:00
315 lines
12 KiB
Nix
315 lines
12 KiB
Nix
{
|
|
inputs,
|
|
self,
|
|
...
|
|
}: {
|
|
flake.nixosModules.nixUtils-laptop = _: {
|
|
# nixpkgs-review crashed my laptop multiple times. We must reduce how much ressources it can take.
|
|
# for reference, my laptop is a 12 core ryzen 7
|
|
nix.settings.max-jobs = 6;
|
|
nix.settings.cores = 6;
|
|
};
|
|
flake.nixosModules.nixUtils = {pkgs-unstable, ...}: {
|
|
# Optimise the nix store
|
|
nix.optimise = {
|
|
automatic = true;
|
|
persistent = true;
|
|
randomizedDelaySec = "30min";
|
|
dates = "Thu *-*-* 16:00:00";
|
|
};
|
|
# Garbage collector of generations
|
|
nix.gc = {
|
|
automatic = true;
|
|
dates = "Wed *-*-* 16:00:00";
|
|
persistent = true;
|
|
options = "--delete-older-than 7d"; # every week delete generations older than a month
|
|
};
|
|
|
|
#manix is unhappy without this
|
|
nix.nixPath = [
|
|
"nixpkgs=${inputs.nixpkgs.outPath}"
|
|
"home-manager=${inputs.home-manager.outPath}"
|
|
];
|
|
|
|
#adds nixos experimental features:
|
|
nix.settings.experimental-features = ["nix-command" "flakes"];
|
|
|
|
environment.systemPackages = with pkgs-unstable; [
|
|
nixpkgs-review
|
|
nixfmt-tree
|
|
treefmt
|
|
nixd
|
|
deadnix
|
|
alejandra
|
|
vimPluginsUpdater # used for building plugins
|
|
nix-index
|
|
statix
|
|
self.packages.${pkgs-unstable.system}.custom-trimmer
|
|
];
|
|
};
|
|
perSystem = {pkgs, ...}: {
|
|
# https://gist.github.com/MaxwellDupre/3077cd229490cf93ecab08ef2a79c852
|
|
# better garbage collector
|
|
packages.custom-trimmer = pkgs.writeShellApplication {
|
|
name = "custom-trimmer";
|
|
runtimeInputs = with pkgs; [
|
|
nix
|
|
];
|
|
text = ''
|
|
set -euo pipefail
|
|
|
|
## Defaults
|
|
keepGensDef=30; keepDaysDef=7
|
|
keepGens=$keepGensDef; keepDays=$keepDaysDef
|
|
|
|
## Usage
|
|
usage () {
|
|
printf "Usage:\n\t ./trim-generations.sh <keep-generations> <keep-days> <profile> \n\n
|
|
(defaults are: Keep-Gens=%d Keep-Days=%d Profile=user)\n\n" "$keepGensDef" "$keepDaysDef"
|
|
printf "If you enter any parameters, you must enter all three, or none to use defaults.\n"
|
|
printf "Example:\n\t trim-generations.sh 15 10 home-manager\n"
|
|
printf " this will work on the home-manager profile and keep all generations from the\n"
|
|
printf "last 10 days, and keep at least 15 generations no matter how old.\n"
|
|
printf "\nProfiles available are:\tuser, home-manager, channels, system (root)\n"
|
|
printf "\n-h or --help prints this help text."
|
|
}
|
|
|
|
if [ $# -eq 1 ]; then # if help requested
|
|
if [ "$1" = "-h" ]; then
|
|
usage
|
|
exit 1;
|
|
fi
|
|
if [ "$1" = "--help" ]; then
|
|
usage
|
|
exit 2;
|
|
fi
|
|
printf "Dont recognise your option exiting..\n\n"
|
|
usage
|
|
exit 3;
|
|
|
|
elif [ $# -eq 0 ]; then # print the defaults
|
|
printf "The current defaults are:\n Keep-Gens=%d Keep-Days=%d \n\n" "$keepGensDef" "$keepDaysDef"
|
|
read -r -p "Keep these defaults? (y/n):" answer
|
|
|
|
case "$answer" in
|
|
[yY1] )
|
|
printf "Using defaults..\n"
|
|
;;
|
|
[nN0] ) printf "ok, doing nothing, exiting..\n"
|
|
exit 6;
|
|
;;
|
|
* ) printf "%b" "Doing nothing, exiting.."
|
|
exit 7;
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
## Handle parameters (and change if root)
|
|
if [[ $EUID -ne 0 ]]; then # if not root
|
|
profile=$(readlink /home/"$USER"/.nix-profile)
|
|
else
|
|
if [ -d /nix/var/nix/profiles/system ]; then # maybe this or the other
|
|
profile="/nix/var/nix/profiles/system"
|
|
elif [ -d /nix/var/nix/profiles/default ]; then
|
|
profile="/nix/var/nix/profiles/default"
|
|
else
|
|
echo "Cant find profile for root. Exiting"
|
|
exit 8
|
|
fi
|
|
fi
|
|
if (( $# < 1 )); then
|
|
printf "Keeping default: %d generations OR %d days, whichever is more\n" "$keepGensDef" "$keepDaysDef"
|
|
elif [[ $# -le 2 ]]; then
|
|
printf "\nError: Not enough arguments.\n\n" >&2
|
|
usage
|
|
exit 1
|
|
elif (( $# > 4)); then
|
|
printf "\nError: Too many arguments.\n\n" >&2
|
|
usage
|
|
exit 2
|
|
else
|
|
if [ "$1" -lt 1 ]; then
|
|
printf "using Gen numbers less than 1 not recommended. Setting to min=1\n"
|
|
read -r -p "is that ok? (y/n): " answer
|
|
printf "%s" "$answer"
|
|
case "$answer" in
|
|
[yY1] )
|
|
printf "ok, continuing..\n"
|
|
;;
|
|
[nN0] )
|
|
printf "ok, doing nothing, exiting..\n"
|
|
exit 6;
|
|
;;
|
|
* )
|
|
printf "%b" "Doing nothing, exiting.."
|
|
exit 7;
|
|
;;
|
|
esac
|
|
fi
|
|
if [ "$2" -lt 0 ]; then
|
|
printf "using negative days number not recommended. Setting to min=0\n"
|
|
read -r -p "is that ok? (y/n): " answer
|
|
|
|
case "$answer" in
|
|
[yY1] )
|
|
printf "ok, continuing..\n"
|
|
;;
|
|
[nN0] )
|
|
printf "ok, doing nothing, exiting..\n"
|
|
exit 6;
|
|
;;
|
|
* )
|
|
printf "%b" "Doing nothing, exiting.."
|
|
exit 7;
|
|
;;
|
|
esac
|
|
fi
|
|
keepGens=$1; keepDays=$2;
|
|
(( keepGens < 1 )) && keepGens=1
|
|
(( keepDays < 0 )) && keepDays=0
|
|
if [[ $EUID -ne 0 ]]; then
|
|
if [[ $3 == "user" ]] || [[ $3 == "default" ]]; then
|
|
profile=$(readlink /home/"$USER"/.nix-profile)
|
|
elif [[ $3 == "home-manager" ]]; then
|
|
# home-manager defaults to $XDG_STATE_HOME; otherwise, use
|
|
# `home-manager generations` and `nix-store --query --roots
|
|
# /nix/store/...` to figure out what reference is keeping the old
|
|
# generations alive.
|
|
profile="''${XDG_STATE_HOME:-$HOME/.local/state}/nix/profiles/home-manager"
|
|
elif [[ $3 == "channels" ]]; then
|
|
profile="/nix/var/nix/profiles/per-user/$USER/channels"
|
|
else
|
|
printf "\nError: Do not understand your third argument. Should be one of: (user / home-manager/ channels)\n\n"
|
|
usage
|
|
exit 3
|
|
fi
|
|
else
|
|
if [[ $3 == "system" ]]; then
|
|
profile="/nix/var/nix/profiles/system"
|
|
elif [[ $3 == "user" ]] || [[ $3 == "default" ]]; then
|
|
profile="/nix/var/nix/profiles/default"
|
|
else
|
|
printf "\nError: Do not understand your third argument. Should be one of: (user / system)\n\n"
|
|
usage
|
|
exit 3
|
|
fi
|
|
fi
|
|
printf "OK! \t Keep Gens = %s \t Keep Days = %s \n\n" "$keepGens" "$keepDays"
|
|
|
|
|
|
fi
|
|
|
|
printf "Operating on profile: %s \t \n\n" "$profile"
|
|
|
|
## Runs at the end, to decide whether to delete profiles that match chosen parameters.
|
|
choose () {
|
|
local default="$1"
|
|
local prompt="$2"
|
|
local answer
|
|
|
|
read -r -p "$prompt" answer
|
|
[ -z "$answer" ] && answer="$default"
|
|
|
|
case "$answer" in
|
|
[yY1] ) #printf "answered yes!\n"
|
|
nix-env --delete-generations -p "$profile" "''${!gens[@]}"
|
|
exit 0
|
|
;;
|
|
[nN0] ) printf "Ok doing nothing exiting..\n"
|
|
exit 6;
|
|
;;
|
|
* ) printf "%b" "Unexpected answer '$answer'!" >&2
|
|
exit 7;
|
|
;;
|
|
esac
|
|
} # end of function choose
|
|
|
|
# printf "profile = %s \n\n" "$profile"
|
|
## Query nix-env for generations list
|
|
#IFS=$'\n' nixGens=( $(nix-env --list-generations -p "$profile" | sed 's:^\s*::; s:\s*$::' | tr '\t' ' ' | tr -s ' ') )
|
|
# gave errors replaced by:
|
|
mapfile -t nixGens < <(
|
|
nix-env --list-generations -p "$profile" |
|
|
sed 's:^\s*::; s:\s*$::' |
|
|
tr '\t' ' ' |
|
|
tr -s ' '
|
|
)
|
|
timeNow=$(date +%s)
|
|
|
|
## Get info on oldest generation
|
|
IFS=' ' read -r -a oldestGenArr <<< "''${nixGens[0]}"
|
|
oldestGen=''${oldestGenArr[0]}
|
|
oldestDate=''${oldestGenArr[1]}
|
|
printf "%-30s %s\n" "oldest generation:" "$oldestGen"
|
|
#oldestDate=''${nixGens[0]:3:19}
|
|
printf "%-30s %s\n" "oldest generation created:" "$oldestDate"
|
|
oldestTime=$(date -d "$oldestDate" +%s)
|
|
oldestElapsedSecs=$((timeNow-oldestTime))
|
|
oldestElapsedMins=$((oldestElapsedSecs/60))
|
|
oldestElapsedHours=$((oldestElapsedMins/60))
|
|
oldestElapsedDays=$((oldestElapsedHours/24))
|
|
printf "%-30s %s\n" "minutes before now:" "$oldestElapsedMins"
|
|
printf "%-30s %s\n" "hours before now:" "$oldestElapsedHours"
|
|
printf "%-30s %s\n\n" "days before now:" "$oldestElapsedDays"
|
|
|
|
## Get info on current generation
|
|
for i in "''${nixGens[@]}"; do
|
|
IFS=' ' read -r -a iGenArr <<< "$i"
|
|
genNumber=''${iGenArr[0]}
|
|
genDate=''${iGenArr[1]}
|
|
if [[ "$i" =~ current ]]; then
|
|
currentGen=$genNumber
|
|
printf "%-30s %s\n" "current generation:" "$currentGen"
|
|
currentDate=$genDate
|
|
printf "%-30s %s\n" "current generation created:" "$currentDate"
|
|
currentTime=$(date -d "$currentDate" +%s)
|
|
currentElapsedSecs=$((timeNow-currentTime))
|
|
currentElapsedMins=$((currentElapsedSecs/60))
|
|
currentElapsedHours=$((currentElapsedMins/60))
|
|
currentElapsedDays=$((currentElapsedHours/24))
|
|
printf "%-30s %s\n" "minutes before now:" "$currentElapsedMins"
|
|
printf "%-30s %s\n" "hours before now:" "$currentElapsedHours"
|
|
printf "%-30s %s\n\n" "days before now:" "$currentElapsedDays"
|
|
fi
|
|
done
|
|
|
|
## Compare oldest and current generations
|
|
timeBetweenOldestAndCurrent=$((currentTime-oldestTime))
|
|
elapsedDays=$((timeBetweenOldestAndCurrent/60/60/24))
|
|
generationsDiff=$((currentGen-oldestGen))
|
|
|
|
## Figure out what we should do, based on generations and options
|
|
if [[ elapsedDays -le keepDays ]]; then
|
|
printf "All generations are no more than %s days older than current generation. \nOldest gen days difference from current gen: %s \n\n\tNothing to do!\n" "$keepDays" "$elapsedDays"
|
|
exit 4;
|
|
elif [[ generationsDiff -lt keepGens ]]; then
|
|
printf "Oldest generation (%d) is only %d generations behind current (%d). \n\n\t Nothing to do!\n" "$oldestGen" "$generationsDiff" "$currentGen"
|
|
exit 5;
|
|
else
|
|
printf "\tSomething to do...\n"
|
|
declare -a gens
|
|
for i in "''${nixGens[@]}"; do
|
|
IFS=' ' read -r -a iGenArr <<< "$i"
|
|
genNumber=''${iGenArr[0]}
|
|
genDiff=$((currentGen-genNumber))
|
|
genDate=''${iGenArr[1]}
|
|
genTime=$(date -d "$genDate" +%s)
|
|
elapsedSecs=$((timeNow-genTime))
|
|
genDaysOld=$((elapsedSecs/60/60/24))
|
|
if [[ genDaysOld -gt keepDays ]] && [[ genDiff -ge keepGens ]]; then
|
|
gens["$genNumber"]="$genDate, $genDaysOld day(s) old"
|
|
fi
|
|
done
|
|
printf "\nFound the following generation(s) to delete:\n"
|
|
for K in "''${!gens[@]}"; do
|
|
printf "generation %d \t ''${gens[$K]}\n" "$K"
|
|
done
|
|
printf "\n"
|
|
choose "y" "Do you want to delete these? [Y/n]: "
|
|
fi
|
|
|
|
'';
|
|
};
|
|
};
|
|
}
|