docker: heal deleted notebooks on boot + fix notebooks helper dockerignore

The boot-time notebook sync now restores notebooks the user deleted, on
every boot, from the baked template (offline, even when upstream has not
advanced). It only restores files that are missing, so it never resurrects
or overwrites an edited notebook, and the GitHub refresh still bumps a
restored file to the latest upstream. Opt out with
UNSLOTH_KEEP_DELETED_NOTEBOOKS=1.

Also add unsloth_nb_content_sig.py to docker/.dockerignore's allowlist; it
was referenced by the Dockerfile COPY but excluded from the build context,
which broke the image build.
This commit is contained in:
danielhanchen 2026-06-16 06:14:33 +00:00
commit 921ab18618
2 changed files with 32 additions and 0 deletions

View file

@ -10,3 +10,4 @@
!unsloth_ipython_startup.py
!unsloth_run.py
!unsloth_sync_notebooks.sh
!unsloth_nb_content_sig.py

View file

@ -16,6 +16,8 @@
# UNSLOTH_SKIP_NOTEBOOK_SYNC=1 do nothing (no populate, no refresh)
# UNSLOTH_SKIP_NOTEBOOK_REFRESH=1 populate from the baked template only;
# never touch the network
# UNSLOTH_KEEP_DELETED_NOTEBOOKS=1 do not restore notebooks the user deleted
# (default: deleted files are healed back)
# UNSLOTH_NOTEBOOKS_DIR=<path> target dir (default /workspace/unsloth-notebooks)
# UNSLOTH_NOTEBOOKS_REPO=<url> source repo (default unslothai/notebooks)
# UNSLOTH_NOTEBOOK_FETCH_TIMEOUT=N seconds for each network op (default 60)
@ -87,6 +89,35 @@ if [ ! -f "$STATE" ]; then
echo "[unsloth-nb] notebooks ready at $DEST"
fi
# 1b) Every-boot OFFLINE restore of deleted notebooks. A file we previously wrote
# that the user has since DELETED is restored from the baked template -- works
# with no network and even when upstream has not advanced. Files that still exist
# (edited or not) are never touched, so this cannot resurrect or clobber an edit;
# the GitHub refresh below then bumps any restored file to the latest upstream.
# The restored file's recorded hash is reset to the template's so the refresh
# treats it as pristine (not as a user edit). Opt out with
# UNSLOTH_KEEP_DELETED_NOTEBOOKS=1 (for users who prune notebooks on purpose).
if [ -f "$STATE" ] && [ "${UNSLOTH_KEEP_DELETED_NOTEBOOKS:-0}" != "1" ]; then
restored=0
RS_TMP="$(mktemp)"
while IFS= read -r line; do
h="${line%% *}"; rel="${line#* }"
if [ -n "$rel" ] && [ "$rel" != "$line" ] \
&& [ ! -e "$DEST/$rel" ] && [ -f "$TEMPLATE/$rel" ]; then
mkdir -p "$DEST/$(dirname "$rel")" 2>/dev/null || true
if cp -a "$TEMPLATE/$rel" "$DEST/$rel" 2>/dev/null; then
printf '%s %s\n' "$(hash_of "$DEST/$rel")" "$rel" >> "$RS_TMP"
restored=$((restored + 1))
continue
fi
fi
printf '%s\n' "$line" >> "$RS_TMP"
done < "$STATE"
mv "$RS_TMP" "$STATE" 2>/dev/null || rm -f "$RS_TMP"
[ "$restored" -gt 0 ] \
&& echo "[unsloth-nb] restored $restored deleted notebook(s) from the baked set"
fi
# 2) Best-effort GitHub refresh -- only when upstream has advanced. Edits win.
[ "${UNSLOTH_SKIP_NOTEBOOK_REFRESH:-0}" = "1" ] && exit 0
command -v git >/dev/null 2>&1 || exit 0