feat: add model-cache-redirect extra for /devl-topology nodes
Ports the ~/.cache -> /devl/user-cache redirect pattern (already applied
manually on heimdall) into cf-node-bootstrap's extras/ plugin system, so
it's an optional step for any future node with the same secondary-SSD
layout (heimdall/navi/sif convention: small root + /devl for fast local
storage). Skips cleanly on nodes without a separate /devl mount.
Redirects XDG_CACHE_HOME plus symlinks the hardcoded ~/.cache/{pip,
whisper,clip,huggingface} paths that ignore XDG_CACHE_HOME. Leaves
HF_HOME (curated model store) untouched.
Verified with -D (dry-run) and -i (real) against sif.
This commit is contained in:
parent
e33d6bb1ad
commit
3d00409b4e
1 changed files with 166 additions and 0 deletions
166
extras/model-cache-redirect.install
Executable file
166
extras/model-cache-redirect.install
Executable file
|
|
@ -0,0 +1,166 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Model/dev-tool cache redirect installer
|
||||||
|
#
|
||||||
|
# Nodes with a fast secondary local disk mounted at /devl (the convention
|
||||||
|
# across CF's rack machines — heimdall, navi, sif) fill up their small root
|
||||||
|
# partition fast once pip/torch/vllm/whisper/clip/huggingface caches land in
|
||||||
|
# ~/.cache. This redirects those caches to /devl/user-cache and leaves
|
||||||
|
# symlinks at the old ~/.cache paths so tools that hardcode ~/.cache (rather
|
||||||
|
# than respecting $XDG_CACHE_HOME) still land on the fast disk.
|
||||||
|
#
|
||||||
|
# Deliberately does NOT touch $HF_HOME — that's the curated model store
|
||||||
|
# convention (/Library/Assets/LLM, NFS) and is unrelated to this cache.
|
||||||
|
#
|
||||||
|
# Only applicable on nodes with a real, separate /devl mount. Skips cleanly
|
||||||
|
# (not an error) on nodes without one, since it's an optional extra.
|
||||||
|
|
||||||
|
scriptname="${BASH_SOURCE[0]##*/}"
|
||||||
|
script_title="${grn}Cache${blu}Redirect${dfl}"
|
||||||
|
rundir="${BASH_SOURCE[0]%/*}"
|
||||||
|
|
||||||
|
# Source PRbL Functions locally or retrieve from online
|
||||||
|
if [ ! -z $prbl_functions ] ; then
|
||||||
|
source $prbl_functions
|
||||||
|
else
|
||||||
|
if [ -f ${rundir}/functions ] ; then
|
||||||
|
source ${rundir}/functions
|
||||||
|
else
|
||||||
|
if command -v curl >/dev/null 2>&1; then
|
||||||
|
source <(curl -ks 'https://raw.githubusercontent.com/pyr0ball/PRbL/main/functions')
|
||||||
|
elif command -v wget >/dev/null 2>&1; then
|
||||||
|
source <(wget -qO- 'https://raw.githubusercontent.com/pyr0ball/PRbL/main/functions')
|
||||||
|
elif command -v fetch >/dev/null 2>&1; then
|
||||||
|
source <(fetch -qo- 'https://raw.githubusercontent.com/pyr0ball/PRbL/main/functions')
|
||||||
|
else
|
||||||
|
echo "Error: curl, wget, and fetch commands are not available. Please install one to retrieve PRbL functions."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
logfile="${rundir}/${pretty_date}_${scriptname}.log"
|
||||||
|
|
||||||
|
cache_root="/devl/user-cache"
|
||||||
|
redirected_tools=(pip whisper clip huggingface)
|
||||||
|
|
||||||
|
# Real, separate mount at /devl (not just a directory that happens to exist
|
||||||
|
# on root) — mirrors how sif/heimdall/navi are actually laid out.
|
||||||
|
_devl-is-separate-mount() {
|
||||||
|
[ -d /devl ] && mountpoint -q /devl
|
||||||
|
}
|
||||||
|
|
||||||
|
check-cache-redirect(){
|
||||||
|
if [[ -n "$XDG_CACHE_HOME" ]] && grep -q "XDG_CACHE_HOME=${cache_root}" "$HOME/.bashrc" 2>/dev/null; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
install(){
|
||||||
|
if ! _devl-is-separate-mount ; then
|
||||||
|
warn "No separate /devl mount found on this node — skipping cache redirect (nothing to do)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if check-cache-redirect ; then
|
||||||
|
boxline "Cache redirect already configured (XDG_CACHE_HOME=${cache_root})"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
boxborder "${lyl}Redirecting dev-tool caches to ${cache_root}${dfl}"
|
||||||
|
|
||||||
|
# run() executes its argument directly when not in dry-run (and only
|
||||||
|
# boxlines it otherwise) — fine for single literal commands like this.
|
||||||
|
run "mkdir -p ${cache_root}"
|
||||||
|
|
||||||
|
if [[ $dry_run == true ]] ; then
|
||||||
|
boxline "DryRun: append 'export XDG_CACHE_HOME=${cache_root}' to $HOME/.bashrc"
|
||||||
|
else
|
||||||
|
take-backup "$HOME/.bashrc"
|
||||||
|
echo "" >> "$HOME/.bashrc"
|
||||||
|
echo "# Dev-tool caches redirected to fast local disk (see model-cache-redirect extra)" >> "$HOME/.bashrc"
|
||||||
|
echo "export XDG_CACHE_HOME=${cache_root}" >> "$HOME/.bashrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tools that hardcode ~/.cache/<name> and ignore XDG_CACHE_HOME: move
|
||||||
|
# existing contents onto the fast disk, then symlink the old path back.
|
||||||
|
# This is multi-step (move-if-present, then symlink) so it's driven by
|
||||||
|
# $dry_run directly rather than run() (which only handles single literal
|
||||||
|
# commands).
|
||||||
|
for tool in "${redirected_tools[@]}"; do
|
||||||
|
local old_path="$HOME/.cache/${tool}"
|
||||||
|
local new_path="${cache_root}/${tool}"
|
||||||
|
|
||||||
|
if [ -L "$old_path" ]; then
|
||||||
|
boxline " ${tool}: already redirected"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $dry_run == true ]] ; then
|
||||||
|
boxline "DryRun: move ${old_path} (if present) to ${new_path}, symlink ${old_path} -> ${new_path}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$new_path"
|
||||||
|
if [ -d "$old_path" ]; then
|
||||||
|
# Move existing cache contents onto the fast disk rather than
|
||||||
|
# discarding them — avoids a cold-cache redownload.
|
||||||
|
cp -a "$old_path/." "$new_path/" 2>/dev/null
|
||||||
|
rm -rf "$old_path"
|
||||||
|
fi
|
||||||
|
ln -s "$new_path" "$old_path"
|
||||||
|
installed_files+=("$old_path -> $new_path")
|
||||||
|
boxline " ${tool}: ${gry}~/.cache/${tool} -> ${new_path}${dfl}"
|
||||||
|
done
|
||||||
|
|
||||||
|
boxline ""
|
||||||
|
boxline "${gry}Note: HF_HOME (curated model store) is untouched by design.${dfl}"
|
||||||
|
boxline "${gry}Re-login (or 'source ~/.bashrc') for XDG_CACHE_HOME to take effect.${dfl}"
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(){
|
||||||
|
warn "Remove is manual for this extra — restoring ~/.cache/<tool> as real dirs"
|
||||||
|
warn "risks re-duplicating data already moved onto ${cache_root}. Not automated."
|
||||||
|
}
|
||||||
|
|
||||||
|
dry-run-report(){
|
||||||
|
box-rounded
|
||||||
|
boxborder "${grn}Dry-run Report:${dfl}"
|
||||||
|
box-norm
|
||||||
|
boxborder \
|
||||||
|
"installed_files= " \
|
||||||
|
"${installed_files[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
usage(){
|
||||||
|
boxborder \
|
||||||
|
"${script_title} usage:" \
|
||||||
|
" -i | --install Redirect dev-tool caches to /devl/user-cache" \
|
||||||
|
" -D | --dry-run Show what would change without doing it" \
|
||||||
|
" -r | --remove (manual only, see warning)" \
|
||||||
|
" -h | --help This menu"
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
-i | --install)
|
||||||
|
install && success " [${script_title} ${lyl}Installed${dfl}]"
|
||||||
|
;;
|
||||||
|
-r | --remove)
|
||||||
|
remove
|
||||||
|
;;
|
||||||
|
-D | --dry-run)
|
||||||
|
export dry_run=true
|
||||||
|
install
|
||||||
|
dry-run-report
|
||||||
|
usage
|
||||||
|
unset dry_run
|
||||||
|
success "${script_title} ${lyl}Installer Dry-Run Complete!${dfl}"
|
||||||
|
;;
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
warn "Invalid argument $@"
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Loading…
Reference in a new issue