Compare commits

...

8 Commits

Author SHA1 Message Date
Kenji Morishige
28485a9be6 add ~/.local/bin to PATH and git tree alias
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 08:18:57 -05:00
Kenji Morishige
72ffe3c30d initial dotfiles migration from kenjim-mbm 2026-03-30 08:41:51 -05:00
Kenji Morishige
b23f5d7e5f latest to support taas shells 2026-02-25 15:20:07 -06:00
Kenji Morishige
d25dac1897 added taas machines as work type machines 2026-02-24 10:00:10 -06:00
Kenji Morishige
67926c37bd NFS-aware .bashrc.local and VS Code dirs for work servers
- Remove zet* from _is_work_host (local git server, not a work host)
- setup_enterprise_ai_bash.sh: detect NFS home on work servers, relocate
  .bashrc.local to /opt/kenjim/ with symlink, handle re-runs safely
- setup_enterprise_ai_bash.sh: symlink ~/.vscode-server and
  ~/.vscode-remote-containers to /opt/kenjim/ on NFS hosts
- dotfiles_manager.sh: deploy-to detects NFS on remote, deploys
  .bashrc.local to /opt/kenjim/ with symlink, backs up symlink targets
- hosts/etqc-kenjim-11.bashrc.local: add NFS note to header
2026-02-24 09:57:29 -06:00
Kenji Morishige
074ab05908 adding ollama installer 2026-02-23 19:53:49 -06:00
Kenji Morishige
0fc1b3cba0 docs: document --run-setup and --profile flags in deploy-to section 2026-02-23 17:27:21 -06:00
Kenji Morishige
3860c8a33d feat: deploy-to --run-setup flag to bootstrap directory structure on remote 2026-02-23 17:27:00 -06:00
12 changed files with 514 additions and 14 deletions

View File

@@ -32,3 +32,8 @@ fi
# Legacy aliases file (kept for compatibility)
[ -f ~/.aliases ] && source ~/.aliases
# OpenClaw Completion
#source "/Users/kenjim/.openclaw/completions/openclaw.bash"
#export OPENCLAW_MODEL=kimi-k2.5:cloud
export PATH="$HOME/.local/bin:$PATH"

View File

@@ -14,7 +14,7 @@ _is_work_host() {
[[ "${MACHINE_PROFILE:-}" == "work" ]] && return 0
# Fallback hostname pattern for work servers where .bashrc.local may not exist
case "$(hostname -s)" in
kenjim-mbp*|etqc-*|etbg-*|engtech-dev-*|zet*) return 0 ;;
kenjim-mbp*|etqc-*|etbg-*|engtech-dev-*|qnc-kenjim-toby-shell*|qtaas*|bng-kenjim-toby-shell*|btaas*|kenjim-taas*) return 0 ;;
*) return 1 ;;
esac
}

View File

@@ -20,3 +20,4 @@ email = kenjim@juniper.net
br = branch
ci = commit
unstage = reset HEAD --
tree = log --graph --oneline --all --decorate

View File

@@ -84,9 +84,12 @@ Host kold
HostName etqc-kenjim-01.juniper.net
# TaaS dev machine
Host ktaas
Host qtaas
HostName kenjim-taas.qengk8.juniper.net
Host btaas
HostName kenjim-taas.bengk8.juniper.net
# Temp machine — Bangalore K8
Host ktb
HostName kenjim-temp.bengk8.juniper.net

View File

