initial dotfiles migration from kenjim-mbp-work
This commit is contained in:
16
.bash_profile
Normal file
16
.bash_profile
Normal file
@@ -0,0 +1,16 @@
|
||||
. ~/.bashrc
|
||||
|
||||
[[ -r "/opt/homebrew/etc/profile.d/bash_completion.sh" ]] && . "/opt/homebrew/etc/profile.d/bash_completion.sh"
|
||||
|
||||
test -e "${HOME}/.iterm2_shell_integration.bash" && source "${HOME}/.iterm2_shell_integration.bash" || true
|
||||
|
||||
export BASH_SILENCE_DEPRECATION_WARNING=1
|
||||
|
||||
eval "$(/opt/homebrew/bin/brew shellenv)"
|
||||
|
||||
export DOCKER_DEFAULT_PLATFORM=linux/amd64
|
||||
|
||||
# Load .bashrc if it exists
|
||||
if [ -f ~/.bashrc ]; then
|
||||
source ~/.bashrc
|
||||
fi
|
||||
558
.bashrc
Normal file
558
.bashrc
Normal file
@@ -0,0 +1,558 @@
|
||||
# Kenji's .bashrc file
|
||||
# Should be symlinked to DBX/projects/unix/.bashrc
|
||||
# Also should be synced to /homes/kenjim/.bashrc
|
||||
|
||||
if [ -f /etc/profile ]; then source /etc/profile; fi
|
||||
if [ -f /etc/bashrc ]; then source /etc/bashrc; fi
|
||||
|
||||
export PS1='\h:\w\$ '
|
||||
export PS2='> '
|
||||
export FTP_PASSIVE_MODE=YES
|
||||
export RSYNC_RSH=ssh
|
||||
|
||||
OSTYPE=$(uname -s)
|
||||
HOSTNAME=$(hostname -f)
|
||||
HOSTDOMAIN=$(hostname -d)
|
||||
EDITOR=vim
|
||||
set -o vi
|
||||
|
||||
alias gitresetpw='git config --global'
|
||||
alias giturl='git config --get remote.origin.url'
|
||||
|
||||
# OS specific ####################
|
||||
case $OSTYPE in
|
||||
Linux)
|
||||
alias ls='ls -F'
|
||||
alias pst='ps axjf'
|
||||
# specify default shell tools ###########
|
||||
if type $EDITOR >/dev/null 2>&1; then
|
||||
export EDITOR=$EDITOR
|
||||
alias vi=${EDITOR}
|
||||
else
|
||||
export EDITOR=vi
|
||||
fi
|
||||
|
||||
if type less >/dev/null 2>&1; then
|
||||
export PAGER='less'
|
||||
else
|
||||
export PAGER=more
|
||||
fi
|
||||
|
||||
function yaml2json {
|
||||
python -c 'import sys, yaml, json; print(json.dumps(yaml.safe_load(sys.stdin.read())))'
|
||||
}
|
||||
|
||||
;;
|
||||
Darwin)
|
||||
# pstree install with brew
|
||||
alias pst='pstree'
|
||||
;;
|
||||
FreeBSD)
|
||||
export CLICOLOR=1
|
||||
LSCOLORS=fxgxcxdxbxegedabagacad
|
||||
;;
|
||||
esac
|
||||
|
||||
# terminal specific ###############
|
||||
case $TERM in
|
||||
xterm*)
|
||||
export LS_COLORS='no=00:fi=00:di=00;35:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;31:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:*.pl=00;32:'
|
||||
alias ls='ls -F --color'
|
||||
#PROMPT_COMMAND='echo -ne "\033]0;${HOSTNAME}: ${PWD}\007"'
|
||||
#HOSTNAMESHORT="${HOSTNAME%%.*}"
|
||||
#export PROMPT_COMMAND='echo -ne "\033]0;${HOSTNAMESHORT}: ${PWD##*/}\007"'
|
||||
#export PROMPT_COMMAND='echo -ne "\033];${PWD##*/}\007"; ':"$PROMPT_COMMAND";
|
||||
;;
|
||||
esac
|
||||
|
||||
# Domain specific environment #################
|
||||
case $HOSTDOMAIN in
|
||||
juniper.net | jnpr.net)
|
||||
# juniper.net hosts
|
||||
export PATH=$PATH:/volume/labtools/bin
|
||||
export PGUSER=ddladmin
|
||||
export PGHOST=localhost
|
||||
|
||||
function setawx() {
|
||||
echo -n "AWX Host: "
|
||||
read TOWER_HOST
|
||||
echo -n "AWX Username: "
|
||||
read TOWER_USERNAME
|
||||
echo -n "AWX Password: "
|
||||
read TOWER_PASSWORD
|
||||
awx -k -f human login
|
||||
awx config -f human | grep base_url
|
||||
}
|
||||
|
||||
alias awxjobs='awx jobs list -f human --filter id,name,limit,failed --all'
|
||||
|
||||
alias j_proxy_on='proxy_on qcwebproxylb.juniper.net:3128'
|
||||
|
||||
case $OSTYPE in
|
||||
Linux)
|
||||
alias pstree='/usr/bin/pstree -c -l -a -n -p -u'
|
||||
;;
|
||||
FreeBSD) ;;
|
||||
esac
|
||||
|
||||
case $HOSTNAME in
|
||||
# Special configuration specific for Juniper hosts
|
||||
etqc-kenjim* | engtech-dev*)
|
||||
# applies to both workstations
|
||||
#export MAIL=${HOME}/Mail/mbox
|
||||
#export MAILCHECK=600
|
||||
PATH=${HOME}/bin:${PATH}
|
||||
alias awx='~/.local/bin/awx'
|
||||
|
||||
source /usr/share/bash-completion/bash_completion
|
||||
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
#alias realias='$EDITOR ~/.aliases; source ~/.aliases; PWDSAVE=${PWD}; cd ~/cvs/kenjim; cvs -d kenji@rad.kenjim.com:/home/cvs commit -m "updated" .aliases; cd ${PWDSAVE}'
|
||||
#alias rebash='$EDITOR ~/.bashrc; source ~/.bashrc; PWDSAVE=${PWD}; cd ~/cvs/kenjim; cvs -d kenji@rad.kenjim.com:/home/cvs commit -m "updated" .bashrc; cd ${PWDSAVE}'
|
||||
|
||||
# Host specific configurations
|
||||
case $HOSTNAME in
|
||||
kenjim-mbp | etqc-kenjim-* | engtech-dev-01*)
|
||||
# default aliases to override whatever is in .aliases
|
||||
source $HOME/k8configs/engtech_k8_env.sh
|
||||
|
||||
# Add RVM to PATH for scripting
|
||||
# /usr/texbin for MacTex/Latex stuff
|
||||
#PATH=$PATH:/usr/local/sbin:$HOME/bin:$HOME/.rvm/bin:/usr/texbin
|
||||
PATH=$HOME/bin:~/.local/bin:$PATH
|
||||
#PATH=/Users/kenjim/bin/Sencha/Cmd/5.1.2.52:$PATH
|
||||
#export SENCHA_CMD_3_0_0="/Users/kenjim/bin/Sencha/Cmd/5.1.2.52"
|
||||
export CLICOLOR=1
|
||||
|
||||
export RAILS_ENV=development
|
||||
#export TIM_SSH_USER_PASS='B3k1nD+'
|
||||
#export TIM_EK_R_LP='emccolganoansarikenjimjhayespsen'
|
||||
export SN_USERNAME='_integ-soap-read'
|
||||
export SN_PASSWORD='e3Qw&%b7'
|
||||
|
||||
#export PYENV_VERSION='3.8.1'
|
||||
#export ANSIBLE_CONFIG='/Users/kenjim/Juniper/git-m16/infra-ansible/ansible_cli.cfg'
|
||||
#export KUBECONFIG='/Users/kenjim/Juniper/K8_Configs/kenjim-k8-config'
|
||||
|
||||
# Personal Shortcuts
|
||||
alias l='less'
|
||||
alias t='tail -f'
|
||||
alias psg='pstree | grep'
|
||||
alias sl='screen -list'
|
||||
alias sr='screen -r'
|
||||
#alias conncount='netstat -ant | awk "{print $6}" | sort | uniq -c | sort -n'
|
||||
alias a='alias'
|
||||
alias h='history 25'
|
||||
alias la='ls -a'
|
||||
alias lf='ls -FA'
|
||||
alias ll='ls -lAh|more'
|
||||
alias lt='ls -tlAh|more'
|
||||
alias tl='tail -f /var/log/messages'
|
||||
alias sl='screen -list'
|
||||
alias sr='screen -r'
|
||||
alias ps-m='ps aux --sort -rss'
|
||||
|
||||
#alias sa='ssh-add /export/kenjim/.ssh/juniper_kenjim_rsa_id'
|
||||
#alias lair='ssh-keygen -f "/home/kenjim/.ssh/known_hosts" -R lair.kenjim.com; ssh -f -N -R 11322:localhost:22 lair'
|
||||
#alias bar='ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ServerAliveInterval=540 -o Compression=no -f -N -R 11322:localhost:22 root@192.241.205.115'
|
||||
#alias sa='ssh-add /export/kenjim/.ssh/juniper_kenjim_rsa_id'
|
||||
|
||||
alias rvmi='source "$HOME/.rvm/scripts/rvm"; echo "rvm initialized..."'
|
||||
#alias psql='/Applications/Postgres.app/Contents/Versions/9.6/bin/psql'
|
||||
#alias ctags='/usr/local/bin/ctags'
|
||||
#alias rtags='/usr/local/bin/ctags -R -f .tags --languages=ruby --exclude=.git --exclude=log . $(bundle list --paths)'
|
||||
|
||||
alias pstat='passenger status'
|
||||
alias pstart='passenger start'
|
||||
alias pstop='passenger stop'
|
||||
alias prest='passenger stop; sleep 2; passenger start'
|
||||
alias renv='env|sort|egrep -i "(gem|ruby|rvm|rails|tim)"'
|
||||
|
||||
# Postgres Logins
|
||||
alias pgtimdev='psql -U tim_api tim_api_dev'
|
||||
alias pgtimqdev='psql -U tim_api -h ttqc-tim-mmonit-02 kenjim_devel'
|
||||
alias pgtimqdev2='psql -U tim_api -h ttqc-tim-mmonit-02 kenjim_devel2'
|
||||
alias pgtimtest='psql -U tim_api tim_api_test'
|
||||
alias pgtimint='psql -h ttqc-tim-mm-02.juniper.net -U tim_api tim_api_int'
|
||||
alias pgtimint2='psql -h ttsv-db-03.juniper.net -U tim_api tim_api_int2'
|
||||
alias pgtimprod='psql -h ttqc-tim-mm-02.juniper.net -p 5432 -U tim_api tim'
|
||||
alias pgtimloc='psql -U tim_api kenjim_tim'
|
||||
alias pgtimweekly='psql -h ttqc-testdb-01 -U tim_api weekly_systest_live'
|
||||
alias pgtimqmm='psql -h ttqc-tim-mmonit-02 -U mmonit mmonit'
|
||||
alias pgtimbmm='psql -h ttbg-tim-mmonit-01 -U mmonit mmonit'
|
||||
alias pgbdrqc='psql -h ttqc-bdr-db01.juniper.net -U tim_api systest_live'
|
||||
alias pgbdrbg='psql -h ttbg-bdr-db01.juniper.net -U tim_api systest_live'
|
||||
alias pgdlm='psql -h ttqc-dlm-db-ms.ttglb.juniper.net -U ddladmin systest_live'
|
||||
|
||||
alias jira='jira-cli --v2 view --oneline --search-jql "assignee=kenjim and status!=closed and status!=resolved order by priority desc, created asc"'
|
||||
|
||||
# retired
|
||||
#alias tim='GLI_DEBUG=true bundle exec bin/timcl'
|
||||
|
||||
#alias ap='ansible-playbook -i inventory/engtech-prod'
|
||||
#alias ai='ANSIBLE_CONFIG=/Users/kenjim/Juniper/git-m16/infra-ansible/ansible_cli.cfg ansible-inventory -i inventory/cmdb/now.py -i inventory/engtech_prod'
|
||||
|
||||
alias ai='ANSIBLE_CONFIG=/Users/kenjim/Juniper/git-m16/infra-ansible/ansible_cli.cfg ansible-inventory -i inventory/cmdb_rendered/engtech.yml'
|
||||
alias ans='ANSIBLE_CONFIG=/Users/kenjim/Juniper/git-m16/infra-ansible/ansible_cli.cfg ansible -i ~/ansible/inventory/cmdb/now.py -i ~/ansible/inventory/engtech_prod'
|
||||
#alias apy='rm ~/ansible.log ; ANSIBLE_CONFIG=/Users/kenjim/Juniper/git/infra-ansible/ansible_cli.cfg ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook -i inventory/cmdb/now.py -i inventory/engtech_prod'
|
||||
alias apy='rm ~/ansible.log ; ANSIBLE_CONFIG=/Users/kenjim/Juniper/git/infra-ansible/ansible_cli.cfg ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook -i inventory/cmdb_rendered/engtech.yml --vault-id vault_engtech_default'
|
||||
alias aps='rm ~/ansible.log ; ANSIBLE_CONFIG=/Users/kenjim/Juniper/git/infra-ansible/ansible_cli.cfg ANSIBLE_STDOUT_CALLBACK=selective ansible-playbook -i inventory/cmdb_rendered/engtech.yml --vault-id vault_engtech_default'
|
||||
alias apa='rm ~/ansible.log ; ANSIBLE_CONFIG=/Users/kenjim/Juniper/git/infra-ansible/ansible_cli.cfg ANSIBLE_STDOUT_CALLBACK=actionable ansible-playbook -i inventory/cmdb_rendered/engtech.yml --vault-id vault_engtech_default'
|
||||
alias apd='rm ~/ansible.log ; ANSIBLE_CONFIG=/Users/kenjim/Juniper/git/infra-ansible/ansible_cli.cfg ANSIBLE_STDOUT_CALLBACK=debug ansible-playbook -i inventory/cmdb/now.py -i inventory/engtech_prod'
|
||||
alias apj='rm ~/ansible.log ; ANSIBLE_CONFIG=/Users/kenjim/Juniper/git/infra-ansible/ansible_cli.cfg ANSIBLE_STDOUT_CALLBACK=json ansible-playbook -i inventory/cmdb/now.py -i inventory/engtech_prod'
|
||||
alias giturl='git config --get remote.origin.url'
|
||||
alias gitresetpw='git config --global credential.helper osxkeychain'
|
||||
|
||||
alias d='docker'
|
||||
alias di='docker images'
|
||||
alias dp='docker ps'
|
||||
alias dr='docker run'
|
||||
alias db='docker build'
|
||||
alias dbash='docker run -it --entrypoint /bin/bash'
|
||||
|
||||
function tmls { ssh $1 ls /etc/monit.d; }
|
||||
function tmlog { ssh $1 tail -f /var/log/monit.log; }
|
||||
|
||||
function tdiffstat { svn diff -x --ignore-eol-style -x -w https://tt-svn.juniper.net/svn/adp/projects/tim/tags/$1/rails-api https://tt-svn.juniper.net/svn/adp/projects/tim/trunk/rails-api | diffstat; }
|
||||
function tdiff { svn diff -x --ignore-eol-style -x -w https://tt-svn.juniper.net/svn/adp/projects/tim/tags/$1/rails-api https://tt-svn.juniper.net/svn/adp/projects/tim/trunk/rails-api; }
|
||||
|
||||
function timsvncopy { svn copy --parents https://tt-svn.juniper.net/svn/adp/projects/tim/trunk/rails-api https://tt-svn.juniper.net/svn/adp/projects/tim/tags/$1/rails-api -m "$1 new branch"; }
|
||||
|
||||
function curl_time { curl -w "@curl-format.txt" -o /dev/null -s "$1"; }
|
||||
|
||||
# copies my protected ssh pub key
|
||||
function copy_pub_key { cat ~/.ssh/authorized_keys.kenjim-protected | ssh $1 'umask 0077; mkdir -p .ssh; cat >> .ssh/authorized_keys && echo "Key copied"'; }
|
||||
|
||||
function ldaps() {
|
||||
ldapsearch -LLL -x -b 'dc=jnpr,dc=net' -h ldap-eqx-lb.jnpr.net -D 'CN=_eng_jira_bind_new,OU=Service Accounts,OU=Misc,OU=Common,DC=jnpr,DC=net' -w 'xqYzhL%lLe!FIr!67LJX%7a^PWOWY0' sAMAccountName=$1 | perl -p00e 's/\r?\n //g'
|
||||
}
|
||||
|
||||
function ldaps2() {
|
||||
ldapsearch -LLL -x -b 'dc=jnpr,dc=net' -h ldap-qnc-lb.jnpr.net -D 'CN=_eng_labrsrcmgr_bind,OU=Service Accounts,OU=Misc,OU=Common,DC=jnpr,DC=net' -w 'tF#w3St@nGqq36XZDym#857U)v4xKw' sAMAccountName=$1 | perl -p00e 's/\r?\n //g'
|
||||
}
|
||||
|
||||
function netseg() {
|
||||
curl -k https://netseg.juniper.net/api/find_ip?hostname=$1 | jq '.'
|
||||
}
|
||||
|
||||
function dbash() {
|
||||
docker exec -it $1 bash
|
||||
}
|
||||
|
||||
# Kubectl Autocomplete
|
||||
source <(kubectl completion bash)
|
||||
alias k=kubectl
|
||||
complete -o default -F __start_kubectl k
|
||||
|
||||
alias kc='kubectl config view'
|
||||
alias kd='kubectl describe'
|
||||
alias ke='kubectl explain'
|
||||
alias kg='kubectl get'
|
||||
alias kl='kubectl logs -f'
|
||||
alias kp='kubectl get pods -o wide'
|
||||
alias kq='kubectl describe quota'
|
||||
alias ks='kubectl get services'
|
||||
alias kuc='kubectl config use-context'
|
||||
alias kpl='kubectl get pods --show-labels'
|
||||
alias kdp='kubectl describe pod'
|
||||
alias kgs='kubectl get secrets'
|
||||
|
||||
# Kubectl aliases
|
||||
alias kx='f() { [ "$1" ] && kubectl config use-context $1 || kubectl config current-context ; } ; f'
|
||||
alias kn='f() { [ "$1" ] && kubectl config set-context --current --namespace $1 || kubectl config view --minify | grep namespace | cut -d" " -f6 ; } ; f'
|
||||
|
||||
#export NVM_DIR="$HOME/.nvm"
|
||||
#[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||
#[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
||||
|
||||
#export COPYFILE_DISABLE=1
|
||||
#export GRAPHVIZ_DOT=/usr/local/bin/dot
|
||||
;;
|
||||
esac
|
||||
|
||||
case $HOSTNAME in
|
||||
################################################################################
|
||||
kenjim-mbp*)
|
||||
#export DOCKER_DEFAULT_PLATFORM=linux/amd64
|
||||
|
||||
# add MacTex Path, installer unable to add symlink in /usr/texbin
|
||||
#PATH=/usr/local/opt/libiconv/bin:/Library/TeX/texbin:$PATH
|
||||
#PATH=/usr/local/opt/libiconv/bin:/Library/TeX/texbin:$PATH
|
||||
#PATH=/opt/homebrew/bin:$PATH
|
||||
|
||||
#export LDFLAGS="-L/usr/local/opt/zlib/lib"
|
||||
#export CPPFLAGS="-I/usr/local/opt/zlib/include"
|
||||
#source ~/perl5/perlbrew/etc/bashrc
|
||||
|
||||
if command -v pyenv 1>/dev/null 2>&1; then
|
||||
export PYENV_ROOT="$HOME/.pyenv"
|
||||
export PATH="$PYENV_ROOT/bin:$PATH"
|
||||
eval "$(pyenv init --path)"
|
||||
eval "$(pyenv init -)"
|
||||
fi
|
||||
|
||||
export AWS_PROFILE=kenjim-qnc
|
||||
# make connection to k ssh config first localhost forward: LocalForward 8888 qnc-engdata5vs3.juniper.net:80
|
||||
#alias aws='aws --endpoint-url http://localhost:8888'
|
||||
alias aws-pgdb-qnc-du="aws --profile pgdb-qnc s3 ls s3://engtech-pgdb-s3-qnc/ --recursive | awk 'BEGIN {total=0}{total+=\$3}END{print total/1024/1024/1024\" GB\"}'"
|
||||
alias aws-pgdb-bng-du="aws --profile pgdb-bng s3 ls s3://engtech-pgdb-s3-bng/ --recursive | awk 'BEGIN {total=0}{total+=\$3}END{print total/1024/1024/1024\" GB\"}'"
|
||||
alias aws-pgdb-qnc-ls="aws --profile pgdb-qnc s3 ls s3://engtech-pgdb-s3-qnc/ --recursive"
|
||||
alias aws-pgdb-bng-ls="aws --profile pgdb-bng s3 ls s3://engtech-pgdb-s3-bng/ --recursive"
|
||||
export AWS_SDK_LOAD_CONFIG=1
|
||||
|
||||
#export KUBECONFIG='/Users/kenjim/.kube/config'
|
||||
|
||||
function k8proxy {
|
||||
export KUBECONFIG='/Users/kenjim/Juniper/K8_Configs/kenjim-k8-config'
|
||||
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"
|
||||
export http_proxy="socks5://localhost:3133/"
|
||||
export https_proxy=$http_proxy
|
||||
export ftp_proxy=$http_proxy
|
||||
export rsync_proxy=$http_proxy
|
||||
}
|
||||
|
||||
function killcrashplan() {
|
||||
sudo launchctl unload /Library/LaunchDaemons/com.crashplan.engine.plist
|
||||
}
|
||||
;;
|
||||
|
||||
etqc-kenjim-* | engtech-dev-01*)
|
||||
# Make symlink git checkout location
|
||||
# ~k8configs -> ~/EngTech/Infra/k8configs
|
||||
source $HOME/k8configs/engtech_k8_env.sh
|
||||
export AWS_PROFILE=pgdb-qnc
|
||||
# make connection to k8dev ssh config first localhost forward: LocalForward 8888 qnc-engdata5vs3.juniper.net:80
|
||||
alias aws='aws --endpoint-url http://qnc-engdata5vs3.juniper.net'
|
||||
alias aws-pgdb-qnc-du="aws s3 ls s3://engtech-pgdb-s3-qnc/ --recursive | awk 'BEGIN {total=0}{total+=\$3}END{print total/1024/1024/1024\" GB\"}'"
|
||||
alias aws-pgdb-bng-du="aws s3 ls s3://engtech-pgdb-s3-bng/ --recursive | awk 'BEGIN {total=0}{total+=\$3}END{print total/1024/1024/1024\" GB\"}'"
|
||||
alias aws-pgdb-qnc-ls="aws s3 ls s3://engtech-pgdb-s3-qnc/ --recursive"
|
||||
alias aws-pgdb-bng-ls="aws s3 ls s3://engtech-pgdb-s3-bng/ --recursive"
|
||||
export AWS_SDK_LOAD_CONFIG=1
|
||||
;;
|
||||
|
||||
################################################################################
|
||||
# akira-mt*)
|
||||
# #export CVSROOT=ace.kenjim.com:/cvs
|
||||
# alias rvmi='source "$HOME/.rvm/scripts/rvm"; echo "rvm initialized..."'
|
||||
# alias kl='ssh kenjim-lnx-tun'
|
||||
# #dispwin -d1 -I ~/projects/monitor_calibration/GTX660_VP2770_C60_B29_D65.icm
|
||||
# #dispwin -d2 -I ~/projects/monitor_calibration/GTX660_HDMI_23EA63_C83_B26_D65.icm
|
||||
# export RAILS_ENV=kenjim_local
|
||||
|
||||
# ;;
|
||||
################################################################################
|
||||
esac
|
||||
|
||||
function proxy_on() {
|
||||
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"
|
||||
|
||||
if (($# > 0)); then
|
||||
#valid=$(echo $@ | sed -n 's/\([0-9]\{1,3\}.\)\{4\}:\([0-9]\+\)/&/p')
|
||||
#if [[ $valid != $@ ]]; then
|
||||
# >&2 echo "Invalid address"
|
||||
# return 1
|
||||
#fi
|
||||
|
||||
export http_proxy="http://$1/"
|
||||
export https_proxy=$http_proxy
|
||||
export ftp_proxy=$http_proxy
|
||||
export rsync_proxy=$http_proxy
|
||||
echo "Proxy environment variable set."
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -n "username: "
|
||||
read username
|
||||
if [[ $username != "" ]]; then
|
||||
echo -n "password: "
|
||||
read -es password
|
||||
local pre="$username:$password@"
|
||||
fi
|
||||
|
||||
echo -n "server: "
|
||||
read server
|
||||
echo -n "port: "
|
||||
read port
|
||||
|
||||
export http_proxy="http://$pre$server:$port/"
|
||||
export https_proxy=$http_proxy
|
||||
export ftp_proxy=$http_proxy
|
||||
export rsync_proxy=$http_proxy
|
||||
export HTTP_PROXY=$http_proxy
|
||||
export HTTPS_PROXY=$http_proxy
|
||||
export FTP_PROXY=$http_proxy
|
||||
export RSYNC_PROXY=$http_proxy
|
||||
}
|
||||
|
||||
function proxy_off() {
|
||||
unset http_proxy
|
||||
unset https_proxy
|
||||
unset ftp_proxy
|
||||
unset rsync_proxy
|
||||
echo -e "Proxy environment variable removed."
|
||||
}
|
||||
|
||||
function unified-hub-login() {
|
||||
UNIFIED_HUB_URL="unified-hub.juniper.net"
|
||||
UNIFIED_HUB_USERNAME="kenjim@juniper.net"
|
||||
UNIFIED_HUB_PASSWORD="cmVmdGtuOjAxOjE3NDA3ODI3NDk6OGt6WUJvcFJwa29RdEhKWWE1U1MzNkJnZXVE"
|
||||
echo $UNIFIED_HUB_PASSWORD | docker login -u "$UNIFIED_HUB_USERNAME" --password-stdin $UNIFIED_HUB_URL
|
||||
}
|
||||
|
||||
unified-hub-engtech-bin-upload() {
|
||||
local file="$1"
|
||||
local remote_path="$2"
|
||||
|
||||
# Validation
|
||||
if [[ -z "$file" ]] || [[ -z "$remote_path" ]]; then
|
||||
echo "Usage: unified-hub-engtech-bin-upload <local-file> <remote-path>"
|
||||
echo ""
|
||||
echo "Example:"
|
||||
echo " unified-hub-engtech-bin-upload kubectl dl.k8s.io/release/v1.28.4/bin/linux/amd64/kubectl"
|
||||
echo ""
|
||||
echo "Uploads to: https://unified-hub.juniper.net/artifactory/engtech-binaries/<remote-path>"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$file" ]]; then
|
||||
echo "Error: File '$file' not found in current directory"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Configuration
|
||||
local username="kenjim@juniper.net"
|
||||
local token="cmVmdGtuOjAxOjE3NzY5NzgzNDY6Nm4xZU9uOEZvUzVLM1RNQkxXY2ZVdThBOVFY"
|
||||
local base_url="https://unified-hub.juniper.net/artifactory/engtech-binaries"
|
||||
local full_url="${base_url}/${remote_path}"
|
||||
|
||||
echo "📦 Uploading: $file"
|
||||
echo "📍 To: $full_url"
|
||||
echo ""
|
||||
|
||||
# Upload with progress
|
||||
if curl -u "${username}:${token}" \
|
||||
-T "$file" \
|
||||
--progress-bar \
|
||||
"$full_url"; then
|
||||
echo ""
|
||||
echo "✅ Upload successful!"
|
||||
echo "🔗 URL: $full_url"
|
||||
else
|
||||
echo ""
|
||||
echo "❌ Upload failed!"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Add this to your ~/.bashrc or ~/.zshrc
|
||||
|
||||
git-prune-branches() {
|
||||
echo "🌿 Git Branch Cleanup"
|
||||
echo "===================="
|
||||
echo ""
|
||||
|
||||
# Check if we're in a git repo
|
||||
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||
echo "❌ Error: Not in a git repository"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Get main branch name (main or master)
|
||||
local main_branch=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
|
||||
if [[ -z "$main_branch" ]]; then
|
||||
main_branch="main"
|
||||
fi
|
||||
|
||||
echo "📡 Fetching latest from remote and pruning..."
|
||||
git fetch --all --prune
|
||||
echo ""
|
||||
|
||||
# Show merged branches
|
||||
echo "🗑️ Local branches merged into $main_branch:"
|
||||
local merged_branches=$(git branch --merged "$main_branch" | grep -v "^\*" | grep -v "$main_branch" | grep -v "master")
|
||||
if [[ -z "$merged_branches" ]]; then
|
||||
echo " (none)"
|
||||
else
|
||||
echo "$merged_branches"
|
||||
echo ""
|
||||
read -p "Delete these merged local branches? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "$merged_branches" | xargs -n 1 git branch -d
|
||||
echo "✅ Merged branches deleted"
|
||||
else
|
||||
echo "⏭️ Skipped"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
# Show orphaned branches
|
||||
echo "🗑️ Local branches tracking deleted remotes:"
|
||||
local orphaned_branches=$(git branch -vv | grep ': gone]' | awk '{print $1}')
|
||||
if [[ -z "$orphaned_branches" ]]; then
|
||||
echo " (none)"
|
||||
else
|
||||
echo "$orphaned_branches"
|
||||
echo ""
|
||||
read -p "Delete these orphaned local branches? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "$orphaned_branches" | xargs -n 1 git branch -D
|
||||
echo "✅ Orphaned branches deleted"
|
||||
else
|
||||
echo "⏭️ Skipped"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "📊 Remaining local branches:"
|
||||
git branch -vv
|
||||
|
||||
echo ""
|
||||
echo "✨ Cleanup complete!"
|
||||
}
|
||||
|
||||
alias git-clean='git-prune-branches'
|
||||
|
||||
touch ~/.aliases
|
||||
source ~/.aliases
|
||||
|
||||
|
||||
### ENTERPRISE_AI_ENV ###
|
||||
export WORKSPACE="$HOME/workspace"
|
||||
export DATA_ROOT="$HOME/data"
|
||||
export MODEL_ROOT="$HOME/models"
|
||||
|
||||
# HuggingFace cache location
|
||||
export HF_HOME="$MODEL_ROOT/huggingface"
|
||||
|
||||
# Ollama model location
|
||||
export OLLAMA_MODELS="$MODEL_ROOT/ollama"
|
||||
|
||||
# Convenience aliases
|
||||
alias ws='cd $WORKSPACE'
|
||||
alias src='cd $WORKSPACE/src'
|
||||
alias data='cd $DATA_ROOT'
|
||||
alias models='cd $MODEL_ROOT'
|
||||
|
||||
# Machine-local overrides (cloud paths, work vs personal — not synced via dotfiles)
|
||||
[ -f ~/.bashrc.local ] && source ~/.bashrc.local
|
||||
|
||||
|
||||
### DOTFILES_ALIASES ###
|
||||
export DOTFILES_DIR="$HOME/dotfiles"
|
||||
export DOTFILES_REMOTE="http://172.27.0.35:3000/kenjim/dotfiles"
|
||||
|
||||
# Dotfiles manager shortcut
|
||||
alias dotfiles='bash $HOME/scripts/dotfiles_manager.sh'
|
||||
alias dot='bash $HOME/scripts/dotfiles_manager.sh'
|
||||
|
||||
# Quick sync alias
|
||||
alias dots-sync='bash $HOME/scripts/dotfiles_manager.sh sync'
|
||||
alias dots-push='bash $HOME/scripts/dotfiles_manager.sh push'
|
||||
alias dots-status='bash $HOME/scripts/dotfiles_manager.sh status'
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
.bash_profile
|
||||
.bashrc
|
||||
.gitconfig
|
||||
.ssh/config
|
||||
.ssh/known_hosts
|
||||
scripts/bootstrap.sh
|
||||
scripts/dotfiles_manager.sh
|
||||
scripts/setup_enterprise_ai_bash.sh
|
||||
|
||||
22
.gitconfig
Normal file
22
.gitconfig
Normal file
@@ -0,0 +1,22 @@
|
||||
# This is Git's per-user configuration file.
|
||||
[user]
|
||||
# Please adapt and uncomment the following lines:
|
||||
name = Kenji Morishige
|
||||
email = kenjim@juniper.net
|
||||
[push]
|
||||
default = matching
|
||||
autoSetupRemote = true
|
||||
default = current
|
||||
autoSetupRemote = true
|
||||
[credential]
|
||||
helper = osxkeychain
|
||||
[alias]
|
||||
st = status
|
||||
stat = status
|
||||
co = checkout
|
||||
lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all
|
||||
lg2 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all
|
||||
lg = !"git lg1"
|
||||
br = branch
|
||||
ci = commit
|
||||
unstage = reset HEAD --
|
||||
227
.ssh/config
Normal file
227
.ssh/config
Normal file
@@ -0,0 +1,227 @@
|
||||
ForwardAgent yes
|
||||
#ForwardX11 yes
|
||||
UserKnownHostsFile /dev/null
|
||||
StrictHostKeyChecking no
|
||||
Protocol 2,1
|
||||
Compression yes
|
||||
KeepAlive yes
|
||||
#ServerAliveInterval 540
|
||||
#LocalForward 57711 127.0.0.1:57711
|
||||
AddKeysToAgent yes
|
||||
IgnoreUnknown UseKeychain
|
||||
UseKeychain yes
|
||||
|
||||
Host k
|
||||
HostName etqc-kenjim-11.juniper.net
|
||||
#ProxyJump engdmz
|
||||
DynamicForward 3139
|
||||
# For aws S3 command
|
||||
LocalForward 8888 qnc-engdata5vs3.juniper.net:80
|
||||
# VMM Telemetry DB
|
||||
#LocalForward 5445 etus-tel-db-k8.ttglb.juniper.net:5432
|
||||
# Notification DB
|
||||
#LocalForward 5446 etus-not-db-k8.ttglb.juniper.net:5432
|
||||
# LRM Beta DB
|
||||
LocalForward 5447 engtech-lrm-snap1-qnc.engtech-pgdb-qnc.qengk8.juniper.net:5432
|
||||
# TIM-API DB
|
||||
#LocalForward 5448 engtech.timdb.qengk8.juniper.net:5432
|
||||
# Limited Use
|
||||
RemoteForward 2222 localhost:22
|
||||
ServerAliveInterval 30
|
||||
ServerAliveCountMax 20
|
||||
|
||||
Host zet
|
||||
HostName 172.27.0.35
|
||||
ServerAliveInterval 540
|
||||
|
||||
Host kenjim-mbm
|
||||
HostName kenjim-mbm.home.arpa
|
||||
|
||||
Host ktaas
|
||||
HostName kenjim-taas.qengk8.juniper.net
|
||||
|
||||
Host ttqc-shell
|
||||
HostName ttqc-shell012.juniper.net
|
||||
|
||||
Host ktq
|
||||
HostName kenjim-temp.qengk8.juniper.net
|
||||
|
||||
Host ktb
|
||||
HostName kenjim-temp.bengk8.juniper.net
|
||||
|
||||
Host kold
|
||||
HostName etqc-kenjim-01.juniper.net
|
||||
|
||||
|
||||
# Paul's machine in labdmz
|
||||
Host p
|
||||
HostName etqc-pms-02.juniper.net
|
||||
DynamicForward 3140
|
||||
|
||||
|
||||
# Quincy K8 Dev Server
|
||||
Host k8dev
|
||||
HostName engtech-dev-01.juniper.net
|
||||
#ProxyJump engdmz
|
||||
DynamicForward 3132
|
||||
# For aws S3 command
|
||||
LocalForward 8889 qnc-engdata5vs3.juniper.net:80
|
||||
|
||||
Host ttqc-shell005
|
||||
HostName ttqc-shell005
|
||||
ProxyJump engdmz
|
||||
|
||||
|
||||
Host router
|
||||
User root
|
||||
HostName 172.27.0.254
|
||||
|
||||
Host bar
|
||||
User root
|
||||
HostName bar.kenjim.com
|
||||
DynamicForward 3128
|
||||
Port 22
|
||||
Compression yes
|
||||
ServerAliveInterval 540
|
||||
|
||||
Host akira
|
||||
HostName lair.kenjim.com
|
||||
Port 11722
|
||||
#RemoteForward 11522 localhost:22
|
||||
ForwardAgent yes
|
||||
ForwardX11 yes
|
||||
Compression yes
|
||||
IdentityFile /export/kenjim/.ssh/juniper_kenjim_rsa_id
|
||||
# for VNCing to home system
|
||||
#LocalForward 55900 localhost:5900
|
||||
#LocalForward 53389 t41xp:3389
|
||||
ServerAliveInterval 540
|
||||
|
||||
|
||||
Host akira-mt
|
||||
HostName 172.27.0.11
|
||||
#RemoteForward 11522 localhost:22
|
||||
#ForwardAgent yes
|
||||
#ForwardX11 yes
|
||||
#Compression yes
|
||||
#IdentityFile /export/kenjim/.ssh/juniper_kenjim_rsa_id
|
||||
# for VNCing to home system
|
||||
#LocalForward 55900 localhost:5900
|
||||
#LocalForward 53389 t41xp:3389
|
||||
#ServerAliveInterval 540
|
||||
|
||||
# Port forwarded through home router
|
||||
Host lair-t430-vm
|
||||
HostName lair.kenjim.com
|
||||
Port 11922
|
||||
#RemoteForward 11522 localhost:22
|
||||
ForwardAgent yes
|
||||
#ForwardX11 yes
|
||||
Compression yes
|
||||
#IdentityFile /export/kenjim/.ssh/juniper_kenjim_rsa_id
|
||||
# for VNCing to home system
|
||||
#LocalForward 55900 localhost:5900
|
||||
#LocalForward 53389 t41xp:3389
|
||||
#ServerAliveInterval 540
|
||||
|
||||
# This is for connecting from kenjim-lnx
|
||||
Host mbp
|
||||
HostName 192.168.0.100
|
||||
User kenjim
|
||||
ForwardAgent yes
|
||||
|
||||
# This is for connecting to mint vm on macbook fusion
|
||||
Host kenjim-vm
|
||||
HostName 192.168.168.130
|
||||
User kenjim
|
||||
ForwardAgent yes
|
||||
|
||||
Host p-qnc-tt*
|
||||
User kenjim
|
||||
ServerAliveInterval 250
|
||||
|
||||
Host engdmz
|
||||
User kenjim
|
||||
HostName qceng-dmz-01
|
||||
Ciphers aes256-ctr,chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
|
||||
ServerAliveInterval 250
|
||||
DynamicForward 3130
|
||||
LocalForward 5433 10.47.245.41:5432
|
||||
# Engineering K8 Clusters
|
||||
LocalForward 8443 qnengapp1-vip.juniper.net:443
|
||||
LocalForward 9443 bnengapp1-vip.juniper.net:443
|
||||
LocalForward 5430 10.47.245.65:5432
|
||||
# TIM Production
|
||||
LocalForward 5450 10.47.245.53:5432
|
||||
#LocalForward 5452 etus-pgb-lrm.ttglb.juniper.net:5432
|
||||
#LocalForward 3306 engtech-metrics.juniper.net:3306
|
||||
|
||||
Host encdmz
|
||||
User kenjim
|
||||
HostName qcencl-dmz-01
|
||||
ServerAliveInterval 250
|
||||
DynamicForward 3135
|
||||
|
||||
Host labdmz
|
||||
User kenjim
|
||||
HostName ttqc-tim-sh01.juniper.net
|
||||
Ciphers aes256-ctr,chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com
|
||||
ServerAliveInterval 250
|
||||
DynamicForward 3129
|
||||
#LocalForward 22211 ttqc-tim-sh01:22
|
||||
#LocalForward 22221 ttqc-awx-01:22
|
||||
#LocalForward 22222 ttqc-awx-02:22
|
||||
#LocalForward 22231 ttqc-tim-app-01:22
|
||||
#LocalForward 22232 ttqc-tim-app-02:22
|
||||
#LocalForward 22233 ttqc-tim-app-03:22
|
||||
#LocalForward 22234 ttqc-tim-app-04:22
|
||||
#LocalForward 22235 ttqc-tim-app-05:22
|
||||
#LocalForward 22236 ttqc-tim-app-06:22
|
||||
#LocalForward 22241 ttqc-tim-utl-01:22
|
||||
#LocalForward 22242 ttqc-tim-utl-02:22
|
||||
#LocalForward 6548 etus-pgb-lrm-snap1.ttglb.juniper.net:6548
|
||||
LocalForward 6548 etus-pgb-lrm.ttglb.juniper.net:6548
|
||||
#LocalForward 5433 ttqc-testdb-01:5432
|
||||
#LocalForward 7432 p-qnc-ttdb03.juniper.net:5432
|
||||
|
||||
#Host etqc-awx-ez-*
|
||||
#Compression yes
|
||||
#ServerAliveInterval 60
|
||||
#ProxyJump engdmz
|
||||
|
||||
Host evncdmz
|
||||
User kenjim
|
||||
HostName qceng-evnc-02.juniper.net
|
||||
|
||||
# Bangalore K8 Dev Server
|
||||
Host k8devb
|
||||
HostName engtech-bdev-01
|
||||
ProxyJump engdmz
|
||||
|
||||
Host etqc-pgtools-01
|
||||
HostName etqc-pgtools-01
|
||||
ProxyJump engdmz
|
||||
|
||||
Host etbg-vmpgdb-02
|
||||
HostName etbg-vmpgdb-02
|
||||
ProxyJump engdmz
|
||||
DynamicForward 3133
|
||||
|
||||
Host etqc-tim-agt-*
|
||||
ProxyJump engdmz
|
||||
|
||||
Host pfsense
|
||||
HostName 172.27.0.1
|
||||
User root
|
||||
|
||||
Host ttqc-testdb-01
|
||||
#LocalForward 5433 localhost:5432
|
||||
ProxyJump labdmz
|
||||
|
||||
Host etqc-dlm-db-01
|
||||
HostName etqc-dlm-db-01
|
||||
User kenjim
|
||||
LocalForward 5433 localhost:5431
|
||||
|
||||
Host awx-lz-01
|
||||
HostName etqc-awx-lz-01
|
||||
BIN
.ssh/keys/id_rsa.gpg
Normal file
BIN
.ssh/keys/id_rsa.gpg
Normal file
Binary file not shown.
BIN
.ssh/keys/id_rsa.jnpr.gpg
Normal file
BIN
.ssh/keys/id_rsa.jnpr.gpg
Normal file
Binary file not shown.
BIN
.ssh/keys/id_rsa.kenjim-protected.gpg
Normal file
BIN
.ssh/keys/id_rsa.kenjim-protected.gpg
Normal file
Binary file not shown.
1
.ssh/keys/id_rsa.pub
Normal file
1
.ssh/keys/id_rsa.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDJGNwM6dI8ZNwvPKWl6VYP83l5vHUbCfbhmKVYYABgja/A0iluI2iPTutXZDwpLM8f4nCeeAONeFpX12OsFhVMc8OnpR36i6mOa3GbZJDMgt22ciESQF/m8IbHw+zdQoWC7gd9+pV7yCxVTE3NKbdHP/WWyqUt2AV51jJ0E/ZRf1KXY+YSyZVNWoah8YVfOKIRFZzJhJZ43rkl/8ZJpeZNnM28YLZ0Pfnxuk0fVpjx334rCy9oqehoG/5x3ycUtEHGo1T1AjVUYpJiCYOkh0CrFeo+L/AiJ5jI7n3OZJP157EmpZgWq9i30qnuwLJOSNugLrICkvDIY+MbUzi5MOMJ kenjim@akira-ub
|
||||
1
.ssh/keys/kenjim-backup-id.pub
Normal file
1
.ssh/keys/kenjim-backup-id.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDlTn6uLryI4sBX8AO46I8FSPmQs0tTO5yVb9ZMn3VGK4B6CstcGU1CSykubnV+EzT/FNfwsYaER+u/uIIUHUSQNkQzwDgU4m6zSuCqYGMORq85e2JtvcEn3nH944hEBtOyza2cmxi241npsfskb3c7yDZ3VTNwOjDy7fSZ+QpbWnjhn/POh1MgkzuOdOWCeTXfcphLnu442OS5x9g6/44+tWynIotjpbt822H1pgnh7QmmygfHG214N/0TzpjQsY0t0aV9POSNO09dZvoVOw+DxPDq4HW0sBV0Pfu6YhCuTuYSskZVzyxaef/HrnZ1nMmMBswYImELJab0sDCMNQm9ZJUtXUT0pRrnH4beE4owvIh7g5NKcFQR0kfd6cWz1WJGSKW3iOoXx8zZxWzuKaixQEl9F+tz01N8N4i3Td37sic1lVa2zc+h4yjKMuv3lXNOisvWhWbW7yUujT69WrI89/96z8CQ+96APCoppI6xuez6IFyxFkSYz9fx5k0tQ+E= kenjim@kenjim-mbp
|
||||
1
.ssh/keys/kenjim-testtool-futsuu.pub
Normal file
1
.ssh/keys/kenjim-testtool-futsuu.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCxodjkxzlFCxYRzDkoxN1NHnQTc9WhiovufEuciR/I85n5JWJ/EnN6V5UdXSNnnvkaHdn9F7wZS2+wdg6qyuMffJwVHsx7yhqRs4s37d7RNu3VHpKpCr6cWEyLUTpC3vOoIY4vGC7ruX3Y96hGRNR0C6h6jUS/LabBmZq98bXumgjRvomw6Vaa7teLI5t06yA9AvrzzSB9g6IeyzciBcG+i8LHmwb3UbVfht9l88TMo2joNViqapDOm/Xq8EEONeNY52c80SmEvF4NaN0oT3bqtXLKavD95rTXmDC1bJedRBatYR1fRxvqCJ3QO4RBDYhmJsKTosX2GPTfoB/21bekzTvRi+WwBVWodAF6TD9atY4AUofxH+XL9j58d070fBQTOcYFUaRuMVn+477OVJlHcrXjKusd8/Y0DK7GlrcEp8cU480OkGzKpKG6XYzs3Cl9+3Gg0tpw5IEDI4Xt2oIlRhNDVIOeem48wSc32nbHgc/kxiJx1opHkONmQtzSg+c= kenjim@kenjim-m16
|
||||
1
.ssh/keys/testtool-awx-ssh-key.pub
Normal file
1
.ssh/keys/testtool-awx-ssh-key.pub
Normal file
@@ -0,0 +1 @@
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDtasZMNQR0QoGvLTgfoj/SDfQ2Ob4GTQNbtv5iSCX6mN9/hRH8jc0j8chS50RDQdB6IQfT67C+7Tr4WR2idRW9N9M4o8h6/vmyMaYk7rwjEL+tTnS26ArgTy0mAKm+MpBz2q5J96wRRBCusrH9pONbPrEOYa9iOE6MosQlkYM9gHDqRQcuL4nIOp1Oiw5RjKm0ZQ77lrPPpDXN++i0RBJb7GikHdDa5GjMol2BBoswgAcKFzXYZljIe+RoMhZRWGbzSaO0QwfhWHwmSFr1kmLu2NfSInsQ6IeTNY7DtfOUZushhssEljvXIe3ZRKcImHOgNwm0pZsT/ZRWNBa/k29F testtool-awx-key
|
||||
16
.ssh/known_hosts
Normal file
16
.ssh/known_hosts
Normal file
@@ -0,0 +1,16 @@
|
||||
kenjim-lnx ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC20Jm+3OIYp7bnQnydjnDPPzQBiC20M41AIwy60No5FVCviAfzvoYiaMd7J2DG7Yr3OEO+T6UQI8JVkcYdgHxKBD5OywUKY00V+XnKbPMwIFjOxCeFLzL3HKYtsgy4SE6e0BB13GZ0Mw0L/YNX2D3zm12vRpBQjg/KM9W7v0nDJvwJCF/qKIqhb/R+2652TAQcvEObUXKwvxK7HnTX1oFxyQ7eA0nAfU1r4Sk2603r6StptFy2LjM8+JUgCKQU1Q/vwC7IXEcl1JiwxCyIYzWKlkQpOzdzArwreyMj1bxJZU8djwqrsIMVce1TBnuttXxHbBsGtVXvxHpiCX7BIept
|
||||
172.21.16.87 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC20Jm+3OIYp7bnQnydjnDPPzQBiC20M41AIwy60No5FVCviAfzvoYiaMd7J2DG7Yr3OEO+T6UQI8JVkcYdgHxKBD5OywUKY00V+XnKbPMwIFjOxCeFLzL3HKYtsgy4SE6e0BB13GZ0Mw0L/YNX2D3zm12vRpBQjg/KM9W7v0nDJvwJCF/qKIqhb/R+2652TAQcvEObUXKwvxK7HnTX1oFxyQ7eA0nAfU1r4Sk2603r6StptFy2LjM8+JUgCKQU1Q/vwC7IXEcl1JiwxCyIYzWKlkQpOzdzArwreyMj1bxJZU8djwqrsIMVce1TBnuttXxHbBsGtVXvxHpiCX7BIept
|
||||
ace.kenjim.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCoxcHNz6bIus6udT265ukz/DvyVcxGdjmMUDvR/KzVOF5r0y49PTsFAn3JM5UsxNQuE8mOMa4RI+0dK65s8VcEjI6KWLSUzGuunPbyxu7n28h3QwiON2kRXTwBrC43GXoo8DA7O8/iPu0vgSWxa54h9vU92q3jL/vRZ0JZj6OhuGWlVVFi6n5mc1pebRQu+7fivMt2O7DibxKIgfQ4BFWtEkWZGidtmWXxshVTKdiM6hQyODgJLuxyx9unCO8W1wns1JH+WFVuR+essrszG2ESyq/D7UkqckW0RiR/yrbrqgnv/MbREMa6hHU14QGwrspyhYu3c1d30UQ3h8bBQhdD
|
||||
216.241.98.198 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCoxcHNz6bIus6udT265ukz/DvyVcxGdjmMUDvR/KzVOF5r0y49PTsFAn3JM5UsxNQuE8mOMa4RI+0dK65s8VcEjI6KWLSUzGuunPbyxu7n28h3QwiON2kRXTwBrC43GXoo8DA7O8/iPu0vgSWxa54h9vU92q3jL/vRZ0JZj6OhuGWlVVFi6n5mc1pebRQu+7fivMt2O7DibxKIgfQ4BFWtEkWZGidtmWXxshVTKdiM6hQyODgJLuxyx9unCO8W1wns1JH+WFVuR+essrszG2ESyq/D7UkqckW0RiR/yrbrqgnv/MbREMa6hHU14QGwrspyhYu3c1d30UQ3h8bBQhdD
|
||||
kenjim.englab.juniper.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2gTGBv0gmUO0zfFo5VRFsjQ4mTvADMMuchP22C0RyrOrwvTzO4fuJUnU3B3526IGjyszoHPyxTmHGRIlV1DrkO8CjeGCAPKotNMC9c7A08oxgc99+zqJuLAJnlEyoXsWXTZr6PO0oNTmS5wOb7FHRLaQKjkYY6ytjrdzIketvt40KEXw05oE4I+aeOCAH/Zl4xpqe8iUfT4TDKjdB9g5bmxjA8gr9xAZOSOUdzguHSwqxm/6iN2KX4/VmI0HsVQ6jJ10JdbDvuWG82qgtatjYcxfsfolKSEdXAkl6yGPbcLAvi8UpiB5iXPFdOe45QAHGOPt0FcAVJhEyx7OdQ+DTQ==
|
||||
192.168.186.120 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2gTGBv0gmUO0zfFo5VRFsjQ4mTvADMMuchP22C0RyrOrwvTzO4fuJUnU3B3526IGjyszoHPyxTmHGRIlV1DrkO8CjeGCAPKotNMC9c7A08oxgc99+zqJuLAJnlEyoXsWXTZr6PO0oNTmS5wOb7FHRLaQKjkYY6ytjrdzIketvt40KEXw05oE4I+aeOCAH/Zl4xpqe8iUfT4TDKjdB9g5bmxjA8gr9xAZOSOUdzguHSwqxm/6iN2KX4/VmI0HsVQ6jJ10JdbDvuWG82qgtatjYcxfsfolKSEdXAkl6yGPbcLAvi8UpiB5iXPFdOe45QAHGOPt0FcAVJhEyx7OdQ+DTQ==
|
||||
ttsv-db-01 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtzrCQYyzWDmWV83/wKvsjdX5YlpWybUuuPeGihaoBW0vmo+qd9osNXOrE6h+rTCZcdFdDD7SdXYE8LiDEAqXAa8yIzsD6KtiVrYdsELYnXOP5jYPmi57TyRRhEsfIUNkji1yPPzixQoNQx63ehyv/i7EpV6YbtjXjJMihnrq7ipWQvHvubgwjLiHCnpm1Ie7TpQZZruhQdXOHnyhxisZG6Yc4MKXwd0cuIPgVDq0hOsC3++ouEU15hoepxWPFYKL76JIb0pnALStl8y3IhBDQbFiFXBWPiIw8fYHzDtFeX2Q6WMncoq7+aOeTvEIgEdI1j7XLjtbh+dfhRE5l7muYQ==
|
||||
172.17.28.151 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtzrCQYyzWDmWV83/wKvsjdX5YlpWybUuuPeGihaoBW0vmo+qd9osNXOrE6h+rTCZcdFdDD7SdXYE8LiDEAqXAa8yIzsD6KtiVrYdsELYnXOP5jYPmi57TyRRhEsfIUNkji1yPPzixQoNQx63ehyv/i7EpV6YbtjXjJMihnrq7ipWQvHvubgwjLiHCnpm1Ie7TpQZZruhQdXOHnyhxisZG6Yc4MKXwd0cuIPgVDq0hOsC3++ouEU15hoepxWPFYKL76JIb0pnALStl8y3IhBDQbFiFXBWPiIw8fYHzDtFeX2Q6WMncoq7+aOeTvEIgEdI1j7XLjtbh+dfhRE5l7muYQ==
|
||||
bng-tt-db01 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA636YWeKfI0e9lkzUiwYagKJtA6WAYB6Yu1prTJ70uStY5/Jh0jx/eTKz9I3UkzucHc4HpHo/rib6BMO+qAHtEcn2ZJTvTO+QvWPO8Es6bU3tIxuIhL1sjFZfZL8HFS25udv8++7FZ/mALnoCDdyMGN16tRMrmPdW3WB9j3xPfbD231/jEj7ArQSc61YTF5TuTSh0e+bd4T4NY8QZ4sKHv86GbryT5XIbx4sm37dzI+F66MXCa90xPfujqRhgZ9Lmj32I6plKjbwVaGc8/12lzcZcnhMO9TiuLts81wSYBGg3+W96keyZNV+SaVaRqQYdTq97e2KGiAHYidlNIBS9pQ==
|
||||
10.212.163.154 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA636YWeKfI0e9lkzUiwYagKJtA6WAYB6Yu1prTJ70uStY5/Jh0jx/eTKz9I3UkzucHc4HpHo/rib6BMO+qAHtEcn2ZJTvTO+QvWPO8Es6bU3tIxuIhL1sjFZfZL8HFS25udv8++7FZ/mALnoCDdyMGN16tRMrmPdW3WB9j3xPfbD231/jEj7ArQSc61YTF5TuTSh0e+bd4T4NY8QZ4sKHv86GbryT5XIbx4sm37dzI+F66MXCa90xPfujqRhgZ9Lmj32I6plKjbwVaGc8/12lzcZcnhMO9TiuLts81wSYBGg3+W96keyZNV+SaVaRqQYdTq97e2KGiAHYidlNIBS9pQ==
|
||||
adp-www-01.englab.juniper.net ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2gTGBv0gmUO0zfFo5VRFsjQ4mTvADMMuchP22C0RyrOrwvTzO4fuJUnU3B3526IGjyszoHPyxTmHGRIlV1DrkO8CjeGCAPKotNMC9c7A08oxgc99+zqJuLAJnlEyoXsWXTZr6PO0oNTmS5wOb7FHRLaQKjkYY6ytjrdzIketvt40KEXw05oE4I+aeOCAH/Zl4xpqe8iUfT4TDKjdB9g5bmxjA8gr9xAZOSOUdzguHSwqxm/6iN2KX4/VmI0HsVQ6jJ10JdbDvuWG82qgtatjYcxfsfolKSEdXAkl6yGPbcLAvi8UpiB5iXPFdOe45QAHGOPt0FcAVJhEyx7OdQ+DTQ==
|
||||
192.168.186.238 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2gTGBv0gmUO0zfFo5VRFsjQ4mTvADMMuchP22C0RyrOrwvTzO4fuJUnU3B3526IGjyszoHPyxTmHGRIlV1DrkO8CjeGCAPKotNMC9c7A08oxgc99+zqJuLAJnlEyoXsWXTZr6PO0oNTmS5wOb7FHRLaQKjkYY6ytjrdzIketvt40KEXw05oE4I+aeOCAH/Zl4xpqe8iUfT4TDKjdB9g5bmxjA8gr9xAZOSOUdzguHSwqxm/6iN2KX4/VmI0HsVQ6jJ10JdbDvuWG82qgtatjYcxfsfolKSEdXAkl6yGPbcLAvi8UpiB5iXPFdOe45QAHGOPt0FcAVJhEyx7OdQ+DTQ==
|
||||
ttsv-shell11 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2gTGBv0gmUO0zfFo5VRFsjQ4mTvADMMuchP22C0RyrOrwvTzO4fuJUnU3B3526IGjyszoHPyxTmHGRIlV1DrkO8CjeGCAPKotNMC9c7A08oxgc99+zqJuLAJnlEyoXsWXTZr6PO0oNTmS5wOb7FHRLaQKjkYY6ytjrdzIketvt40KEXw05oE4I+aeOCAH/Zl4xpqe8iUfT4TDKjdB9g5bmxjA8gr9xAZOSOUdzguHSwqxm/6iN2KX4/VmI0HsVQ6jJ10JdbDvuWG82qgtatjYcxfsfolKSEdXAkl6yGPbcLAvi8UpiB5iXPFdOe45QAHGOPt0FcAVJhEyx7OdQ+DTQ==
|
||||
172.17.38.151 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2gTGBv0gmUO0zfFo5VRFsjQ4mTvADMMuchP22C0RyrOrwvTzO4fuJUnU3B3526IGjyszoHPyxTmHGRIlV1DrkO8CjeGCAPKotNMC9c7A08oxgc99+zqJuLAJnlEyoXsWXTZr6PO0oNTmS5wOb7FHRLaQKjkYY6ytjrdzIketvt40KEXw05oE4I+aeOCAH/Zl4xpqe8iUfT4TDKjdB9g5bmxjA8gr9xAZOSOUdzguHSwqxm/6iN2KX4/VmI0HsVQ6jJ10JdbDvuWG82qgtatjYcxfsfolKSEdXAkl6yGPbcLAvi8UpiB5iXPFdOe45QAHGOPt0FcAVJhEyx7OdQ+DTQ==
|
||||
127.0.0.1 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDqMmo6L9Q5prZ28h8QzyNwmWTu1Xx2lEwVfbpyY0YwzMU6MB8bb8e/zYMfmSTmh4bIxjJIiGtyJHLPuJnXEG08nl/4fJmiAPxUOJzDDp4f5xojrnDc2+4q8vHxQ8EWSuesJf7wUR93H8tm7z6GwADQCk40MGb2BHI0XpBxoZHMPZnyaPLFBn3n76O2B9a5manhJH8rHJt5XaASm47eH9YK4CV+HcSBP13lLFVZg2S6Qcb57sq3ctzRkk4Pp9/LgFcgMwAhPTaNTdoESUozIOfoy/kdPjCYm2QE2F2u//xrseyaKqK/ZZxE8Ho/CCsov/3tQI/UPVXSNe0xXljejxid
|
||||
ttsv-lrm-apps-01 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAlhhVZyBk526hHZ8F1rHK7IhxevyXRP8Bwui3PvDC32LVXA34L/Adcg5XLLK2tItbMTiU9pvuLYunoqo2wVABPuDEXNzJJO3LF2lE8HJHC4989Ot519DJw8HGxtDVvhTHOhQSBXx1uaRgqsv5ipMB6oHZzVw8AhzbfFayWVN0EXd4EEYUIPWjt8KglTpboInGWZ0P2B67WXffVwzQIrJ0jkimn+Soxq8Ah4f6V33fNGx0wXZ5jMtmsIg+SzgdPtNlmcnZDqdXBVij/oUy+4r7Z07uD/Gs8EV6QoGTElcr2RJ66VzV6rlr5Hre4YboNAE3ChF9OmH7MZKW5PjXvvZ3cQ==
|
||||
67
install.sh
Executable file
67
install.sh
Executable file
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env bash
|
||||
# Portable dotfiles restore script — generated by dotfiles_manager.sh
|
||||
# Run on a new machine after: git clone http://172.27.0.35:3000/kenjim/dotfiles ~/dotfiles
|
||||
set -euo pipefail
|
||||
|
||||
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
MANIFEST="$DOTFILES_DIR/.dotfiles_manifest"
|
||||
BACKUP_DIR="$HOME/.dotfiles_backup/$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
echo "=== Restoring dotfiles from $DOTFILES_DIR ==="
|
||||
|
||||
[ -f "$MANIFEST" ] || { echo "No manifest found."; exit 1; }
|
||||
|
||||
while IFS= read -r rel || [ -n "$rel" ]; do
|
||||
[ -z "$rel" ] && continue
|
||||
src="$DOTFILES_DIR/$rel"
|
||||
dest="$HOME/$rel"
|
||||
[ -e "$src" ] || { echo " MISSING: $src"; continue; }
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
if [ -e "$dest" ] && [ ! -L "$dest" ]; then
|
||||
mkdir -p "$BACKUP_DIR/$(dirname "$rel")"
|
||||
cp -a "$dest" "$BACKUP_DIR/$rel"
|
||||
echo " Backed up: $dest"
|
||||
rm -f "$dest"
|
||||
elif [ -L "$dest" ]; then
|
||||
rm "$dest"
|
||||
fi
|
||||
[[ "$rel" == .ssh/* ]] && chmod 600 "$src" 2>/dev/null || true
|
||||
ln -sf "$src" "$dest"
|
||||
echo " Linked: ~/$rel"
|
||||
done < "$MANIFEST"
|
||||
|
||||
echo
|
||||
echo "✓ Dotfiles symlinks applied."
|
||||
|
||||
# ---- Machine-local config ----
|
||||
# Write a minimal .bashrc.local if one does not exist (user edits profile)
|
||||
if [ ! -f "$HOME/.bashrc.local" ]; then
|
||||
echo
|
||||
echo "Select profile for this machine:"
|
||||
echo " [1] work — OneDrive"
|
||||
echo " [2] personal — ProtonDrive + GoogleDrive"
|
||||
read -r -p "Profile (1/2) [2]: " _choice
|
||||
_profile="personal"
|
||||
[[ "${_choice:-2}" == "1" ]] && _profile="work"
|
||||
# setup script lives inside dotfiles now: dotfiles/scripts/setup_enterprise_ai_bash.sh
|
||||
if [ -f "$DOTFILES_DIR/scripts/setup_enterprise_ai_bash.sh" ]; then
|
||||
MACHINE_PROFILE="$_profile" bash "$DOTFILES_DIR/scripts/setup_enterprise_ai_bash.sh"
|
||||
else
|
||||
echo " ⚠ Could not find setup_enterprise_ai_bash.sh — create ~/.bashrc.local manually."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---- SSH key decrypt ----
|
||||
gpg_count=$(find "$DOTFILES_DIR/.ssh/keys" -maxdepth 1 -name '*.gpg' 2>/dev/null | wc -l | tr -d ' ')
|
||||
if [[ "$gpg_count" -gt 0 ]]; then
|
||||
echo
|
||||
echo "Found $gpg_count GPG-encrypted SSH key(s) in dotfiles."
|
||||
read -r -p "Decrypt SSH private keys now? (y/n): " _dec
|
||||
if [[ "$_dec" == [yY] ]]; then
|
||||
# dotfiles_manager.sh lives inside dotfiles now: dotfiles/scripts/dotfiles_manager.sh
|
||||
bash "$DOTFILES_DIR/scripts/dotfiles_manager.sh" ssh-import
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "✓ Restore complete. Run: source ~/.bash_profile"
|
||||
26
scripts/bootstrap.sh
Executable file
26
scripts/bootstrap.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env bash
|
||||
# bootstrap.sh — Restore Enterprise AI Environment on this machine
|
||||
set -euo pipefail
|
||||
|
||||
echo "🔄 Restoring Enterprise AI Environment..."
|
||||
|
||||
# Reload shell config
|
||||
# shellcheck disable=SC1091
|
||||
[ -f ~/.bashrc ] && source ~/.bashrc
|
||||
[ -f ~/.bash_profile ] && source ~/.bash_profile
|
||||
|
||||
echo " WORKSPACE : ${WORKSPACE:-not set}"
|
||||
echo " DATA_ROOT : ${DATA_ROOT:-not set}"
|
||||
echo " MODEL_ROOT : ${MODEL_ROOT:-not set}"
|
||||
echo
|
||||
|
||||
# Sync latest dotfiles from git server
|
||||
if [ -f "$HOME/scripts/dotfiles_manager.sh" ]; then
|
||||
echo "📦 Syncing dotfiles..."
|
||||
bash "$HOME/scripts/dotfiles_manager.sh" sync
|
||||
else
|
||||
echo "⚠️ dotfiles_manager.sh not found — run setup_enterprise_ai_bash.sh first."
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "✅ Bootstrap complete."
|
||||
958
scripts/dotfiles_manager.sh
Executable file
958
scripts/dotfiles_manager.sh
Executable file
@@ -0,0 +1,958 @@
|
||||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# dotfiles_manager.sh — Centralized Dotfiles Management
|
||||
#
|
||||
# Manages shell configs, SSH config, and editor settings via a git repo
|
||||
# hosted on your local Gitea server.
|
||||
#
|
||||
# Remote: http://172.27.0.35:3000/kenjim/dotfiles
|
||||
# Strategy: Files live in ~/dotfiles/, HOME locations are symlinked to them.
|
||||
#
|
||||
# Usage:
|
||||
# ./dotfiles_manager.sh <command> [args]
|
||||
#
|
||||
# Commands:
|
||||
# init Clone remote repo (or init + set remote if new machine)
|
||||
# add <file> Track a file: move it into ~/dotfiles, create symlink back
|
||||
# remove <file> Untrack: restore file to HOME, remove symlink record
|
||||
# install Reapply all symlinks (use on a new machine after cloning)
|
||||
# sync Pull latest from remote, reapply any new symlinks
|
||||
# push [message] Stage all changes, commit, and push to remote
|
||||
# status Show tracked files and their symlink health
|
||||
# list Alias for status
|
||||
# ssh-setup Interactively add SSH config and optionally keys
|
||||
# ssh-export GPG-encrypt private keys → dotfiles/.ssh/keys/*.gpg
|
||||
# ssh-import Decrypt GPG-encrypted keys from dotfiles to ~/.ssh/
|
||||
# remote-bootstrap SSH into another machine and run full setup
|
||||
# help Show this message
|
||||
#
|
||||
# File layout inside ~/dotfiles/:
|
||||
# .bashrc → symlinked from ~/.bashrc
|
||||
# .bash_profile → symlinked from ~/.bash_profile
|
||||
# .bash_aliases → symlinked from ~/.bash_aliases
|
||||
# .gitconfig → symlinked from ~/.gitconfig
|
||||
# .ssh/config → symlinked from ~/.ssh/config
|
||||
# .ssh/keys/ → encrypted or public-only keys (see ssh-setup)
|
||||
# .vimrc → symlinked from ~/.vimrc
|
||||
# .tmux.conf → symlinked from ~/.tmux.conf
|
||||
# .inputrc → symlinked from ~/.inputrc
|
||||
# .dotfiles_manifest internal list of tracked HOME paths
|
||||
# install.sh portable restore script (run on new machines)
|
||||
# README.md documentation
|
||||
# =============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# CONFIG — override with env vars if needed
|
||||
# -----------------------------------------------------------------------
|
||||
DOTFILES_DIR="${DOTFILES_DIR:-$HOME/dotfiles}"
|
||||
DOTFILES_REMOTE="${DOTFILES_REMOTE:-http://172.27.0.35:3000/kenjim/dotfiles}"
|
||||
MANIFEST="$DOTFILES_DIR/.dotfiles_manifest"
|
||||
BACKUP_DIR="$HOME/.dotfiles_backup/$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COLORS
|
||||
# -----------------------------------------------------------------------
|
||||
RED='\033[0;31m'; YELLOW='\033[1;33m'; GREEN='\033[0;32m'
|
||||
CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m'
|
||||
|
||||
info() { echo -e "${CYAN}[dotfiles]${RESET} $*"; }
|
||||
success() { echo -e "${GREEN}[dotfiles]${RESET} ✓ $*"; }
|
||||
warn() { echo -e "${YELLOW}[dotfiles]${RESET} ⚠ $*"; }
|
||||
error() { echo -e "${RED}[dotfiles]${RESET} ✗ $*" >&2; }
|
||||
bold() { echo -e "${BOLD}$*${RESET}"; }
|
||||
die() { error "$*"; exit 1; }
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# HELPERS
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
# Resolve the relative path stored in manifest → absolute HOME path
|
||||
manifest_to_home() {
|
||||
# entries are stored relative to HOME, e.g. ".bashrc" or ".ssh/config"
|
||||
echo "$HOME/$1"
|
||||
}
|
||||
|
||||
# Compute the path inside dotfiles/ for a given HOME path
|
||||
home_to_dotfiles() {
|
||||
local home_path="$1"
|
||||
local rel="${home_path#"$HOME/"}"
|
||||
echo "$DOTFILES_DIR/$rel"
|
||||
}
|
||||
|
||||
# Add entry to manifest (deduplicates)
|
||||
manifest_add() {
|
||||
local rel="${1#"$HOME/"}"
|
||||
mkdir -p "$(dirname "$MANIFEST")"
|
||||
touch "$MANIFEST"
|
||||
grep -qxF "$rel" "$MANIFEST" || echo "$rel" >> "$MANIFEST"
|
||||
# Keep manifest sorted for clean diffs
|
||||
sort -o "$MANIFEST" "$MANIFEST"
|
||||
}
|
||||
|
||||
# Remove entry from manifest
|
||||
manifest_remove() {
|
||||
local rel="${1#"$HOME/"}"
|
||||
[ -f "$MANIFEST" ] && sed -i.bak "/^${rel//\//\\/}$/d" "$MANIFEST" && rm -f "${MANIFEST}.bak"
|
||||
}
|
||||
|
||||
# Check if dotfiles dir is a git repo
|
||||
is_git_repo() {
|
||||
git -C "$DOTFILES_DIR" rev-parse --git-dir &>/dev/null
|
||||
}
|
||||
|
||||
# Git command scoped to dotfiles dir
|
||||
dgit() {
|
||||
git -C "$DOTFILES_DIR" "$@"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: init
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_init() {
|
||||
bold "=== Initializing dotfiles repo ==="
|
||||
info "Local path : $DOTFILES_DIR"
|
||||
info "Remote : $DOTFILES_REMOTE"
|
||||
echo
|
||||
|
||||
# Check if remote is reachable
|
||||
if curl --silent --max-time 5 --output /dev/null "$DOTFILES_REMOTE" 2>/dev/null; then
|
||||
info "Remote server is reachable."
|
||||
else
|
||||
warn "Remote server not reachable right now. Will init locally and set remote for later."
|
||||
fi
|
||||
|
||||
if [ -d "$DOTFILES_DIR/.git" ]; then
|
||||
warn "Dotfiles repo already exists at $DOTFILES_DIR"
|
||||
# Ensure remote is set correctly
|
||||
if ! dgit remote get-url origin &>/dev/null; then
|
||||
dgit remote add origin "$DOTFILES_REMOTE"
|
||||
success "Remote 'origin' added: $DOTFILES_REMOTE"
|
||||
else
|
||||
local current_remote
|
||||
current_remote=$(dgit remote get-url origin)
|
||||
if [ "$current_remote" != "$DOTFILES_REMOTE" ]; then
|
||||
dgit remote set-url origin "$DOTFILES_REMOTE"
|
||||
success "Remote updated to: $DOTFILES_REMOTE"
|
||||
else
|
||||
info "Remote already set correctly."
|
||||
fi
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
# Try to clone first
|
||||
if curl --silent --max-time 5 --output /dev/null "$DOTFILES_REMOTE" 2>/dev/null; then
|
||||
info "Attempting to clone from remote..."
|
||||
if git clone "$DOTFILES_REMOTE" "$DOTFILES_DIR" 2>/dev/null; then
|
||||
success "Cloned from $DOTFILES_REMOTE"
|
||||
info "Run './dotfiles_manager.sh install' to apply symlinks."
|
||||
return
|
||||
else
|
||||
warn "Clone failed (repo may be empty). Initializing locally instead."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Init fresh repo
|
||||
mkdir -p "$DOTFILES_DIR"
|
||||
cd "$DOTFILES_DIR"
|
||||
git init
|
||||
dgit remote add origin "$DOTFILES_REMOTE"
|
||||
|
||||
# Create .gitignore — protect private SSH keys by default
|
||||
cat > "$DOTFILES_DIR/.gitignore" <<'GITIGNORE'
|
||||
# macOS
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
|
||||
# Backup artifacts
|
||||
*.bak
|
||||
*.orig
|
||||
|
||||
# SSH private keys — never commit unencrypted private keys
|
||||
# Remove a line below only if you store GPG-encrypted versions
|
||||
.ssh/id_rsa
|
||||
.ssh/id_ed25519
|
||||
.ssh/id_ecdsa
|
||||
.ssh/id_dsa
|
||||
.ssh/keys/*_rsa
|
||||
.ssh/keys/*_ed25519
|
||||
.ssh/keys/*_ecdsa
|
||||
.ssh/keys/*.pem
|
||||
# Public keys and config are fine
|
||||
!.ssh/*.pub
|
||||
!.ssh/keys/*.pub
|
||||
!.ssh/config
|
||||
!.ssh/known_hosts
|
||||
|
||||
# GPG-encrypted private key backups are safe to commit
|
||||
!.ssh/keys/*.gpg
|
||||
|
||||
# Secrets / tokens — never commit
|
||||
.env
|
||||
.env.*
|
||||
*.token
|
||||
*.secrets
|
||||
vault/
|
||||
|
||||
# Machine-local overrides — never commit (written by setup_enterprise_ai_bash.sh)
|
||||
.bashrc.local
|
||||
.bash_profile.local
|
||||
GITIGNORE
|
||||
|
||||
# Seed README
|
||||
cat > "$DOTFILES_DIR/README.md" <<MARKDOWN
|
||||
# dotfiles
|
||||
|
||||
Centralized configuration management for $(whoami)@$(hostname -s).
|
||||
|
||||
## Remote
|
||||
\`$DOTFILES_REMOTE\`
|
||||
|
||||
## Structure
|
||||
\`\`\`
|
||||
dotfiles/
|
||||
├── .bashrc → ~/.bashrc
|
||||
├── .bash_profile → ~/.bash_profile
|
||||
├── .bash_aliases → ~/.bash_aliases
|
||||
├── .gitconfig → ~/.gitconfig
|
||||
├── .ssh/
|
||||
│ ├── config → ~/.ssh/config
|
||||
│ └── keys/ (public keys + GPG-encrypted private keys)
|
||||
├── scripts/
|
||||
│ ├── dotfiles_manager.sh → ~/scripts/dotfiles_manager.sh
|
||||
│ ├── setup_enterprise_ai_bash.sh → ~/scripts/setup_enterprise_ai_bash.sh
|
||||
│ └── bootstrap.sh → ~/scripts/bootstrap.sh
|
||||
├── .vimrc → ~/.vimrc
|
||||
├── .dotfiles_manifest (list of managed HOME paths)
|
||||
├── install.sh (new-machine restore script)
|
||||
└── README.md
|
||||
\`\`\`
|
||||
|
||||
## Quick start — restore on a new machine
|
||||
\`\`\`bash
|
||||
git clone $DOTFILES_REMOTE ~/dotfiles
|
||||
bash ~/dotfiles/install.sh
|
||||
\`\`\`
|
||||
|
||||
## Managed files
|
||||
<!-- auto-updated by dotfiles_manager.sh status -->
|
||||
MARKDOWN
|
||||
|
||||
touch "$MANIFEST"
|
||||
|
||||
dgit add .
|
||||
dgit commit -m "chore: initial dotfiles skeleton"
|
||||
|
||||
success "Dotfiles repo initialized at $DOTFILES_DIR"
|
||||
info "Push when ready: ./dotfiles_manager.sh push 'initial commit'"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: add
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_add() {
|
||||
[ $# -ge 1 ] || die "Usage: add <file-or-dir> [<file-or-dir> ...]"
|
||||
|
||||
for target in "$@"; do
|
||||
# Expand ~
|
||||
target="${target/#\~/$HOME}"
|
||||
target="$(realpath -m "$target" 2>/dev/null || echo "$target")"
|
||||
|
||||
if [ ! -e "$target" ] && [ ! -L "$target" ]; then
|
||||
warn "Skipping '$target': does not exist."
|
||||
continue
|
||||
fi
|
||||
|
||||
local rel="${target#"$HOME/"}"
|
||||
local dest="$DOTFILES_DIR/$rel"
|
||||
|
||||
if [ -L "$target" ] && [ "$(readlink "$target")" = "$dest" ]; then
|
||||
info "$rel is already tracked and symlinked."
|
||||
continue
|
||||
fi
|
||||
|
||||
# Create destination parent directories
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
|
||||
# Back up existing dotfiles destination if present and not a symlink
|
||||
if [ -e "$dest" ] && [ ! -L "$dest" ]; then
|
||||
mkdir -p "$BACKUP_DIR/$(dirname "$rel")"
|
||||
cp -a "$dest" "$BACKUP_DIR/$rel"
|
||||
warn "Backed up existing $dest → $BACKUP_DIR/$rel"
|
||||
fi
|
||||
|
||||
# Move file
|
||||
if [ -L "$target" ]; then
|
||||
# If it's already a symlink to somewhere else, copy the contents
|
||||
cp -a "$(readlink "$target")" "$dest"
|
||||
rm "$target"
|
||||
else
|
||||
mv "$target" "$dest"
|
||||
fi
|
||||
|
||||
# Create symlink
|
||||
ln -sf "$dest" "$target"
|
||||
manifest_add "$target"
|
||||
|
||||
success "Tracked: $rel\n $target → $dest"
|
||||
done
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: remove
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_remove() {
|
||||
[ $# -ge 1 ] || die "Usage: remove <file>"
|
||||
local target="$1"
|
||||
target="${target/#\~/$HOME}"
|
||||
local rel="${target#"$HOME/"}"
|
||||
local src="$DOTFILES_DIR/$rel"
|
||||
|
||||
if [ ! -e "$src" ]; then
|
||||
die "Not tracked: $rel"
|
||||
fi
|
||||
|
||||
if [ -L "$target" ]; then
|
||||
rm "$target"
|
||||
fi
|
||||
|
||||
cp -a "$src" "$target"
|
||||
manifest_remove "$target"
|
||||
success "Untracked $rel — file restored to $target"
|
||||
info "The copy in $src still exists. Remove it manually if desired."
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: install (idempotent — safe to re-run)
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_install() {
|
||||
bold "=== Applying dotfiles symlinks ==="
|
||||
[ -f "$MANIFEST" ] || { warn "Manifest empty — nothing to install."; return; }
|
||||
|
||||
local count=0 skipped=0 errors=0
|
||||
while IFS= read -r rel || [ -n "$rel" ]; do
|
||||
[ -z "$rel" ] && continue
|
||||
local src="$DOTFILES_DIR/$rel"
|
||||
local dest="$HOME/$rel"
|
||||
|
||||
if [ ! -e "$src" ]; then
|
||||
warn "Missing in dotfiles: $src — skipping."
|
||||
(( errors++ )) || true
|
||||
continue
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "$dest")"
|
||||
|
||||
if [ -L "$dest" ] && [ "$(readlink "$dest")" = "$src" ]; then
|
||||
(( skipped++ )) || true
|
||||
continue
|
||||
fi
|
||||
|
||||
# Back up conflicting file
|
||||
if [ -e "$dest" ] && [ ! -L "$dest" ]; then
|
||||
mkdir -p "$BACKUP_DIR/$(dirname "$rel")"
|
||||
cp -a "$dest" "$BACKUP_DIR/$rel"
|
||||
warn "Backed up existing $dest"
|
||||
rm -f "$dest"
|
||||
elif [ -L "$dest" ]; then
|
||||
rm "$dest"
|
||||
fi
|
||||
|
||||
# Set safe permissions for SSH files
|
||||
if [[ "$rel" == .ssh/* ]]; then
|
||||
if [ -d "$src" ]; then
|
||||
chmod 700 "$src"
|
||||
else
|
||||
chmod 600 "$src"
|
||||
fi
|
||||
fi
|
||||
|
||||
ln -sf "$src" "$dest"
|
||||
success "Linked: ~/$rel → $src"
|
||||
(( count++ )) || true
|
||||
done < "$MANIFEST"
|
||||
|
||||
echo
|
||||
bold "Install complete: $count linked, $skipped already up-to-date, $errors errors."
|
||||
|
||||
# Offer ssh-import if GPG-encrypted keys are present but private key is missing
|
||||
local gpg_count=0
|
||||
gpg_count=$(find "$DOTFILES_DIR/.ssh/keys" -maxdepth 1 -name '*.gpg' 2>/dev/null | wc -l | tr -d ' ')
|
||||
if [[ "$gpg_count" -gt 0 ]]; then
|
||||
local missing_keys=false
|
||||
for gpg_f in "$DOTFILES_DIR/.ssh/keys/"*.gpg; do
|
||||
local base_name; base_name="$(basename "${gpg_f%.gpg}")"
|
||||
[ ! -f "$HOME/.ssh/$base_name" ] && missing_keys=true && break
|
||||
done
|
||||
if $missing_keys; then
|
||||
echo
|
||||
warn "$gpg_count GPG-encrypted SSH key(s) found in dotfiles but not yet decrypted."
|
||||
read -r -p "Decrypt SSH keys now? (y/n): " _imp
|
||||
[[ "$_imp" == [yY] ]] && cmd_ssh_import
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: sync
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_sync() {
|
||||
bold "=== Syncing from remote ==="
|
||||
is_git_repo || die "Not a git repo: $DOTFILES_DIR. Run 'init' first."
|
||||
|
||||
# Stash any local changes so pull is clean
|
||||
local stashed=false
|
||||
if ! dgit diff --quiet || ! dgit diff --cached --quiet; then
|
||||
warn "Local changes detected — stashing before pull."
|
||||
dgit stash push -m "dotfiles_manager auto-stash before sync"
|
||||
stashed=true
|
||||
fi
|
||||
|
||||
dgit pull --rebase origin main 2>/dev/null || dgit pull --rebase origin master 2>/dev/null || {
|
||||
warn "Could not pull (remote unreachable or branch mismatch). Working offline."
|
||||
}
|
||||
|
||||
if $stashed; then
|
||||
dgit stash pop || warn "Stash pop had conflicts. Resolve in $DOTFILES_DIR"
|
||||
fi
|
||||
|
||||
cmd_install
|
||||
success "Sync complete."
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: push
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_push() {
|
||||
local msg="${1:-"chore: update dotfiles $(date '+%Y-%m-%d %H:%M')"}"
|
||||
bold "=== Pushing to remote ==="
|
||||
is_git_repo || die "Not a git repo. Run 'init' first."
|
||||
|
||||
dgit add --all
|
||||
|
||||
if dgit diff --cached --quiet; then
|
||||
info "Nothing to commit."
|
||||
else
|
||||
dgit commit -m "$msg"
|
||||
success "Committed: $msg"
|
||||
fi
|
||||
|
||||
# Determine default branch
|
||||
local branch
|
||||
branch=$(dgit rev-parse --abbrev-ref HEAD)
|
||||
|
||||
# Set upstream on first push if needed
|
||||
if ! dgit config "branch.$branch.remote" &>/dev/null; then
|
||||
dgit push --set-upstream origin "$branch"
|
||||
else
|
||||
dgit push origin "$branch"
|
||||
fi
|
||||
|
||||
success "Pushed to $DOTFILES_REMOTE ($branch)."
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: status
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_status() {
|
||||
bold "=== Dotfiles Status ==="
|
||||
info "Repo : $DOTFILES_DIR"
|
||||
info "Remote : $DOTFILES_REMOTE"
|
||||
echo
|
||||
|
||||
if [ ! -f "$MANIFEST" ] || [ ! -s "$MANIFEST" ]; then
|
||||
echo " (no files tracked yet — use 'add' to start)"
|
||||
return
|
||||
fi
|
||||
|
||||
printf " %-42s %s\n" "HOME PATH" "STATUS"
|
||||
printf " %-42s %s\n" "-----------------------------------------" "-------"
|
||||
|
||||
while IFS= read -r rel || [ -n "$rel" ]; do
|
||||
[ -z "$rel" ] && continue
|
||||
local home_path="$HOME/$rel"
|
||||
local src="$DOTFILES_DIR/$rel"
|
||||
local status
|
||||
|
||||
if [ ! -e "$src" ]; then
|
||||
status="${RED}MISSING in dotfiles${RESET}"
|
||||
elif [ -L "$home_path" ] && [ "$(readlink "$home_path")" = "$src" ]; then
|
||||
status="${GREEN}OK (symlinked)${RESET}"
|
||||
elif [ -e "$home_path" ] && [ ! -L "$home_path" ]; then
|
||||
status="${YELLOW}CONFLICT (real file exists at HOME)${RESET}"
|
||||
elif [ ! -e "$home_path" ]; then
|
||||
status="${YELLOW}NOT LINKED (run install)${RESET}"
|
||||
else
|
||||
status="${YELLOW}STALE SYMLINK${RESET}"
|
||||
fi
|
||||
|
||||
printf " %-42s " "~/$rel"
|
||||
echo -e "$status"
|
||||
done < "$MANIFEST"
|
||||
|
||||
echo
|
||||
if is_git_repo; then
|
||||
bold "Git status:"
|
||||
dgit status --short
|
||||
echo
|
||||
local last_commit
|
||||
last_commit=$(dgit log -1 --format="%h %s (%ar)" 2>/dev/null || echo "no commits yet")
|
||||
info "Last commit: $last_commit"
|
||||
fi
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: ssh-setup
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_ssh_setup() {
|
||||
bold "=== SSH Config & Key Management ==="
|
||||
echo
|
||||
warn "SECURITY REMINDER: Private SSH key files are in .gitignore by default."
|
||||
warn "Only ~/.ssh/config, known_hosts, and .pub files will be committed."
|
||||
warn "To store encrypted private keys, use GPG encryption first."
|
||||
echo
|
||||
|
||||
local ssh_config="$HOME/.ssh/config"
|
||||
local ssh_known="$HOME/.ssh/known_hosts"
|
||||
local dotfiles_ssh="$DOTFILES_DIR/.ssh"
|
||||
mkdir -p "$dotfiles_ssh/keys"
|
||||
chmod 700 "$dotfiles_ssh"
|
||||
|
||||
# Track ssh/config
|
||||
if [ -f "$ssh_config" ]; then
|
||||
read -r -p "Track ~/.ssh/config in dotfiles? (y/n): " yn
|
||||
if [[ "$yn" == [yY] ]]; then
|
||||
cmd_add "$ssh_config"
|
||||
fi
|
||||
else
|
||||
info "No ~/.ssh/config found. Creating a template..."
|
||||
mkdir -p "$HOME/.ssh"
|
||||
cat > "$dotfiles_ssh/config" <<'SSH_CONFIG'
|
||||
# SSH Client Configuration
|
||||
# Managed by dotfiles_manager.sh
|
||||
# See: man ssh_config
|
||||
|
||||
Host *
|
||||
ServerAliveInterval 60
|
||||
ServerAliveCountMax 3
|
||||
AddKeysToAgent yes
|
||||
IdentitiesOnly yes
|
||||
|
||||
# Example host alias:
|
||||
# Host myserver
|
||||
# HostName 192.168.1.100
|
||||
# User kenji
|
||||
# IdentityFile ~/.ssh/id_ed25519
|
||||
# Port 22
|
||||
|
||||
# Local Gitea server
|
||||
Host gitea-local
|
||||
HostName 172.27.0.35
|
||||
User git
|
||||
Port 22
|
||||
IdentitiesOnly yes
|
||||
# IdentityFile ~/.ssh/id_ed25519_gitea
|
||||
|
||||
SSH_CONFIG
|
||||
chmod 600 "$dotfiles_ssh/config"
|
||||
ln -sf "$dotfiles_ssh/config" "$HOME/.ssh/config"
|
||||
manifest_add "$HOME/.ssh/config"
|
||||
success "Created and tracked ~/.ssh/config"
|
||||
fi
|
||||
|
||||
# Track known_hosts (useful for pre-seeding new machines)
|
||||
if [ -f "$ssh_known" ]; then
|
||||
read -r -p "Track ~/.ssh/known_hosts in dotfiles? (y/n): " yn
|
||||
[[ "$yn" == [yY] ]] && cmd_add "$ssh_known"
|
||||
fi
|
||||
|
||||
# Track public keys
|
||||
local pub_keys=()
|
||||
while IFS= read -r -d '' f; do
|
||||
pub_keys+=("$f")
|
||||
done < <(find "$HOME/.ssh" -maxdepth 1 -name "*.pub" -print0 2>/dev/null)
|
||||
|
||||
if [ ${#pub_keys[@]} -gt 0 ]; then
|
||||
echo
|
||||
info "Found public keys:"
|
||||
for k in "${pub_keys[@]}"; do echo " $k"; done
|
||||
read -r -p "Copy public keys to dotfiles/.ssh/keys/? (y/n): " yn
|
||||
if [[ "$yn" == [yY] ]]; then
|
||||
for pubkey in "${pub_keys[@]}"; do
|
||||
cp "$pubkey" "$dotfiles_ssh/keys/"
|
||||
success "Copied: $(basename "$pubkey") → dotfiles/.ssh/keys/"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Offer to store encrypted private keys
|
||||
echo
|
||||
warn "Private key storage (advanced — optional):"
|
||||
info "If you want to store encrypted private key backups, use:"
|
||||
echo " gpg --symmetric --cipher-algo AES256 ~/.ssh/id_ed25519"
|
||||
echo " mv ~/.ssh/id_ed25519.gpg ~/dotfiles/.ssh/keys/"
|
||||
echo " Then amend .gitignore to allow the .gpg file."
|
||||
echo
|
||||
success "SSH setup complete."
|
||||
echo
|
||||
info "Next step: GPG-encrypt your private keys for cross-machine sharing:"
|
||||
info " dotfiles ssh-export → encrypt keys into dotfiles/.ssh/keys/*.gpg"
|
||||
info " dotfiles push → commit and push to $DOTFILES_REMOTE"
|
||||
info " dotfiles ssh-import → decrypt on any other machine after sync"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: ssh-export (GPG-encrypt private keys → dotfiles/.ssh/keys/)
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_ssh_export() {
|
||||
bold "=== Export SSH Private Keys (GPG-encrypted) ==="
|
||||
command -v gpg &>/dev/null || die "gpg not installed. Install with: brew install gnupg"
|
||||
|
||||
local dotfiles_ssh="$DOTFILES_DIR/.ssh/keys"
|
||||
mkdir -p "$dotfiles_ssh"
|
||||
|
||||
# Collect private keys (id_* files, no .pub extension, no .gpg)
|
||||
local private_keys=()
|
||||
while IFS= read -r -d '' f; do
|
||||
private_keys+=("$f")
|
||||
done < <(find "$HOME/.ssh" -maxdepth 1 -type f \
|
||||
\( -name "id_*" ! -name "*.pub" ! -name "*.gpg" \) -print0 2>/dev/null)
|
||||
|
||||
if [ ${#private_keys[@]} -eq 0 ]; then
|
||||
info "No private keys found in ~/.ssh/"
|
||||
return
|
||||
fi
|
||||
|
||||
info "Found private keys:"
|
||||
for k in "${private_keys[@]}"; do echo " $k"; done
|
||||
echo
|
||||
warn "Each key will be GPG-encrypted with a symmetric passphrase you choose."
|
||||
warn "Store this passphrase in a password manager — you need it to restore keys."
|
||||
echo
|
||||
read -r -p "Proceed? (y/n): " yn
|
||||
[[ "$yn" == [yY] ]] || return
|
||||
|
||||
for key in "${private_keys[@]}"; do
|
||||
local key_name; key_name="$(basename "$key")"
|
||||
local encrypted="$dotfiles_ssh/${key_name}.gpg"
|
||||
|
||||
if [ -f "$encrypted" ]; then
|
||||
read -r -p " $key_name.gpg exists. Re-encrypt? (y/n): " re_enc
|
||||
[[ "$re_enc" == [yY] ]] || continue
|
||||
rm "$encrypted"
|
||||
fi
|
||||
|
||||
if gpg --symmetric --cipher-algo AES256 --output "$encrypted" "$key"; then
|
||||
success "Encrypted: $key → $encrypted"
|
||||
else
|
||||
warn "Encryption failed for $key_name — skipping."
|
||||
rm -f "$encrypted"
|
||||
fi
|
||||
done
|
||||
|
||||
# Ensure .gitignore allows .gpg files (idempotent)
|
||||
local gitignore="$DOTFILES_DIR/.gitignore"
|
||||
if ! grep -q "^!.ssh/keys/\*.gpg" "$gitignore" 2>/dev/null; then
|
||||
printf '\n# GPG-encrypted private key backups are safe to commit\n!.ssh/keys/*.gpg\n' >> "$gitignore"
|
||||
success "Updated .gitignore to allow .gpg files"
|
||||
fi
|
||||
|
||||
echo
|
||||
success "SSH export complete. Run 'push' to save to $DOTFILES_REMOTE"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: ssh-import (decrypt GPG keys from dotfiles/.ssh/keys/ → ~/.ssh/)
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_ssh_import() {
|
||||
bold "=== Import SSH Private Keys (GPG decrypt) ==="
|
||||
command -v gpg &>/dev/null || die "gpg not installed. Install with: brew install gnupg"
|
||||
|
||||
local dotfiles_ssh="$DOTFILES_DIR/.ssh/keys"
|
||||
local gpg_keys=()
|
||||
while IFS= read -r -d '' f; do
|
||||
gpg_keys+=("$f")
|
||||
done < <(find "$dotfiles_ssh" -maxdepth 1 -name "*.gpg" -print0 2>/dev/null)
|
||||
|
||||
if [ ${#gpg_keys[@]} -eq 0 ]; then
|
||||
info "No GPG-encrypted keys found in dotfiles/.ssh/keys/"
|
||||
info "Run 'ssh-export' first to encrypt your private keys."
|
||||
return
|
||||
fi
|
||||
|
||||
info "Found encrypted keys:"
|
||||
for k in "${gpg_keys[@]}"; do echo " $(basename "$k")"; done
|
||||
echo
|
||||
read -r -p "Decrypt and install to ~/.ssh/? (y/n): " yn
|
||||
[[ "$yn" == [yY] ]] || return
|
||||
|
||||
mkdir -p "$HOME/.ssh"
|
||||
chmod 700 "$HOME/.ssh"
|
||||
|
||||
local imported=0
|
||||
for gpg_key in "${gpg_keys[@]}"; do
|
||||
local key_name; key_name="$(basename "${gpg_key%.gpg}")"
|
||||
local dest="$HOME/.ssh/$key_name"
|
||||
|
||||
if [ -f "$dest" ]; then
|
||||
warn " $dest already exists — skipping. Remove it first to re-import."
|
||||
continue
|
||||
fi
|
||||
|
||||
if gpg --decrypt --output "$dest" "$gpg_key"; then
|
||||
chmod 600 "$dest"
|
||||
success "Decrypted: $(basename "$gpg_key") → $dest"
|
||||
(( imported++ )) || true
|
||||
else
|
||||
warn " Failed to decrypt $(basename "$gpg_key")"
|
||||
rm -f "$dest"
|
||||
fi
|
||||
done
|
||||
|
||||
# Add freshly imported keys to the running ssh-agent
|
||||
if [[ "$imported" -gt 0 ]] && ssh-add -l &>/dev/null 2>&1; then
|
||||
for gpg_key in "${gpg_keys[@]}"; do
|
||||
local key_name; key_name="$(basename "${gpg_key%.gpg}")"
|
||||
local dest="$HOME/.ssh/$key_name"
|
||||
[ -f "$dest" ] && ssh-add "$dest" 2>/dev/null && info " Added to agent: $key_name"
|
||||
done
|
||||
fi
|
||||
|
||||
echo
|
||||
success "SSH import complete ($imported key(s) decrypted)."
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: remote-bootstrap (SSH into another machine and run full setup)
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_remote_bootstrap() {
|
||||
[ $# -ge 1 ] || die "Usage: remote-bootstrap <user@host> [--profile work|personal]"
|
||||
|
||||
local target="$1"; shift
|
||||
local profile="personal"
|
||||
|
||||
# Parse optional --profile flag
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--profile) profile="${2:-personal}"; shift 2 ;;
|
||||
*) die "Unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
bold "=== Remote Bootstrap: $target (profile: $profile) ==="
|
||||
echo
|
||||
|
||||
# ---- 1. Verify SSH connectivity (prefer key-based auth) ----
|
||||
info "Testing SSH connectivity..."
|
||||
if ! ssh -o ConnectTimeout=10 -o BatchMode=yes -o StrictHostKeyChecking=accept-new \
|
||||
"$target" "exit 0" 2>/dev/null; then
|
||||
warn "Key-based SSH auth failed for $target."
|
||||
read -r -p "Copy your SSH public key to $target now? (y/n): " yn
|
||||
if [[ "$yn" == [yY] ]]; then
|
||||
ssh-copy-id "$target" || die "ssh-copy-id failed. Fix SSH access to $target first."
|
||||
else
|
||||
die "SSH key access required. Run:\n ssh-copy-id $target"
|
||||
fi
|
||||
fi
|
||||
success "SSH connection OK."
|
||||
echo
|
||||
|
||||
# ---- 2. Upload scripts ----
|
||||
local self_dir; self_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
info "Uploading scripts to $target:~/scripts/ ..."
|
||||
ssh "$target" "mkdir -p ~/scripts"
|
||||
scp -q \
|
||||
"$self_dir/dotfiles_manager.sh" \
|
||||
"$self_dir/setup_enterprise_ai_bash.sh" \
|
||||
"$target:~/scripts/"
|
||||
ssh "$target" "chmod +x ~/scripts/dotfiles_manager.sh ~/scripts/setup_enterprise_ai_bash.sh"
|
||||
success "Scripts uploaded."
|
||||
echo
|
||||
|
||||
# ---- 3. Run setup interactively over SSH (-t allocates a tty) ----
|
||||
info "Launching setup on $target (profile=$profile)..."
|
||||
info "You will be prompted interactively on the remote machine."
|
||||
echo
|
||||
ssh -t "$target" \
|
||||
"MACHINE_PROFILE=${profile} DOTFILES_REMOTE=${DOTFILES_REMOTE} bash ~/scripts/setup_enterprise_ai_bash.sh"
|
||||
|
||||
echo
|
||||
success "Remote bootstrap of $target complete."
|
||||
info "Log in and verify: ssh $target 'dotfiles status'"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# COMMAND: help
|
||||
# -----------------------------------------------------------------------
|
||||
cmd_help() {
|
||||
cat <<HELP
|
||||
${BOLD}dotfiles_manager.sh${RESET} — Centralized dotfiles management
|
||||
|
||||
${BOLD}USAGE${RESET}
|
||||
./dotfiles_manager.sh <command> [args]
|
||||
|
||||
${BOLD}COMMANDS — Core${RESET}
|
||||
init Clone from remote or init locally with remote set
|
||||
add <file> [...] Track file(s): move to ~/dotfiles, symlink back to HOME
|
||||
remove <file> Untrack: restore file to HOME
|
||||
install Reapply all symlinks (use on a new machine after cloning)
|
||||
sync Pull latest from remote, reapply symlinks
|
||||
push [message] Commit all changes and push to $DOTFILES_REMOTE
|
||||
status / list Show tracked files and symlink health
|
||||
|
||||
${BOLD}COMMANDS — SSH & Keys${RESET}
|
||||
ssh-setup Guided SSH config + key migration
|
||||
ssh-export GPG-encrypt private keys → dotfiles/.ssh/keys/*.gpg
|
||||
ssh-import Decrypt GPG-encrypted keys from dotfiles to ~/.ssh/
|
||||
|
||||
${BOLD}COMMANDS — Multi-machine${RESET}
|
||||
remote-bootstrap <user@host> [--profile work|personal]
|
||||
Upload scripts and run full setup on a remote machine
|
||||
|
||||
${BOLD}QUICK START — this machine (work)${RESET}
|
||||
./dotfiles_manager.sh init
|
||||
./dotfiles_manager.sh add ~/.bashrc ~/.bash_profile ~/.gitconfig
|
||||
./dotfiles_manager.sh ssh-setup
|
||||
./dotfiles_manager.sh ssh-export # GPG-encrypt private keys
|
||||
./dotfiles_manager.sh push "initial migration"
|
||||
|
||||
${BOLD}QUICK START — personal machine restore${RESET}
|
||||
# Option A: remote bootstrap from work machine
|
||||
./dotfiles_manager.sh remote-bootstrap user@personal-mac --profile personal
|
||||
|
||||
# Option B: manual steps on the personal machine
|
||||
git clone $DOTFILES_REMOTE ~/dotfiles
|
||||
~/dotfiles/install.sh # applies symlinks, prompts for key decrypt
|
||||
|
||||
${BOLD}.bashrc STRATEGY${RESET}
|
||||
~/.bashrc → tracked in dotfiles, shared across all machines
|
||||
~/.bashrc.local → NOT tracked, written by setup_enterprise_ai_bash.sh
|
||||
contains profile-specific vars (cloud paths, MACHINE_PROFILE)
|
||||
Work: OneDrive paths, CLOUD_ROOT=~/OneDrive
|
||||
Personal: ProtonDrive + Google Drive, CLOUD_ROOT=~/Cloud
|
||||
|
||||
${BOLD}SSH KEY SHARING STRATEGY${RESET}
|
||||
~/.ssh/config → tracked in dotfiles (shared)
|
||||
~/.ssh/*.pub → copied to dotfiles/.ssh/keys/ (shared)
|
||||
~/.ssh/id_* → NOT committed plain-text
|
||||
~/.ssh/id_*.gpg → GPG-encrypted backups committed to dotfiles, decrypted
|
||||
on new machines with 'ssh-import'
|
||||
|
||||
${BOLD}ENVIRONMENT OVERRIDES${RESET}
|
||||
DOTFILES_DIR=$DOTFILES_DIR
|
||||
DOTFILES_REMOTE=$DOTFILES_REMOTE
|
||||
HELP
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# GENERATE PORTABLE install.sh (regenerated on each push)
|
||||
# -----------------------------------------------------------------------
|
||||
generate_install_sh() {
|
||||
cat > "$DOTFILES_DIR/install.sh" <<INSTALL
|
||||
#!/usr/bin/env bash
|
||||
# Portable dotfiles restore script — generated by dotfiles_manager.sh
|
||||
# Run on a new machine after: git clone $DOTFILES_REMOTE ~/dotfiles
|
||||
set -euo pipefail
|
||||
|
||||
DOTFILES_DIR="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
|
||||
MANIFEST="\$DOTFILES_DIR/.dotfiles_manifest"
|
||||
BACKUP_DIR="\$HOME/.dotfiles_backup/\$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
echo "=== Restoring dotfiles from \$DOTFILES_DIR ==="
|
||||
|
||||
[ -f "\$MANIFEST" ] || { echo "No manifest found."; exit 1; }
|
||||
|
||||
while IFS= read -r rel || [ -n "\$rel" ]; do
|
||||
[ -z "\$rel" ] && continue
|
||||
src="\$DOTFILES_DIR/\$rel"
|
||||
dest="\$HOME/\$rel"
|
||||
[ -e "\$src" ] || { echo " MISSING: \$src"; continue; }
|
||||
mkdir -p "\$(dirname "\$dest")"
|
||||
if [ -e "\$dest" ] && [ ! -L "\$dest" ]; then
|
||||
mkdir -p "\$BACKUP_DIR/\$(dirname "\$rel")"
|
||||
cp -a "\$dest" "\$BACKUP_DIR/\$rel"
|
||||
echo " Backed up: \$dest"
|
||||
rm -f "\$dest"
|
||||
elif [ -L "\$dest" ]; then
|
||||
rm "\$dest"
|
||||
fi
|
||||
[[ "\$rel" == .ssh/* ]] && chmod 600 "\$src" 2>/dev/null || true
|
||||
ln -sf "\$src" "\$dest"
|
||||
echo " Linked: ~/\$rel"
|
||||
done < "\$MANIFEST"
|
||||
|
||||
echo
|
||||
echo "✓ Dotfiles symlinks applied."
|
||||
|
||||
# ---- Machine-local config ----
|
||||
# Write a minimal .bashrc.local if one does not exist (user edits profile)
|
||||
if [ ! -f "\$HOME/.bashrc.local" ]; then
|
||||
echo
|
||||
echo "Select profile for this machine:"
|
||||
echo " [1] work — OneDrive"
|
||||
echo " [2] personal — ProtonDrive + GoogleDrive"
|
||||
read -r -p "Profile (1/2) [2]: " _choice
|
||||
_profile="personal"
|
||||
[[ "\${_choice:-2}" == "1" ]] && _profile="work"
|
||||
# setup script lives inside dotfiles now: dotfiles/scripts/setup_enterprise_ai_bash.sh
|
||||
if [ -f "\$DOTFILES_DIR/scripts/setup_enterprise_ai_bash.sh" ]; then
|
||||
MACHINE_PROFILE="\$_profile" bash "\$DOTFILES_DIR/scripts/setup_enterprise_ai_bash.sh"
|
||||
else
|
||||
echo " ⚠ Could not find setup_enterprise_ai_bash.sh — create ~/.bashrc.local manually."
|
||||
fi
|
||||
fi
|
||||
|
||||
# ---- SSH key decrypt ----
|
||||
gpg_count=\$(find "\$DOTFILES_DIR/.ssh/keys" -maxdepth 1 -name '*.gpg' 2>/dev/null | wc -l | tr -d ' ')
|
||||
if [[ "\$gpg_count" -gt 0 ]]; then
|
||||
echo
|
||||
echo "Found \$gpg_count GPG-encrypted SSH key(s) in dotfiles."
|
||||
read -r -p "Decrypt SSH private keys now? (y/n): " _dec
|
||||
if [[ "\$_dec" == [yY] ]]; then
|
||||
# dotfiles_manager.sh lives inside dotfiles now: dotfiles/scripts/dotfiles_manager.sh
|
||||
bash "\$DOTFILES_DIR/scripts/dotfiles_manager.sh" ssh-import
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "✓ Restore complete. Run: source ~/.bash_profile"
|
||||
INSTALL
|
||||
chmod +x "$DOTFILES_DIR/install.sh"
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# ENTRYPOINT
|
||||
# -----------------------------------------------------------------------
|
||||
main() {
|
||||
local cmd="${1:-help}"
|
||||
shift || true
|
||||
|
||||
# Auto-generate install.sh when pushing
|
||||
case "$cmd" in
|
||||
init) cmd_init "$@" ;;
|
||||
add) cmd_add "$@" ;;
|
||||
remove) cmd_remove "$@" ;;
|
||||
install) cmd_install "$@" ;;
|
||||
sync) cmd_sync "$@" ;;
|
||||
push)
|
||||
generate_install_sh
|
||||
cmd_push "$@"
|
||||
;;
|
||||
status|list) cmd_status "$@" ;;
|
||||
ssh-setup) cmd_ssh_setup "$@" ;;
|
||||
ssh-export) cmd_ssh_export "$@" ;;
|
||||
ssh-import) cmd_ssh_import "$@" ;;
|
||||
remote-bootstrap) cmd_remote_bootstrap "$@" ;;
|
||||
help|--help|-h) cmd_help ;;
|
||||
*)
|
||||
error "Unknown command: $cmd"
|
||||
cmd_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
410
scripts/setup_enterprise_ai_bash.sh
Executable file
410
scripts/setup_enterprise_ai_bash.sh
Executable file
@@ -0,0 +1,410 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "🚀 Setting up Enterprise + AI Development Environment (Bash Edition)"
|
||||
echo
|
||||
|
||||
HOME_DIR="$HOME"
|
||||
BASHRC="$HOME_DIR/.bashrc"
|
||||
BASH_PROFILE="$HOME_DIR/.bash_profile"
|
||||
|
||||
# Dotfiles remote — your local Gitea server
|
||||
DOTFILES_REMOTE="http://172.27.0.35:3000/kenjim/dotfiles"
|
||||
DOTFILES_DIR="$HOME_DIR/dotfiles"
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 0️⃣ MACHINE PROFILE SELECTION
|
||||
# ------------------------------------------------------
|
||||
# Override: MACHINE_PROFILE=work ./setup_enterprise_ai_bash.sh
|
||||
# MACHINE_PROFILE=personal ./setup_enterprise_ai_bash.sh
|
||||
|
||||
MACHINE_PROFILE="${MACHINE_PROFILE:-}"
|
||||
|
||||
if [[ -z "$MACHINE_PROFILE" ]]; then
|
||||
echo "Select machine profile:"
|
||||
echo " [1] work — OneDrive cloud, work workspace"
|
||||
echo " [2] personal — ProtonDrive + GoogleDrive, personal workspace"
|
||||
echo
|
||||
read -r -p "Profile (1=work / 2=personal) [2]: " _choice
|
||||
case "${_choice:-2}" in
|
||||
1|work) MACHINE_PROFILE="work" ;;
|
||||
2|personal) MACHINE_PROFILE="personal" ;;
|
||||
*) MACHINE_PROFILE="personal" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
export MACHINE_PROFILE
|
||||
echo " ▶ Profile: $MACHINE_PROFILE"
|
||||
echo
|
||||
|
||||
# Derive hostname tag used to tag commits
|
||||
MACHINE_TAG="$(hostname -s)-${MACHINE_PROFILE}"
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 1️⃣ CREATE DIRECTORY STRUCTURE
|
||||
# ------------------------------------------------------
|
||||
|
||||
echo "📁 Creating directory structure..."
|
||||
|
||||
mkdir -p "$HOME_DIR/workspace/src/"{personal,work,research}
|
||||
mkdir -p "$HOME_DIR/workspace/"{experiments,notebooks,sandboxes,archive}
|
||||
|
||||
mkdir -p "$HOME_DIR/data/"{raw,processed,embeddings,synthetic}
|
||||
mkdir -p "$HOME_DIR/models/"{huggingface,ollama,fine-tuned}
|
||||
|
||||
mkdir -p "$HOME_DIR/infra/"{docker,terraform,scripts}
|
||||
mkdir -p "$HOME_DIR/ops"
|
||||
mkdir -p "$HOME_DIR/scripts"
|
||||
mkdir -p "$HOME_DIR/vault"
|
||||
mkdir -p "$HOME_DIR/dotfiles"
|
||||
mkdir -p "$HOME_DIR/dotfiles/.ssh/keys"
|
||||
|
||||
# Profile-specific cloud directories
|
||||
if [[ "$MACHINE_PROFILE" == "work" ]]; then
|
||||
# OneDrive is managed by the Microsoft OneDrive app and auto-mounts at:
|
||||
# ~/Library/CloudStorage/OneDrive-<OrgName>/ (modern macOS)
|
||||
# We create a stable symlink at ~/OneDrive for convenience.
|
||||
ONEDRIVE_MOUNT=$(find "$HOME_DIR/Library/CloudStorage" -maxdepth 1 -iname 'OneDrive*' -type d 2>/dev/null | head -1 || true)
|
||||
if [[ -n "$ONEDRIVE_MOUNT" ]]; then
|
||||
ln -sfn "$ONEDRIVE_MOUNT" "$HOME_DIR/OneDrive" 2>/dev/null || true
|
||||
echo " Linked ~/OneDrive → $ONEDRIVE_MOUNT"
|
||||
else
|
||||
mkdir -p "$HOME_DIR/OneDrive"
|
||||
echo " Created ~/OneDrive placeholder (link manually once OneDrive app is signed in)"
|
||||
fi
|
||||
else
|
||||
# Personal machine: ProtonDrive + Google Drive
|
||||
mkdir -p "$HOME_DIR/Cloud/"{ProtonDrive,GoogleDrive}
|
||||
fi
|
||||
|
||||
echo "✅ Directories created."
|
||||
echo
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 2️⃣ ENSURE .bash_profile LOADS .bashrc (macOS FIX)
|
||||
# ------------------------------------------------------
|
||||
|
||||
if ! grep -q "source ~/.bashrc" "$BASH_PROFILE" 2>/dev/null; then
|
||||
cat <<'EOF' >> "$BASH_PROFILE"
|
||||
|
||||
# Load .bashrc if it exists
|
||||
if [ -f ~/.bashrc ]; then
|
||||
source ~/.bashrc
|
||||
fi
|
||||
EOF
|
||||
echo "✅ .bash_profile updated to load .bashrc"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 3️⃣ ADD ENTERPRISE AI ENV VARIABLES
|
||||
# ------------------------------------------------------
|
||||
|
||||
if ! grep -q "### ENTERPRISE_AI_ENV ###" "$BASHRC" 2>/dev/null; then
|
||||
cat <<'EOF' >> "$BASHRC"
|
||||
|
||||
### ENTERPRISE_AI_ENV ###
|
||||
export WORKSPACE="$HOME/workspace"
|
||||
export DATA_ROOT="$HOME/data"
|
||||
export MODEL_ROOT="$HOME/models"
|
||||
|
||||
# HuggingFace cache location
|
||||
export HF_HOME="$MODEL_ROOT/huggingface"
|
||||
|
||||
# Ollama model location
|
||||
export OLLAMA_MODELS="$MODEL_ROOT/ollama"
|
||||
|
||||
# Convenience aliases
|
||||
alias ws='cd $WORKSPACE'
|
||||
alias src='cd $WORKSPACE/src'
|
||||
alias data='cd $DATA_ROOT'
|
||||
alias models='cd $MODEL_ROOT'
|
||||
|
||||
# Machine-local overrides (cloud paths, work vs personal — not synced via dotfiles)
|
||||
[ -f ~/.bashrc.local ] && source ~/.bashrc.local
|
||||
|
||||
EOF
|
||||
echo "✅ Environment variables added to .bashrc"
|
||||
else
|
||||
# Ensure .bashrc.local sourcing is present even on existing installs
|
||||
if ! grep -q ".bashrc.local" "$BASHRC" 2>/dev/null; then
|
||||
cat >> "$BASHRC" <<'LOCALEOF'
|
||||
|
||||
# Machine-local overrides (cloud paths, work vs personal — not synced via dotfiles)
|
||||
[ -f ~/.bashrc.local ] && source ~/.bashrc.local
|
||||
LOCALEOF
|
||||
echo "✅ Added .bashrc.local sourcing to existing .bashrc"
|
||||
fi
|
||||
echo "ℹ️ Environment already configured."
|
||||
fi
|
||||
|
||||
# ---- Write machine-specific .bashrc.local (never committed to dotfiles) ----
|
||||
BASHRC_LOCAL="$HOME_DIR/.bashrc.local"
|
||||
# Preserve any existing custom content below the managed block
|
||||
LOCAL_CUSTOM=""
|
||||
if [ -f "$BASHRC_LOCAL" ] && grep -q "### MACHINE_LOCAL_END ###" "$BASHRC_LOCAL" 2>/dev/null; then
|
||||
LOCAL_CUSTOM=$(awk '/### MACHINE_LOCAL_END ###/{found=1; next} found{print}' "$BASHRC_LOCAL")
|
||||
fi
|
||||
|
||||
cat > "$BASHRC_LOCAL" <<LOCALEOF
|
||||
### MACHINE_LOCAL — managed by setup_enterprise_ai_bash.sh — DO NOT SYNC ###
|
||||
# Profile : ${MACHINE_PROFILE}
|
||||
# Host : $(hostname -s)
|
||||
# Generated: $(date)
|
||||
export MACHINE_PROFILE="${MACHINE_PROFILE}"
|
||||
export MACHINE_HOST="$(hostname -s)"
|
||||
LOCALEOF
|
||||
|
||||
if [[ "$MACHINE_PROFILE" == "work" ]]; then
|
||||
cat >> "$BASHRC_LOCAL" <<'WORKEOF'
|
||||
# --- Work / OneDrive ---
|
||||
export CLOUD_ROOT="$HOME/OneDrive"
|
||||
export ONEDRIVE_ROOT="$HOME/OneDrive"
|
||||
alias cloud='cd $CLOUD_ROOT'
|
||||
alias onedrive='cd $ONEDRIVE_ROOT'
|
||||
WORKEOF
|
||||
else
|
||||
cat >> "$BASHRC_LOCAL" <<'PERSONALEOF'
|
||||
# --- Personal / ProtonDrive + Google Drive ---
|
||||
export CLOUD_ROOT="$HOME/Cloud"
|
||||
export PROTON_ROOT="$HOME/Cloud/ProtonDrive"
|
||||
export GDRIVE_ROOT="$HOME/Cloud/GoogleDrive"
|
||||
alias cloud='cd $CLOUD_ROOT'
|
||||
alias proton='cd $PROTON_ROOT'
|
||||
alias gdrive='cd $GDRIVE_ROOT'
|
||||
PERSONALEOF
|
||||
fi
|
||||
|
||||
cat >> "$BASHRC_LOCAL" <<'TAILEOF'
|
||||
### MACHINE_LOCAL_END ###
|
||||
TAILEOF
|
||||
|
||||
# Re-append any custom content that was below the managed block
|
||||
if [[ -n "$LOCAL_CUSTOM" ]]; then
|
||||
echo "$LOCAL_CUSTOM" >> "$BASHRC_LOCAL"
|
||||
fi
|
||||
|
||||
echo "✅ .bashrc.local written for profile: $MACHINE_PROFILE"
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 4️⃣ INITIALIZE DOTFILES REPO (with Gitea remote)
|
||||
# ------------------------------------------------------
|
||||
|
||||
echo "📦 Setting up dotfiles repo..."
|
||||
|
||||
# Copy the dotfiles manager into scripts/ if it isn't already there
|
||||
SCRIPTS_DIR="$HOME_DIR/scripts"
|
||||
DFM="$SCRIPTS_DIR/dotfiles_manager.sh"
|
||||
if [ ! -f "$DFM" ]; then
|
||||
SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
if [ -f "$SELF_DIR/dotfiles_manager.sh" ]; then
|
||||
cp "$SELF_DIR/dotfiles_manager.sh" "$DFM"
|
||||
chmod +x "$DFM"
|
||||
echo "✅ dotfiles_manager.sh copied to $DFM"
|
||||
else
|
||||
echo "⚠️ dotfiles_manager.sh not found next to this script — skipping copy."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run init via the manager (handles clone-or-init and remote setup)
|
||||
if [ -f "$DFM" ]; then
|
||||
DOTFILES_DIR="$DOTFILES_DIR" DOTFILES_REMOTE="$DOTFILES_REMOTE" bash "$DFM" init
|
||||
else
|
||||
# Minimal fallback if manager isn't available
|
||||
cd "$DOTFILES_DIR"
|
||||
if [ ! -d ".git" ]; then
|
||||
git init
|
||||
git remote add origin "$DOTFILES_REMOTE"
|
||||
echo ".DS_Store" > .gitignore
|
||||
touch README.md
|
||||
git add .
|
||||
git commit -m "Initial dotfiles commit"
|
||||
echo "✅ Dotfiles repo initialized."
|
||||
else
|
||||
echo "ℹ️ Dotfiles repo already exists."
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 5️⃣ ADD DOTFILES ALIASES TO .bashrc
|
||||
# ------------------------------------------------------
|
||||
|
||||
if ! grep -q "### DOTFILES_ALIASES ###" "$BASHRC" 2>/dev/null; then
|
||||
cat >> "$BASHRC" <<BASHEOF
|
||||
|
||||
### DOTFILES_ALIASES ###
|
||||
export DOTFILES_DIR="\$HOME/dotfiles"
|
||||
export DOTFILES_REMOTE="$DOTFILES_REMOTE"
|
||||
|
||||
# Dotfiles manager shortcut
|
||||
alias dotfiles='bash \$HOME/scripts/dotfiles_manager.sh'
|
||||
alias dot='bash \$HOME/scripts/dotfiles_manager.sh'
|
||||
|
||||
# Quick sync alias
|
||||
alias dots-sync='bash \$HOME/scripts/dotfiles_manager.sh sync'
|
||||
alias dots-push='bash \$HOME/scripts/dotfiles_manager.sh push'
|
||||
alias dots-status='bash \$HOME/scripts/dotfiles_manager.sh status'
|
||||
|
||||
BASHEOF
|
||||
echo "✅ Dotfiles aliases added to .bashrc"
|
||||
else
|
||||
echo "ℹ️ Dotfiles aliases already configured."
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 6️⃣ CREATE MACHINE BOOTSTRAP SCRIPT
|
||||
# ------------------------------------------------------
|
||||
|
||||
cat <<'EOF' > "$HOME_DIR/scripts/bootstrap.sh"
|
||||
#!/usr/bin/env bash
|
||||
# bootstrap.sh — Restore Enterprise AI Environment on this machine
|
||||
set -euo pipefail
|
||||
|
||||
echo "🔄 Restoring Enterprise AI Environment..."
|
||||
|
||||
# Reload shell config
|
||||
# shellcheck disable=SC1091
|
||||
[ -f ~/.bashrc ] && source ~/.bashrc
|
||||
[ -f ~/.bash_profile ] && source ~/.bash_profile
|
||||
|
||||
echo " WORKSPACE : ${WORKSPACE:-not set}"
|
||||
echo " DATA_ROOT : ${DATA_ROOT:-not set}"
|
||||
echo " MODEL_ROOT : ${MODEL_ROOT:-not set}"
|
||||
echo
|
||||
|
||||
# Sync latest dotfiles from git server
|
||||
if [ -f "$HOME/scripts/dotfiles_manager.sh" ]; then
|
||||
echo "📦 Syncing dotfiles..."
|
||||
bash "$HOME/scripts/dotfiles_manager.sh" sync
|
||||
else
|
||||
echo "⚠️ dotfiles_manager.sh not found — run setup_enterprise_ai_bash.sh first."
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "✅ Bootstrap complete."
|
||||
EOF
|
||||
|
||||
chmod +x "$HOME_DIR/scripts/bootstrap.sh"
|
||||
|
||||
echo "✅ Bootstrap script created at ~/scripts/bootstrap.sh"
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 7️⃣ INITIAL DOTFILES MIGRATION (interactive)
|
||||
# ------------------------------------------------------
|
||||
|
||||
echo
|
||||
read -p "Migrate critical shell & config files into dotfiles repo now? (y/n): " MIGRATE_NOW
|
||||
|
||||
if [[ "$MIGRATE_NOW" == "y" ]] && [ -f "$DFM" ]; then
|
||||
echo
|
||||
echo "📂 Tracking shell config files..."
|
||||
|
||||
# .bashrc.local is machine-specific — never track it in dotfiles
|
||||
TRACK_FILES=()
|
||||
[ -f "$BASHRC" ] && TRACK_FILES+=("$BASHRC")
|
||||
[ -f "$BASH_PROFILE" ] && TRACK_FILES+=("$BASH_PROFILE")
|
||||
[ -f "$HOME_DIR/.bash_aliases" ] && TRACK_FILES+=("$HOME_DIR/.bash_aliases")
|
||||
[ -f "$HOME_DIR/.inputrc" ] && TRACK_FILES+=("$HOME_DIR/.inputrc")
|
||||
[ -f "$HOME_DIR/.gitconfig" ] && TRACK_FILES+=("$HOME_DIR/.gitconfig")
|
||||
[ -f "$HOME_DIR/.vimrc" ] && TRACK_FILES+=("$HOME_DIR/.vimrc")
|
||||
[ -f "$HOME_DIR/.tmux.conf" ] && TRACK_FILES+=("$HOME_DIR/.tmux.conf")
|
||||
# Scripts — track so they are part of the dotfiles repo and re-bootstrap any machine
|
||||
[ -f "$SCRIPTS_DIR/dotfiles_manager.sh" ] && TRACK_FILES+=("$SCRIPTS_DIR/dotfiles_manager.sh")
|
||||
[ -f "$SCRIPTS_DIR/setup_enterprise_ai_bash.sh" ] && TRACK_FILES+=("$SCRIPTS_DIR/setup_enterprise_ai_bash.sh")
|
||||
[ -f "$SCRIPTS_DIR/bootstrap.sh" ] && TRACK_FILES+=("$SCRIPTS_DIR/bootstrap.sh")
|
||||
# NOTE: ~/.bashrc.local intentionally excluded — it is machine-specific
|
||||
|
||||
if [ ${#TRACK_FILES[@]} -gt 0 ]; then
|
||||
DOTFILES_DIR="$DOTFILES_DIR" DOTFILES_REMOTE="$DOTFILES_REMOTE" \
|
||||
bash "$DFM" add "${TRACK_FILES[@]}"
|
||||
else
|
||||
echo "ℹ️ No standard config files found to track."
|
||||
fi
|
||||
|
||||
echo
|
||||
read -p "Set up SSH config and keys now? (y/n): " DO_SSH
|
||||
if [[ "$DO_SSH" == "y" ]]; then
|
||||
DOTFILES_DIR="$DOTFILES_DIR" DOTFILES_REMOTE="$DOTFILES_REMOTE" \
|
||||
bash "$DFM" ssh-setup
|
||||
echo
|
||||
read -p "GPG-encrypt and store private SSH keys in dotfiles? (y/n): " DO_EXPORT
|
||||
if [[ "$DO_EXPORT" == "y" ]]; then
|
||||
DOTFILES_DIR="$DOTFILES_DIR" DOTFILES_REMOTE="$DOTFILES_REMOTE" \
|
||||
bash "$DFM" ssh-export
|
||||
fi
|
||||
fi
|
||||
|
||||
echo
|
||||
read -p "Push initial dotfiles to $DOTFILES_REMOTE now? (y/n): " DO_PUSH
|
||||
if [[ "$DO_PUSH" == "y" ]]; then
|
||||
DOTFILES_DIR="$DOTFILES_DIR" DOTFILES_REMOTE="$DOTFILES_REMOTE" \
|
||||
bash "$DFM" push "initial dotfiles migration from ${MACHINE_TAG}"
|
||||
fi
|
||||
else
|
||||
echo "ℹ️ Skipped. Run manually:"
|
||||
echo " dotfiles add ~/.bashrc ~/.bash_profile ~/.gitconfig"
|
||||
echo " dotfiles ssh-setup"
|
||||
echo " dotfiles push"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 8️⃣ OPTIONAL TIME MACHINE EXCLUSIONS
|
||||
# ------------------------------------------------------
|
||||
|
||||
echo
|
||||
read -p "Exclude large AI folders from Time Machine? (y/n): " EXCLUDE_TM
|
||||
|
||||
if [[ "$EXCLUDE_TM" == "y" ]]; then
|
||||
sudo tmutil addexclusion "$HOME_DIR/data/raw"
|
||||
sudo tmutil addexclusion "$HOME_DIR/models"
|
||||
echo "✅ Time Machine exclusions added."
|
||||
else
|
||||
echo "ℹ️ Skipped Time Machine exclusions."
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------
|
||||
# DONE
|
||||
# ------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------
|
||||
# 9️⃣ REMOTE BOOTSTRAP (optional)
|
||||
# ------------------------------------------------------
|
||||
|
||||
echo
|
||||
read -r -p "Bootstrap a remote machine over SSH now? (y/n): " DO_REMOTE
|
||||
if [[ "$DO_REMOTE" == "y" ]] && [ -f "$DFM" ]; then
|
||||
read -r -p "Remote target (user@host): " REMOTE_TARGET
|
||||
read -r -p "Profile for remote machine (work/personal) [personal]: " REMOTE_PROFILE
|
||||
REMOTE_PROFILE="${REMOTE_PROFILE:-personal}"
|
||||
DOTFILES_DIR="$DOTFILES_DIR" DOTFILES_REMOTE="$DOTFILES_REMOTE" \
|
||||
bash "$DFM" remote-bootstrap "$REMOTE_TARGET" --profile "$REMOTE_PROFILE"
|
||||
else
|
||||
echo "ℹ️ To bootstrap a remote machine later:"
|
||||
echo " dotfiles remote-bootstrap user@hostname"
|
||||
echo " dotfiles remote-bootstrap user@hostname --profile work"
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------
|
||||
# DONE
|
||||
# ------------------------------------------------------
|
||||
|
||||
echo
|
||||
echo "🎉 Enterprise + AI Bash Environment Setup Complete!"
|
||||
echo " Profile : $MACHINE_PROFILE"
|
||||
echo " Host : $(hostname -s)"
|
||||
echo
|
||||
echo "👉 Run : source ~/.bash_profile"
|
||||
echo "👉 Spaces : ws | src | data | models"
|
||||
if [[ "$MACHINE_PROFILE" == "work" ]]; then
|
||||
echo "👉 Cloud : onedrive"
|
||||
else
|
||||
echo "👉 Cloud : cloud | proton | gdrive"
|
||||
fi
|
||||
echo "👉 Dotfiles: dotfiles status"
|
||||
echo "👉 Sync : dotfiles sync"
|
||||
echo "👉 SSH keys: dotfiles ssh-setup (then: dotfiles ssh-export)"
|
||||
echo "👉 Remote : dotfiles remote-bootstrap user@personal-mac"
|
||||
echo "👉 Restore : git clone $DOTFILES_REMOTE ~/dotfiles && ~/dotfiles/install.sh"
|
||||
echo
|
||||
|
||||
Reference in New Issue
Block a user