gitolite-down: disable write-access to take backups
(we quietly do not document the 'able' adc, which is now the most "official" adc in the sense that it has a new test, t64-write-able!) other notes: fix bug in 'able' (not setting $loc)
This commit is contained in:
parent
16ab95665c
commit
7313d48247
|
@ -18,6 +18,7 @@ do
|
||||||
locs="$locs $HOME"
|
locs="$locs $HOME"
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
|
loc="$GL_REPO_BASE_ABS/$1.git"
|
||||||
[ -d $loc ] && locs="$locs $GL_REPO_BASE_ABS/$1.git"
|
[ -d $loc ] && locs="$locs $GL_REPO_BASE_ABS/$1.git"
|
||||||
[ -d $loc ] || echo "ignoring $1..."
|
[ -d $loc ] || echo "ignoring $1..."
|
||||||
;;
|
;;
|
||||||
|
@ -25,6 +26,8 @@ do
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
|
[[ -z "$locs" ]] && die "give me '@all' or some reponame"
|
||||||
|
|
||||||
case $op in
|
case $op in
|
||||||
en|enable )
|
en|enable )
|
||||||
for l in $locs
|
for l in $locs
|
||||||
|
@ -35,9 +38,13 @@ case $op in
|
||||||
dis|disable )
|
dis|disable )
|
||||||
# bashism
|
# bashism
|
||||||
read msg <<<$(cat)
|
read msg <<<$(cat)
|
||||||
|
echo disabling following locations with message:
|
||||||
|
echo $msg
|
||||||
|
echo
|
||||||
for l in $locs
|
for l in $locs
|
||||||
do
|
do
|
||||||
echo $msg > $l/.gitolite.down
|
echo $msg > $l/.gitolite.down
|
||||||
|
echo $l
|
||||||
done
|
done
|
||||||
;;
|
;;
|
||||||
* )
|
* )
|
||||||
|
|
|
@ -28,6 +28,7 @@ In this document:
|
||||||
* <a href="#_personal_branches">"personal" branches</a>
|
* <a href="#_personal_branches">"personal" branches</a>
|
||||||
* <a href="#_custom_hooks_and_custom_git_config">custom hooks and custom git config</a>
|
* <a href="#_custom_hooks_and_custom_git_config">custom hooks and custom git config</a>
|
||||||
* <a href="#_bypassing_gitolite">bypassing gitolite</a>
|
* <a href="#_bypassing_gitolite">bypassing gitolite</a>
|
||||||
|
* <a href="#_disabling_write_access_to_take_backups">disabling write access to take backups</a>
|
||||||
* <a href="#_INconvenience_features">INconvenience features</a>
|
* <a href="#_INconvenience_features">INconvenience features</a>
|
||||||
* <a href="#_deleting_a_repo">deleting a repo</a>
|
* <a href="#_deleting_a_repo">deleting a repo</a>
|
||||||
* <a href="#_helping_with_gitweb">helping with gitweb</a>
|
* <a href="#_helping_with_gitweb">helping with gitweb</a>
|
||||||
|
@ -540,6 +541,33 @@ is NOT available if you bypass gitolite. Mucking with that repo in this
|
||||||
manner is strongly discouraged, as in "are you feeling lucky today?". Use
|
manner is strongly discouraged, as in "are you feeling lucky today?". Use
|
||||||
`gl-dont-panic` if you need to do some server-side surgery for that repo.
|
`gl-dont-panic` if you need to do some server-side surgery for that repo.
|
||||||
|
|
||||||
|
<a name="_disabling_write_access_to_take_backups"></a>
|
||||||
|
|
||||||
|
##### disabling write access to take backups
|
||||||
|
|
||||||
|
If you want to take normal, OS-level, backups of the system, you might want
|
||||||
|
git to be quiescent during that time, so that the backup is clean. The best
|
||||||
|
way to do this is to disable write-access to the server for the duration of
|
||||||
|
the backup.
|
||||||
|
|
||||||
|
Here's how:
|
||||||
|
|
||||||
|
cd $HOME # if running as "git" user, else "cd ~git" or whatever
|
||||||
|
echo writes disabled during backup window > .gitolite.down
|
||||||
|
|
||||||
|
# << RUN YOUR BACKUP COMMAND(s) HERE >>
|
||||||
|
|
||||||
|
rm .gitolite.down
|
||||||
|
|
||||||
|
I leave it to you to
|
||||||
|
|
||||||
|
* make sure that if the backup script fails, the `.gitolite.down` file is
|
||||||
|
still removed (or not; maybe your policy is that if the backup failed, no
|
||||||
|
further writes are allowed. Whatever...)
|
||||||
|
* if you're extremely paranoid (even I wouldn't worry about this!) make sure
|
||||||
|
that no push is *in progress* by checking for any `git-receive-pack`
|
||||||
|
processes in a `ps` output.
|
||||||
|
|
||||||
<a name="_INconvenience_features"></a>
|
<a name="_INconvenience_features"></a>
|
||||||
|
|
||||||
#### INconvenience features
|
#### INconvenience features
|
||||||
|
|
|
@ -189,26 +189,9 @@ You can also do this for one or more individual repos; in place of `@all`,
|
||||||
just use a space separated list of reponames (exactly as they would appear in
|
just use a space separated list of reponames (exactly as they would appear in
|
||||||
the config file). Wildcards are not supported; patches welcome ;-)
|
the config file). Wildcards are not supported; patches welcome ;-)
|
||||||
|
|
||||||
**NOTE: This needs a specific secondary update hook**. Creating a secondary
|
Note: please see [this][diswr] for more on this.
|
||||||
update hook is described in the sections on "custom hooks" and "hook chaining"
|
|
||||||
in doc/2. You need code like this in `update.secondary` (don't forget to
|
|
||||||
`chmod +x` the file):
|
|
||||||
|
|
||||||
#!/bin/bash
|
[diswr]: http://github.com/sitaramc/gitolite/blob/pu/doc/3-faq-tips-etc.mkd#_disabling_write_access_to_take_backups
|
||||||
|
|
||||||
for f in $HOME/.gitolite.down $PWD/.gitolite.down
|
|
||||||
do
|
|
||||||
if [ -f $f ]
|
|
||||||
then
|
|
||||||
echo >&2
|
|
||||||
echo '*** ABORT ***' >&2
|
|
||||||
echo >&2
|
|
||||||
cat $f >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
|
|
||||||
<a name="_bonus_restricted_admin"></a>
|
<a name="_bonus_restricted_admin"></a>
|
||||||
|
|
||||||
|
|
|
@ -787,6 +787,16 @@ sub can_read {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# helper to manage "disabling" a repo or the whole site for "W" access
|
||||||
|
sub check_repo_write_enabled {
|
||||||
|
my ($repo) = shift;
|
||||||
|
for my $d ("$ENV{HOME}/.gitolite.down", "$ENV{GL_REPO_BASE_ABS}/$repo.git/.gitolite.down") {
|
||||||
|
next unless -f $d;
|
||||||
|
die $ABRT . `cat $d` if -s $d;
|
||||||
|
die $ABRT . "writes are currently disabled\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# setup the ~/.ssh/authorized_keys file
|
# setup the ~/.ssh/authorized_keys file
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -246,6 +246,9 @@ my $aa = ($verb =~ $R_COMMANDS ? 'R' : 'W');
|
||||||
die "$aa access for $repo DENIED to $user
|
die "$aa access for $repo DENIED to $user
|
||||||
(Or there may be no repository at the given path. Did you spell it correctly?)\n" unless $perm =~ /$aa/;
|
(Or there may be no repository at the given path. Did you spell it correctly?)\n" unless $perm =~ /$aa/;
|
||||||
|
|
||||||
|
# check if repo is write-enabled
|
||||||
|
&check_repo_write_enabled($repo) if $aa eq 'W';
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# over to git now
|
# over to git now
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
154
t/t64-write-able
Normal file
154
t/t64-write-able
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
# vim: syn=sh:
|
||||||
|
for bc in 0 1
|
||||||
|
do
|
||||||
|
cd $TESTDIR
|
||||||
|
$TESTDIR/rollback || die "rollback failed"
|
||||||
|
editrc GL_BIG_CONFIG $bc
|
||||||
|
editrc GL_WILDREPOS 1
|
||||||
|
|
||||||
|
rm -rf /tmp/glt-adc
|
||||||
|
mkdir /tmp/glt-adc || die "mkdir /tmp/glt-adc failed"
|
||||||
|
cp ../contrib/adc/* /tmp/glt-adc
|
||||||
|
echo "\$GL_ADC_PATH = '/tmp/glt-adc';" | addrc
|
||||||
|
runremote rm -f .gitolite.down
|
||||||
|
|
||||||
|
# ----------
|
||||||
|
|
||||||
|
name "INTERNAL"
|
||||||
|
echo "
|
||||||
|
@leads = u1 u2
|
||||||
|
@devs = u1 u2 u3 u4
|
||||||
|
|
||||||
|
repo foo
|
||||||
|
RW+ = u1
|
||||||
|
|
||||||
|
@gbar = bar/CREATOR/..*
|
||||||
|
repo @gbar
|
||||||
|
C = @leads
|
||||||
|
RW+ = @leads
|
||||||
|
RW = @devs
|
||||||
|
" | ugc
|
||||||
|
expect_push_ok "master -> master"
|
||||||
|
|
||||||
|
name "u1 push foo"
|
||||||
|
cd ~/td
|
||||||
|
rm -rf foo
|
||||||
|
runlocal git clone u1:foo
|
||||||
|
expect "warning: You appear to have cloned an empty repository."
|
||||||
|
cd foo
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect_push_ok "master -> master"
|
||||||
|
|
||||||
|
name "u2 create and push bar/u2/r1"
|
||||||
|
cd ~/td
|
||||||
|
runlocal git clone u2:bar/u2/r1
|
||||||
|
expect "Initialized empty Git repository in /home/gitolite-test/repositories/bar/u2/r1.git/"
|
||||||
|
expect "warning: You appear to have cloned an empty repository."
|
||||||
|
cd r1
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect_push_ok "master -> master"
|
||||||
|
|
||||||
|
name "disable entire site"
|
||||||
|
runremote ls -al .gitolite.down
|
||||||
|
expect "ls: cannot access .gitolite.down: No such file or directory"
|
||||||
|
(echo first line; echo second line) | runlocal ssh gitolite able dis
|
||||||
|
expect "give me '@all' or some reponame"
|
||||||
|
(echo first line; echo second line) | runlocal ssh gitolite able dis @all
|
||||||
|
expect "disabling following locations with message:"
|
||||||
|
expect "first line second line"
|
||||||
|
expect "/home/gitolite-test"
|
||||||
|
runremote ls -al .gitolite.down
|
||||||
|
expect "^.rw------- 1 gitolite-test gitolite-test .. ... .. ..:.. .gitolite.down"
|
||||||
|
|
||||||
|
name "u1 push foo fail"
|
||||||
|
cd ~/td/foo
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect ABORTING
|
||||||
|
expect "first line second line"
|
||||||
|
expect "fatal: The remote end hung up unexpectedly"
|
||||||
|
|
||||||
|
name "u2 create and push bar/u2/r1 fail"
|
||||||
|
cd ~/td/r1
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect ABORTING
|
||||||
|
expect "first line second line"
|
||||||
|
expect "fatal: The remote end hung up unexpectedly"
|
||||||
|
|
||||||
|
name "enable entire site"
|
||||||
|
runlocal ssh gitolite able en
|
||||||
|
expect "give me '@all' or some reponame"
|
||||||
|
runlocal ssh gitolite able en @all
|
||||||
|
expect "removed ./home/gitolite-test/.gitolite.down."
|
||||||
|
runremote ls -al .gitolite.down
|
||||||
|
expect "ls: cannot access .gitolite.down: No such file or directory"
|
||||||
|
|
||||||
|
name "u1 push foo"
|
||||||
|
cd ~/td/foo
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect_push_ok "master -> master"
|
||||||
|
|
||||||
|
name "u2 create and push bar/u2/r1"
|
||||||
|
cd ~/td/r1
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect_push_ok "master -> master"
|
||||||
|
|
||||||
|
name "disable foo"
|
||||||
|
runlocal ssh u1 able dis foo
|
||||||
|
expect "just .what. are you trying to pull, young man"
|
||||||
|
echo foo down|runlocal ssh gitolite able dis foo
|
||||||
|
expect "disabling following locations with message:"
|
||||||
|
expect "foo down"
|
||||||
|
expect "/home/gitolite-test/repositories/foo.git"
|
||||||
|
runremote ls -al /home/gitolite-test/repositories/foo.git/.gitolite.down
|
||||||
|
expect ".rw------- 1 gitolite-test gitolite-test . ... .. ..:.. /home/gitolite-test/repositories/foo.git/.gitolite.down"
|
||||||
|
|
||||||
|
name "u1 push foo fail"
|
||||||
|
cd ~/td/foo
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect ABORTING
|
||||||
|
expect "foo down"
|
||||||
|
expect "fatal: The remote end hung up unexpectedly"
|
||||||
|
|
||||||
|
name "u2 create and push bar/u2/r1"
|
||||||
|
cd ~/td/r1
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect_push_ok "master -> master"
|
||||||
|
|
||||||
|
name "enable foo, disable bar/u2/r1"
|
||||||
|
runlocal ssh u1 able en foo
|
||||||
|
expect "just .what. are you trying to pull, young man"
|
||||||
|
runlocal ssh gitolite able en foo
|
||||||
|
expect "removed ./home/gitolite-test/repositories/foo.git/.gitolite.down."
|
||||||
|
echo bar/u2/r1 down | runlocal ssh u1 able dis foo
|
||||||
|
expect "just .what. are you trying to pull, young man"
|
||||||
|
echo bar/u2/r1 down | runlocal ssh gitolite able dis bar/u2/r1
|
||||||
|
expect "disabling following locations with message:"
|
||||||
|
expect "bar/u2/r1 down"
|
||||||
|
expect "/home/gitolite-test/repositories/bar/u2/r1.git"
|
||||||
|
runremote ls -al /home/gitolite-test/repositories/bar/u2/r1.git/.gitolite.down
|
||||||
|
expect ".rw------- 1 gitolite-test gitolite-test .. ... .. ..:.. /home/gitolite-test/repositories/bar/u2/r1.git/.gitolite.down"
|
||||||
|
|
||||||
|
name "u1 push foo"
|
||||||
|
cd ~/td/foo
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect_push_ok "master -> master"
|
||||||
|
|
||||||
|
name "u2 create and push bar/u2/r1i fail"
|
||||||
|
cd ~/td/r1
|
||||||
|
mdc; mdc
|
||||||
|
runlocal git push origin master
|
||||||
|
expect ABORTING
|
||||||
|
expect "bar/u2/r1 down"
|
||||||
|
expect "fatal: The remote end hung up unexpectedly"
|
||||||
|
|
||||||
|
name "INTERNAL"
|
||||||
|
done
|
Loading…
Reference in a new issue