@@ -232,6 +232,13 @@ on the remote.
# Push everything (dotfiles + scripts):
dotfiles deploy-to user@server
# After file transfer, also run setup_enterprise_ai_bash.sh on the remote
# to create ~/workspace, ~/data, ~/models and write shell config:
dotfiles deploy-to user@server --run-setup
# Specify a machine profile for the setup script (default: work):
dotfiles deploy-to user@server --run-setup --profile work
# Scripts only (dotfiles_manager.sh, bootstrap.sh, setup script):
dotfiles deploy-to user@server --scripts-only
@@ -251,6 +258,10 @@ Files are copied directly (not symlinked). Re-run `deploy-to` any time you
want to push updates. `~/.ssh/` is skipped by default to avoid accidentally
pushing private keys or your personal known_hosts to a shared server.
> **First-time setup on a server?** Use `--run-setup` to create the full
> directory structure after file transfer, or answer `y` when prompted
> interactively at the end of a normal `deploy-to` run.
### Centrally managing `~/.bashrc.local` for servers
Work servers can't reach the Gitea repo, so their `~/.bashrc.local` is managed
@@ -345,3 +356,83 @@ To add manually:
sudo tmutil addexclusion ~/data/raw
sudo tmutil addexclusion ~/models
```
**Ollama Bootstrap & Usage**
- **Bootstrap (macOS)**: Run the macOS installer/check + create model folders:
```bash
bash scripts/bootstrap_ollama_mac.sh
```
- **Bootstrap (Linux)**: Run the Linux helper (attempts to detect package manager and prepares model folders):
```bash
bash scripts/bootstrap_ollama_linux.sh
```
- The scripts create the model directory referenced by the setup script as `OLLAMA_MODELS` (by default `$HOME/models/ollama`).
- Start the Ollama server inside a tmux session (helper functions):
```bash
# Load helper functions (one-liner to source from dotfiles workspace)
source scripts/ollama_tmux.sh
# Start the server in a detached tmux session named 'ollama' (default command):
start_ollama_tmux
# To attach to the session:
tmux attach -t ollama
# To stop the server session:
stop_ollama_tmux
```
- Model management (two simple options):
- Pull a remote model (via the `ollama` CLI):
```bash
# example: pull a model by reference
pull_ollama_model <model-ref>
```
- Import or stage a local model into the $OLLAMA_MODELS path (creates a symlink):
```bash
import_local_model /path/to/local/model-dir-or-file
# The helper will link it into the directory created by setup_enterprise_ai_bash.sh
```
- Scripts referenced:
- [scripts/bootstrap_ollama_mac.sh](scripts/bootstrap_ollama_mac.sh)
- [scripts/bootstrap_ollama_linux.sh](scripts/bootstrap_ollama_linux.sh)
- [scripts/ollama_tmux.sh](scripts/ollama_tmux.sh)
- How to use Ollama from other AI applications:
- Run the server with `start_ollama_tmux` (above). By default the helper uses `ollama serve --host 127.0.0.1 --port 11434`.
- Many client apps can be pointed at the local Ollama HTTP API (default: `http://127.0.0.1:11434`). Check the Ollama docs for exact endpoints and payloads.
- Example using the `ollama` CLI to run a model directly from scripts or other programs:
```bash
# Run a model locally (interactive / CLI). Replace <model> with the model name.
ollama run <model> --prompt "Write a short haiku about trees"
```
- Example (generic) using HTTP from another application (replace endpoint/payload per Ollama docs):
```bash
curl -X POST "http://127.0.0.1:11434/api/generate" \
-H "Content-Type: application/json" \
-d '{"model":"<model>","prompt":"Hello from my app"}'
```
- When integrating from other AI tooling, supply the Ollama host/port (e.g. `OLLAMA_URL=http://127.0.0.1:11434`) or call the `ollama` CLI directly from the application process.
If you want, I can also:
- Make the new scripts executable (`chmod +x`) automatically in the repo
- Attempt to detect the Ollama default model storage path and auto-configure a symlink

View File

@@ -1,6 +1,8 @@
### MACHINE_LOCAL — managed centrally in dotfiles/hosts/ on kenjim-mbp
### Deployed via: dotfiles deploy-to kenjim@etqc-kenjim-11
### DO NOT edit directly on the server — edit in ~/dotfiles/hosts/ and re-deploy
### NFS NOTE: On NFS-home servers, this file lives at /opt/kenjim/.bashrc.local
### with a symlink from ~/.bashrc.local → /opt/kenjim/.bashrc.local
# Host : etqc-kenjim-11
# Profile : work (server)
# =============================================================================

