install.sh: compute a 'usejail' value and use it
[girocco.git] / install.sh
blobb41d8abc9bbdc589c9c09a7bdab9cd06856854f8
1 #!/bin/sh
2 # The Girocco installation script
3 # We will OVERWRITE basedir!
5 set -e
7 [ -n "$MAKE" ] || MAKE="$(MAKEFLAGS= make -s gnu_make_command_name | grep '^gnu_make_command_name=' | sed 's/^[^=]*=//')"
8 if [ -z "$MAKE" ]; then
9 echo "ERROR: cannot determine name of the GNU make command" >&2
10 echo "Please set MAKE to the name of the GNU make executable" >&2
11 exit 1
14 # Run perl module checker
15 if ! [ -f toolbox/check-perl-modules.pl ] || ! [ -x toolbox/check-perl-modules.pl ]; then
16 echo "ERROR: missing toolbox/check-perl-modules.pl!" >&2
17 exit 1
20 # What Config should we use?
21 [ -n "$GIROCCO_CONF" ] || GIROCCO_CONF=Girocco::Config
22 echo "*** Initializing using $GIROCCO_CONF..."
24 # First run Girocco::Config consistency checks
25 perl -I"$PWD" -M$GIROCCO_CONF -e ''
27 . ./shlib.sh
28 umask 0022
29 "$var_perl_bin" toolbox/check-perl-modules.pl
31 # Config.pm already checked $cfg_reporoot to require an absolute path, but
32 # we also require it does not contain a : or ; that would cause problems when
33 # used in GIT_ALTERNATE_OBJECT_DIRECTORIES
34 probch=':;'
35 case "$cfg_reporoot" in *[$probch]*)
36 echo "fatal: \$Girocco::Config::reporoot may not contain ':' or ';' characters" >&2
37 exit 1
38 esac
40 warn() { printf >&2 '%s\n' "$*"; }
41 die() { warn "$@"; exit 1; }
43 # Either we must run as root (but preferably not if disable_jailsetup is true)
44 # or the mirror_user (preferred choice for disable_jailsetup).
45 isroot=
46 [ "$(id -u)" -ne 0 ] || isroot=1
47 if [ -n "$isroot" ]; then
48 if [ "${cfg_disable_jailsetup:-0}" != "0" ]; then
49 cat <<'EOT'
51 ***
52 *** WARNING: $Girocco::Config::disable_jailsetup has been enabled
53 *** WARNING: but installation is being performed as the superuser
54 ***
56 You appear to have disabled jailsetup which is perfectly fine for installations
57 that will not be using an ssh jail. However, in that case, running the install
58 process as the superuser is highly discouraged.
60 Instead, running it as the configured $Girocco::Config::mirror_user is much
61 preferred.
63 The install process will now pause for 10 seconds to give you a chance to abort
64 it before continuing to install a disable_jailsetup config as the superuser.
66 EOT
67 sleep 10 || die "install aborted"
69 else
70 [ -n "$cfg_mirror_user" ] || die 'Girocco::Config.pm $mirror_user must be set'
71 curuname="$(id -un)"
72 [ -n "$curuname" ] || die "Cannot determine name of current user"
73 if [ "$cfg_mirror_user" != "$curuname" ]; then
74 warn "ERROR: install must run as superuser or Config.pm's \$mirror_user ($cfg_mirror_user)"
75 die "ERROR: install is currently running as $curuname"
79 # $1 must exist and be a dir
80 # $2 may exist but must be a dir
81 # $3 must not exist
82 # After call $2 will be renamed to $3 (if $2 existed)
83 # And $1 will be renamed to $2
84 quick_move() {
85 [ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] || { echo "fatal: quick_move: bad args: '$1' '$2' '$3'" >&2; exit 1; }
86 ! [ -e "$3" ] || { echo "fatal: quick_move: already exists: $3" >&2; exit 1; }
87 [ -d "$1" ] || { echo "fatal: quick_move: no such dir: $1" >&2; exit 1; }
88 ! [ -e "$2" ] || [ -d "$2" ] || { echo "fatal: quick_move: not a dir: $2" >&2; exit 1; }
89 perl -e 'rename($ARGV[1], $ARGV[2]) or die "rename failed: $!\n" if -d $ARGV[1];
90 rename($ARGV[0], $ARGV[1]) or die "rename failed: $!\n"; exit 0;' "$1" "$2" "$3" || {
91 echo "fatal: quick_move: rename failed" >&2
92 exit 1
94 ! [ -d "$1" ] && [ -d "$2" ] || {
95 echo "fatal: quick_move: rename failed" >&2
96 exit 1
100 check_sh_builtin() (
101 "unset" -f command
102 "command" "$var_sh_bin" -c '{ "unset" -f unalias command "$1" || :; "unalias" "$1" || :; } >/dev/null 2>&1; "command" -v "$1"' "$var_sh_bin" "$1"
103 ) 2>/dev/null
105 owngroup=
106 [ -z "$cfg_owning_group" ] || owngroup=":$cfg_owning_group"
107 if [ -n "$cfg_httpspushurl" ] && [ -z "$cfg_certsdir" ]; then
108 echo "ERROR: \$httpspushurl is set but \$certsdir is not!" >&2
109 echo "ERROR: perhaps you have an incorrect Config.pm?" >&2
110 exit 1
114 # Check for extra required tools
115 if [ "${cfg_xmllint_readme:-0}" != "0" ] && ! command -v xmllint >/dev/null; then
116 echo "ERROR: \$xmllint_readme set but xmllint not in \$PATH!" >&2
117 exit 1
121 echo "*** Checking for compiled utilities..."
122 if ! [ -f src/can_user_push ] || ! [ -x src/can_user_push ]; then
123 echo "ERROR: src/can_user_push is not built! Did you _REALLY_ read INSTALL?" >&2
124 echo "ERROR: perhaps you forgot to run make?" >&2
125 exit 1
127 if ! [ -f src/can_user_push_http ] || ! [ -x src/can_user_push_http ]; then
128 echo "ERROR: src/can_user_push_http is not built! Did you _REALLY_ read INSTALL?" >&2
129 echo "ERROR: perhaps you forgot to run make?" >&2
130 exit 1
132 if ! [ -f src/getent ] || ! [ -x src/getent ]; then
133 echo "ERROR: src/getent is not built! Did you _REALLY_ read INSTALL?" >&2
134 echo "ERROR: perhaps you forgot to run make?" >&2
135 exit 1
137 if ! [ -f src/get_user_uuid ] || ! [ -x src/get_user_uuid ]; then
138 echo "ERROR: src/get_user_uuid is not built! Did you _REALLY_ read INSTALL?" >&2
139 echo "ERROR: perhaps you forgot to run make?" >&2
140 exit 1
142 if ! [ -f src/list_packs ] || ! [ -x src/list_packs ]; then
143 echo "ERROR: src/list_packs is not built! Did you _REALLY_ read INSTALL?" >&2
144 echo "ERROR: perhaps you forgot to run make?" >&2
145 exit 1
147 if ! [ -f src/peek_packet ] || ! [ -x src/peek_packet ]; then
148 echo "ERROR: src/peek_packet is not built! Did you _REALLY_ read INSTALL?" >&2
149 echo "ERROR: perhaps you forgot to run make?" >&2
150 exit 1
152 if ! [ -f src/rangecgi ] || ! [ -x src/rangecgi ]; then
153 echo "ERROR: src/rangecgi is not built! Did you _REALLY_ read INSTALL?" >&2
154 echo "ERROR: perhaps you forgot to run make?" >&2
155 exit 1
157 if ! [ -f src/readlink ] || ! [ -x src/readlink ]; then
158 echo "ERROR: src/readlink is not built! Did you _REALLY_ read INSTALL?" >&2
159 echo "ERROR: perhaps you forgot to run make?" >&2
160 exit 1
162 if ! [ -f src/strftime ] || ! [ -x src/strftime ]; then
163 echo "ERROR: src/strftime is not built! Did you _REALLY_ read INSTALL?" >&2
164 echo "ERROR: perhaps you forgot to run make?" >&2
165 exit 1
167 if ! [ -f src/throttle ] || ! [ -x src/throttle ]; then
168 echo "ERROR: src/throttle is not built! Did you _REALLY_ read INSTALL?" >&2
169 echo "ERROR: perhaps you forgot to run make?" >&2
170 exit 1
172 if ! [ -f src/ulimit512 ] || ! [ -x src/ulimit512 ]; then
173 echo "ERROR: src/ulimit512 is not built! Did you _REALLY_ read INSTALL?" >&2
174 echo "ERROR: perhaps you forgot to run make?" >&2
175 exit 1
177 ebin="/bin/echo"
178 if [ ! -x "$ebin" ] && [ -x "/usr/bin/echo" ]; then
179 ebin="/usr/bin/echo"
181 if [ ! -x "$ebin" ]; then
182 echo "ERROR: neither /bin/echo nor /usr/bin/echo found" >&2
183 echo "ERROR: at least one must be present for testing during install" >&2
184 exit 1
186 ec=999
187 tmpfile="$(mktemp "/tmp/ul512-$$-XXXXXX")"
188 { src/ulimit512 -f 0 "$ebin" test >"$tmpfile" || ec=$?; } >/dev/null 2>&1
189 rm -f "$tmpfile"
190 if [ "$ec" = "999" ] || [ "$ec" = "0" ]; then
191 echo "ERROR: src/ulimit512 is built, but broken!" >&2
192 echo "ERROR: exceeding file size limit did not fail!" >&2
193 exit 1
195 if ! [ -f src/ltsha256 ] || ! [ -x src/ltsha256 ]; then
196 echo "ERROR: src/ltsha256 is not built! Did you _REALLY_ read INSTALL?" >&2
197 echo "ERROR: perhaps you forgot to run make?" >&2
198 exit 1
200 sha256check="15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225"
201 sha256result="$(printf '%s' '123456789' | src/ltsha256)"
202 if [ "$sha256check" != "$sha256result" ]; then
203 echo "ERROR: src/ltsha256 is built, but broken!" >&2
204 echo "ERROR: verifying sha256 hash of '123456789' failed!" >&2
205 exit 1
209 echo "*** Checking for ezcert..."
210 if ! [ -f ezcert.git/CACreateCert ] || ! [ -x ezcert.git/CACreateCert ]; then
211 echo "ERROR: ezcert.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
212 exit 1
216 echo "*** Checking for git..."
217 case "$cfg_git_bin" in /*) :;; *)
218 echo 'ERROR: $Girocco::Config::git_bin must be set to an absolute path' >&2
219 exit 1
220 esac
221 if ! [ -f "$cfg_git_bin" ] || ! [ -x "$cfg_git_bin" ]; then
222 echo "ERROR: $cfg_git_bin does not exist or is not executable" >&2
223 exit 1
225 if ! git_version="$("$cfg_git_bin" version)" || [ -z "$git_version" ]; then
226 echo "ERROR: $cfg_git_bin version failed" >&2
227 exit 1
229 case "$git_version" in
230 [Gg]"it version "*) :;;
232 echo "ERROR: '$cfg_git_bin version' output does not start with 'git version '" >&2
233 exit 1
234 esac
235 echo "Found $cfg_git_bin $git_version"
236 git_vernum="$(echo "$git_version" | sed -ne 's/^[^0-9]*\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$/\1/p')"
237 echo "*** Checking Git $git_vernum for compatibility..."
238 if [ "$(vcmp "$git_vernum" 1.6.6)" -lt 0 ]; then
239 echo 'ERROR: $Girocco::Config::git_bin must be at least Git version 1.6.6'
240 exit 1
242 if [ "$(vcmp "$git_vernum" 1.6.6.3)" -lt 0 ]; then
243 echo 'WARNING: $Girocco::Config::git_bin version < 1.6.6.3, clients will not see useful error messages'
245 if [ "$(vcmp "$git_vernum" 1.7.3)" -lt 0 ]; then
246 cat <<'EOT'
249 *** SEVERE WARNING: $Girocco::Config::git_bin is set to a version of Git before 1.7.3
252 Some Girocco functionality will be gracefully disabled and other things will
253 just not work at all such as race condition protection against simultaneous
254 client pushes and server garbage collections.
258 if [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 1.7.5)" -lt 0 ]; then
259 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.5 and mirroring enabled, some sources can cause an infinite fetch loop'
261 if [ "$(vcmp "$git_vernum" 1.7.6.6)" -lt 0 ]; then
262 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.6.6, performance may be degraded'
264 if [ "$(uname -m 2>/dev/null)" = "x86_64" ] && [ "$(vcmp "$git_vernum" 1.7.11)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.12.0)" -lt 0 ]; then
265 echo 'WARNING: $Girocco::Config::git_bin version >= 1.7.11 and < 2.12.0 and x86_64, make sure Git built WITHOUT XDL_FAST_HASH'
266 echo 'WARNING: See https://lore.kernel.org/git/20141222041944.GA441@peff.net/ for details'
268 if [ "$(vcmp "$git_vernum" 1.8.4.2)" -ge 0 ] && [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 2)" -lt 0 ]; then
269 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, git-daemon needs write access for shallow clones'
270 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, shallow clones will leave repository turds'
272 if [ "$(vcmp "$git_vernum" 1.8.4.3)" -lt 0 ]; then
273 echo 'WARNING: $Girocco::Config::git_bin version < 1.8.4.3, clients will not receive symref=HEAD:refs/heads/...'
275 if [ "$(vcmp "$git_vernum" 2.1)" -lt 0 ]; then
276 echo 'WARNING: $Girocco::Config::git_bin version < 2.1.0, pack bitmaps will not be available'
278 if [ "$(vcmp "$git_vernum" 2.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.1.3)" -lt 0 ]; then
279 echo 'WARNING: $Girocco::Config::git_bin version >= 2.1.0 and < 2.1.3, pack bitmaps may not be reliable, please upgrade to at least Git version 2.1.3'
281 if [ "$(vcmp "$git_vernum" 2.2)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.3.2)" -lt 0 ]; then
282 cat <<'EOT'
285 *** ERROR: $Girocco::Config::git_bin is set to an incompatible version of Git
288 Git versions starting with 2.2.0 and continuing up through 2.3.1 are incompatible
289 with Girocco due to various unresolved issues. Please either downgrade to 2.1.4
290 or earlier or, more preferred, upgrade to 2.3.2 (ideally 2.4.11) or later.
292 In order to bypass this check you will have to modify install.sh in which case
293 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
296 exit 1
298 if [ "$(vcmp "$git_vernum" 2.3.3)" -lt 0 ]; then
299 echo 'WARNING: $Girocco::Config::git_bin version < 2.3.3, performance will be sub-optimal'
301 if [ "$(vcmp "$git_vernum" 2.4.4)" -lt 0 ]; then
302 echo 'WARNING: $Girocco::Config::git_bin version < 2.4.4, many refs smart HTTP fetches can deadlock'
304 if [ "$(vcmp "$git_vernum" 2.10.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.12.3)" -lt 0 ]; then
305 echo 'WARNING: $Girocco::Config::git_bin version >= 2.10.1 and < 2.12.3, --pickaxe-regex can segfault'
306 echo 'WARNING: If gitweb pickaxe regular expression searches are enabled, --pickaxe-regex will be used'
307 echo 'WARNING: See the fix at http://repo.or.cz/git.git/f53c5de29cec68e3 for details'
308 echo 'WARNING: The fix is trivial and easily cherry-picked into a custom 2.10.1 - 2.12.2 build'
309 echo 'WARNING: Leaving the gitweb/gitweb_config.perl "regexp" feature off as recommended avoids the issue'
311 secmsg=
312 if [ "$(vcmp "$git_vernum" 2.4.11)" -lt 0 ]; then
313 secmsg='prior to 2.4.11'
315 if [ "$(vcmp "$git_vernum" 2.5)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.5.5)" -lt 0 ]; then
316 secmsg='2.5.x prior to 2.5.5'
318 if [ "$(vcmp "$git_vernum" 2.6)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.6.6)" -lt 0 ]; then
319 secmsg='2.6.x prior to 2.6.6'
321 if [ "$(vcmp "$git_vernum" 2.7)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.7.4)" -lt 0 ]; then
322 secmsg='2.7.x prior to 2.7.4'
324 if [ -n "$secmsg" ]; then
325 cat <<EOT
328 *** SEVERE WARNING: \$Girocco::Config::git_bin is set to a version of Git $secmsg
331 Security issues exist in Git versions prior to 2.4.11, 2.5.x prior to 2.5.5,
332 2.6.x prior to 2.6.6 and 2.7.x prior to 2.7.4.
334 Besides the security fixes included in later versions, versions prior to
335 2.2.0 may accidentally prune unreachable loose objects earlier than
336 intended. Since Git version 2.4.11 is the minimum version to include all
337 security fixes to date, it should be considered the absolute minimum
338 version of Git to use when running Girocco.
340 This is not enforced, but Git is easy to build from the git.git submodule
341 and upgrading to GIT VERSION 2.4.11 OR LATER IS HIGHLY RECOMMENDED.
343 We will now pause for a moment so you can reflect on this warning.
346 sleep 60
348 if [ -n "$cfg_mirror" ] && [ "$cfg_mirror" != 0 ] && grep -q ns_parserr "$cfg_git_bin"; then
349 cat <<'EOT'
352 *** WARNING: $Girocco::Config::git_bin is set to a questionable Git binary
355 You appear to have enabled mirroring and the Git binary you have selected
356 appears to contain an experimental patch that cannot be disabled. This
357 patch can generate invalid network DNS traffic and/or cause long delays
358 when fetching using the "git:" protocol when no port number is specified.
359 It may also end up retrieving repsitory contents from a host other than
360 the one specified in the "git:" URL when the port is omitted.
362 You are advised to either build your own version of Git (the problem patch
363 is not part of the official Git repository) or disable mirroring (via the
364 $Girocco::Config:mirror setting) to avoid these potential problems.
366 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
369 sleep 5
372 test_nc_U() {
373 [ -n "$1" ] || return 1
374 _cmdnc="$(command -v "$1" 2>/dev/null)" || :
375 [ -n "$_cmdnc" ] && [ -f "$_cmdnc" ] && [ -x "$_cmdnc" ] || return 1
376 _tmpdir="$(mktemp -d /tmp/nc-u-XXXXXX)"
377 [ -n "$_tmpdir" ] && [ -d "$_tmpdir" ] || return 1
378 >"$_tmpdir/output"
379 (sleep 3 | "$_cmdnc" -l -U "$_tmpdir/socket" 2>/dev/null >"$_tmpdir/output" || >"$_tmpdir/failed")&
380 _bgpid="$!"
381 sleep 1
382 echo "testing" | "$_cmdnc" -w 1 -U "$_tmpdir/socket" >/dev/null 2>&1 || >"$_tmpdir/failed"
383 sleep 1
384 kill "$_bgpid" >/dev/null 2>&1 || :
385 read -r _result <"$_tmpdir/output" || :
386 _bad=
387 ! [ -e "$_tmpdir/failed" ] || _bad=1
388 rm -rf "$_tmpdir"
389 [ -z "$_bad" ] && [ "$_result" = "testing" ]
390 } >/dev/null 2>&1
392 echo "*** Verifying \$Girocco::Config::nc_openbsd_bin supports -U option..."
393 test_nc_U "$var_nc_openbsd_bin" || {
394 echo "ERROR: invalid Girocco::Config::nc_openbsd_bin setting" >&2
395 echo "ERROR: \"$var_nc_openbsd_bin\" does not grok the -U option" >&2
396 uname_s="$(uname -s 2>/dev/null | tr A-Z a-z 2>/dev/null)" || :
397 case "$uname_s" in
398 *dragonfly*)
399 echo "ERROR: see the src/dragonfly/README file for a solution" >&2;;
400 *kfreebsd*|*linux*)
401 echo "ERROR: try installing the package named 'netcat-openbsd'" >&2;;
402 esac
403 exit 1
406 echo "*** Verifying selected POSIX sh is sane..."
407 shbin="$var_sh_bin"
408 [ -n "$shbin" ] && [ -f "$shbin" ] && [ -x "$shbin" ] && [ "$("$shbin" -c 'echo sh $(( 1 + 1 ))' 2>/dev/null)" = "sh 2" ] || {
409 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting' >&2
410 exit 1
412 [ "$(check_sh_builtin command)" = "command" ] || {
413 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting (does not understand command -v)' >&2
414 exit 1
416 sh_not_builtin=
417 sh_extra_chroot_installs=
418 badsh=
419 for sbi in cd pwd read umask unset unalias; do
420 if [ "$(check_sh_builtin "$sbi")" != "$sbi" ]; then
421 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing built-in $sbi)" >&2
422 badsh=1
424 done
425 [ -z "$badsh" ] || exit 1
426 for sbi in '[' echo printf test; do
427 if ! extra="$(check_sh_builtin "$sbi")"; then
428 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing command $sbi)" >&2
429 badsh=1
430 continue
432 if [ "$extra" != "$sbi" ]; then
433 case "$extra" in /*) :;; *)
434 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (bad command -v $sbi result: $extra)" >&2
435 badsh=1
436 continue
437 esac
438 withspc=
439 case "$extra" in *" "*) withspc=1; esac
440 [ -z "$withspc" ] && [ -f "$extra" ] && [ -r "$extra" ] && [ -x "$extra" ] || {
441 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (unusable command -v $sbi result: $extra)" >&2
442 badsh=1
443 continue
445 echo "WARNING: slow \$Girocco::Config::posix_sh_bin setting (not built-in $sbi)" >&2
446 sh_not_builtin="$sh_not_builtin $sbi"
447 sh_extra_chroot_installs="$sh_extra_chroot_installs $extra"
449 done
450 [ -z "$badsh" ] || exit 1
451 [ -z "$sh_extra_chroot_installs" ] || {
452 echo "WARNING: the selected POSIX sh implements these as non-built-in:$sh_not_builtin" >&2
453 echo "WARNING: as a result it will run slower than necessary" >&2
454 echo "WARNING: consider building and switching to dash which can be found at:" >&2
455 echo "WARNING: http://gondor.apana.org.au/~herbert/dash/" >&2
456 echo "WARNING: (download a tarball from the files section or clone the Git repository" >&2
457 echo "WARNING: and checkout the latest tag, run autogen.sh, configure and build)" >&2
458 echo "WARNING: dash is licensed under the 3-clause BSD license" >&2
461 echo "*** Verifying xargs is sane..."
462 _xargsr="$(</dev/null command xargs printf %s -r)" || :
463 xtest1="$(</dev/null command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
464 xtest2="$(printf '%s\n' one two | command xargs $_xargsr printf 'test %s ' 2>/dev/null)" || :
465 [ -z "$xtest1" ] && [ "$xtest2" = "test one test two " ] || {
466 echo 'ERROR: xargs is unusable' >&2
467 echo 'ERROR: either `test -z "$(</dev/null xargs echo test 2>/dev/null)"`' >&2
468 echo 'ERROR: or `test -z "$(</dev/null xargs -r echo test 2>/dev/null)"`' >&2
469 echo 'ERROR: must be true, but neither is' >&2
470 exit 1
473 echo "*** Verifying selected perl is sane..."
474 perlbin="$var_perl_bin"
475 [ -n "$perlbin" ] && [ -f "$perlbin" ] && [ -x "$perlbin" ] && [ "$("$perlbin" -wle 'print STDOUT "perl ", + ( 1 + 1 )' 2>/dev/null)" = "perl 2" ] || {
476 echo 'ERROR: invalid $Girocco::Config::perl_bin setting' >&2
477 exit 1
480 echo "*** Verifying selected gzip is sane..."
481 gzipbin="$var_gzip_bin"
482 [ -n "$gzipbin" ] && [ -f "$gzipbin" ] && [ -x "$gzipbin" ] && "$gzipbin" -V 2>&1 | grep -q gzip &&
483 [ "$(echo Girocco | "$gzipbin" -c -n -9 | "$gzipbin" -c -d)" = "Girocco" ] || {
484 echo 'ERROR: invalid $Girocco::Config::gzip_bin setting' >&2
485 exit 1
488 echo "*** Verifying basedir, webroot, webreporoot and cgiroot paths..."
489 # Make sure $cfg_basedir, $cfg_webroot and $cfg_cgiroot are absolute paths
490 case "$cfg_basedir" in /*) :;; *)
491 echo "ERROR: invalid Girocco::Config::basedir setting" >&2
492 echo "ERROR: \"$cfg_basedir\" must be an absolute path (start with '/')" >&2
493 exit 1
494 esac
495 case "$cfg_webroot" in /*) :;; *)
496 echo "ERROR: invalid Girocco::Config::webroot setting" >&2
497 echo "ERROR: \"$cfg_webroot\" must be an absolute path (start with '/')" >&2
498 exit 1
499 esac
500 if [ -n "$cfg_webreporoot" ]; then
501 case "$cfg_webreporoot" in /*) :;; *)
502 echo "ERROR: invalid Girocco::Config::webreporoot setting" >&2
503 echo "ERROR: \"$cfg_webreporoot\" must be an absolute path (start with '/') or undef" >&2
504 exit 1
505 esac
507 case "$cfg_cgiroot" in /*) :;; *)
508 echo "ERROR: invalid Girocco::Config::cgiroot setting" >&2
509 echo "ERROR: \"$cfg_cgiroot\" must be an absolute path (start with '/')" >&2
510 exit 1
511 esac
513 # return the input with trailing slashes stripped but return "/" for all "/"s
514 striptrsl() {
515 [ -n "$1" ] || return 0
516 _s="${1##*[!/]}"
517 [ "$_s" != "$1" ] || _s="${_s#?}"
518 printf "%s\n" "${1%$_s}"
521 # a combination of realpath + dirname where the realpath of the deepest existing
522 # directory is returned with the rest of the non-existing components appended
523 # and trailing slashes and multiple slashes are removed
524 realdir() {
525 _d="$(striptrsl "$1")"
526 if [ "$_d" = "/" ] || [ -z "$_d" ]; then
527 echo "$_d"
528 return 0
530 _c=""
531 while ! [ -d "$_d" ]; do
532 _c="/$(basename "$_d")$_c"
533 _d="$(dirname "$_d")"
534 [ "$_d" != "/" ] || _c="${_c#/}"
535 done
536 printf "%s%s\n" "$(cd "$_d" && pwd -P)" "$_c"
539 # Use basedir, webroot and cgiroot for easier control of filesystem locations
540 # Wherever we are writing/copying/installing files we use these, but where we
541 # are editing, adding config settings or printing advice we always stick to the
542 # cfg_xxx Config variable versions. These are like a set of DESTDIR variables.
543 # Only the file system directories that could be asynchronously accessed (by
544 # the web server, jobd.pl, taskd.pl or incoming pushes) get these special vars.
545 # The chroot is handled specially and does not need one of these.
546 # We must be careful to allow cgiroot and/or webroot to be under basedir in which
547 # case the prior contents of cgiroot and/or webroot are discarded.
548 rbasedir="$(realdir "$cfg_basedir")"
549 rwebroot="$(realdir "$cfg_webroot")"
550 rwebreporoot=
551 [ -z "$cfg_webreporoot" ] || {
552 # avoid resolving a pre-existing symlink from a previous install
553 rwebreporoot="$(realdir "${cfg_webreporoot%/}_NOSUCHDIR")"
554 rwebreporoot="${rwebreporoot%_NOSUCHDIR}"
556 rcgiroot="$(realdir "$cfg_cgiroot")"
557 case "$rbasedir" in "$rwebroot"/?*)
558 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under webroot" >&2
559 exit 1
560 esac
561 case "$rbasedir" in "$rcgiroot"/?*)
562 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under cgiroot" >&2
563 exit 1
564 esac
565 if [ "$rwebroot" = "$rcgiroot" ]; then
566 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::cgiroot settings; must not be the same" >&2
567 exit 1
569 case "$rcgiroot" in "$rwebroot"/?*)
570 echo "ERROR: invalid Girocco::Config::cgiroot setting; must not be under webroot" >&2
571 exit 1
572 esac
573 case "$rwebroot" in "$rcgiroot"/?*)
574 echo "ERROR: invalid Girocco::Config::webroot setting; must not be under cgiroot" >&2
575 exit 1
576 esac
577 if [ -n "$rwebreporoot" ]; then
578 if [ "$rwebreporoot" = "$rwebroot" ]; then
579 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::webreporoot settings; must not be the same" >&2
580 exit 1
582 case "$rwebreporoot" in "$rwebroot"/?*);;*)
583 echo "ERROR: invalid Girocco::Config::webreporoot setting; must be under webroot or undef" >&2
584 exit 1
585 esac
587 basedir="$rbasedir-new"
588 case "$rwebroot" in
589 "$rbasedir"/?*)
590 webroot="$basedir${rwebroot#$rbasedir}"
591 webrootsub=1
594 webroot="$rwebroot-new"
595 webrootsub=
597 esac
598 webreporoot=
599 [ -z "$rwebreporoot" ] || webreporoot="$webroot${rwebreporoot#$rwebroot}"
600 case "$rcgiroot" in
601 "$rbasedir"/?*)
602 cgiroot="$basedir${rcgiroot#$rbasedir}"
603 cgirootsub=1
606 cgiroot="$rcgiroot-new"
607 cgirootsub=
609 esac
611 echo "*** Setting up basedir..."
613 chown_make() {
614 if [ "$LOGNAME" = root ] && [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != root ]; then
615 find -H "$@" -user root -exec chown "$SUDO_USER:$(id -gn "$SUDO_USER")" '{}' + 2>/dev/null || :
616 elif [ "$LOGNAME" = root ] && { [ -z "$SUDO_USER" ] || [ "$SUDO_USER" = root ]; }; then
617 echo "*** WARNING: running make as root w/o sudo may leave root-owned: $*"
621 "$MAKE" --no-print-directory --silent apache.conf
622 chown_make apache.conf
623 "$MAKE" --no-print-directory --silent -C src
624 chown_make src
625 rm -fr "$basedir"
626 mkdir -p "$basedir" "$basedir/gitweb" "$basedir/cgi"
627 # make the mtlinesfile with 1000 empty lines
628 yes '' | dd bs=1000 count=1 2>/dev/null >"$basedir/mtlinesfile"
629 chmod a+r "$basedir/mtlinesfile"
630 cp cgi/*.cgi "$basedir/cgi"
631 cp -pR Girocco jobd taskd html jobs toolbox hooks apache.conf shlib.sh bin screen "$basedir"
632 rm -f "$basedir/Girocco/Dumper.pm" # Dumper.pm is only for the install.sh process
633 find -H "$basedir" -type l -exec rm -f '{}' +
634 cp -p src/can_user_push src/can_user_push_http src/get_user_uuid src/list_packs src/peek_packet \
635 src/rangecgi src/readlink src/strftime src/throttle src/ulimit512 src/ltsha256 \
636 ezcert.git/CACreateCert cgi/authrequired.cgi cgi/snapshot.cgi \
637 "$basedir/bin"
638 cp -p gitweb/*.sh gitweb/*.perl "$basedir/gitweb"
639 if [ -n "$cfg_httpspushurl" ]; then
640 [ -z "$cfg_pretrustedroot" ] || rm -f "$basedir"/html/rootcert.html
641 else
642 rm -f "$basedir"/html/rootcert.html "$basedir"/html/httpspush.html
644 [ -n "$cfg_mob" ] || rm -f "$basedir"/html/mob.html
646 # Put the frozen Config in place
647 VARLIST="$(get_girocco_config_var_list varonly)" && export VARLIST
648 perl -I"$PWD" -MGirocco::Dumper=FreezeConfig -MScalar::Util=looks_like_number -e '
649 my $usemod = $ARGV[0];
650 my $f = sub { return () unless $_[0] =~ /^(var_[^=\s]+)=(.*)$/;
651 my ($k,$v) = ($1,$2);
652 $v =~ s/([\@\%])/\\$1/gos;
653 $v = "\"".$v."\"" unless substr($v,0,1) eq "\"" || looks_like_number($v);
654 my $e = eval $v;
655 [$k, $e] };
656 my @vars = map({&$f($_)} split(/\n+/, $ENV{VARLIST}));
657 my $s = sub { my $conf = shift;
658 foreach (@vars) {
659 my ($k,$v) = @{$_};
660 eval "\$${conf}::$k=\$v";
663 print FreezeConfig($usemod, undef, $s);
664 ' -- "$GIROCCO_CONF" >"$basedir/Girocco/Config.pm"
665 unset VARLIST
667 # Create symbolic links to selected binaries
668 ln -s "$cfg_git_bin" "$basedir/bin/git"
669 ln -s "$shbin" "$basedir/bin/sh"
670 ln -s "$perlbin" "$basedir/bin/perl"
671 ln -s "$gzipbin" "$basedir/bin/gzip"
672 [ -z "$var_openssl_bin" ] || ln -s "$var_openssl_bin" "$basedir/bin/openssl"
674 echo "*** Preprocessing scripts..."
675 SHBIN="$shbin" && export SHBIN
676 PERLBIN="$perlbin" && export PERLBIN
677 perl -I"$PWD" -M$GIROCCO_CONF -i -p \
678 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
679 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
680 -e 's/(?<!")\@basedir\@/"$Girocco::Config::basedir"/g;' \
681 -e 's/(?<=")\@basedir\@/$Girocco::Config::basedir/g;' \
682 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
683 -e 's/\@reporoot\@/"$Girocco::Config::reporoot"/g;' \
684 -e 's/\@shbin\@/"$ENV{SHBIN}"/g;' \
685 -e 's/\@perlbin\@/"$ENV{PERLBIN}"/g;' \
686 -e 's/\@jailreporoot\@/"$Girocco::Config::jailreporoot"/g;' \
687 -e 's/\@chroot\@/"$Girocco::Config::chroot"/g;' \
688 -e 's/\@webadmurl\@/"$Girocco::Config::webadmurl"/g;' \
689 -e 's/\@screen_acl_file\@/"$Girocco::Config::screen_acl_file"/g;' \
690 -e 's/\@mob\@/"$Girocco::Config::mob"/g;' \
691 -e 's/\@autogchack\@/"$Girocco::Config::autogchack"/g;' \
692 -e 's/\@git_server_ua\@/"$Girocco::Config::git_server_ua"/g;' \
693 -e 's/\@defined_git_server_ua\@/defined($Girocco::Config::git_server_ua)/ge;' \
694 -e 's/\@git_no_mmap\@/"$Girocco::Config::git_no_mmap"/g;' \
695 -e 's/\@big_file_threshold\@/"'"$var_big_file_threshold"'"/g;' \
696 -e 's/\@upload_pack_window\@/"'"$var_upload_window"'"/g;' \
697 -e 's/\@fetch_stash_refs\@/"$Girocco::Config::fetch_stash_refs"/g;' \
698 -e 's/\@suppress_git_ssh_logging\@/"$Girocco::Config::suppress_git_ssh_logging"/g;' \
699 -e 's/\@max_file_size512\@/"$Girocco::Config::max_file_size512"/g;' \
700 -e 'close ARGV if eof;' \
701 "$basedir"/jobs/*.sh "$basedir"/jobd/*.sh \
702 "$basedir"/taskd/*.sh "$basedir"/gitweb/*.sh \
703 "$basedir"/shlib.sh "$basedir"/hooks/* \
704 "$basedir"/toolbox/*.sh "$basedir"/toolbox/*.pl \
705 "$basedir"/toolbox/reports/*.sh \
706 "$basedir"/bin/git-* "$basedir"/bin/*.sh \
707 "$basedir"/bin/create-* "$basedir"/bin/update-* \
708 "$basedir"/bin/*.cgi "$basedir"/screen/*
709 perl -I"$PWD" -M$GIROCCO_CONF -i -p \
710 -e 's/__BASE''DIR__/$Girocco::Config::basedir/g;' \
711 "$basedir"/cgi/*.cgi "$basedir"/gitweb/*.perl \
712 "$basedir"/jobd/*.pl "$basedir"/taskd/*.pl
713 perl -i -p \
714 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
715 -e 'close ARGV if eof;' \
716 "$basedir"/jobd/jobd.pl "$basedir"/taskd/taskd.pl \
717 "$basedir"/bin/sendmail.pl "$basedir"/bin/CACreateCert
718 perl -i -p \
719 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
720 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
721 -e 'close ARGV if eof;' \
722 "$basedir"/bin/format-readme "$basedir/cgi"/*.cgi
723 unset PERLBIN
724 unset SHBIN
726 # Dump all the cfg_ and defined_ variables to shlib_vars.sh
727 get_girocco_config_var_list >"$basedir"/shlib_vars.sh
729 if [ "${cfg_mirror_darcs:-0}" != "0" ]; then
730 echo "*** Setting up darcs-fast-export from girocco-darcs-fast-export.git..."
731 if ! [ -f girocco-darcs-fast-export.git/darcs-fast-export ] ||
732 ! [ -x girocco-darcs-fast-export.git/darcs-fast-export ]; then
733 echo "ERROR: girocco-darcs-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
734 exit 1
736 mkdir -p "$basedir"/bin
737 cp girocco-darcs-fast-export.git/darcs-fast-export "$basedir"/bin
740 if [ "${cfg_mirror_hg:-0}" != "0" ]; then
741 echo "*** Setting up hg-fast-export from girocco-hg-fast-export.git..."
742 if ! [ -f girocco-hg-fast-export.git/hg-fast-export.py ] || ! [ -f girocco-hg-fast-export.git/hg2git.py ]; then
743 echo "ERROR: girocco-hg-fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
744 exit 1
746 mkdir -p "$basedir"/bin
747 cp girocco-hg-fast-export.git/hg-fast-export.py girocco-hg-fast-export.git/hg2git.py "$basedir"/bin
750 echo "*** Setting up markdown from markdown.git..."
751 if ! [ -f markdown.git/Markdown.pl ]; then
752 echo "ERROR: markdown.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
753 exit 1
755 mkdir -p "$basedir"/bin
756 (PERLBIN="$perlbin" && export PERLBIN &&
757 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
758 markdown.git/Markdown.pl >"$basedir"/bin/Markdown.pl.$$ &&
759 chmod a+x "$basedir"/bin/Markdown.pl.$$ &&
760 mv -f "$basedir"/bin/Markdown.pl.$$ "$basedir"/bin/Markdown.pl)
761 test $? -eq 0
763 # Some permission sanity on basedir/bin just in case
764 find -H "$basedir"/bin -type f -exec chmod go-w '{}' +
765 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir"/bin
767 if [ -n "$cfg_mirror" ]; then
768 echo "--- Remember to start $cfg_basedir/taskd/taskd.pl"
770 echo "--- Also remember to either start $cfg_basedir/jobd/jobd.pl, or add this"
771 echo "--- to the crontab of $cfg_mirror_user (adjust frequency on number of repos):"
772 echo "*/30 * * * * /usr/bin/nice -n 18 $cfg_basedir/jobd/jobd.pl -q --all-once"
775 echo "*** Setting up repository root..."
776 [ -d "$cfg_reporoot" ] || {
777 mkdir -p "$cfg_reporoot"
778 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot" ||
779 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot"
781 [ -z "$cfg_owning_group" ] ||
782 chgrp "$cfg_owning_group" "$cfg_reporoot" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot"
783 chmod 02775 "$cfg_reporoot" || echo "WARNING: Cannot chmod $cfg_reporoot properly"
784 mkdir -p "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty"
785 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_recyclebin" "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" ||
786 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_reporoot/{_recyclebin,_global} properly"
787 if [ "$cfg_owning_group" ]; then
788 chgrp "$cfg_owning_group" "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot/_recyclebin"
789 chgrp -R "$cfg_owning_group" "$cfg_reporoot/_global" || echo "WARNING: Cannot chgrp -R $cfg_owning_group $cfg_reporoot/_global"
791 chmod 02775 "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chmod $cfg_reporoot/_recyclebin properly"
792 chmod 00755 "$cfg_reporoot/_global" "$cfg_reporoot/_global/hooks" "$cfg_reporoot/_global/empty" || echo "WARNING: Cannot chmod $cfg_reporoot/_global properly"
795 usejail=
796 [ "${cfg_disable_jailsetup:-0}" != "0" ] || [ "${cfg_chrooted:-0}" = "0" ] || usejail=1
797 if [ -n "$usejail" ]; then
798 echo "*** Setting up chroot jail for pushing..."
799 if [ -n "$isroot" ]; then
800 # jailsetup may install things from $cfg_basedir/bin into the
801 # chroot so we do a mini-update of just that portion now
802 mkdir -p "$cfg_basedir"
803 rm -rf "$cfg_basedir/bin-new"
804 cp -pR "$basedir/bin" "$cfg_basedir/bin-new" >/dev/null 2>&1
805 rm -rf "$cfg_basedir/bin-old"
806 quick_move "$cfg_basedir/bin-new" "$cfg_basedir/bin" "$cfg_basedir/bin-old"
807 rm -rf "$cfg_basedir/bin-old"
808 if [ -n "$sh_extra_chroot_installs" ]; then
809 GIROCCO_CHROOT_EXTRA_INSTALLS="$sh_extra_chroot_installs"
810 export GIROCCO_CHROOT_EXTRA_INSTALLS
812 ./jailsetup.sh
813 unset GIROCCO_CHROOT_EXTRA_INSTALLS
814 else
815 echo "WARNING: Skipping jail setup, not root"
820 echo "*** Setting up jail configuration (project database)..."
821 [ -n "$usejail" ] && [ -n "$isroot" ] || ./jailsetup.sh dbonly
822 mkdir -p "$cfg_chroot" "$cfg_chroot/etc"
823 touch "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group"
824 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc" ||
825 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_chroot/etc"
826 chown "$cfg_cgi_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
827 echo "WARNING: Cannot chown $cfg_cgi_user$owngroup the etc/passwd and/or etc/group files"
828 chmod g+w "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
829 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
830 chmod 02775 "$cfg_chroot/etc" || echo "WARNING: Cannot chmod 02775 $cfg_chroot/etc"
833 echo "*** Setting up global hook scripts..."
834 # It is absolutely CRUCIAL that hook script replacements are done atomically!
835 # Otherwise an incoming push might slip in and fail to run the hook script!
836 # The underlying rename(2) function call provides this and mv will use it.
837 # First add hook scripts
838 hooks="pre-auto-gc pre-receive post-commit post-receive update"
839 for hook in $hooks; do
840 cat "$basedir/hooks/$hook" >"$cfg_reporoot/_global/hooks/$hook.$$"
841 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_global/hooks/$hook.$$" ||
842 echo "WARNING: Cannot chown $cfg_reporoot/_global/hooks/$hook"
843 chmod 0755 "$cfg_reporoot/_global/hooks/$hook.$$"
844 mv -f "$cfg_reporoot/_global/hooks/$hook.$$" "$cfg_reporoot/_global/hooks/$hook"
845 done
846 # Then remove any hook scripts that do not belong
847 for hook in "$cfg_reporoot/_global/hooks"/*; do
848 hook="${hook##*/}"
849 [ -f "$cfg_reporoot/_global/hooks/$hook" ] || continue
850 case " $hooks " in *" $hook "*);;*)
851 rm -f "$cfg_reporoot/_global/hooks/$hook" ||
852 echo "WARNING: Cannot remove extraneous $cfg_reporoot/_global/hooks/$hook"
853 esac
854 done
857 echo "*** Setting up gitweb from git.git..."
858 if ! [ -f git.git/Makefile ]; then
859 echo "ERROR: git.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
860 exit 1
863 # We do not wholesale replace either webroot or cgiroot unless they are under
864 # basedir so if they exist and are not we make a copy to start working on them.
865 # We make a copy using -p which can result in some warnings so we suppress
866 # error output as it's of no consequence in this case.
867 rm -rf "$webroot" "$cgiroot"
868 [ -n "$webrootsub" ] || ! [ -d "$rwebroot" ] || cp -pR "$rwebroot" "$webroot" >/dev/null 2>&1 || :
869 [ -n "$cgirootsub" ] || ! [ -d "$rcgiroot" ] || cp -pR "$rcgiroot" "$cgiroot" >/dev/null 2>&1 || :
870 mkdir -p "$webroot" "$cgiroot"
873 cd git.git &&
874 "$MAKE" --no-print-directory --silent NO_SUBDIR=: bindir="$(dirname "$cfg_git_bin")" \
875 GITWEB_CONFIG_COMMON="" GITWEB_CONFIG_SYSTEM="" \
876 GITWEB_CONFIG="$cfg_basedir/gitweb/gitweb_config.perl" SHELL_PATH="$shbin" gitweb &&
877 chown_make gitweb &&
878 PERLBIN="$perlbin" && export PERLBIN &&
879 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
880 -e 's/^(\s*use\s+warnings\s*;.*)$/#$1/;' gitweb/gitweb.cgi >"$cgiroot"/gitweb.cgi.$$ &&
881 chmod a+x "$cgiroot"/gitweb.cgi.$$ &&
882 chown_make "$cgiroot"/gitweb.cgi.$$ &&
883 mv -f "$cgiroot"/gitweb.cgi.$$ "$cgiroot"/gitweb.cgi &&
884 cp gitweb/static/*.png gitweb/static/*.css gitweb/static/*.js "$webroot"
886 test $? -eq 0
889 echo "*** Setting up git-browser from git-browser.git..."
890 if ! [ -f git-browser.git/git-browser.cgi ]; then
891 echo "ERROR: git-browser.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
892 exit 1
894 mkdir -p "$webroot"/git-browser "$cgiroot"
896 cd git-browser.git &&
897 CFG="$cfg_basedir/gitweb/git-browser.conf" && export CFG &&
898 PERLBIN="$perlbin" && export PERLBIN && perl -p \
899 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
900 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-browser.cgi >"$cgiroot"/git-browser.cgi.$$ &&
901 chmod a+x "$cgiroot"/git-browser.cgi.$$ &&
902 chown_make "$cgiroot"/git-browser.cgi.$$ &&
903 perl -p \
904 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
905 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-diff.cgi >"$cgiroot"/git-diff.cgi.$$ &&
906 chmod a+x "$cgiroot"/git-diff.cgi.$$ &&
907 chown_make "$cgiroot"/git-diff.cgi.$$ &&
908 mv -f "$cgiroot"/git-browser.cgi.$$ "$cgiroot"/git-browser.cgi &&
909 mv -f "$cgiroot"/git-diff.cgi.$$ "$cgiroot"/git-diff.cgi &&
910 for h in *.html; do
911 [ "$h" != "index.html" ] || continue
912 if [ "$h" = "by-commit.html" ] || [ "$h" = "by-date.html" ]; then
913 FAVLINE='<link rel="shortcut icon" href="/git-favicon.png" type="image/png" />' &&
914 export FAVLINE && perl -p -e 'print "$ENV{FAVLINE}\n" if m{</head>};' "$h" \
915 >"$webroot/git-browser/$h.$$" &&
916 chmod a+r "$webroot/git-browser/$h.$$" &&
917 mv -f "$webroot/git-browser/$h.$$" "$webroot/git-browser/$h"
918 else
919 cp -p "$h" "$webroot/git-browser/"
921 done
922 cp -pR *.js *.css js.lib "$webroot/git-browser/" &&
923 cp -pR JSON "$cgiroot/"
925 test $? -eq 0
926 gitwebabs="$cfg_gitweburl"
927 case "$gitwebabs" in "http://"[!/]*|"https://"[!/]*)
928 gitwebabs="${gitwebabs#*://}"
929 case "$gitwebabs" in
930 *"/"*) gitwebabs="/${gitwebabs#*/}";;
931 *) gitwebabs="";;
932 esac
933 esac
934 case "$gitwebabs" in */);;*) gitwebabs="$gitwebabs/"; esac
935 cat >"$basedir/gitweb"/git-browser.conf.$$ <<-EOT
936 gitbin: $cfg_git_bin
937 gitweb: $gitwebabs
938 warehouse: $cfg_reporoot
939 doconfig: $cfg_basedir/gitweb/gitbrowser_config.perl
941 chown_make "$basedir/gitweb"/git-browser.conf.$$
942 mv -f "$basedir/gitweb"/git-browser.conf.$$ "$basedir/gitweb"/git-browser.conf
943 esctitle="$(printf '%s\n' "$cfg_title" | LC_ALL=C sed 's/\\/\\\\/g;s/"/\\"/g;')" || :
944 cat >"$webroot"/git-browser/GitConfig.js.$$ <<-EOT
945 cfg_gitweb_url="$cfg_gitweburl/"
946 cfg_browsercgi_url="$cfg_webadmurl/git-browser.cgi"
947 cfg_home_url="$cfg_gitweburl/%n"
948 cfg_home_text="summary"
949 cfg_bycommit_title="$esctitle - %n/graphiclog1"
950 cfg_bydate_title="$esctitle - %n/graphiclog2"
952 chown_make "$webroot"/git-browser/GitConfig.js.$$
953 mv -f "$webroot"/git-browser/GitConfig.js.$$ "$webroot"/git-browser/GitConfig.js
956 echo "*** Setting up our part of the website..."
957 mkdir -p "$webroot" "$cgiroot"
958 cp "$basedir"/bin/snapshot.cgi "$basedir/cgi"
959 cp "$basedir"/bin/authrequired.cgi "$basedir/cgi"
960 [ -n "$cfg_httpspushurl" ] || rm -f "$basedir/cgi"/usercert.cgi "$cgiroot"/usercert.cgi
961 cp "$basedir/cgi"/*.cgi "$cgiroot"
962 rm -rf "$basedir/cgi"
963 [ -z "$webreporoot" ] || { rm -f "$webreporoot" && ln -s "$cfg_reporoot" "$webreporoot"; }
964 if [ -z "$cfg_httpspushurl" ] || [ -n "$cfg_pretrustedroot" ]; then
965 grep -v 'rootcert[.]html' gitweb/indextext.html >"$basedir/gitweb/indextext.html"
966 else
967 cp gitweb/indextext.html "$basedir/gitweb"
969 mv "$basedir"/html/*.css "$basedir"/html/*.js "$webroot"
970 cp mootools.js "$webroot"
971 cp htaccess "$webroot/.htaccess"
972 cp cgi/htaccess "$cgiroot/.htaccess"
973 cp git-favicon.ico "$webroot/favicon.ico"
974 cp robots.txt "$webroot"
975 cat gitweb/gitweb.css >>"$webroot"/gitweb.css
978 if [ -n "$cfg_httpspushurl" ]; then
979 echo "*** Setting up SSL certificates..."
980 openssl="${var_openssl_bin:-openssl}"
981 createcert() { PATH="$basedir/bin:$PATH" "$basedir/bin/CACreateCert" "$@"; }
982 bits=2048
983 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev/null; then
984 bits="$cfg_rsakeylength"
986 mkdir -p "$cfg_certsdir"
987 [ -d "$cfg_certsdir" ]
988 wwwcertcn=
989 if [ -e "$cfg_certsdir/girocco_www_crt.pem" ]; then
990 wwwcertcn="$(
991 "$openssl" x509 -in "$cfg_certsdir/girocco_www_crt.pem" -noout -subject |
992 sed -e 's,[^/]*,,'
995 wwwcertdns=
996 if [ -n "$cfg_wwwcertaltnames" ]; then
997 for dnsopt in $cfg_wwwcertaltnames; do
998 wwwcertdns="${wwwcertdns:+$wwwcertdns }--dns $dnsopt"
999 done
1001 wwwcertdnsfile=
1002 if [ -r "$cfg_certsdir/girocco_www_crt.dns" ]; then
1003 wwwcertdnsfile="$(cat "$cfg_certsdir/girocco_www_crt.dns")"
1005 needroot=
1006 [ -e "$cfg_certsdir/girocco_client_crt.pem" ] &&
1007 [ -e "$cfg_certsdir/girocco_client_key.pem" ] &&
1008 [ -e "$cfg_certsdir/girocco_www_key.pem" ] &&
1009 [ -e "$cfg_certsdir/girocco_www_crt.pem" ] && [ "$wwwcertcn" = "/CN=$cfg_httpsdnsname" ] &&
1010 [ -e "$cfg_certsdir/girocco_root_crt.pem" ] || needroot=1
1011 if [ -n "$needroot" ] && ! [ -e "$cfg_certsdir/girocco_root_key.pem" ]; then
1012 rm -f "$cfg_certsdir/girocco_root_crt.pem" "$cfg_certsdir/girocco_root_key.pem"
1013 umask 0077
1014 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_root_key.pem" $bits
1015 chmod 0600 "$cfg_certsdir/girocco_root_key.pem"
1016 rm -f "$cfg_certsdir/girocco_root_crt.pem"
1017 umask 0022
1018 echo "Created new root key"
1020 if ! [ -e "$cfg_certsdir/girocco_root_crt.pem" ]; then
1021 createcert --root --key "$cfg_certsdir/girocco_root_key.pem" \
1022 --out "$cfg_certsdir/girocco_root_crt.pem" "girocco $cfg_nickname root certificate"
1023 rm -f "$cfg_certsdir/girocco_www_crt.pem" "$cfg_certsdir/girocco_www_chain.pem"
1024 rm -f "$cfg_certsdir/girocco_client_crt.pem" "$cfg_certsdir/girocco_client_suffix.pem"
1025 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1026 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1027 echo "Created new root certificate"
1029 if ! [ -e "$cfg_certsdir/girocco_www_key.pem" ]; then
1030 umask 0077
1031 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_www_key.pem" $bits
1032 chmod 0600 "$cfg_certsdir/girocco_www_key.pem"
1033 rm -f "$cfg_certsdir/girocco_www_crt.pem"
1034 umask 0022
1035 echo "Created new www key"
1037 if ! [ -e "$cfg_certsdir/girocco_www_crt.pem" ] ||
1038 [ "$wwwcertcn" != "/CN=$cfg_httpsdnsname" ] || [ "$wwwcertdns" != "$wwwcertdnsfile" ]; then
1039 "$openssl" rsa -in "$cfg_certsdir/girocco_www_key.pem" -pubout |
1040 createcert --server --key "$cfg_certsdir/girocco_root_key.pem" \
1041 --cert "$cfg_certsdir/girocco_root_crt.pem" $wwwcertdns \
1042 --out "$cfg_certsdir/girocco_www_crt.pem" "$cfg_httpsdnsname"
1043 printf '%s\n' "$wwwcertdns" >"$cfg_certsdir/girocco_www_crt.dns"
1044 echo "Created www certificate"
1046 if ! [ -e "$cfg_certsdir/girocco_www_chain.pem" ]; then
1047 cat "$cfg_certsdir/girocco_root_crt.pem" >"$cfg_certsdir/girocco_www_chain.pem"
1048 echo "Created www certificate chain file"
1050 if ! [ -e "$cfg_certsdir/girocco_client_key.pem" ]; then
1051 umask 0037
1052 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_client_key.pem" $bits
1053 chmod 0640 "$cfg_certsdir/girocco_client_key.pem"
1054 rm -f "$cfg_certsdir/girocco_client_crt.pem"
1055 umask 0022
1056 echo "Created new client key"
1058 if ! [ -e "$cfg_certsdir/girocco_client_crt.pem" ]; then
1059 "$openssl" rsa -in "$cfg_certsdir/girocco_client_key.pem" -pubout |
1060 createcert --subca --key "$cfg_certsdir/girocco_root_key.pem" \
1061 --cert "$cfg_certsdir/girocco_root_crt.pem" \
1062 --out "$cfg_certsdir/girocco_client_crt.pem" "girocco $cfg_nickname client authority"
1063 rm -f "$cfg_certsdir/girocco_client_suffix.pem"
1064 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1065 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1066 echo "Created client certificate"
1068 if ! [ -e "$cfg_certsdir/girocco_client_suffix.pem" ]; then
1069 cat "$cfg_certsdir/girocco_client_crt.pem" >"$cfg_certsdir/girocco_client_suffix.pem"
1070 echo "Created client certificate suffix file"
1072 if [ -z "$cfg_pretrustedroot" ]; then
1073 cat "$cfg_rootcert" >"$webroot/${cfg_nickname}_root_cert.pem"
1074 else
1075 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1077 if [ -n "$cfg_mob" ]; then
1078 if ! [ -e "$cfg_certsdir/girocco_mob_user_key.pem" ]; then
1079 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_mob_user_key.pem" $bits
1080 chmod 0644 "$cfg_certsdir/girocco_mob_user_key.pem"
1081 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1082 echo "Created new mob user key"
1084 if ! [ -e "$cfg_certsdir/girocco_mob_user_crt.pem" ]; then
1085 "$openssl" rsa -in "$cfg_mobuserkey" -pubout |
1086 createcert --client --key "$cfg_clientkey" \
1087 --cert "$cfg_clientcert" \
1088 --out "$cfg_certsdir/girocco_mob_user_crt.pem" 'mob'
1089 echo "Created mob user client certificate"
1091 cat "$cfg_mobuserkey" >"$webroot/${cfg_nickname}_mob_key.pem"
1092 cat "$cfg_mobusercert" "$cfg_clientcertsuffix" >"$webroot/${cfg_nickname}_mob_user.pem"
1093 else
1094 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1096 else
1097 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1098 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1102 echo "*** Processing website html templates..."
1103 rm -f "$cgiroot/html.cgi"
1104 rm -rf "$cgiroot/html"
1105 mkdir -p "$cgiroot/html"
1106 for tf in "$basedir/html"/*.html; do
1107 tfb="${tf##*/}"
1108 "$perlbin" -I"$basedir" cgi/html.cgi "$webroot" "$tfb" "$basedir" >"$cgiroot/html/$tfb"
1109 rm -f "$tf"
1110 done
1112 echo "*** Formatting markdown documentation..."
1113 mkdir -p "$cgiroot/html/gfm"
1114 for d in basics.md syntax.md; do
1116 cat <<-HEADER
1117 <!DOCTYPE html>
1118 <html xmlns="http://www.w3.org/1999/xhtml">
1119 <head>
1120 <meta charset="utf-8" />
1121 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1122 <title>$d</title>
1123 </head>
1124 <body><pre>
1125 HEADER
1126 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1127 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1128 -e 's/ by adding `.md` to the URL//' \
1129 -e 's/&/\&amp;/g' -e 's/</\&lt;/g' <"markdown.git/$d"
1130 cat <<-FOOTER
1131 </pre></body>
1132 </html>
1133 FOOTER
1134 } >"$cgiroot/html/gfm/$d.html"
1136 title="Markdown: $(echo "${d%.md}" | "$perlbin" -pe '$_=ucfirst')"
1137 gwfpath="$cfg_gitwebfiles"
1138 case "$gwfpath" in *"//"*)
1139 case "$gwfpath" in *"/");;*) gwfpath="$gwfpath/"; esac
1140 gwfpath="${gwfpath#*//}"; gwfpath="${gwfpath#*/}"
1141 esac
1142 case "$gwfpath" in "/"*);;*) gwfpath="/$gwfpath"; esac
1143 gwfpath="${gwfpath%/}"
1144 cat <<-HEADER
1145 <!DOCTYPE html>
1146 <html xmlns="http://www.w3.org/1999/xhtml">
1147 <head>
1148 <meta charset="utf-8" />
1149 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1150 <title>$title</title>
1151 <link rel="stylesheet" type="text/css" href="$gwfpath/gitweb.css" />
1152 <link rel="stylesheet" type="text/css" href="$gwfpath/girocco.css" />
1153 <link rel="shortcut icon" href="$gwfpath/git-favicon.png" type="image/png" />
1154 </head>
1155 <body style="text-align:center">
1156 <div class="readme" style="overflow:inherit;display:inline-block;text-align:left;max-width:42pc">
1157 HEADER
1158 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1159 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1160 -e 's/ by adding `.md` to the URL//' |
1161 "$perlbin" "markdown.git/Markdown.pl"
1162 cat <<-FOOTER
1163 </div>
1164 </body>
1165 </html>
1166 FOOTER
1167 } >"$cgiroot/html/gfm/${d%.md}.html"
1168 done
1171 echo "*** Finalizing permissions and moving into place..."
1172 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir" "$webroot" "$cgiroot"
1173 [ -z "$cfg_httpspushurl" ] || chown -R -h "$cfg_mirror_user""$owngroup" "$cfg_certsdir"
1175 # This should always be the very last thing install.sh does
1176 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1177 quick_move "$basedir" "$rbasedir" "$rbasedir-old"
1178 [ -n "$webrootsub" ] || quick_move "$webroot" "$rwebroot" "$rwebroot-old"
1179 [ -n "$cgirootsub" ] || quick_move "$cgiroot" "$rcgiroot" "$rcgiroot-old"
1180 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1181 echo "--- Update hooks and config with $cfg_basedir/toolbox/update-all-projects.sh"
1182 ! [ -S "$cfg_chroot/etc/taskd.socket" ] || {
1183 echo "*** Requesting graceful restart of running taskd (and, if running, jobd)..."
1184 touch "$cfg_chroot/etc/taskd.restart"
1185 chown_make "$cfg_chroot/etc/taskd.restart"
1186 trap ':' PIPE
1187 echo "nop" | nc_openbsd -w 5 -U "$cfg_chroot/etc/taskd.socket" || :
1188 trap - PIPE