TT#12952 Add 'ngcpcfg clean' action to simplify cleanups

It is hard to clean ngcpcfg framework for users with
limited git knowledge, lets introduce action 'clean'.

It should allows users easily reset to 'previous safe state'
in the case 'if something went wrong'.

Also remove old and unreliable error handling hint from manuals,
as we have switched to fast-forward rebase long time ago.

Change-Id: I961e681d55cac15ba8d772b9345c668218313bf4
changes/54/13154/11
Alexander Lutay 8 years ago committed by Victor Seva
parent 42624f5c60
commit 7800af7b22

@ -18,6 +18,7 @@ sbin/ngcpcfg usr/sbin/
scripts/apply usr/share/ngcp-ngcpcfg/scripts/
scripts/build usr/share/ngcp-ngcpcfg/scripts/
scripts/check usr/share/ngcp-ngcpcfg/scripts/
scripts/clean usr/share/ngcp-ngcpcfg/scripts/
scripts/commit usr/share/ngcp-ngcpcfg/scripts/
scripts/diff usr/share/ngcp-ngcpcfg/scripts/
scripts/etckeeper usr/share/ngcp-ngcpcfg/scripts/

@ -274,6 +274,33 @@ shell globbing patterns - so argument 'mo..t' will match the files
You can combine _<files_or_directories>_ and _<pattern>_ and use multiple
arguments.
**clean** [--all] [--branches] [--force] [--help] [--reset-master] [--stashes] [--tracked-files] [--untracked-files]::
Clean ngcpcfg from not-yet committed/applied changes, reset git state and remove
any possibly existing git stashes. It also proposes to delete unnecessary git
branches if available.
Note: the action (possibly) deletes some files inside /etc/ngcp-config,
it should be used with care!.
Option _--all_ is an alias for _--branches_ + _--reset-master_ + _--stashes_ +
_--tracked-files_ + _--untracked-files_. It should restore local
/etc/ngcp-config in a clean state.
Note: The option _--reset-master_ is involved in the High Availability setup only.
Option _--branches_ proposes to clean all the unnecessary local git branches.
Active branch will be switched to 'master'.
Option _--force_ answers 'yes' automatically on all the cleanup questions.
Option _--help_ shows list of options for the action 'clean'.
Option _--reset-master_ proposes to back up local branch 'master' and restore
branch 'master' from origin. It will effectively clean all locally committed and
not-yet pushed changes.
Note: Already pushed changes won't be removed while they can be reverted using
'git revert <commit>'.
Note: This option is available in the High Availability setup only.
Option _--stashed_ proposes to clean all the changes in git stash.
Option _--tracked-files_ resets cached git files and restore all tracked files
to HEAD of branch master.
Option _--untracked-files_ deletes all untracked files available in
/etc/ngcp-config/, including files ignored by /etc/ngcp-config/.gitignore.
**commit** [<commit_message>]::
Commit all modified files in _/etc/ngcp-config_ and record changes in _/etc_ by

@ -58,6 +58,7 @@ Actions:
status [<opts>] display status of configuration file
log [<opts>] show log of config changes
show [<id>] show latest config change (or <id> if specified)
clean [<opts>] clean /etc/ngcp-config folder configs/templates (see available options)
" "$PN"
# display only if ngcp-ngcpcfg-ha is available
@ -100,6 +101,7 @@ case ${1:-} in
apply|\
build|\
check|\
clean|\
commit|\
decrypt|\
diff|\