View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail
echo "🔧 Ollama Linux bootstrap — starting"
# Load environment (MODEL_ROOT, OLLAMA_MODELS)
# Temporarily disable "nounset" when sourcing user shell files to avoid
# failures from system /etc/bashrc referencing undefined vars like PS1.
if [ -f "$HOME/.bashrc" ]; then
set +u
# shellcheck disable=SC1091
source "$HOME/.bashrc" || true
set -u
fi
: "${OLLAMA_MODELS:=$HOME/models/ollama}"
mkdir -p "$OLLAMA_MODELS"
if command -v ollama >/dev/null 2>&1; then
echo "✅ ollama already installed: $(ollama version 2>/dev/null || echo 'unknown')"
else
echo " Attempting to install ollama on Linux"
if command -v apt-get >/dev/null 2>&1; then
echo "Using apt to install prerequisites..."
sudo apt-get update -y || true
sudo apt-get install -y ca-certificates curl gnupg lsb-release || true
echo "⚠️ Please follow the official ollama Linux install instructions if a package is not available: https://ollama.com/docs/install"
echo "If you have a .deb from Ollama, install it with: sudo dpkg -i <file.deb>"
elif command -v dnf >/dev/null 2>&1; then
echo "Using dnf; please refer to Ollama docs for distro-specific instructions: https://ollama.com/docs/install"
else
echo "⚠️ Could not detect package manager. Please install ollama manually. See: https://ollama.com/docs/install"
fi
fi
echo "📁 Ensuring model directory exists: $OLLAMA_MODELS"
mkdir -p "$OLLAMA_MODELS"
echo "✅ Linux Ollama bootstrap complete."
echo "Next steps: run scripts/ollama_tmux.sh to start the server in tmux, and place models under $OLLAMA_MODELS"

41
scripts/bootstrap_ollama_mac.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -euo pipefail
echo "🔧 Ollama macOS bootstrap — starting"
# Load environment (MODEL_ROOT, OLLAMA_MODELS)
# Temporarily disable "nounset" when sourcing user shell files to avoid
# failures from system /etc/bashrc referencing undefined vars like PS1.
if [ -f "$HOME/.bashrc" ]; then
set +u
# shellcheck disable=SC1091
source "$HOME/.bashrc" || true
set -u
fi
: "${OLLAMA_MODELS:=$HOME/models/ollama}"
mkdir -p "$OLLAMA_MODELS"
if command -v ollama >/dev/null 2>&1; then
echo "✅ ollama already installed: $(ollama version 2>/dev/null || echo 'unknown')"
else
if command -v brew >/dev/null 2>&1; then
echo "🍺 Installing ollama via Homebrew..."
brew update || true
brew install ollama || {
echo "⚠️ Homebrew install failed. See https://ollama.com/docs/install"
exit 1
}
echo "✅ ollama installed"
else
echo "⚠️ Homebrew not found. Install Homebrew first: https://brew.sh"
echo "Then re-run this script: $0"
exit 2
fi
fi
echo "📁 Ensuring model directory exists: $OLLAMA_MODELS"
mkdir -p "$OLLAMA_MODELS"
echo "✅ macOS Ollama bootstrap complete."
echo "Next steps: run scripts/ollama_tmux.sh to start the server in tmux, and place models under $OLLAMA_MODELS"

View File

