#!/bin/bash IDM_MOD_DEPS="id gpg git" IDM_MOD_TAGS="id tool" IDM_MOD_PROG="safe yadm" IDM_MOD_PREF="core id" IDM_DISABLE_AUTO+=" tomb__enable tomb__disable tomb__kill " ## Environments ########################################## idm_tomb_header () { local id=$1 # Check if id is valid lib_id_has_config $id # Load local repo vars idm_git_header $id git_id_enc=$IDM_DIR_CACHE/git/$id/local.git.tar.gz.asc # Load tomb vars idm_vars_git_tomb $id git_tomb_config=${IDM_CONFIG_DIR}/git/$id/local_gitconfig git_tomb_dir=$git_dir git_tomb_work_tree=$git_work_tree git_tomb_enc=$IDM_CONFIG_DIR/enc/$id.tomb git_id_tomb_repo_name=tomb } idm_vars_git_tomb () { local id=$1 git_dir=$IDM_DIR_CACHE/git/$id/tomb.git git_work_tree=$git_dir/.git } ## Front functions ############################## idm_tomb__help () { local id=$1 echo "tomb" echo " workflow:" printf " %-20s: %s\n" "tomb ls" "Show tomb status" printf " %-20s: %s\n" "tomb import [] " "Import a config" printf " %-20s: %s\n" "tomb decrypt" "Decrypt the tomb" printf " %-20s: %s\n" "tomb sync" "Synchronise tomb(s)" printf " %-20s: %s\n" "tomb encrypt" "Save the current configuration into the tomb" printf " %-20s: %s\n" "tomb push |all" "Save the current configuration into the tomb" printf " %-20s: %s\n" "tomb leave" "Remove all traces of your passage" if lib_id_is_enabled $id; then idm_tomb_header $id echo " config:" printf " %-20s: %s\n" "git_tomb_enc" "$git_tomb_enc" printf " %-20s: %s\n" "git_tomb_dir" "$git_tomb_dir" printf " %-20s: %s\n" "git_tomb_config" "$git_tomb_config" fi } idm_tomb__ls () { local id=$1 echo " Tombs:" find $IDM_CONFIG_DIR/enc/ -type f -name "*.tomb" | sed "s@$HOME@ ~@" if lib_id_is_enabled $id; then local tomb_status= local tomb_date= local git_status= local git_date= # Load local vars idm_tomb_header $id # Get status of tomb file if [ -f "$git_tomb_enc" ]; then tomb_status=open tomb_date=$( lib_date_diff_human $(find $git_tomb_enc -printf "%Ts") ) tomb_date=", $tomb_date old" else tomb_status=closed fi # Get status of git repo if [ -d "$git_tomb_dir" ]; then git_status=present #git_date=$( lib_date_diff_human $(find $git_tomb_dir -maxdepth 0 -printf "%Ts") ) #git_date=" $git_date" else git_status=absent fi # Display echo " Status:" printf " %-20s: %s\n" "encrypted tomb" "$tomb_status${tomb_date}" printf " %-20s: %s\n" "encrypted file" "$git_tomb_enc" printf " %-20s: %s\n" "tomb git status" "$git_status${git_date}" printf " %-20s: %s\n" "tomb git dir" "$git_tomb_dir" # Show git remotes if lib_git_is_repo id; then echo " Git remotes:" lib_git id remote -v | sed 's/^/ /' echo " Last commits:" lib_git id l --color=always | sed 's/^/ /' echo fi fi } idm_tomb__rm () { local id=$1 local report= # Load tomb variables idm_tomb_header $id # Delete local remote branch if lib_git id remote show $git_id_tomb_repo_name &>/dev/null ; then lib_git id remote rm $git_id_tomb_repo_name || { lib_log INFO "Could not remote tomb remote" return 1 } else lib_log INFO "Tomb remote is already absent" fi # Delete git repo if [ -d "$git_tomb_dir" ] ; then rm -rf "$git_tomb_dir" else lib_log INFO "Tomb repository is already absent" fi # Notify lib_log NOTICE "Tomb repository has been deleted" } idm_tomb__init () { local id=$1 # Check if local repo is not empty lib_git_is_repo_with_commits id || { lib_log INFO "Local repository must be present first" return 0 } # Load tomb variables idm_tomb_header $id # Check if local repo already exists # TOFIX !!! use lib_git_is_repo instead if [ -d "$git_tomb_dir" ] ; then lib_log INFO "Tomb repository alreay exists" return 0 fi # Create tomb: from local files if [ -f "$git_tomb_enc" ]; then lib_log WARN "An encrypted tomb has been found. Do you want to decrypt it? ($git_tomb_enc)" if idm_cli_timeout 1 || false ; then lib_log "Extracting existing tomb ..." idm_tomb__decrypt $id || idm_exit 1 ERR "Failed to create tomb repo" else lib_log INFO "Skipping existing tomb, creating a fresh one ..." fi fi # Create tomb: from other file #TODO # Create tomb: from other host #TODO # Create tomb: from scratch if [ -f "$git_tomb_enc" ]; then mkdir -p "$git_tomb_dir" _git_tomb clone --bare $git_id_dir $git_tomb_dir || \ idm_exit 1 ERR "Could not create tomb repo" lib_log NOTICE "Tomb repository has been created" fi # Add tomb remote to local repo lib_git id remote | grep -q $git_id_tomb_repo_name || lib_git id remote add $git_id_tomb_repo_name $git_tomb_dir || idm_exit 1 ERR "Failed to add tomb remote to local git" # Syncrhonise with tomb #if lib_git_is_repo_with_commits id ; then # idm_tomb__sync $id #fi } idm_tomb__sync () { local id=$1 # Sanity check: id and local repo idm_tomb_header $id lib_git_is_repo_with_commits id # Tomb repo check lib_git_is_repo tomb || idm_tomb__init $id || { lib_log ERR "Failed to create tomb repo" return 1 } # Work on local { lib_git id fetch --all --tags && lib_git id push -u $git_id_tomb_repo_name --all && lib_git id push -u $git_id_tomb_repo_name --tags } >/dev/null || idm_exit 1 ERR "Something where wrong while syncinc" # Notify user lib_log NOTICE "Tomb and local repository are now synced" } #### THIS PART BELOW NEED REFACTOOOORRRR idm_tomb__encrypt () { local id=$1 #set -x idm_tomb_header $id lib_git_is_all_commited id # We check tomb repo here lib_git_is_repo tomb || idm_tomb__init $id || { lib_log ERR "Failed to create tomb repo" return 1 } # Full sync both repo idm_tomb__sync $id || idm_exit 1 ERR "Failed to push commits to tomb repo" # Encrypt tomb data lib_gpg_encrypt_dir $git_tomb_dir $git_tomb_enc _PASS || \ idm_exit 1 ERR "Failed to create tomb" ## Encrypt local data lib_gpg_encrypt_dir $git_id_dir $git_id_enc $GIT_AUTHOR_EMAIL || \ idm_exit 1 ERR "Could not create local repo data" # Clean tomb rm -rf $git_tomb_dir lib_log NOTICE "Tomb has been closed into: $git_tomb_enc" } idm_tomb__decrypt () { local id=$1 shift || true local opt=${@-} # Sanity check idm_tomb_require_enabled $id # Check if tomb repo is absent if lib_git_is_repo $git_tomb_dir $git_id_work_tree ; then lib_log WARN "A local repo is already present, we will overwrite it. Do you want to continue?" idm_cli_timeout 0 || idm_exit 1 ERR "Refuse to override existing repo" # Let's not delete existing repo, just for fun and wee how git react :p fi # Extract tomb lib_gpg_decrypt_dir $git_tomb_enc $git_tomb_dir || \ idm_exit 1 ERR "Could not extract tomb" # Extract local repo if lib_git_is_repo id ; then # Local repo always win !, so we just sync lib_log INFO "Local repo already present, we just start sync" idm_tomb__sync $id elif [ -f "$git_id_enc" ]; then lib_gpg_decrypt_dir $git_id_enc $git_id_dir || \ idm_exit 1 ERR "Could not extract local repo" else idm_git__init $id && idm_tomb__sync $id || idm_exit 1 "Something wrong happened while working on local repo" fi # Sync :D #idm_tomb__sync $id lib_log NOTICE "Your tomb has been decrypted" } # We manage distribution of our repo # but maybe it should be the liblib_git id roles ... idm_tomb__push () { local id=$1 local arg=${2-} idm_tomb_header $id # Manage argument if grep -sq "$arg" $IDM_CONFIG_DIR/git/$id/known_hosts ; then arg=$( grep -s "$arg" $IDM_CONFIG_DIR/git/$id/known_hosts | head -n 1 ) idm_tomb_ssh_sync $arg || idm_exit 1 "Could not copy tomb to $arg" lib_log NOTICE "Tomb has been exported: to $arg" elif [ "$arg" == 'all' ]; then remotes="$(_git_tomb remote -v | awk '{ print $1 }' | uniq )" for repo_name in $remotes; do lib_log INFO "Synchronising remote $repo_name ..." lib_git id fetch --all --tags && lib_git id push -u $repo_name --all && lib_git id push -u $repo_name --tags || lib_log WARN "Could not sync with $reponame" done elif _git_tomb remote -v | grep -q "^$arg"; then idm_tomb__sync $id $arg else # Actually export the tomb :p #ssh $arg "hostname" || # idm_exit 1 "Could not connect to $arg" #idm_tomb_gen_script_export | lib_log DUMP - lib_log INFO "Trying to connect to $arg ..." dst=$( ssh $arg "$(idm_tomb_gen_script_export)" ) || idm_exit 1 "Something failed $arg" echo "$arg" >> $IDM_CONFIG_DIR/git/$id/known_hosts scp $git_tomb_enc $arg:$dst/$id.tomb || idm_exit 1 "Could not copy tomb to $arg" lib_log NOTICE "Tomb has been exported: $arg:$dst/$id.tomb" fi #if ssh $arg "hostname" > /den/null; then # idm_exit 0 "SSH sync not implemented yet " #else # # Propagate with git # idm_tomb__sync $id #fi } # COMPLETELY DEPRECATED, see with __rm idm_tomb__shred () { local id=$1 local arg=${2-} local files= idm_tomb_require_enabled $id case $arg in local) files="$git_id_dir" ;; tomb) files="$git_tomb_dir" ;; all) files="$git_tomb_dir $git_id_dir" ;; full) files="$git_tomb_dir $git_id_dir $git_id_enc" ;; disapear) files="$git_tomb_dir $git_id_dir $git_id_enc $( idm_git__get_files_of_interest $id | sed 's@^@~/@' | xargs )" ;; *) idm_exit 1 "You need to say: local|tomb|all|full" ;; esac lib_log WARN "All these files will be IRREVOCABLY DELETED." xargs -n 1 <<< "$files" | lib_log DUMP - lib_log WARN "Do you want to continue ?" idm_cli_timeout 1 || idm_exit 1 ERR "No data deleted" lib_log WARN "Run it yourself: rm -rf $files" } idm_tomb__enable () { return 0; } idm_tomb__disable () { return 0; } idm_tomb__kill () { return 0; } ## Internal functions ############################## _git_tomb () { lib_git tomb $@ || return rc=$? #echo "RETURN2: $rc" return $rc } ## Module functions ############################## idm_tomb_ssh_sync () { local host=$1 local dst= # Test connection and prepare destination lib_log INFO "Trying to connect to $host ..." dst=$( ssh $host "$(idm_tomb_gen_script_export)" ) || idm_exit 1 "Something failed $host" # Save host echo "$host" >> $IDM_CONFIG_DIR/git/$id/known_hosts # Copy tomb to remote scp $git_tomb_enc $host:$dst/$id.tomb } idm_tomb_gen_script_export () { cat <