scripts: purge use of test '-a' and '-o' ops and clean up
[girocco.git] / install.sh
blobdd632c5f68b6e94616afb47128daced20cbc18a2
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. -M$GIROCCO_CONF -e ''
27 . ./shlib.sh
28 umask 0022
29 "$var_perl_bin" toolbox/check-perl-modules.pl
31 # $1 must exist and be a dir
32 # $2 may exist but must be a dir
33 # $3 must not exist
34 # After call $2 will be renamed to $3 (if $2 existed)
35 # And $1 will be renamed to $2
36 quick_move() {
37 [ -n "$1" ] && [ -n "$2" ] && [ -n "$3" ] || { echo "fatal: quick_move: bad args: '$1' '$2' '$3'" >&2; exit 1; }
38 ! [ -e "$3" ] || { echo "fatal: quick_move: already exists: $3" >&2; exit 1; }
39 [ -d "$1" ] || { echo "fatal: quick_move: no such dir: $1" >&2; exit 1; }
40 ! [ -e "$2" ] || [ -d "$2" ] || { echo "fatal: quick_move: not a dir: $2" >&2; exit 1; }
41 perl -e 'rename($ARGV[1], $ARGV[2]) or die "rename failed: $!\n" if -d $ARGV[1];
42 rename($ARGV[0], $ARGV[1]) or die "rename failed: $!\n"; exit 0;' "$1" "$2" "$3" || {
43 echo "fatal: quick_move: rename failed" >&2
44 exit 1
46 ! [ -d "$1" ] && [ -d "$2" ] || {
47 echo "fatal: quick_move: rename failed" >&2
48 exit 1
52 check_sh_builtin() (
53 "unset" -f command
54 "command" "$var_sh_bin" -c '{ "unset" -f unalias command "$1" || :; "unalias" "$1" || :; } >/dev/null 2>&1; "command" -v "$1"' "$var_sh_bin" "$1"
55 ) 2>/dev/null
57 owngroup=
58 [ -z "$cfg_owning_group" ] || owngroup=":$cfg_owning_group"
59 if [ -n "$cfg_httpspushurl" ] && [ -z "$cfg_certsdir" ]; then
60 echo "ERROR: \$httpspushurl is set but \$certsdir is not!" >&2
61 echo "ERROR: perhaps you have an incorrect Config.pm?" >&2
62 exit 1
66 # Check for extra required tools
67 if [ "${cfg_xmllint_readme:-0}" != "0" ] && ! command -v xmllint >/dev/null; then
68 echo "ERROR: \$xmllint_readme set but xmllint not in \$PATH!" >&2
69 exit 1
73 echo "*** Checking for compiled utilities..."
74 if ! [ -f src/can_user_push ] || ! [ -x src/can_user_push ]; then
75 echo "ERROR: src/can_user_push is not built! Did you _REALLY_ read INSTALL?" >&2
76 echo "ERROR: perhaps you forgot to run make?" >&2
77 exit 1
79 if ! [ -f src/can_user_push_http ] || ! [ -x src/can_user_push_http ]; then
80 echo "ERROR: src/can_user_push_http is not built! Did you _REALLY_ read INSTALL?" >&2
81 echo "ERROR: perhaps you forgot to run make?" >&2
82 exit 1
84 if ! [ -f src/getent ] || ! [ -x src/getent ]; then
85 echo "ERROR: src/getent is not built! Did you _REALLY_ read INSTALL?" >&2
86 echo "ERROR: perhaps you forgot to run make?" >&2
87 exit 1
89 if ! [ -f src/get_user_uuid ] || ! [ -x src/get_user_uuid ]; then
90 echo "ERROR: src/get_user_uuid is not built! Did you _REALLY_ read INSTALL?" >&2
91 echo "ERROR: perhaps you forgot to run make?" >&2
92 exit 1
94 if ! [ -f src/list_packs ] || ! [ -x src/list_packs ]; then
95 echo "ERROR: src/list_packs is not built! Did you _REALLY_ read INSTALL?" >&2
96 echo "ERROR: perhaps you forgot to run make?" >&2
97 exit 1
99 if ! [ -f src/peek_packet ] || ! [ -x src/peek_packet ]; then
100 echo "ERROR: src/peek_packet is not built! Did you _REALLY_ read INSTALL?" >&2
101 echo "ERROR: perhaps you forgot to run make?" >&2
102 exit 1
104 if ! [ -f src/rangecgi ] || ! [ -x src/rangecgi ]; then
105 echo "ERROR: src/rangecgi is not built! Did you _REALLY_ read INSTALL?" >&2
106 echo "ERROR: perhaps you forgot to run make?" >&2
107 exit 1
109 if ! [ -f src/strftime ] || ! [ -x src/strftime ]; then
110 echo "ERROR: src/strftime is not built! Did you _REALLY_ read INSTALL?" >&2
111 echo "ERROR: perhaps you forgot to run make?" >&2
112 exit 1
114 if ! [ -f src/throttle ] || ! [ -x src/throttle ]; then
115 echo "ERROR: src/throttle is not built! Did you _REALLY_ read INSTALL?" >&2
116 echo "ERROR: perhaps you forgot to run make?" >&2
117 exit 1
121 echo "*** Checking for ezcert..."
122 if ! [ -f ezcert.git/CACreateCert ] || ! [ -x ezcert.git/CACreateCert ]; then
123 echo "ERROR: ezcert.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
124 exit 1
128 echo "*** Checking for git..."
129 case "$cfg_git_bin" in /*) :;; *)
130 echo 'ERROR: $Girocco::Config::git_bin must be set to an absolute path' >&2
131 exit 1
132 esac
133 if ! [ -f "$cfg_git_bin" ] || ! [ -x "$cfg_git_bin" ]; then
134 echo "ERROR: $cfg_git_bin does not exist or is not executable" >&2
135 exit 1
137 if ! git_version="$("$cfg_git_bin" version)" || [ -z "$git_version" ]; then
138 echo "ERROR: $cfg_git_bin version failed" >&2
139 exit 1
141 case "$git_version" in
142 [Gg]"it version "*) :;;
144 echo "ERROR: '$cfg_git_bin version' output does not start with 'git version '" >&2
145 exit 1
146 esac
147 echo "Found $cfg_git_bin $git_version"
148 git_vernum="$(echo "$git_version" | sed -ne 's/^[^0-9]*\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$/\1/p')"
149 echo "*** Checking Git $git_vernum for compatibility..."
150 if [ "$(vcmp "$git_vernum" 1.6.6)" -lt 0 ]; then
151 echo 'ERROR: $Girocco::Config::git_bin must be at least Git version 1.6.6'
152 exit 1
154 if [ "$(vcmp "$git_vernum" 1.6.6.3)" -lt 0 ]; then
155 echo 'WARNING: $Girocco::Config::git_bin version < 1.6.6.3, clients will not see useful error messages'
157 if [ "$(vcmp "$git_vernum" 1.7.3)" -lt 0 ]; then
158 cat <<'EOT'
161 *** SEVERE WARNING: $Girocco::Config::git_bin is set to a version of Git before 1.7.3
164 Some Girocco functionality will be gracefully disabled and other things will
165 just not work at all such as race condition protection against simultaneous
166 client pushes and server garbage collections.
170 if [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 1.7.5)" -lt 0 ]; then
171 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.5 and mirroring enabled, some sources can cause an infinite fetch loop'
173 if [ "$(vcmp "$git_vernum" 1.7.6.6)" -lt 0 ]; then
174 echo 'WARNING: $Girocco::Config::git_bin version < 1.7.6.6, performance may be degraded'
176 if [ "$(uname -m 2>/dev/null)" = "x86_64" ] && [ "$(vcmp "$git_vernum" 1.7.11)" -ge 0 ]; then
177 echo 'WARNING: $Girocco::Config::git_bin version >= 1.7.11 and x86_64, make sure Git built WITHOUT XDL_FAST_HASH'
178 echo 'WARNING: See http://mid.mail-archive.com/20141222041944.GA441@peff.net for details'
180 if [ "$(vcmp "$git_vernum" 1.8.4.2)" -ge 0 ] && [ -n "$cfg_mirror" ] && [ "$(vcmp "$git_vernum" 2)" -lt 0 ]; then
181 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, git-daemon needs write access for shallow clones'
182 echo 'WARNING: $Girocco::Config::git_bin version >= 1.8.4.2 and < 2.0.0, shallow clones will leave repository turds'
184 if [ "$(vcmp "$git_vernum" 1.8.4.3)" -lt 0 ]; then
185 echo 'WARNING: $Girocco::Config::git_bin version < 1.8.4.3, clients will not receive symref=HEAD:refs/heads/...'
187 if [ "$(vcmp "$git_vernum" 2.1)" -lt 0 ]; then
188 echo 'WARNING: $Girocco::Config::git_bin version < 2.1.0, pack bitmaps will not be available'
190 if [ "$(vcmp "$git_vernum" 2.1)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.1.3)" -lt 0 ]; then
191 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'
193 if [ "$(vcmp "$git_vernum" 2.2)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.3.2)" -lt 0 ]; then
194 cat <<'EOT'
197 *** ERROR: $Girocco::Config::git_bin is set to an incompatible version of Git
200 Git versions starting with 2.2.0 and continuing up through 2.3.1 are incompatible
201 with Girocco due to various unresolved issues. Please either downgrade to 2.1.4
202 or earlier or, more preferred, upgrade to 2.3.2 (ideally 2.4.11) or later.
204 In order to bypass this check you will have to modify install.sh in which case
205 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
208 exit 1
210 if [ "$(vcmp "$git_vernum" 2.3.3)" -lt 0 ]; then
211 echo 'WARNING: $Girocco::Config::git_bin version < 2.3.3, performance will be sub-optimal'
213 if [ "$(vcmp "$git_vernum" 2.4.4)" -lt 0 ]; then
214 echo 'WARNING: $Girocco::Config::git_bin version < 2.4.4, many refs smart HTTP fetches can deadlock'
216 secmsg=
217 if [ "$(vcmp "$git_vernum" 2.4.11)" -lt 0 ]; then
218 secmsg='prior to 2.4.11'
220 if [ "$(vcmp "$git_vernum" 2.5)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.5.5)" -lt 0 ]; then
221 secmsg='2.5.x prior to 2.5.5'
223 if [ "$(vcmp "$git_vernum" 2.6)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.6.6)" -lt 0 ]; then
224 secmsg='2.6.x prior to 2.6.6'
226 if [ "$(vcmp "$git_vernum" 2.7)" -ge 0 ] && [ "$(vcmp "$git_vernum" 2.7.4)" -lt 0 ]; then
227 secmsg='2.7.x prior to 2.7.4'
229 if [ -n "$secmsg" ]; then
230 cat <<EOT
233 *** SEVERE WARNING: \$Girocco::Config::git_bin is set to a version of Git $secmsg
236 Security issues exist in Git versions prior to 2.4.11, 2.5.x prior to 2.5.5,
237 2.6.x prior to 2.6.6 and 2.7.x prior to 2.7.4.
239 Besides the security fixes included in later versions, versions prior to
240 2.2.0 may accidentally prune unreachable loose objects earlier than
241 intended. Since Git version 2.4.11 is the minimum version to include all
242 security fixes to date, it should be considered the absolute minimum
243 version of Git to use when running Girocco.
245 This is not enforced, but Git is easy to build from the git.git submodule
246 and upgrading to GIT VERSION 2.4.11 OR LATER IS HIGHLY RECOMMENDED.
248 We will now pause for a moment so you can reflect on this warning.
251 sleep 60
253 if [ -n "$cfg_mirror" ] && [ "$cfg_mirror" != 0 ] && grep -q ns_parserr "$cfg_git_bin"; then
254 cat <<'EOT'
257 *** WARNING: $Girocco::Config::git_bin is set to a questionable Git binary
260 You appear to have enabled mirroring and the Git binary you have selected
261 appears to contain an experimental patch that cannot be disabled. This
262 patch can generate invalid network DNS traffic and/or cause long delays
263 when fetching using the "git:" protocol when no port number is specified.
264 It may also end up retrieving repsitory contents from a host other than
265 the one specified in the "git:" URL when the port is omitted.
267 You are advised to either build your own version of Git (the problem patch
268 is not part of the official Git repository) or disable mirroring (via the
269 $Girocco::Config:mirror setting) to avoid these potential problems.
271 USE THE SELECTED GIT BINARY AT YOUR OWN RISK!
274 sleep 5
277 test_nc_U() {
278 [ -n "$1" ] || return 1
279 _cmdnc="$(command -v "$1" 2>/dev/null)" || :
280 [ -n "$_cmdnc" ] && [ -f "$_cmdnc" ] && [ -x "$_cmdnc" ] || return 1
281 _tmpdir="$(mktemp -d /tmp/nc-u-XXXXXX)"
282 [ -n "$_tmpdir" ] && [ -d "$_tmpdir" ] || return 1
283 >"$_tmpdir/output"
284 (sleep 3 | "$_cmdnc" -l -U "$_tmpdir/socket" 2>/dev/null >"$_tmpdir/output" || >"$_tmpdir/failed")&
285 _bgpid="$!"
286 sleep 1
287 echo "testing" | "$_cmdnc" -w 1 -U "$_tmpdir/socket" >/dev/null 2>&1 || >"$_tmpdir/failed"
288 sleep 1
289 kill "$_bgpid" >/dev/null 2>&1 || :
290 read -r _result <"$_tmpdir/output" || :
291 _bad=
292 ! [ -e "$_tmpdir/failed" ] || _bad=1
293 rm -rf "$_tmpdir"
294 [ -z "$_bad" ] && [ "$_result" = "testing" ]
295 } >/dev/null 2>&1
297 echo "*** Verifying \$Girocco::Config::nc_openbsd_bin supports -U option..."
298 test_nc_U "$var_nc_openbsd_bin" || {
299 echo "ERROR: invalid Girocco::Config::nc_openbsd_bin setting" >&2
300 echo "ERROR: \"$var_nc_openbsd_bin\" does not grok the -U option" >&2
301 if [ "$(uname -s 2>/dev/null)" = "DragonFly" ]; then
302 echo "ERROR: see the src/dragonfly/README file for a solution" >&2
304 exit 1
307 echo "*** Verifying selected POSIX sh is sane..."
308 shbin="$var_sh_bin"
309 [ -n "$shbin" ] && [ -f "$shbin" ] && [ -x "$shbin" ] && [ "$("$shbin" -c 'echo sh $(( 1 + 1 ))' 2>/dev/null)" = "sh 2" ] || {
310 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting' >&2
311 exit 1
313 [ "$(check_sh_builtin command)" = "command" ] || {
314 echo 'ERROR: invalid $Girocco::Config::posix_sh_bin setting (does not understand command -v)' >&2
315 exit 1
317 sh_not_builtin=
318 sh_extra_chroot_installs=
319 badsh=
320 for sbi in cd pwd read umask unset unalias; do
321 if [ "$(check_sh_builtin "$sbi")" != "$sbi" ]; then
322 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing built-in $sbi)" >&2
323 badsh=1
325 done
326 [ -z "$badsh" ] || exit 1
327 for sbi in '[' echo printf test; do
328 if ! extra="$(check_sh_builtin "$sbi")"; then
329 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (missing command $sbi)" >&2
330 badsh=1
331 continue
333 if [ "$extra" != "$sbi" ]; then
334 case "$extra" in /*) :;; *)
335 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (bad command -v $sbi result: $extra)" >&2
336 badsh=1
337 continue
338 esac
339 withspc=
340 case "$extra" in *" "*) withspc=1; esac
341 [ -z "$withspc" ] && [ -f "$extra" ] && [ -r "$extra" ] && [ -x "$extra" ] || {
342 echo "ERROR: invalid \$Girocco::Config::posix_sh_bin setting (unusable command -v $sbi result: $extra)" >&2
343 badsh=1
344 continue
346 echo "WARNING: slow \$Girocco::Config::posix_sh_bin setting (not built-in $sbi)" >&2
347 sh_not_builtin="$sh_not_builtin $sbi"
348 sh_extra_chroot_installs="$sh_extra_chroot_installs $extra"
350 done
351 [ -z "$badsh" ] || exit 1
352 [ -z "$sh_extra_chroot_installs" ] || {
353 echo "WARNING: the selected POSIX sh implements these as non-built-in:$sh_not_builtin" >&2
354 echo "WARNING: as a result it will run slower than necessary" >&2
355 echo "WARNING: consider building and switching to dash which can be found at:" >&2
356 echo "WARNING: http://gondor.apana.org.au/~herbert/dash/" >&2
357 echo "WARNING: (download a tarball from the files section or clone the Git repository" >&2
358 echo "WARNING: and checkout the latest tag, run autogen.sh, configure and build)" >&2
359 echo "WARNING: dash is licensed under the 3-clause BSD license" >&2
362 echo "*** Verifying selected perl is sane..."
363 perlbin="$var_perl_bin"
364 [ -n "$perlbin" ] && [ -f "$perlbin" ] && [ -x "$perlbin" ] && [ "$("$perlbin" -wle 'print STDOUT "perl ", + ( 1 + 1 )' 2>/dev/null)" = "perl 2" ] || {
365 echo 'ERROR: invalid $Girocco::Config::perl_bin setting' >&2
366 exit 1
369 echo "*** Verifying selected gzip is sane..."
370 gzipbin="$var_gzip_bin"
371 [ -n "$gzipbin" ] && [ -f "$gzipbin" ] && [ -x "$gzipbin" ] && "$gzipbin" -V 2>&1 | grep -q gzip &&
372 [ "$(echo Girocco | "$gzipbin" -c -n -9 | "$gzipbin" -c -d)" = "Girocco" ] || {
373 echo 'ERROR: invalid $Girocco::Config::gzip_bin setting' >&2
374 exit 1
377 echo "*** Verifying basedir, webroot and cgiroot paths..."
378 # Make sure $cfg_basedir, $cfg_webroot and $cfg_cgiroot are absolute paths
379 case "$cfg_basedir" in /*) :;; *)
380 echo "ERROR: invalid Girocco::Config::basedir setting" >&2
381 echo "ERROR: \"$cfg_basedir\" must be an absolute path (start with '/')" >&2
382 exit 1
383 esac
384 case "$cfg_webroot" in /*) :;; *)
385 echo "ERROR: invalid Girocco::Config::webroot setting" >&2
386 echo "ERROR: \"$cfg_webroot\" must be an absolute path (start with '/')" >&2
387 exit 1
388 esac
389 case "$cfg_cgiroot" in /*) :;; *)
390 echo "ERROR: invalid Girocco::Config::cgiroot setting" >&2
391 echo "ERROR: \"$cfg_cgiroot\" must be an absolute path (start with '/')" >&2
392 exit 1
393 esac
395 # return the input with trailing slashes stripped but return "/" for all "/"s
396 striptrsl() {
397 [ -n "$1" ] || return 0
398 _s="${1##*[!/]}"
399 [ "$_s" != "$1" ] || _s="${_s#?}"
400 printf "%s\n" "${1%$_s}"
403 # a combination of realpath + dirname where the realpath of the deepest existing
404 # directory is returned with the rest of the non-existing components appended
405 # and trailing slashes and multiple slashes are removed
406 realdir() {
407 _d="$(striptrsl "$1")"
408 if [ "$_d" = "/" ] || [ -z "$_d" ]; then
409 echo "$_d"
410 return 0
412 _c=""
413 while ! [ -d "$_d" ]; do
414 _c="/$(basename "$_d")$_c"
415 _d="$(dirname "$_d")"
416 [ "$_d" != "/" ] || _c="${_c#/}"
417 done
418 printf "%s%s\n" "$(cd "$_d" && pwd -P)" "$_c"
421 # Use basedir, webroot and cgiroot for easier control of filesystem locations
422 # Wherever we are writing/copying/installing files we use these, but where we
423 # are editing, adding config settings or printing advice we always stick to the
424 # cfg_xxx Config variable versions. These are like a set of DESTDIR variables.
425 # Only the file system directories that could be asynchronously accessed (by
426 # the web server, jobd.pl, taskd.pl or incoming pushes) get these special vars.
427 # The chroot is handled specially and does not need one of these.
428 # We must be careful to allow cgiroot and/or webroot to be under basedir in which
429 # case the prior contents of cgiroot and/or webroot are discarded.
430 rbasedir="$(realdir "$cfg_basedir")"
431 rwebroot="$(realdir "$cfg_webroot")"
432 rcgiroot="$(realdir "$cfg_cgiroot")"
433 case "$rbasedir" in "$rwebroot"/?*)
434 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under webroot" >&2
435 exit 1
436 esac
437 case "$rbasedir" in "$rcgiroot"/?*)
438 echo "ERROR: invalid Girocco::Config::basedir setting; must not be under cgiroot" >&2
439 exit 1
440 esac
441 if [ "$rwebroot" = "$rcgiroot" ]; then
442 echo "ERROR: invalid Girocco::Config::webroot and Girocco::Config::cgiroot settings; must not be the same" >&2
443 exit 1
445 case "$rcgiroot" in "$rwebroot"/?*)
446 echo "ERROR: invalid Girocco::Config::cgiroot setting; must not be under webroot" >&2
447 exit 1
448 esac
449 case "$rwebroot" in "$rcgiroot"/?*)
450 echo "ERROR: invalid Girocco::Config::webroot setting; must not be under cgiroot" >&2
451 exit 1
452 esac
453 basedir="$rbasedir-new"
454 case "$rwebroot" in
455 "$rbasedir"/?*)
456 webroot="$basedir${rwebroot#$rbasedir}"
457 webrootsub=1
460 webroot="$rwebroot-new"
461 webrootsub=
463 esac
464 case "$rcgiroot" in
465 "$rbasedir"/?*)
466 cgiroot="$basedir${rcgiroot#$rbasedir}"
467 cgirootsub=1
470 cgiroot="$rcgiroot-new"
471 cgirootsub=
473 esac
475 echo "*** Setting up basedir..."
477 chown_make() {
478 if [ "$LOGNAME" = root ] && [ -n "$SUDO_USER" ] && [ "$SUDO_USER" != root ]; then
479 find "$@" -user root -print0 2>/dev/null |
480 xargs -0 chown "$SUDO_USER:$(id -gn "$SUDO_USER")"
481 elif [ "$LOGNAME" = root ] && { [ -z "$SUDO_USER" ] || [ "$SUDO_USER" = root ]; }; then
482 echo "*** WARNING: running make as root w/o sudo may leave root-owned: $*"
486 "$MAKE" --no-print-directory --silent apache.conf
487 chown_make apache.conf
488 "$MAKE" --no-print-directory --silent -C src
489 chown_make src
490 rm -fr "$basedir"
491 mkdir -p "$basedir" "$basedir/gitweb" "$basedir/cgi"
492 cp cgi/*.cgi "$basedir/cgi"
493 cp -pR Girocco jobd taskd html jobs toolbox hooks apache.conf shlib.sh bin screen "$basedir"
494 cp -p src/can_user_push src/can_user_push_http src/get_user_uuid src/list_packs src/peek_packet \
495 src/rangecgi src/strftime src/throttle ezcert.git/CACreateCert cgi/authrequired.cgi \
496 cgi/snapshot.cgi "$basedir/bin"
497 cp -p gitweb/*.sh gitweb/*.perl "$basedir/gitweb"
498 [ -n "$cfg_httpspushurl" ] || rm -f "$basedir"/html/rootcert.html "$basedir"/html/httpspush.html
499 [ -n "$cfg_mob" ] || rm -f "$basedir"/html/mob.html
501 # Put the correct Config in place
502 [ "$GIROCCO_CONF" = "Girocco::Config" ] || cp "$(echo "$GIROCCO_CONF" | sed 's#::#/#g; s/$/.pm/')" "$basedir/Girocco/Config.pm"
504 # Create symbolic links to selected binaries
505 ln -s "$cfg_git_bin" "$basedir/bin/git"
506 ln -s "$shbin" "$basedir/bin/sh"
507 ln -s "$perlbin" "$basedir/bin/perl"
508 ln -s "$gzipbin" "$basedir/bin/gzip"
510 echo "*** Preprocessing scripts..."
511 SHBIN="$shbin" && export SHBIN
512 PERLBIN="$perlbin" && export PERLBIN
513 perl -I. -M$GIROCCO_CONF -i -p \
514 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
515 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
516 -e 's/(?<!")\@basedir\@/"$Girocco::Config::basedir"/g;' \
517 -e 's/(?<=")\@basedir\@/$Girocco::Config::basedir/g;' \
518 -e 's/\@reporoot\@/"$Girocco::Config::reporoot"/g;' \
519 -e 's/\@shbin\@/"$ENV{SHBIN}"/g;' \
520 -e 's/\@perlbin\@/"$ENV{PERLBIN}"/g;' \
521 -e 's/\@jailreporoot\@/"$Girocco::Config::jailreporoot"/g;' \
522 -e 's/\@chroot\@/"$Girocco::Config::chroot"/g;' \
523 -e 's/\@webadmurl\@/"$Girocco::Config::webadmurl"/g;' \
524 -e 's/\@screen_acl_file\@/"$Girocco::Config::screen_acl_file"/g;' \
525 -e 's/\@mob\@/"$Girocco::Config::mob"/g;' \
526 -e 's/\@git_server_ua\@/"$Girocco::Config::git_server_ua"/g;' \
527 -e 's/\@defined_git_server_ua\@/defined($Girocco::Config::git_server_ua)/ge;' \
528 -e 's/\@git_no_mmap\@/"$Girocco::Config::git_no_mmap"/g;' \
529 -e 's/\@var_xargs_r\@/"'"$var_xargs_r"'"/g;' \
530 -e 's/\@big_file_threshold\@/"'"$var_big_file_threshold"'"/g;' \
531 -e 's/\@upload_pack_window\@/"'"$var_upload_window"'"/g;' \
532 -e 'close ARGV if eof;' \
533 "$basedir"/jobs/*.sh "$basedir"/jobd/*.sh \
534 "$basedir"/taskd/*.sh "$basedir"/gitweb/*.sh \
535 "$basedir"/shlib.sh "$basedir"/hooks/* \
536 "$basedir"/toolbox/*.sh "$basedir"/toolbox/*.pl \
537 "$basedir"/toolbox/reports/*.sh \
538 "$basedir"/bin/git-* "$basedir"/bin/*.sh \
539 "$basedir"/bin/create-* "$basedir"/bin/update-* \
540 "$basedir"/bin/*.cgi "$basedir"/screen/*
541 perl -i -p \
542 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
543 -e 'close ARGV if eof;' \
544 "$basedir"/jobd/jobd.pl "$basedir"/taskd/taskd.pl \
545 "$basedir"/bin/sendmail.pl "$basedir"/bin/CACreateCert
546 perl -i -p \
547 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
548 -e 's/^#!.*sh/#!$ENV{SHBIN}/ if $. == 1;' \
549 -e 'close ARGV if eof;' \
550 "$basedir"/bin/format-readme "$basedir/cgi"/*.cgi
551 unset PERLBIN
552 unset SHBIN
554 # Dump all the cfg_ and defined_ variables to shlib_vars.sh
555 get_girocco_config_var_list >"$basedir"/shlib_vars.sh
557 echo "*** Setting up darcs-fast-export from bzr-fastimport.git..."
558 if ! [ -f bzr-fastimport.git/exporters/darcs/darcs-fast-export ] ||
559 ! [ -x bzr-fastimport.git/exporters/darcs/darcs-fast-export ]; then
560 echo "ERROR: bzr-fastimport.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
561 exit 1
563 mkdir -p "$basedir"/bin
564 cp bzr-fastimport.git/exporters/darcs/darcs-fast-export "$basedir"/bin
566 echo "*** Setting up hg-fast-export from fast-export.git..."
567 if ! [ -f fast-export.git/hg-fast-export.py ] || ! [ -f fast-export.git/hg2git.py ]; then
568 echo "ERROR: fast-export.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
569 exit 1
571 mkdir -p "$basedir"/bin
572 cp fast-export.git/hg-fast-export.py fast-export.git/hg2git.py "$basedir"/bin
574 echo "*** Setting up markdown from markdown.git..."
575 if ! [ -f markdown.git/Markdown.pl ]; then
576 echo "ERROR: markdown.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
577 exit 1
579 mkdir -p "$basedir"/bin
580 (PERLBIN="$perlbin" && export PERLBIN &&
581 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
582 markdown.git/Markdown.pl >"$basedir"/bin/Markdown.pl.$$ &&
583 chmod a+x "$basedir"/bin/Markdown.pl.$$ &&
584 mv -f "$basedir"/bin/Markdown.pl.$$ "$basedir"/bin/Markdown.pl)
585 test $? -eq 0
587 # Some permission sanity on basedir/bin just in case
588 find "$basedir"/bin -type f -print0 | xargs -0 chmod go-w
589 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir"/bin
591 if [ -n "$cfg_mirror" ]; then
592 echo "--- Remember to start $cfg_basedir/taskd/taskd.pl"
594 echo "--- Also remember to either start $cfg_basedir/jobd/jobd.sh, or add this"
595 echo "--- to the crontab of $cfg_mirror_user (adjust frequency on number of repos):"
596 echo "*/30 * * * * /usr/bin/nice -n 18 $cfg_basedir/jobd/jobd.sh -q --all-once"
599 echo "*** Setting up repository root..."
600 mkdir -p "$cfg_reporoot" "$cfg_reporoot/_recyclebin"
601 if [ "$cfg_owning_group" ]; then
602 chgrp "$cfg_owning_group" "$cfg_reporoot" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot"
603 chgrp "$cfg_owning_group" "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chgrp $cfg_owning_group $cfg_reporoot/_recyclebin"
605 chmod 02775 "$cfg_reporoot" || echo "WARNING: Cannot chmod $cfg_reporoot properly"
606 chmod 02775 "$cfg_reporoot/_recyclebin" || echo "WARNING: Cannot chmod $cfg_reporoot/_recyclebin properly"
609 if [ -n "$cfg_chrooted" ]; then
610 echo "*** Setting up chroot jail for pushing..."
611 if [ "$(id -u)" -eq 0 ]; then
612 # jailsetup may install things from $cfg_basedir/bin into the
613 # chroot so we do a mini-update of just that portion now
614 mkdir -p "$cfg_basedir"
615 rm -rf "$cfg_basedir/bin-new"
616 cp -pR "$basedir/bin" "$cfg_basedir/bin-new" >/dev/null 2>&1
617 rm -rf "$cfg_basedir/bin-old"
618 quick_move "$cfg_basedir/bin-new" "$cfg_basedir/bin" "$cfg_basedir/bin-old"
619 rm -rf "$cfg_basedir/bin-old"
620 if [ -n "$sh_extra_chroot_installs" ]; then
621 GIROCCO_CHROOT_EXTRA_INSTALLS="$sh_extra_chroot_installs"
622 export GIROCCO_CHROOT_EXTRA_INSTALLS
624 ./jailsetup.sh
625 unset GIROCCO_CHROOT_EXTRA_INSTALLS
626 else
627 echo "WARNING: Skipping jail setup, not root"
632 echo "*** Setting up jail configuration (project database)..."
633 [ "$(id -u)" -eq 0 ] || ./jailsetup.sh dbonly
634 mkdir -p "$cfg_chroot" "$cfg_chroot/etc"
635 touch "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group"
636 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc" ||
637 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup $cfg_chroot/etc"
638 chown "$cfg_cgi_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
639 echo "WARNING: Cannot chown $cfg_cgi_user$owngroup the etc/passwd and/or etc/group files"
640 chmod g+w "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
641 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
642 chmod 02775 "$cfg_chroot/etc" || echo "WARNING: Cannot chmod 02775 $cfg_chroot/etc"
645 echo "*** Setting up gitweb from git.git..."
646 if ! [ -f git.git/Makefile ]; then
647 echo "ERROR: git.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
648 exit 1
651 # We do not wholesale replace either webroot or cgiroot unless they are under
652 # basedir so if they exist and are not we make a copy to start working on them.
653 # We make a copy using -p which can result in some warnings so we suppress
654 # error output as it's of no consequence in this case.
655 rm -rf "$webroot" "$cgiroot"
656 [ -n "$webrootsub" ] || ! [ -d "$rwebroot" ] || cp -pR "$rwebroot" "$webroot" >/dev/null 2>&1 || :
657 [ -n "$cgirootsub" ] || ! [ -d "$rcgiroot" ] || cp -pR "$rcgiroot" "$cgiroot" >/dev/null 2>&1 || :
658 mkdir -p "$webroot" "$cgiroot"
661 cd git.git &&
662 "$MAKE" --no-print-directory --silent NO_SUBDIR=: bindir="$(dirname "$cfg_git_bin")" \
663 GITWEB_CONFIG="$cfg_basedir/gitweb/gitweb_config.perl" SHELL_PATH="$shbin" gitweb &&
664 chown_make gitweb &&
665 PERLBIN="$perlbin" && export PERLBIN &&
666 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
667 -e 's/^(\s*use\s+warnings\s*;.*)$/#$1/;' gitweb/gitweb.cgi >"$cgiroot"/gitweb.cgi.$$ &&
668 chmod a+x "$cgiroot"/gitweb.cgi.$$ &&
669 chown_make "$cgiroot"/gitweb.cgi.$$ &&
670 mv -f "$cgiroot"/gitweb.cgi.$$ "$cgiroot"/gitweb.cgi &&
671 cp gitweb/static/*.png gitweb/static/*.css gitweb/static/*.js "$webroot"
673 test $? -eq 0
676 echo "*** Setting up git-browser from git-browser.git..."
677 if ! [ -f git-browser.git/git-browser.cgi ]; then
678 echo "ERROR: git-browser.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
679 exit 1
681 mkdir -p "$webroot"/git-browser "$cgiroot"
683 cd git-browser.git &&
684 CFG="$cfg_basedir/gitweb/git-browser.conf" && export CFG &&
685 PERLBIN="$perlbin" && export PERLBIN && perl -p \
686 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
687 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-browser.cgi >"$cgiroot"/git-browser.cgi.$$ &&
688 chmod a+x "$cgiroot"/git-browser.cgi.$$ &&
689 chown_make "$cgiroot"/git-browser.cgi.$$ &&
690 mv -f "$cgiroot"/git-browser.cgi.$$ "$cgiroot"/git-browser.cgi &&
691 cp -r *.html *.js *.css js.lib "$webroot"/git-browser &&
692 cp -r JSON "$cgiroot"
694 test $? -eq 0
695 rm -f "$webroot"/git-browser/index.html
696 cat >"$basedir/gitweb"/git-browser.conf.$$ <<-EOT
697 gitbin: $cfg_git_bin
698 warehouse: $cfg_reporoot
699 doconfig: $cfg_basedir/gitweb/gitbrowser_config.perl
701 chown_make "$basedir/gitweb"/git-browser.conf.$$
702 mv -f "$basedir/gitweb"/git-browser.conf.$$ "$basedir/gitweb"/git-browser.conf
703 cat >"$webroot"/git-browser/GitConfig.js.$$ <<-EOT
704 cfg_gitweb_url="$cfg_gitweburl/"
705 cfg_browsercgi_url="$cfg_webadmurl/git-browser.cgi"
707 chown_make "$webroot"/git-browser/GitConfig.js.$$
708 mv -f "$webroot"/git-browser/GitConfig.js.$$ "$webroot"/git-browser/GitConfig.js
711 echo "*** Setting up our part of the website..."
712 mkdir -p "$webroot" "$cgiroot"
713 cp "$basedir"/bin/snapshot.cgi "$basedir/cgi"
714 cp "$basedir"/bin/authrequired.cgi "$basedir/cgi"
715 [ -n "$cfg_httpspushurl" ] || rm -f "$basedir/cgi"/usercert.cgi "$cgiroot"/usercert.cgi
716 cp "$basedir/cgi"/*.cgi "$cgiroot"
717 rm -rf "$basedir/cgi"
718 ln -fs "$cfg_basedir"/Girocco "$cgiroot"
719 [ -z "$cfg_webreporoot" ] || { rm -f "$cfg_webreporoot" && ln -s "$cfg_reporoot" "$cfg_webreporoot"; }
720 if [ -z "$cfg_httpspushurl" ]; then
721 grep -v 'rootcert[.]html' gitweb/indextext.html >"$basedir/gitweb/indextext.html"
722 else
723 cp gitweb/indextext.html "$basedir/gitweb"
725 mv "$basedir"/html/*.css "$basedir"/html/*.js "$webroot"
726 cp mootools.js "$webroot"
727 cp htaccess "$webroot/.htaccess"
728 cp cgi/htaccess "$cgiroot/.htaccess"
729 cp git-favicon.ico "$webroot/favicon.ico"
730 cp robots.txt "$webroot"
731 cat gitweb/gitweb.css >>"$webroot"/gitweb.css
734 if [ -n "$cfg_httpspushurl" ]; then
735 echo "*** Setting up SSL certificates..."
736 bits=2048
737 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev/null; then
738 bits="$cfg_rsakeylength"
740 mkdir -p "$cfg_certsdir"
741 [ -d "$cfg_certsdir" ]
742 wwwcertcn=
743 if [ -e "$cfg_certsdir/girocco_www_crt.pem" ]; then
744 wwwcertcn="$(
745 openssl x509 -in "$cfg_certsdir/girocco_www_crt.pem" -noout -subject |
746 sed -e 's,[^/]*,,'
749 wwwcertdns=
750 if [ -n "$cfg_wwwcertaltnames" ]; then
751 for dnsopt in $cfg_wwwcertaltnames; do
752 wwwcertdns="${wwwcertdns:+$wwwcertdns }--dns $dnsopt"
753 done
755 wwwcertdnsfile=
756 if [ -r "$cfg_certsdir/girocco_www_crt.dns" ]; then
757 wwwcertdnsfile="$(cat "$cfg_certsdir/girocco_www_crt.dns")"
759 needroot=
760 [ -e "$cfg_certsdir/girocco_client_crt.pem" ] &&
761 [ -e "$cfg_certsdir/girocco_client_key.pem" ] &&
762 [ -e "$cfg_certsdir/girocco_www_key.pem" ] &&
763 [ -e "$cfg_certsdir/girocco_www_crt.pem" ] && [ "$wwwcertcn" = "/CN=$cfg_httpsdnsname" ] &&
764 [ -e "$cfg_certsdir/girocco_root_crt.pem" ] || needroot=1
765 if [ -n "$needroot" ] && ! [ -e "$cfg_certsdir/girocco_root_key.pem" ]; then
766 rm -f "$cfg_certsdir/girocco_root_crt.pem" "$cfg_certsdir/girocco_root_key.pem"
767 umask 0077
768 openssl genrsa -f4 -out "$cfg_certsdir/girocco_root_key.pem" $bits
769 chmod 0600 "$cfg_certsdir/girocco_root_key.pem"
770 rm -f "$cfg_certsdir/girocco_root_crt.pem"
771 umask 0022
772 echo "Created new root key"
774 if ! [ -e "$cfg_certsdir/girocco_root_crt.pem" ]; then
775 "$basedir/bin/CACreateCert" --root --key "$cfg_certsdir/girocco_root_key.pem" \
776 --out "$cfg_certsdir/girocco_root_crt.pem" "girocco $cfg_nickname root certificate"
777 rm -f "$cfg_certsdir/girocco_www_crt.pem" "$cfg_certsdir/girocco_www_chain.pem"
778 rm -f "$cfg_certsdir/girocco_client_crt.pem" "$cfg_certsdir/girocco_client_suffix.pem"
779 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
780 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
781 echo "Created new root certificate"
783 if ! [ -e "$cfg_certsdir/girocco_www_key.pem" ]; then
784 umask 0077
785 openssl genrsa -f4 -out "$cfg_certsdir/girocco_www_key.pem" $bits
786 chmod 0600 "$cfg_certsdir/girocco_www_key.pem"
787 rm -f "$cfg_certsdir/girocco_www_crt.pem"
788 umask 0022
789 echo "Created new www key"
791 if ! [ -e "$cfg_certsdir/girocco_www_crt.pem" ] ||
792 [ "$wwwcertcn" != "/CN=$cfg_httpsdnsname" ] || [ "$wwwcertdns" != "$wwwcertdnsfile" ]; then
793 openssl rsa -in "$cfg_certsdir/girocco_www_key.pem" -pubout |
794 "$basedir/bin/CACreateCert" --server --key "$cfg_certsdir/girocco_root_key.pem" \
795 --cert "$cfg_certsdir/girocco_root_crt.pem" $wwwcertdns \
796 --out "$cfg_certsdir/girocco_www_crt.pem" "$cfg_httpsdnsname"
797 printf '%s\n' "$wwwcertdns" >"$cfg_certsdir/girocco_www_crt.dns"
798 echo "Created www certificate"
800 if ! [ -e "$cfg_certsdir/girocco_www_chain.pem" ]; then
801 cat "$cfg_certsdir/girocco_root_crt.pem" >"$cfg_certsdir/girocco_www_chain.pem"
802 echo "Created www certificate chain file"
804 if ! [ -e "$cfg_certsdir/girocco_client_key.pem" ]; then
805 umask 0037
806 openssl genrsa -f4 -out "$cfg_certsdir/girocco_client_key.pem" $bits
807 chmod 0640 "$cfg_certsdir/girocco_client_key.pem"
808 rm -f "$cfg_certsdir/girocco_client_crt.pem"
809 umask 0022
810 echo "Created new client key"
812 if ! [ -e "$cfg_certsdir/girocco_client_crt.pem" ]; then
813 openssl rsa -in "$cfg_certsdir/girocco_client_key.pem" -pubout |
814 "$basedir/bin/CACreateCert" --subca --key "$cfg_certsdir/girocco_root_key.pem" \
815 --cert "$cfg_certsdir/girocco_root_crt.pem" \
816 --out "$cfg_certsdir/girocco_client_crt.pem" "girocco $cfg_nickname client authority"
817 rm -f "$cfg_certsdir/girocco_client_suffix.pem"
818 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
819 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
820 echo "Created client certificate"
822 if ! [ -e "$cfg_certsdir/girocco_client_suffix.pem" ]; then
823 cat "$cfg_certsdir/girocco_client_crt.pem" >"$cfg_certsdir/girocco_client_suffix.pem"
824 echo "Created client certificate suffix file"
826 cat "$cfg_rootcert" >"$webroot/${cfg_nickname}_root_cert.pem"
827 if [ -n "$cfg_mob" ]; then
828 if ! [ -e "$cfg_certsdir/girocco_mob_user_key.pem" ]; then
829 openssl genrsa -f4 -out "$cfg_certsdir/girocco_mob_user_key.pem" $bits
830 chmod 0644 "$cfg_certsdir/girocco_mob_user_key.pem"
831 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
832 echo "Created new mob user key"
834 if ! [ -e "$cfg_certsdir/girocco_mob_user_crt.pem" ]; then
835 openssl rsa -in "$cfg_mobuserkey" -pubout |
836 "$basedir/bin/CACreateCert" --client --key "$cfg_clientkey" \
837 --cert "$cfg_clientcert" \
838 --out "$cfg_certsdir/girocco_mob_user_crt.pem" 'mob'
839 echo "Created mob user client certificate"
841 cat "$cfg_mobuserkey" >"$webroot/${cfg_nickname}_mob_key.pem"
842 cat "$cfg_mobusercert" "$cfg_clientcertsuffix" >"$webroot/${cfg_nickname}_mob_user.pem"
843 else
844 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
846 else
847 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
848 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
852 echo "*** Finalizing permissions and moving into place..."
853 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir" "$webroot" "$cgiroot"
854 [ -z "$cfg_httpspushurl" ] || chown -R -h "$cfg_mirror_user""$owngroup" "$cfg_certsdir"
856 # This should always be the very last thing install.sh does
857 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
858 quick_move "$basedir" "$rbasedir" "$rbasedir-old"
859 [ -n "$webrootsub" ] || quick_move "$webroot" "$rwebroot" "$rwebroot-old"
860 [ -n "$cgirootsub" ] || quick_move "$cgiroot" "$rcgiroot" "$rcgiroot-old"
861 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
862 ! [ -S "$cfg_chroot/etc/taskd.socket" ] || {
863 echo "*** Requesting graceful restart of running taskd (and, if running, jobd)..."
864 touch "$cfg_chroot/etc/taskd.restart"
865 echo "nop" | nc_openbsd -w 5 -U "$cfg_chroot/etc/taskd.socket" || :