@@ -883,20 +883,24 @@ cmd_remote_bootstrap() {
# COMMAND: deploy-to (push dotfiles to a server that can't reach Gitea)
# -----------------------------------------------------------------------
cmd_deploy_to() {
[ $# -ge 1 ] || die "Usage: deploy-to <user@host> [--scripts-only] [--include-ssh] [--no-backup] [--dry-run]"
[ $# -ge 1 ] || die "Usage: deploy-to <user@host> [--scripts-only] [--include-ssh] [--no-backup] [--run-setup] [--profile work|personal] [--dry-run]"
local target="$1"; shift
local scripts_only=false
local skip_ssh=true # default: skip .ssh/ — avoid pushing keys/config to servers
local no_backup=false
local run_setup=false
local setup_profile="work" # default profile for servers
local dry_run=false
while [[ $# -gt 0 ]]; do
case "$1" in
--scripts-only) scripts_only=true; shift ;;
--include-ssh) skip_ssh=false; shift ;;
--no-backup) no_backup=true; shift ;;
--dry-run) dry_run=true; shift ;;
--scripts-only) scripts_only=true; shift ;;
--include-ssh) skip_ssh=false; shift ;;
--no-backup) no_backup=true; shift ;;
--run-setup) run_setup=true; shift ;;
--profile) setup_profile="${2:-work}"; shift 2 ;;
--dry-run) dry_run=true; shift ;;
*) die "Unknown option: $1" ;;
esac
done
@@ -1061,14 +1065,43 @@ cmd_deploy_to() {
# Back up existing remote .bashrc.local if not already captured above
if $no_backup; then
: # skip
elif ssh "$target" '[ -L ~/.bashrc.local ]' 2>/dev/null; then
# It's a symlink (NFS setup) — back up the target file
local real_path
real_path=$(ssh "$target" 'readlink -f ~/.bashrc.local' 2>/dev/null || true)
if [[ -n "$real_path" ]]; then
local bl_backup="$HOME/.dotfiles_backup/remote-${remote_short}-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$bl_backup"
scp -q "$target:$real_path" "$bl_backup/.bashrc.local" 2>/dev/null || true
info "Backed up remote $real_path$bl_backup/.bashrc.local"
fi
elif ssh "$target" '[ -f ~/.bashrc.local ]' 2>/dev/null; then
local bl_backup="$HOME/.dotfiles_backup/remote-${remote_short}-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$bl_backup"
scp -q "$target:~/.bashrc.local" "$bl_backup/.bashrc.local" 2>/dev/null || true
info "Backed up remote ~/.bashrc.local → $bl_backup/.bashrc.local"
fi
scp -q "$host_local" "$target:~/.bashrc.local"
success "Deployed: hosts/${remote_short}.bashrc.local → ~/.bashrc.local"
# Detect NFS home on the remote and deploy to /opt/kenjim/ if needed
local _remote_nfs=false
if ssh "$target" 'df -P "$HOME" 2>/dev/null | tail -1 | grep -qE ":|nfs"' 2>/dev/null; then
_remote_nfs=true
fi
if $_remote_nfs; then
info "NFS home detected on $target — deploying to /opt/kenjim/.bashrc.local"
# Ensure /opt/kenjim exists — skip sudo if it already does
if ! ssh "$target" '[ -d /opt/kenjim ]' 2>/dev/null; then
info "Creating /opt/kenjim on $target (requires sudo)..."
ssh -t "$target" 'sudo mkdir -p /opt/kenjim && sudo chown $(id -u):$(id -g) /opt/kenjim && chmod 700 /opt/kenjim'
fi
scp -q "$host_local" "$target:/opt/kenjim/.bashrc.local"
ssh "$target" 'chmod 600 /opt/kenjim/.bashrc.local && ln -sfn /opt/kenjim/.bashrc.local ~/.bashrc.local'
success "Deployed: hosts/${remote_short}.bashrc.local → /opt/kenjim/.bashrc.local (symlinked from ~)"
else
scp -q "$host_local" "$target:~/.bashrc.local"
success "Deployed: hosts/${remote_short}.bashrc.local → ~/.bashrc.local"
fi
(( deployed++ )) || true
fi
else
@@ -1076,6 +1109,26 @@ cmd_deploy_to() {
info "Create one to manage ~/.bashrc.local centrally: dotfiles/hosts/${remote_short}.bashrc.local"
fi
# ---- 6. Optionally run setup on the remote ----
if ! $dry_run; then
local do_setup=$run_setup
if ! $run_setup; then
echo
read -r -p "Run setup_enterprise_ai_bash.sh on $target now? Creates dirs, writes shell config. (y/n): " _ans
[[ "$_ans" == [yY] ]] && do_setup=true
fi
if $do_setup; then
echo
info "Running setup on $target (profile=$setup_profile)..."
info "This will create the directory structure and write shell config."
echo
ssh -t "$target" \
"MACHINE_PROFILE=${setup_profile} DOTFILES_REMOTE=${DOTFILES_REMOTE} bash ~/scripts/setup_enterprise_ai_bash.sh"
success "Setup complete on $target."
fi
fi
echo
if $dry_run; then
info "Dry run complete. Re-run without --dry-run to transfer files."
@@ -1083,6 +1136,7 @@ cmd_deploy_to() {
bold "Deploy complete: $deployed file(s) deployed, $skipped skipped."
info "Files were copied directly (no symlinks). Re-run deploy-to to push updates."
$skip_ssh && info "~/.ssh/ was skipped. Use --include-ssh to also deploy ~/.ssh/config."
! $run_setup && info "Tip: add --run-setup to also create directories and shell config on the remote."
fi
}
@@ -1114,14 +1168,17 @@ ${BOLD}COMMANDS — SSH & Keys${RESET}
${BOLD}COMMANDS — Multi-machine${RESET}
remote-bootstrap <user@host> [--profile work|personal]
Upload scripts and run full setup on a remote machine
deploy-to <user@host> [--scripts-only] [--include-ssh] [--no-backup] [--dry-run]
deploy-to <user@host> [--scripts-only] [--include-ssh] [--no-backup] [--run-setup] [--profile work|personal] [--dry-run]
SCP tracked dotfiles + scripts directly to a server.
Use when the server can't reach the Gitea repo.
Backs up existing remote files locally before overwriting.
--scripts-only Only push ~/scripts/, skip dotfiles
--include-ssh Also deploy ~/.ssh/config (skipped by default)
--no-backup Skip the pre-deploy remote backup
--dry-run Preview what would be transferred
--scripts-only Only push ~/scripts/, skip dotfiles
--include-ssh Also deploy ~/.ssh/config (skipped by default)
--no-backup Skip the pre-deploy remote backup
--run-setup Run setup_enterprise_ai_bash.sh on the remote
after deploy (creates dirs, shell config)
--profile work|personal Profile to pass to setup (default: work)
--dry-run Preview what would be transferred
${BOLD}QUICK START — this machine (work)${RESET}
./dotfiles_manager.sh init

View File

@@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -euo pipefail
echo "🔍 Detecting Ollama model directories and linking into OLLAMA_MODELS"
# Load env if available
if [ -f "$HOME/.bashrc" ]; then
set +u
# shellcheck disable=SC1091
source "$HOME/.bashrc" || true
set -u
fi
OLLAMA_MODELS="${OLLAMA_MODELS:-$HOME/models/ollama}"
mkdir -p "$OLLAMA_MODELS"
candidates=(
"$HOME/.ollama/models"
"$HOME/.local/share/ollama/models"
"/var/lib/ollama/models"
"/usr/local/var/ollama/models"
"$HOME/.ollama"
)
linked=0
for cand in "${candidates[@]}"; do
if [ -d "$cand" ]; then
# skip empty directories
if [ -z "$(ls -A "$cand" 2>/dev/null)" ]; then
echo " Found $cand but it's empty — skipping"
continue
fi
name=$(basename "$cand")
dest="$OLLAMA_MODELS/$name"
if [ -e "$dest" ]; then
echo " Destination exists: $dest — skipping"
continue
fi
ln -sfn "$cand" "$dest"
echo "✅ Linked $cand$dest"
linked=$((linked+1))
fi
done
if [ $linked -eq 0 ]; then
echo "⚠️ No existing Ollama model directories detected in common locations."
echo "You can place models in: $OLLAMA_MODELS or run: pull_ollama_model <model-ref> (see scripts/ollama_tmux.sh)"
else
echo "🎉 Completed linking ($linked). Verify with: ls -la $OLLAMA_MODELS"
fi
echo "Done."

144
scripts/ollama_tmux.sh Executable file
View File

@@ -0,0 +1,144 @@
#!/usr/bin/env bash
set -euo pipefail
# Ollama tmux helper and model utilities
# Source this file or call functions directly: source scripts/ollama_tmux.sh
# Ensure environment variables exist
if [ -f "$HOME/.bashrc" ]; then
set +u
# shellcheck disable=SC1091
source "$HOME/.bashrc" || true
set -u
fi
: "${OLLAMA_MODELS:=$HOME/models/ollama}"
start_ollama_tmux() {
session="ollama"
# Use provided command or sensible default. Ollama uses env vars (OLLAMA_HOST)
# Example: OLLAMA_HOST=0.0.0.0:11434 ollama serve
default_cmd="${OLLAMA_CMD:-ollama serve}"
cmd="${1:-$default_cmd}"
echo "Using command: $cmd"
if [ -n "${OLLAMA_HOST:-}" ]; then
echo "OLLAMA_HOST is set to: $OLLAMA_HOST"
fi
if ! command -v tmux >/dev/null 2>&1; then
echo "⚠️ tmux not installed. Install tmux and re-run."
return 2
fi
# Create models dir if needed
mkdir -p "$OLLAMA_MODELS"
if tmux has-session -t "$session" 2>/dev/null; then
echo " tmux session '$session' already running. Attach with: tmux attach -t $session"
return 0
fi
echo "🔁 Starting ollama in tmux session '$session' with command: $cmd"
tmux new-session -d -s "$session" "$cmd"
sleep 0.5
if tmux has-session -t "$session" 2>/dev/null; then
echo "✅ Started. Attach: tmux attach -t $session"
else
echo "❌ Failed to start tmux session. Check logs or run the command directly: $cmd"
return 1
fi
}
pull_ollama_model() {
if [ "$#" -lt 1 ]; then
echo "Usage: pull_ollama_model <model-ref>"
return 2
fi
if ! command -v ollama >/dev/null 2>&1; then
echo "⚠️ ollama CLI not found. Install first."
return 3
fi
model="$1"
echo "⬇️ Pulling model: $model"
ollama pull "$model"
}
import_local_model() {
if [ "$#" -lt 1 ]; then
echo "Usage: import_local_model <path-to-model-dir-or-file>"
return 2
fi
src="$1"
if [ ! -e "$src" ]; then
echo "⚠️ Source not found: $src"
return 3
fi
mkdir -p "$OLLAMA_MODELS"
dest="$OLLAMA_MODELS/$(basename "$src")"
ln -sfn "$src" "$dest"
echo "🔗 Linked $src$dest"
echo "Note: depending on your ollama installation you may need to reindex or use the ollama CLI to register the model."
}
stop_ollama_tmux() {
session="ollama"
if tmux has-session -t "$session" 2>/dev/null; then
tmux kill-session -t "$session"
echo "🛑 Stopped tmux session '$session'"
else
echo " No tmux session named '$session' running"
fi
}
print_usage() {
cat <<EOF
Usage: $(basename "$0") <command> [args]
Commands:
start [<cmd>] Start ollama in tmux (optional command overrides default)
stop Stop the tmux session named 'ollama'
pull <model-ref> Pull a model using the ollama CLI
import <path> Import/link a local model directory/file into OLLAMA_MODELS
help Show this help
If you want to use these as shell functions, source this file instead:
source scripts/ollama_tmux.sh
EOF
}
if [ "${BASH_SOURCE[0]}" == "${0}" ]; then
# Script executed directly; provide a simple CLI wrapper
cmd="${1:-}"
case "$cmd" in
start)
# shift and pass remaining args as the command
shift || true
start_ollama_tmux "$@"
exit $?
;;
stop)
stop_ollama_tmux
exit $?
;;
pull)
shift || true
pull_ollama_model "$@"
exit $?
;;
import)
shift || true
import_local_model "$@"
exit $?
;;
help|--help|-h|"")
print_usage
exit 0
;;
*)
echo "Unknown command: $cmd"
print_usage
exit 2
;;
esac
else
echo "Loaded ollama tmux helper. Functions: start_ollama_tmux, stop_ollama_tmux, pull_ollama_model, import_local_model"
fi

