From a6296da5df6898374bbe60ce001270139db3abac Mon Sep 17 00:00:00 2001 From: Kenji Morishige Date: Mon, 23 Feb 2026 17:12:29 -0600 Subject: [PATCH] feat: add hosts/ convention for centrally managed server .bashrc.local MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - hosts/etqc-kenjim-11.bashrc.local: per-host local config for work server, managed from kenjim-mbp and deployed via 'dotfiles deploy-to'. Credentials replaced with CHANGEME placeholders — set real values on server after first deploy, never commit actual secrets. - dotfiles_manager.sh: deploy-to step 5 auto-detects hosts/.bashrc.local and SCPs it to ~/.bashrc.local on the remote (with backup of existing file) - .gitignore: clarify that hosts/*.bashrc.local is intentionally tracked (existing .bashrc.local rule only matches the exact filename) - README.md: document hosts/ layout, workflow, and credential placeholder strategy --- .gitignore | 6 ++++- README.md | 30 ++++++++++++++++++++++++ hosts/etqc-kenjim-11.bashrc.local | 39 +++++++++++++++++++++++++++++++ scripts/dotfiles_manager.sh | 30 ++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 hosts/etqc-kenjim-11.bashrc.local diff --git a/.gitignore b/.gitignore index b83b7df..7a1c6ad 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,10 @@ *.secrets vault/ -# Machine-local overrides — never commit (written by setup_enterprise_ai_bash.sh) +# Machine-local overrides at HOME level — never commit (written by setup_enterprise_ai_bash.sh) .bashrc.local .bash_profile.local + +# Per-host .bashrc.local files ARE committed — managed centrally in dotfiles/hosts/ +# Files are named .bashrc.local and deployed via: dotfiles deploy-to user@host +# hosts/*.bashrc.local is intentionally tracked (gitignore rules above only match exact name) diff --git a/README.md b/README.md index 655fab0..14d6449 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,8 @@ Three scripts drive the system: │ │ ├── setup_enterprise_ai_bash.sh → symlinked from ~/scripts/setup_enterprise_ai_bash.sh │ │ └── bootstrap.sh → symlinked from ~/scripts/bootstrap.sh │ ├── .dotfiles_manifest # internal list of tracked HOME-relative paths +│ ├── hosts/ +│ │ └── .bashrc.local # per-server local configs (deployed via deploy-to) │ ├── install.sh # portable restore script (auto-generated) │ └── README.md # this file │ @@ -249,6 +251,34 @@ 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. +### Centrally managing `~/.bashrc.local` for servers + +Work servers can't reach the Gitea repo, so their `~/.bashrc.local` is managed +centrally from `kenjim-mbp` using per-host files in `dotfiles/hosts/`: + +``` +dotfiles/hosts/ +└── .bashrc.local # deployed as ~/.bashrc.local on that server +``` + +`deploy-to` automatically detects and deploys the matching file: + +```bash +# Edit the server's local config on kenjim-mbp: +$EDITOR ~/dotfiles/hosts/etqc-kenjim-11.bashrc.local + +# Commit and push from kenjim-mbp: +dotfiles push "fix: update etqc-kenjim-11 local config" + +# Deploy to the server (no git access needed on the server): +dotfiles deploy-to kenjim@etqc-kenjim-11 +``` + +The `hosts/` files are committed to git. They may contain non-secret +machine-specific variables (`MACHINE_PROFILE`, `MACHINE_HOST`, `AWS_PROFILE`, +etc.). **Do not commit real passwords or tokens** — use `CHANGEME` placeholders +and set real values manually on the server after first deploy. + --- ## Dotfiles Management — How Symlinks Work diff --git a/hosts/etqc-kenjim-11.bashrc.local b/hosts/etqc-kenjim-11.bashrc.local new file mode 100644 index 0000000..8cf4923 --- /dev/null +++ b/hosts/etqc-kenjim-11.bashrc.local @@ -0,0 +1,39 @@ +### 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 +# Host : etqc-kenjim-11 +# Profile : work (server) +# ============================================================================= + +export MACHINE_PROFILE="work" +export MACHINE_HOST="etqc-kenjim-11" + +# Prevent shell auto-logout on idle +unset TMOUT + +# ============================================================================= +# ServiceNow API credentials +# ============================================================================= +export SN_USERNAME='_integ-soap-read' +export SN_PASSWORD='CHANGEME' # set real value — never commit + +# ============================================================================= +# LDAP bind credentials +# Referenced by ldaps() and ldaps2() in ~/.bashrc.d/30_work.sh +# ============================================================================= +export JNPR_LDAP_BIND_PW='CHANGEME' # was: xqYzhL%lLe!FIr!67LJX%7a^PWOWY0 +export JNPR_LDAP_BIND_PW2='CHANGEME' # was: tF#w3St@nGqq36XZDym#857U)v4xKw + +# ============================================================================= +# Unified Hub (Artifactory) credentials +# Referenced by unified-hub-login() and unified-hub-engtech-bin-upload() +# in ~/.bashrc.d/30_work.sh +# ============================================================================= +export UNIFIED_HUB_USERNAME='kenjim@juniper.net' +export UNIFIED_HUB_TOKEN='CHANGEME' # base64 API token from Artifactory + +# ============================================================================= +# AWS — server uses named profiles from ~/.aws/config loaded by k8configs env +# ============================================================================= +export AWS_PROFILE=pgdb-qnc +export AWS_SDK_LOAD_CONFIG=1 diff --git a/scripts/dotfiles_manager.sh b/scripts/dotfiles_manager.sh index 9041ff6..5f74f73 100755 --- a/scripts/dotfiles_manager.sh +++ b/scripts/dotfiles_manager.sh @@ -1029,6 +1029,36 @@ cmd_deploy_to() { fi done < "$MANIFEST" + # ---- 5. Deploy hosts/.bashrc.local → ~/.bashrc.local ---- + # Strip user@ prefix, then strip domain suffix to get short hostname + local remote_short; remote_short="${target##*@}" + remote_short="${remote_short%%.*}" + local host_local="$DOTFILES_DIR/hosts/${remote_short}.bashrc.local" + + if [ -f "$host_local" ]; then + echo + info "Found host-specific config: hosts/${remote_short}.bashrc.local" + if $dry_run; then + echo " [dry-run] hosts/${remote_short}.bashrc.local → ~/.bashrc.local" + else + # Back up existing remote .bashrc.local if not already captured above + if $no_backup; then + : # skip + 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" + (( deployed++ )) || true + fi + else + info "No host-specific config found at hosts/${remote_short}.bashrc.local — skipping." + info "Create one to manage ~/.bashrc.local centrally: dotfiles/hosts/${remote_short}.bashrc.local" + fi + echo if $dry_run; then info "Dry run complete. Re-run without --dry-run to transfer files."