@ -0,0 +1,371 @@
#!/bin/bash
# Purpose: clean ngcpcfg config/templates
################################################################################
set -e
set -u
# support testsuite
FUNCTIONS="${FUNCTIONS:-/usr/share/ngcp-ngcpcfg/functions/}"
HELPER="${HELPER:-/usr/share/ngcp-ngcpcfg/helper/}"
SCRIPTS="${SCRIPTS:-/usr/share/ngcp-ngcpcfg/scripts/}"
if ! [ -r "${FUNCTIONS}"/main ] ; then
printf "Error: %s/main could not be read. Exiting.\n" "${FUNCTIONS}" >&2
exit 1
fi
. "${FUNCTIONS}"/main
cd "${NGCPCTL_MAIN}"
## functions {{{
clean_help() {
export TIME_FORMAT=''
log_info "Sample:"
log_info " ngcpcfg clean [--all] [--branches] [--force] [--help] [--reset-master] [--stashes] [--tracked-files] [--untracked-files]"
log_info ""
log_info "Run 'man ngcpcfg' for more information."
}
request_confirmation() {
if "${force:-false}" ; then
log_info "Forcing action due to option '--force'"
return 0
fi
log_info_n "Please confirm 'yes' or 'no': "
# clearing STDIN
while read -r -t 0; do read -r; done
while true ; do
read a
case "${a,,}" in
yes) return 0 ;;
no) return 1 ;;
*) log_info_n "Please answer 'yes' or 'no': " ;;
esac
unset a
done
}
clean_ensure_branch_master () {
log_info "Ensure local branch is 'master':"
local current_branch
log_debug "Call: compare_active_branch 'master'"
current_branch=$(compare_active_branch 'master')
if [ "${current_branch}" = 'master' ] ; then
log_info "OK: branch master active"
else
log_debug "git checkout master"
if git checkout master ; then
log_info "OK: checked out branch master "
else
log_error "Cannot checkout branch 'master'"
return 1
fi
fi
return 0
}
clean_tracked() {
log_info "Removing all local changes (if any):"
log_debug "git status | grep -qE 'working (directory|tree) clean'"
if git status | grep -qE 'working (directory|tree) clean' ; then
log_info "OK: no local changes found, nothing to clean here."
return 0
fi
log_info "Found local changes in '${NGCPCTL_MAIN}':"
log_debug "git status -s -uall"
git status -s -uall
log_info "Should we remove changes above?"
if ! request_confirmation ; then
log_info "Skipping cleanup of local changes as requested."
return 0
fi
log_debug "git reset --hard HEAD"
if git reset --hard HEAD ; then
log_info "OK: Done"
else
log_error "Cannot reset local changes"
return 1
fi
return 0
}
clean_untracked() {
log_info "Removing all untracked files (if any):"
local tmp
tmp=$(mktemp)
log_debug "git clean -n -f -d -x"
if ! git clean -n -f -d -x > "${tmp}" ; then
log_error "Failed to collect list of untracked files"
return 1
fi
if [ "$(wc -l < "${tmp}")" = "0" ] ; then
log_info "OK: No untracked files found, nothing to clean here."
return 0
fi
log_info "Found untracked files in '${NGCPCTL_MAIN}':"
cat "${tmp}"
log_info "Should we remove untracked files above?"
if ! request_confirmation ; then
log_info "Skipping cleanup of untracked files as requested."
return 0
fi
log_debug "git clean -f -d -x"
if ! git clean -f -d -x ; then
log_error "Failed to clean list of untracked files"
return 1
fi
if [ -n "${DEBUG:-}" ] ; then
log_debug "Not removing temporary file ${tmp}"
else
rm -f "${tmp}"
fi
return 0
}
clean_stash() {
log_info "Removing all stashes (if any):"
local tmp
tmp=$(mktemp)
log_debug "git stash list"
if ! git stash list > "${tmp}" ; then
log_error "Failed to collect list of stashes"
return 1
fi
if [ "$(wc -l < "${tmp}")" = "0" ] ; then
log_info "OK: No stashes found, nothing to clean here."
return 0
fi
log_info "Found stashes in '${NGCPCTL_MAIN}':"
cat "${tmp}"
log_info "Should we remove the stashes above?"
if ! request_confirmation ; then
log_info "Skipping stash cleanup as requested."
return 0
fi
log_debug "git stash clear"
if ! git stash clear ; then
log_error "Failed to clean git stashes"
return 1
fi
if [ -n "${DEBUG:-}" ] ; then
log_debug "Not removing temporary file ${tmp}"
else
rm -f "${tmp}"
fi
return 0
}
clean_old_local_branches() {
log_info "Removing all old branches (if any):"
local tmp
tmp=$(mktemp)
log_debug "git branch"
if ! git branch > "${tmp}" ; then
log_error "Failed to collect list of available branches"
return 1
fi
# do not propose to delete active branch and branch 'master'
sed -i -r '/^\* /d' "${tmp}"
sed -i -r '/ master$/d' "${tmp}"
if [ "$(wc -l < "${tmp}")" = "0" ] ; then
log_info "OK: No branches to delete found, nothing to clean here."
return 0
fi
log_info "Found branches to be removed:"
cat "${tmp}"
log_info "Should we remove the branches above?"
if ! request_confirmation ; then
log_info "Skipping branches cleanup as requested."
return 0
fi
while read -r branch ; do
log_debug "git branch -D '${branch}'"
if ! git branch -D "${branch}" ; then
log_error "Failed to delete local branch '${branch}'"
return 1
fi
done < "${tmp}"
if [ -n "${DEBUG:-}" ] ; then
log_debug "Not removing temporary file ${tmp}"
else
rm -f "${tmp}"
fi
return 0
}
clean_reset_master() {
log_debug "checking 'origin' availability using: git remote show origin"
if ! git remote show origin >/dev/null 2>&1 ; then
log_error "Missing git origin 'origin'. Aborting"
return 1
fi
local tmp
tmp=$(mktemp)
log_debug "git diff origin/master..master"
if ! git diff origin/master..master > "${tmp}" ; then
log_error "Failed to collect diff of 'origin/master' and 'master' branches"
return 1
fi
if [ "$(wc -l < "${tmp}")" = "0" ] ; then
log_info "OK: No committed and push pending changes found, nothing to clean here."
return 0
fi
log_info "Found committed local changes to be removed:"
cat "${tmp}"
log_info "Should we restore branch 'master' from origin to remove local commit?"
if ! request_confirmation ; then
log_info "Skipping restore branch 'master' from origin as requested."
return 0
fi
log_info "Restoring branch 'master' from origin:"
local new_branch
new_branch="ngcpcfg_backup_$(date +%s)"
log_debug "git branch -m '${new_branch}'"
if ! git branch -m "${new_branch}" ; then
log_error "Cannot rename current branch to '${new_branch}'. Aborting"
return 1
fi
log_info "OK: renamed current branch to '${new_branch}'. Feel free to clean it."
log_debug "git checkout -b master --track origin/master"
if ! git checkout -b master --track origin/master ; then
log_error "Cannot checkout branch 'master'"
return 1
fi
log_info "OK: created local branch 'master' to track 'origin/master'"
return 0
}
## }}}
RC=0
branches=false
force=false
help=false
reset_master=false
stashes=false
tracked_files=false
untracked_files=false
clean_options="all,branches,force,help,reset-master,stashes,tracked-files,untracked-files"
_opt_temp=$(getopt --name "$0" -o +h --long ${clean_options} -- "$@")
if [ $? -ne 0 ]; then
log_error "Try 'ngcpcfg clean --help' for more information."
exit 1
fi
eval set -- "${_opt_temp}"
[ "$1" = "--" ] && help=true
while : ; do
case "$1" in
--all)
branches=true
reset_master=true
stashes=true
tracked_files=true
untracked_files=true
;;
--branches) branches=true ;;
--force) force=true ;;
--help) help=true ;;
--reset-master) reset_master=true ;;
--stashes) stashes=true ;;
--tracked-files) tracked_files=true ;;
--untracked-files) untracked_files=true ;;
--) shift ; break ;;
*) log_error "Unknown option '$1'" ; exit 1 ;;
esac
shift
done
if ${help} ; then
clean_help
exit 0
fi
if [ ! -f "${FUNCTIONS}/ha_features" ] ; then
log_debug "Skip function 'clean_reset_master'. It is for HA installation only."
reset_master=false
fi
if ! clean_ensure_branch_master ; then
exit 1
fi
if ${tracked_files} ; then
clean_tracked || RC=$((RC + $?))
fi
if ${untracked_files} ; then
clean_untracked || RC=$((RC + $?))
fi
if ${stashes} ; then
clean_stash || RC=$((RC + $?))
fi
if ${reset_master} ; then
clean_reset_master || RC=$((RC + $?))
fi
if ${branches} ; then
clean_old_local_branches || RC=$((RC + $?))
fi
if [ "${RC}" = "0" ] ; then
log_info "All operations were finished successfully. Good to be clean!"
else
log_error "Some operations finished with an error, see details above."
fi
exit "${RC}"
## END OF FILE #################################################################
Loading…
Cancel
Save