View File

@@ -186,6 +186,69 @@ fi
echo "✅ .bashrc.local written for profile: $MACHINE_PROFILE"
# ---- NFS-aware placement for work servers ----
# Work servers with NFS-mounted home dirs share ~/.bashrc.local across hosts.
# To keep per-machine overrides, store the real file in /opt/kenjim/ and symlink.
if [[ "$MACHINE_PROFILE" == "work" ]]; then
_is_nfs_home=false
case "$(hostname -s)" in
etqc-*|etbg-*|engtech-dev-*|qnc-kenjim-toby-shell*|qtaas*|bng-kenjim-toby-shell*|btaas*|kenjim-taas*)
if df -P "$HOME" 2>/dev/null | tail -1 | grep -qE ':|nfs'; then
_is_nfs_home=true
elif mount | grep -q "on ${HOME%%/} .*type nfs"; then
_is_nfs_home=true
fi
;;
esac
if $_is_nfs_home; then
OPT_DIR="/opt/kenjim"
OPT_LOCAL="$OPT_DIR/.bashrc.local"
echo "🔗 NFS home detected — relocating .bashrc.local to $OPT_LOCAL"
if [ ! -d "$OPT_DIR" ]; then
echo " Creating $OPT_DIR ..."
sudo mkdir -p "$OPT_DIR"
sudo chown "$(id -u):$(id -g)" "$OPT_DIR"
chmod 700 "$OPT_DIR"
fi
# If ~/.bashrc.local is already a symlink (previous run), the cat above
# wrote through it into the target. Remove the symlink first so mv
# doesn't see source and destination as the same file.
if [ -L "$BASHRC_LOCAL" ]; then
rm -f "$BASHRC_LOCAL"
# Content already landed at the symlink target; just ensure perms
chmod 600 "$OPT_LOCAL"
else
mv "$BASHRC_LOCAL" "$OPT_LOCAL"
chmod 600 "$OPT_LOCAL"
fi
ln -sfn "$OPT_LOCAL" "$BASHRC_LOCAL"
echo " Linked: ~/.bashrc.local → $OPT_LOCAL"
# VS Code Remote stores large caches in ~/.vscode-server and
# ~/.vscode-remote-containers — keep them on local disk, not NFS.
for _vsdir in .vscode-server .vscode-remote-containers; do
_opt_target="$OPT_DIR/$_vsdir"
_home_link="$HOME_DIR/$_vsdir"
mkdir -p "$_opt_target"
if [ -d "$_home_link" ] && [ ! -L "$_home_link" ]; then
# Existing real directory — move contents then replace with symlink
echo " Moving ~/$_vsdir$OPT_DIR/$_vsdir ..."
rsync -a "$_home_link/" "$_opt_target/" 2>/dev/null || \
cp -a "$_home_link/." "$_opt_target/" 2>/dev/null || true
rm -rf "$_home_link"
fi
ln -sfn "$_opt_target" "$_home_link"
echo " Linked: ~/$_vsdir$_opt_target"
done
echo "✅ Per-machine .bashrc.local and VS Code dirs stored outside NFS at $OPT_DIR"
fi
fi
# ------------------------------------------------------
# 4⃣ INITIALIZE DOTFILES REPO (with Gitea remote)
# ------------------------------------------------------