@@ -31,7 +31,7 @@ BEGIN {
json_bool from_json ref_indicator get_token_key
get_timed_token get_token_field check_timed_token
valid_branch_name get_project_from_dir
- get_git_chomp);
+ get_git_chomp check_readonly is_readonly);
}
BEGIN {require "Girocco/extra/capture_command.pl"}
@@ -1085,6 +1085,32 @@ sub is_git_dir {
return $hv =~ /^[0-9a-f]{40}/;
}
+# quick check that only tests for the existence of the file but
+# does not attempt to actually open it and read the contents
+sub is_readonly {
+ return -f "$Girocco::Config::chroot/etc/readonly" ? 1 : 0;
+}
+
+# return string containing read-only message if in read-only mode
+# otherwise return empty string
+# if the first argument is true, include a <br /> tag before the second
+# but only if there is a second line
+sub check_readonly {
+ my $brtag = $_[0] ? "<br />" : "";
+ my $msg = "";
+ if (-f "$Girocco::Config::chroot/etc/readonly") {
+ $msg = "$Girocco::Config::name is currently read-only, please try again later.";
+ my $romsg = "";
+ if (open my $fd, '<', "$Girocco::Config::chroot/etc/readonly") {
+ local $/;
+ $romsg = <$fd>;
+ close $fd;
+ }
+ $romsg ne "" and $msg = $msg . "$brtag\n" . $romsg;
+ }
+ return $msg;
+}
+
# Returns a PATH properly prefixed which guarantees that Git is found and the
# basedir/bin utilities are found as intended. $ENV{PATH} is LEFT UNCHANGED!
# Caller is responsible for assigning result to $ENV{PATH} or otherwise
@@ -377,6 +377,19 @@ if ! [ -f "$dir/.nofetch" ]; then
exit 1
fi
+if [ -f "$cfg_chroot/etc/readonly" ]; then
+ msgro="$cfg_name is currently read-only, please try again later."
+ msgro2=""
+ if [ -s "$cfg_chroot/etc/readonly" ]; then
+ msgro2="$(cat "$cfg_chroot/etc/readonly" 2>/dev/null)" || :
+ fi
+ if [ -n "$msgro2" ]; then
+ forbidden "$msgro" "$msgro2"
+ else
+ forbidden "$msgro"
+ fi
+fi
+
# Set up the correct backend command depending on cfg_max_file_size512
if [ "${cfg_max_file_size512:-0}" = "0" ]; then
GIT_HTTP_BACKEND='"$cfg_git_http_backend_bin"'
@@ -33,12 +33,14 @@ if ! [ -x @perlbin@ ]; then
XDG_CONFIG_HOME=/var/empty
HOME=/etc/girocco
GIT_ASKPASS=/bin/git-askpass-password
+ rofile=/etc/readonly
else
# We are NOT INSIDE the chroot
reporoot=@reporoot@
XDG_CONFIG_HOME=@chroot@/var/empty
HOME=@chroot@/etc/girocco
GIT_ASKPASS=@basedir@/bin/git-askpass-password
+ rofile=@chroot@/etc/readonly
fi
mob=@mob@
webadmurl=@webadmurl@
@@ -50,6 +52,7 @@ var_upload_window=@upload_pack_window@
cfg_fetch_stash_refs=@fetch_stash_refs@
cfg_suppress_git_ssh_logging=@suppress_git_ssh_logging@
cfg_max_file_size512=@max_file_size512@
+cfg_name=@cfg_name@
export XDG_CONFIG_HOME
export HOME
@@ -247,6 +250,17 @@ if [ "$type" = 'receive-pack' ] && ! [ -f "$dir/.nofetch" ]; then
exit 3
fi
+if [ -f "$rofile" ]; then
+ msgro="$cfg_name is currently read-only, please try again later."
+ msgro2=""
+ if [ -s "$rofile" ]; then
+ msgro2="$(cat "$rofile" 2>/dev/null)" || :
+ fi
+ echo "$msgro" >&2
+ [ -z "$msgro2" ] || echo "$msgro2" >&2
+ exit 3
+fi
+
GIT_SHELL='git-shell'
if [ "$type" = 'receive-pack' ]; then
git_add_config 'receive.unpackLimit=1'
@@ -31,6 +31,11 @@ if (!Girocco::Project::does_exist($name,1)) {
exit;
}
+if (my $romsg=check_readonly(1)) {
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
my $proj = Girocco::Project->load($name);
if (!$proj) {
print "<p>not found project $name, that's really weird!</p>\n";
@@ -31,6 +31,11 @@ if ($cgi->param('mail')) {
exit;
}
+if (my $romsg=check_readonly(1)) {
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
sub _auth_form {
my ($name, $submit) = @_;
print <<EOT;
@@ -49,6 +49,11 @@ if (!Girocco::Project::does_exist($name,1)) {
exit;
}
+if (my $romsg=check_readonly(1)) {
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
my $proj = Girocco::Project->load($name);
if (!$proj) {
print "<p>not found project $name, that's really weird!</p>\n";
@@ -25,6 +25,11 @@ if ($cgi->param('mail')) {
exit;
}
+if (my $romsg=check_readonly(1)) {
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
sub _auth_form {
my $name = shift;
my $submit = shift;
@@ -32,6 +32,11 @@ if (!Girocco::Project::does_exist($name,1)) {
exit;
}
+if (my $romsg=check_readonly(1)) {
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
my $proj = Girocco::Project->load($name);
if (!$proj) {
print "<p>not found project $name, that's really weird!</p>\n";
@@ -37,6 +37,11 @@ if (!Girocco::Project::does_exist($name,1)) {
exit;
}
+if (my $romsg=check_readonly(1)) {
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
my $proj = Girocco::Project->load($name);
if (!$proj) {
print "<p>not found project $name, that's really weird!</p>\n";
@@ -14,6 +14,11 @@ use Girocco::Util;
my $gcgi = Girocco::CGI->new('Project Registration');
my $cgi = $gcgi->cgi;
+if (my $romsg=check_readonly(1)) {
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
my $name = $cgi->param('name');
defined($name) or $name = '';
@@ -24,6 +24,11 @@ if ($cgi->param('mail')) {
exit;
}
+if (my $romsg=check_readonly(1)) {
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
my $y0 = $cgi->param('y0') || '';
if ($cgi->param('name') && $y0 eq 'Register' && $cgi->request_method eq 'POST') {
# submitted, let's see
@@ -27,6 +27,12 @@ if ($cgi->request_method ne 'POST' || $pname eq '') {
exit;
}
+if (my $romsg=check_readonly(1)) {
+ print $cgi->header(-status=>403);
+ print "<p>$romsg</p>\n";
+ exit;
+}
+
my $proj = Girocco::Project::does_exist($pname, 1) && Girocco::Project->load($pname);
if (not $proj) {
print $cgi->header(-status=>404);
# Pull Girocco config
use lib "__BASEDIR__";
use Girocco::Config;
-use Girocco::Util qw(url_path git_add_config);
+use Girocco::Util qw(url_path git_add_config is_readonly);
use Digest::MD5 qw(md5_hex);
BEGIN {
eval { require HTML::Email::Obfuscate; 1 } or
@@ -174,6 +174,12 @@ our $site_name = $Girocco::Config::title;
## html text to include at home page
our $home_text = "$Girocco::Config::basedir/gitweb/indextext.html";
+## read-only version of text, but only when in read-only mode and this exists
+## note that when running in a fastcgi mode, changes to read-only mode will
+## not show up with regards to this text until the next fastcgi instance
+## spawns -- use a "graceful" web server restart to force an immediate effect
+our $home_text_ro = "$Girocco::Config::basedir/gitweb/indextext_readonly.html";
+
## URI of stylesheets
our @stylesheets = ("@{[url_path($Girocco::Config::gitwebfiles)]}/gitweb.css");
@@ -251,6 +257,10 @@ $feature{'actions'}{'default'}=[
# have already been completed by now it's safe to "cd /" at this point.
chdir "/";
+# If in read-only mode and $home_text_ro exists, set $home_text to it
+defined($home_text_ro) && $home_text_ro ne "" && is_readonly() && -f $home_text_ro and
+ $home_text = $home_text_ro;
+
# Stuff extra Git configuration options into GIT_CONFIG_PARAMETERS
# This mirrors what shlib.sh does (mostly)
# Only the options that are appropriate for gitweb are included here
@@ -1058,8 +1058,15 @@ rm -rf "$basedir/cgi"
[ -z "$webreporoot" ] || { rm -f "$webreporoot" && ln -s "$cfg_reporoot" "$webreporoot"; }
if [ -z "$cfg_httpspushurl" ] || [ -n "$cfg_pretrustedroot" ]; then
grep -v 'rootcert[.]html' gitweb/indextext.html >"$basedir/gitweb/indextext.html"
+ if [ -f gitweb/indextext_readonly.html ]; then
+ grep -v 'rootcert[.]html' gitweb/indextext_readonly.html \
+ >"$basedir/gitweb/indextext_readonly.html"
+ fi
else
cp gitweb/indextext.html "$basedir/gitweb"
+ if [ -f gitweb/indextext_readonly.html ]; then
+ cp gitweb/indextext_readonly.html "$basedir/gitweb"
+ fi
fi
mv "$basedir"/html/*.css "$basedir"/html/*.js "$webroot"
cp mootools.js "$webroot"