ADC "rmrepo" replaced by "rm" and "trash", with helper ADCs

helpers for 'rm': lock, unlock
helpers for 'trash': list-trash, undelete

common functions updated with local settings for ADCs as well
This commit is contained in:
Sitaram Chamarty 2010-10-21 22:36:15 +05:30
parent a0aecbb012
commit cb0a9bdb0c
10 changed files with 204 additions and 17 deletions

View file

@ -2,6 +2,39 @@
# please make sure this file is NOT chmod +x
# ------------------------------------------------------------------------------
# settings for various ADCs, collected in one place for ease of keeping local
# settings intact during upgrades (you only have to worry about this file
# now). Documentation for the variables, however, is in the respective ADC
# settings for 'rm' ADC
ARE_YOU_SURE=1
USE_LOCK_UNLOCK=1
# settings for 'trash' ADC
TRASH_CAN=$GL_REPO_BASE_ABS/deleted
TRASH_SUFFIX=`date +%Y-%m-%d_%H:%M:%S`
# ------------------------------------------------------------------------------
# test an option value more concisely
opt() {
[ "$1" = "1" ] && return 0
return 1
}
valid_owned_repo() {
# check that an arg passed is a valid repo and the current user owns it
repo=$1
[ -z "$1" ] && die need a repo name
get_rights_and_owner $repo
[ "$owner" = "$GL_USER" ] || die "$repo does not exist or is not yours!"
# and we sneak this in too, quietly :)
cd $GL_REPO_BASE_ABS
}
die() { echo "$@"; exit 1; }
get_rights_and_owner() {

13
contrib/adc/list-trash Executable file
View file

@ -0,0 +1,13 @@
#!/bin/sh
. $(dirname $0)/adc.common-functions
# this is a helper ADC for "trash"; see that one for option settings etc
cd $TRASH_CAN 2>/dev/null || exit 0
find . -name gl-creater | sort | while read t
do
owner=
owner=`cat "$t"`
[ "$owner" = "$GL_USER" ] && dirname $t
done | cut -c3-

12
contrib/adc/lock Executable file
View file

@ -0,0 +1,12 @@
#!/bin/sh
. $(dirname $0)/adc.common-functions
# this is a helper ADC for "rm"; see that one for documentation
# cd to repo base and make sure arg1 is a valid repo (also sets $repo)
valid_owned_repo $1
rm -f $repo.git/gl-rm-ok
echo "$repo has been locked"

View file

@ -0,0 +1,48 @@
# deleting repos safely
(see http://groups.google.com/group/gitolite/browse_thread/thread/fb9cf5a464b6dfee )
By default, the old 'rmrepo' ADC (admin-defined command) just went and deleted
the repo -- no questions asked! Sometimes, that could be a disaster -- you
lose the whole thing in one mad moment of typo-ing or frustration. Ouch.
This has been replaced by 2 families of ADCs. I say "families" because each
has one main command and 2 ancillary ones. Admins can choose to install
either, both, or neither family of commands.
Local settings for these ADCs can be found in the common settings file
"adc.common-functions".
1. 'rm' will remove the repo. If USE_LOCK_UNLOCK is set, rm will refuse to
remove a locked repo. All repos are locked by default, and you have to
explicitly 'unlock' a repo to remove it. You can also 'lock' it again
instead of removing it of course.
There's also ARE_YOU_SURE, for situations where a simple warning suffices.
You can also use both these flags if you wish.
2. 'trash' will move the repo to a safe location. There are settings for
where this location is and what suffix is added to the repo name. You can
'list-trash' to see what trash you have collected, and you can 'undelete'
one of the listed repos.
It's easy to automatically clean out the trash occasionally. By default,
entries in the trash look like this:
foo/r1/2010-10-22_13:14:24
foo/r1/2010-10-22_13:14:50
This shows a repo foo/r1 that was created and trashed twice.
Since the date appears in the name, you can use it with a cutoff to clean
up old repos. Untested example:
cutoff=`date -I -d '28 days ago'`
find $TRASH_CAN -type d -name "20??-??-??_*" | while read r
do
d=`basename $r`
[[ $d < $cutoff ]] && rm -rf $d
done
Put this in cron to run once a day and that should be it.

37
contrib/adc/rm Executable file
View file

@ -0,0 +1,37 @@
#!/bin/sh
. $(dirname $0)/adc.common-functions
# options settable in adc.common-functions are
# ARE_YOU_SURE -- prompts "are you sure?"
# USE_LOCK_UNLOCK -- allows delete only if repo is "unlock"ed
# As shipped, both options are set. If you set both of them to "0", repos are
# just deleted blindly, with no confirmation
# helper ADCs: lock, unlock
# cd to repo base and make sure arg1 is a valid repo (also sets $repo)
valid_owned_repo $1
opt $USE_LOCK_UNLOCK && {
if [ -f $repo.git/gl-rm-ok ]
then
:
else
die "$repo is locked! To 'rm' this repository, first 'unlock' it."
fi
}
opt $ARE_YOU_SURE && {
echo "Are you sure? (type 'yes' if you are)" >&2
read s
[ $s = "yes" ] || die aborting...
}
rm -rf $repo.git
echo "$repo is now GONE!"
cd $HOME
PROJECTS_LIST=$(perl -e 'do ".gitolite.rc"; print $PROJECTS_LIST')
export repo
perl -ni -e 'print unless /^\Q$ENV{repo}.git\E$/' $PROJECTS_LIST

View file

@ -1,17 +1,4 @@
#!/bin/sh
#!/bin/bash
. $(dirname $0)/adc.common-functions
delete=$1
get_rights_and_owner $delete
[ "$owner" = "$GL_USER" ] || die "$delete is not yours to delete!"
cd $GL_REPO_BASE_ABS
rm -rf $delete.git
cd $HOME
PROJECTS_LIST=$(perl -e 'do ".gitolite.rc"; print $PROJECTS_LIST')
export delete
perl -ni -e 'print unless /^\Q$ENV{delete}.git\E$/' $PROJECTS_LIST
echo this command has been superceded by the \"rm\" and \"trash\" commands
exit 1

29
contrib/adc/trash Executable file
View file

@ -0,0 +1,29 @@
#!/bin/sh
. $(dirname $0)/adc.common-functions
# options settable in adc.common-functions are
# TRASH_CAN -- where the trashed repos are moved. Can be anywhere that the
# hosting user has write access to. Does not have to be (and ideally
# should NOT be) inside $GL_REPO_BASE_ABS (but see note below)
# TRASH_SUFFIX -- a timestamp, (ideally and by default), to be
# suffixed to the moved repo
# helper ADCs: list-trash, undelete
# NOTE: although I would NOT advise it in the interests of keeping things
# simple, it *is* possible to have even deleted repos be *directly* accessible
# via normal gitolite mechanisms (clone, etc). Here's how:
# (1) make TRASH_CAN point somewhere *within* $REPO_BASE
# (2) change TRASH_SUFFIX to something that has a .git at the end, like:
# TRASH_SUFFIX=`date +%Y-%m-%d-%H-%M-%S`.git
# (3) set ACL rules in conf/gitolite.conf for repos named
# deleted/foo/sitaram/bar.*
# cd to repo base and make sure arg1 is a valid repo (also sets $repo)
valid_owned_repo $1
mkdir -p $TRASH_CAN/$repo 2>/dev/null || die "failed creating directory in trashcan"
[ -d $TRASH_CAN/$repo/$TRASH_SUFFIX ] && die try again in a few seconds
mv $repo.git $TRASH_CAN/$repo/$TRASH_SUFFIX
echo $repo moved to trashcan

16
contrib/adc/undelete Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh
. $(dirname $0)/adc.common-functions
repo=$1
[ -z "$1" ] && die need a repo name
owner=
owner=`cat $TRASH_CAN/$repo/gl-creater 2>/dev/null`
[ "$owner" = "$GL_USER" ] || die "$repo is not yours!"
cd $TRASH_CAN
realrepo=`dirname $repo`
[ -d $GL_REPO_BASE_ABS/$realrepo.git ] && die $realrepo already exists
mv $repo $GL_REPO_BASE_ABS/$realrepo.git
echo $repo restored to $realrepo

12
contrib/adc/unlock Executable file
View file

@ -0,0 +1,12 @@
#!/bin/sh
. $(dirname $0)/adc.common-functions
# this is a helper ADC for "rm"; see that one for documentation
# cd to repo base and make sure arg1 is a valid repo (also sets $repo)
valid_owned_repo $1
touch $repo.git/gl-rm-ok
echo "$repo has been unlocked and can be 'rm'ed or 'lock'ed once again"

View file

@ -37,7 +37,7 @@ our $USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$); # very simple patter
# same as REPONAME, but used for wildcard repos, allows some common regex metas
our $REPOPATT_PATT=qr(^\@?[0-9a-zA-Z[][\\^.$|()[\]*+?{}0-9a-zA-Z._\@/-]*$);
# ADC commands and arguments must match this pattern
our $ADC_CMD_ARGS_PATT=qr(^[0-9a-zA-Z._\@/+-]*$);
our $ADC_CMD_ARGS_PATT=qr(^[0-9a-zA-Z._\@/+:-]*$);
# these come from the RC file
our ($REPO_UMASK, $GL_WILDREPOS, $GL_PACKAGE_CONF, $GL_PACKAGE_HOOKS, $REPO_BASE, $GL_CONF_COMPILED, $GL_BIG_CONFIG, $GL_PERFLOGT, $PROJECTS_LIST, $GL_ALL_INCLUDES_SPECIAL, $GL_SITE_INFO, $GL_GET_MEMBERSHIPS_PGM);