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"
|
||||
;;
|
||||
* )
|
||||
loc="$GL_REPO_BASE_ABS/$1.git"
|
||||
[ -d $loc ] && locs="$locs $GL_REPO_BASE_ABS/$1.git"
|
||||
[ -d $loc ] || echo "ignoring $1..."
|
||||
;;
|
||||
|
@ -25,6 +26,8 @@ do
|
|||
shift
|
||||
done
|
||||
|
||||
[[ -z "$locs" ]] && die "give me '@all' or some reponame"
|
||||
|
||||
case $op in
|
||||
en|enable )
|
||||
for l in $locs
|
||||
|
@ -35,9 +38,13 @@ case $op in
|
|||
dis|disable )
|
||||
# bashism
|
||||
read msg <<<$(cat)
|
||||
echo disabling following locations with message:
|
||||
echo $msg
|
||||
echo
|
||||
for l in $locs
|
||||
do
|
||||
echo $msg > $l/.gitolite.down
|
||||
echo $l
|
||||
done
|
||||
;;
|
||||
* )
|
||||
|
|
|
@ -28,6 +28,7 @@ In this document:
|
|||
* <a href="#_personal_branches">"personal" branches</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="#_disabling_write_access_to_take_backups">disabling write access to take backups</a>
|
||||
* <a href="#_INconvenience_features">INconvenience features</a>
|
||||
* <a href="#_deleting_a_repo">deleting a repo</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
|
||||
`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>
|
||||
|
||||
#### 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
|
||||
the config file). Wildcards are not supported; patches welcome ;-)
|
||||
|
||||
**NOTE: This needs a specific secondary update hook**. Creating a secondary
|
||||
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):
|
||||
Note: please see [this][diswr] for more on this.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
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
|
||||
[diswr]: http://github.com/sitaramc/gitolite/blob/pu/doc/3-faq-tips-etc.mkd#_disabling_write_access_to_take_backups
|
||||
|
||||
<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
|
||||
# ----------------------------------------------------------------------------
|
||||
|
|
|
@ -246,6 +246,9 @@ my $aa = ($verb =~ $R_COMMANDS ? 'R' : 'W');
|
|||
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/;
|
||||
|
||||
# check if repo is write-enabled
|
||||
&check_repo_write_enabled($repo) if $aa eq 'W';
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 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