4563b4d76d
Lint workflows / actionlint (push) Successful in 14s
Adds a _devbox_check_host_ssh() check to ~/.bash_aliases (baked into the image). On first bash session of each container it tries a quick SSH probe to the Mac host; if it fails it prints a clear one-time warning with the exact two steps needed to fix it: 1. Enable Remote Login in macOS System Settings 2. echo '<public key>' >> ~/.ssh/authorized_keys The check is guarded: - only runs inside a container (/.dockerenv) - only when the jump key exists (~/.ssh-local/devbox_jump_ed25519.pub) - only once per container lifetime (/tmp flag, cleared on recreate) After --force-recreate the key changes, the flag is gone, and the check runs again on the first bash window. Subsequent windows are silent.
145 lines
6.7 KiB
Bash
145 lines
6.7 KiB
Bash
# opencode-devbox bash aliases and customizations
|
|
# Sourced by the Debian-default ~/.bashrc on shell startup.
|
|
# To override, bind-mount your host's ~/.bash_aliases over this file
|
|
# via docker-compose.yml.
|
|
|
|
# ── Host-shared shell customizations (devbox-shell bridge) ───────────
|
|
# If the host bind-mounts a directory at ~/.config/devbox-shell/ (the
|
|
# recommended pattern for sharing aliases/PATH/utilities between host
|
|
# and container), source the bash_aliases file from it. This survives
|
|
# --force-recreate because it's baked into the image's skel, not the
|
|
# container's writable layer. Hosts that don't use this pattern are
|
|
# unaffected — the test silently skips if the file doesn't exist.
|
|
[ -r "$HOME/.config/devbox-shell/bash_aliases" ] && . "$HOME/.config/devbox-shell/bash_aliases"
|
|
|
|
# ── History persistence and quality ──────────────────────────────────
|
|
# The named volume devbox-shell-history is mounted at ~/.cache/bash
|
|
# so history survives container recreation.
|
|
export HISTFILE="${HOME}/.cache/bash/history"
|
|
mkdir -p "$(dirname "$HISTFILE")" 2>/dev/null || true
|
|
|
|
# Large, time-stamped, deduplicated history. Append rather than overwrite.
|
|
export HISTSIZE=100000
|
|
export HISTFILESIZE=200000
|
|
export HISTCONTROL=ignoreboth:erasedups
|
|
export HISTTIMEFORMAT='%F %T '
|
|
shopt -s histappend 2>/dev/null
|
|
shopt -s cmdhist 2>/dev/null
|
|
# Note: PROMPT_COMMAND="history -a" is installed LATER in this file,
|
|
# after zoxide's init runs. Installing it here would create a
|
|
# "history -a;;__zoxide_hook" chain because zoxide's init uses ';'
|
|
# as its separator and prepends itself; two adjacent ';' breaks the
|
|
# parser. See https://github.com/ajeetdsouza/zoxide/issues/722.
|
|
|
|
# ── Common aliases ───────────────────────────────────────────────────
|
|
# Prefer eza (modern ls) when available
|
|
if command -v eza >/dev/null 2>&1; then
|
|
alias ls='eza --group-directories-first'
|
|
alias ll='eza -lh --group-directories-first --git'
|
|
alias la='eza -lha --group-directories-first --git'
|
|
alias tree='eza --tree'
|
|
else
|
|
alias ll='ls -lh'
|
|
alias la='ls -lha'
|
|
fi
|
|
|
|
# Prefer bat (syntax-highlighted cat) when available
|
|
if command -v bat >/dev/null 2>&1; then
|
|
alias cat='bat --style=plain --paging=never'
|
|
alias less='bat --paging=always'
|
|
fi
|
|
|
|
# Git shortcuts
|
|
alias gs='git status'
|
|
alias gd='git diff'
|
|
alias gl='git log --oneline --graph --decorate -20'
|
|
|
|
# ── Host SSH reachability check (once per container lifetime) ───────────────
|
|
# Warns at first shell startup if the Mac host is not reachable via SSH.
|
|
# Only runs inside a container, only if the jump key exists, and only once
|
|
# per container lifetime (/tmp flag is cleared on recreate).
|
|
_devbox_check_host_ssh() {
|
|
[ -f "/.dockerenv" ] || return 0
|
|
local ssh_cfg="$HOME/.ssh-local/config"
|
|
[ -f "$ssh_cfg" ] || return 0
|
|
local key_pub="$HOME/.ssh-local/devbox_jump_ed25519.pub"
|
|
[ -f "$key_pub" ] || return 0
|
|
local flag="/tmp/.devbox_host_ssh_ok"
|
|
[ -f "$flag" ] && return 0
|
|
if ssh -F "$ssh_cfg" \
|
|
-o BatchMode=yes \
|
|
-o ConnectTimeout=2 \
|
|
-o StrictHostKeyChecking=accept-new \
|
|
mac true 2>/dev/null; then
|
|
touch "$flag"
|
|
return 0
|
|
fi
|
|
local pub_key
|
|
pub_key=$(cat "$key_pub")
|
|
printf '\n\033[1;33m⚠ devbox: Mac host not reachable via SSH\033[0m\n'
|
|
printf ' Some tools use SSH to run commands on the Mac host.\n'
|
|
printf ' Fix (run both on the Mac):\n\n'
|
|
printf ' \033[1mStep 1\033[0m System Settings → General → Sharing → Remote Login → ON\n\n'
|
|
printf ' \033[1mStep 2\033[0m echo '"'"'%s'"'"' >> ~/.ssh/authorized_keys\n' "$pub_key"
|
|
printf '\n Then open a new shell in the container to verify.\n\n'
|
|
}
|
|
_devbox_check_host_ssh
|
|
unset -f _devbox_check_host_ssh
|
|
|
|
# ── LAN access via the host (dssh) ───────────────────────────────────
|
|
# When running on a VM-backed host (macOS OrbStack / Docker Desktop), the
|
|
# entrypoint's setup-lan-access.sh generates ~/.ssh-local/config so the host
|
|
# can be used as an SSH jump to reach LAN peers. These aliases wrap `ssh -F`
|
|
# / `scp -F` against that config. Guarded so they only appear when the config
|
|
# was actually generated (no-op / absent on native Linux hosts).
|
|
if [ -r "$HOME/.ssh-local/config" ]; then
|
|
alias dssh='ssh -F "$HOME/.ssh-local/config"'
|
|
alias dscp='scp -F "$HOME/.ssh-local/config"'
|
|
fi
|
|
|
|
# Safety: confirm before destructive ops
|
|
alias rm='rm -i'
|
|
alias mv='mv -i'
|
|
alias cp='cp -i'
|
|
|
|
# ── Shell integrations ───────────────────────────────────────────────
|
|
# zoxide — smarter cd. Use 'z <fragment>' to jump to previously-visited dirs.
|
|
if command -v zoxide >/dev/null 2>&1; then
|
|
eval "$(zoxide init bash)"
|
|
fi
|
|
|
|
# fzf — fuzzy finder key bindings (Ctrl-R for history, Ctrl-T for files).
|
|
# We install fzf from GitHub releases (not apt), so sourcing from the
|
|
# apt-path /usr/share/doc/fzf/examples/* would find nothing. Use the
|
|
# binary's own --bash flag (available since fzf 0.48) for setup.
|
|
if command -v fzf >/dev/null 2>&1; then
|
|
eval "$(fzf --bash)" 2>/dev/null || true
|
|
fi
|
|
|
|
# ── PROMPT_COMMAND: flush history every prompt ───────────────────────
|
|
# Installed AFTER zoxide init so zoxide's hook is already in place;
|
|
# we append with a newline separator to avoid the ';;' parse error
|
|
# described at the top of this file. Guarded so repeated sourcing
|
|
# (e.g. `exec bash`) doesn't stack duplicates.
|
|
#
|
|
# The guard MUST stay shell-local (NOT exported): if it leaks into child
|
|
# processes, every nested shell -- crucially each tmux pane, which inherits
|
|
# the tmux server's env -- skips installing `history -a` and only persists
|
|
# history on a clean exit. Abrupt termination (docker stop, tmux kill-server,
|
|
# SIGKILL) then loses that shell's in-memory history. Keeping it unexported
|
|
# means each new interactive shell re-installs its own per-prompt flush.
|
|
if [ -z "${DEVBOX_HIST_SET:-}" ]; then
|
|
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a"
|
|
DEVBOX_HIST_SET=1
|
|
fi
|
|
|
|
# ── Prompt: show [opencode-devbox] tag so it's obvious you're in the container
|
|
# Preserves the default Debian PS1 logic but prefixes with a container marker.
|
|
# We check for the literal '[devbox]' substring in PS1 rather than relying on
|
|
# an exported guard variable — otherwise `exec bash` inherits the guard but
|
|
# gets a fresh (prefix-less) PS1 from .bashrc, and the prefix would never be
|
|
# re-added in the new shell.
|
|
if [ -n "${PS1:-}" ] && [[ "$PS1" != *"[devbox]"* ]]; then
|
|
PS1='\[\e[38;5;39m\][devbox]\[\e[0m\] '"${PS1}"
|
|
fi
|