Skip to content

Instantly share code, notes, and snippets.

@throwup
Created January 30, 2018 23:49
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 throwup/4ba545d77fe5d33e2cf29c9c868a0026 to your computer and use it in GitHub Desktop.
Save throwup/4ba545d77fe5d33e2cf29c9c868a0026 to your computer and use it in GitHub Desktop.
home-manager-generation/activate
#!/nix/store/i0ay05pqkbnvpfijm52mmlrp6kmkl80c-bash-4.4-p12/bin/bash
set -eu
set -o pipefail
cd $HOME
export PATH="/nix/store/i0ay05pqkbnvpfijm52mmlrp6kmkl80c-bash-4.4-p12/bin:/nix/store/qd55j183ym04y43aam889xkimq704rdx-coreutils-8.29/bin:/nix/store/18ak9x2mqr2inprnr4biad04n6pi4bc5-diffutils-3.6/bin:/nix/store/8x05myb28xqwixakpz0xhqyb8735kvy7-findutils-4.6.0/bin:/nix/store/rhbm7javg5n5zmhhld7qbi23n5qc0srf-gnugrep-3.1/bin:/nix/store/zgr9zbw7p8gihn9h0nj8ggkcplrd9g7f-gnused-4.4/bin:/nix/store/hk3s7q3486lkkipv291m7y498q6rj0pp-ncurses-6.0-20171125/bin:/nix/store/ggj0xvnkx0r22x21z4jnz16vq6k76wx0-nix-1.11.16/bin${PATH:+:}$PATH"
. /nix/store/nwyv4ajhvn210ppigg1g9z177g0g4ls4-color-echo.sh
function setupVars() {
local profilesPath="/nix/var/nix/profiles/per-user/$USER"
local gcPath="/nix/var/nix/gcroots/per-user/$USER"
local greatestGenNum
greatestGenNum=$( \
find "$profilesPath" -name 'home-manager-*-link' \
| sed 's/^.*-\([0-9]*\)-link$/\1/' \
| sort -rn \
| head -1)
if [[ -n "$greatestGenNum" ]] ; then
oldGenNum=$greatestGenNum
newGenNum=$((oldGenNum + 1))
else
newGenNum=1
fi
if [[ -e "$gcPath/current-home" ]] ; then
oldGenPath="$(readlink -e "$gcPath/current-home")"
fi
genProfilePath="$profilesPath/home-manager"
newGenPath="/nix/store/35ifr39r4119si4a7mij5dl8vs571c7c-home-manager-generation";
newGenProfilePath="$profilesPath/home-manager-$newGenNum-link"
newGenGcPath="$gcPath/current-home"
}
setupVars
echo "Starting home manager activation"
if [[ -v VERBOSE ]]; then
export VERBOSE_ECHO=echo
export VERBOSE_ARG="--verbose"
else
export VERBOSE_ECHO=true
export VERBOSE_ARG=""
fi
if [[ -v DRY_RUN ]] ; then
echo "This is a dry run"
export DRY_RUN_CMD=echo
else
$VERBOSE_ECHO "This is a live run"
export DRY_RUN_CMD=""
fi
$VERBOSE_ECHO "Activation variables:"
if [[ -v oldGenNum ]] ; then
$VERBOSE_ECHO " oldGenNum=$oldGenNum"
$VERBOSE_ECHO " oldGenPath=$oldGenPath"
else
$VERBOSE_ECHO " oldGenNum undefined (first run?)"
$VERBOSE_ECHO " oldGenPath undefined (first run?)"
fi
$VERBOSE_ECHO " newGenPath=$newGenPath"
$VERBOSE_ECHO " newGenNum=$newGenNum"
$VERBOSE_ECHO " newGenProfilePath=$newGenProfilePath"
$VERBOSE_ECHO " newGenGcPath=$newGenGcPath"
$VERBOSE_ECHO " genProfilePath=$genProfilePath"
noteEcho Activating checkLinkTargets
function checkNewGenCollision() {
local newGenFiles
newGenFiles="$(readlink -e "$newGenPath/home-files")"
find "$newGenFiles" -type f -print0 -or -type l -print0 \
| xargs -0 bash /nix/store/82x5wqxp7fiblr0h4kn1a288d4wqhd0x-check "$newGenFiles"
}
checkNewGenCollision || exit 1
noteEcho Activating writeBoundary
noteEcho Activating installPackages
if nix-env -q | grep '^home-manager-path$'; then
nix-env -e home-manager-path
fi
noteEcho Activating linkGeneration
function linkNewGen() {
echo "Creating home file links in $HOME"
local newGenFiles
newGenFiles="$(readlink -e "$newGenPath/home-files")"
find "$newGenFiles" -type f -print0 -or -type l -print0 \
| xargs -0 bash /nix/store/6cy75vf9p441gv614gdc654183dv0cgr-link "$newGenFiles"
}
function cleanOldGen() {
if [[ ! -v oldGenPath ]] ; then
return
fi
echo "Cleaning up orphan links from $HOME"
local newGenFiles oldGenFiles
newGenFiles="$(readlink -e "$newGenPath/home-files")"
oldGenFiles="$(readlink -e "$oldGenPath/home-files")"
# Apply the cleanup script on each leaf in the old
# generation. The find command below will print the
# relative path of the entry.
find "$oldGenFiles" '(' -type f -or -type l ')' -printf '%P\0' \
| xargs -0 bash /nix/store/4rbvm2brng1fz7qi11sha2890pp4lk36-cleanup "$newGenFiles"
}
cleanOldGen
if [[ ! -v oldGenPath || "$oldGenPath" != "$newGenPath" ]] ; then
echo "Creating profile generation $newGenNum"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenProfilePath"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG $(basename "$newGenProfilePath") "$genProfilePath"
$DRY_RUN_CMD ln -Tsf $VERBOSE_ARG "$newGenPath" "$newGenGcPath"
else
echo "No change so reusing latest profile generation $oldGenNum"
fi
linkNewGen
noteEcho Activating reloadSystemD
if who | grep -q '^leo '; then
XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/run/user/$(id -u)} \
function isStartable() {
local service="$1"
[[ $(/nix/store/kassxrnp9s64mxg98dm4hh1h0138cgnl-systemd-234/bin/systemctl --user show -p RefuseManualStart "$service") == *=no ]]
}
function isStoppable() {
if [[ -v oldGenPath ]] ; then
local service="$1"
[[ $(/nix/store/kassxrnp9s64mxg98dm4hh1h0138cgnl-systemd-234/bin/systemctl --user show -p RefuseManualStop "$service") == *=no ]]
fi
}
function systemdPostReload() {
local workDir
workDir="$(mktemp -d)"
if [[ -v oldGenPath ]] ; then
local oldUserServicePath="$oldGenPath/home-files/.config/systemd/user"
fi
local newUserServicePath="$newGenPath/home-files/.config/systemd/user"
local oldServiceFiles="$workDir/old-files"
local newServiceFiles="$workDir/new-files"
local servicesDiffFile="$workDir/diff-files"
if [[ ! (-v oldUserServicePath && -d "$oldUserServicePath") \
&& ! -d "$newUserServicePath" ]]; then
return
fi
if [[ ! (-v oldUserServicePath && -d "$oldUserServicePath") ]]; then
touch "$oldServiceFiles"
else
find "$oldUserServicePath" \
-maxdepth 1 -name '*.service' -exec basename '{}' ';' \
| sort \
> "$oldServiceFiles"
fi
if [[ ! -d "$newUserServicePath" ]]; then
touch "$newServiceFiles"
else
find "$newUserServicePath" \
-maxdepth 1 -name '*.service' -exec basename '{}' ';' \
| sort \
> "$newServiceFiles"
fi
diff \
--new-line-format='+%L' \
--old-line-format='-%L' \
--unchanged-line-format=' %L' \
"$oldServiceFiles" "$newServiceFiles" \
> $servicesDiffFile || true
local -a maybeRestart=( $(grep '^ ' $servicesDiffFile | cut -c2-) )
local -a maybeStop=( $(grep '^-' $servicesDiffFile | cut -c2-) )
local -a maybeStart=( $(grep '^+' $servicesDiffFile | cut -c2-) )
local -a toRestart=( )
local -a toStop=( )
local -a toStart=( )
for f in ${maybeRestart[@]} ; do
if isStoppable "$f" \
&& isStartable "$f" \
&& /nix/store/kassxrnp9s64mxg98dm4hh1h0138cgnl-systemd-234/bin/systemctl --quiet --user is-active "$f" \
&& ! cmp --quiet \
"$oldUserServicePath/$f" \
"$newUserServicePath/$f" ; then
toRestart+=("$f")
fi
done
for f in ${maybeStop[@]} ; do
if isStoppable "$f" ; then
toStop+=("$f")
fi
done
for f in ${maybeStart[@]} ; do
if isStartable "$f" ; then
toStart+=("$f")
fi
done
rm -r $workDir
local sugg=""
if [[ -n "${toRestart[@]}" ]] ; then
sugg="${sugg}systemctl --user restart ${toRestart[@]}\n"
fi
if [[ -n "${toStop[@]}" ]] ; then
sugg="${sugg}systemctl --user stop ${toStop[@]}\n"
fi
if [[ -n "${toStart[@]}" ]] ; then
sugg="${sugg}systemctl --user start ${toStart[@]}\n"
fi
if [[ -n "$sugg" ]] ; then
echo "Suggested commands:"
echo -n -e "$sugg"
fi
}
$DRY_RUN_CMD /nix/store/kassxrnp9s64mxg98dm4hh1h0138cgnl-systemd-234/bin/systemctl --user daemon-reload
systemdPostReload
else
echo "User leo not logged in. Skipping."
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment