install.sh: avoid pointless warning when not using a jail
[girocco.git] / install.sh
blob4d2b86660ddc0d4aefc63981af08ab5f1b894f6a
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 if [ -n "$usejail" ]; then
827 chown "$cfg_cgi_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
828 echo "WARNING: Cannot chown $cfg_cgi_user$owngroup the etc/passwd and/or etc/group files"
829 else
830 # If a chroot jail is not in use, sudo privileges are neither expected nor required
831 # which means it will not be possible to change the owner of the passwd and group
832 # files if it differs from the mirror user. And that's okay, provided the group
833 # can still be set correctly to the owning group. But, just in case we're running
834 # as root, go ahead and set the owner to the mirror user.
835 chown "$cfg_mirror_user""$owngroup" "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
836 echo "WARNING: Cannot chown $cfg_mirror_user$owngroup the etc/passwd and/or etc/group files"
838 chmod g+w "$cfg_chroot/etc/passwd" "$cfg_chroot/etc/group" ||
839 echo "WARNING: Cannot chmod g+w the etc/passwd and/or etc/group files"
840 chmod 02775 "$cfg_chroot/etc" || echo "WARNING: Cannot chmod 02775 $cfg_chroot/etc"
843 echo "*** Setting up global hook scripts..."
844 # It is absolutely CRUCIAL that hook script replacements are done atomically!
845 # Otherwise an incoming push might slip in and fail to run the hook script!
846 # The underlying rename(2) function call provides this and mv will use it.
847 # First add hook scripts
848 hooks="pre-auto-gc pre-receive post-commit post-receive update"
849 for hook in $hooks; do
850 cat "$basedir/hooks/$hook" >"$cfg_reporoot/_global/hooks/$hook.$$"
851 chown "$cfg_mirror_user""$owngroup" "$cfg_reporoot/_global/hooks/$hook.$$" ||
852 echo "WARNING: Cannot chown $cfg_reporoot/_global/hooks/$hook"
853 chmod 0755 "$cfg_reporoot/_global/hooks/$hook.$$"
854 mv -f "$cfg_reporoot/_global/hooks/$hook.$$" "$cfg_reporoot/_global/hooks/$hook"
855 done
856 # Then remove any hook scripts that do not belong
857 for hook in "$cfg_reporoot/_global/hooks"/*; do
858 hook="${hook##*/}"
859 [ -f "$cfg_reporoot/_global/hooks/$hook" ] || continue
860 case " $hooks " in *" $hook "*);;*)
861 rm -f "$cfg_reporoot/_global/hooks/$hook" ||
862 echo "WARNING: Cannot remove extraneous $cfg_reporoot/_global/hooks/$hook"
863 esac
864 done
867 echo "*** Setting up gitweb from git.git..."
868 if ! [ -f git.git/Makefile ]; then
869 echo "ERROR: git.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
870 exit 1
873 # We do not wholesale replace either webroot or cgiroot unless they are under
874 # basedir so if they exist and are not we make a copy to start working on them.
875 # We make a copy using -p which can result in some warnings so we suppress
876 # error output as it's of no consequence in this case.
877 rm -rf "$webroot" "$cgiroot"
878 [ -n "$webrootsub" ] || ! [ -d "$rwebroot" ] || cp -pR "$rwebroot" "$webroot" >/dev/null 2>&1 || :
879 [ -n "$cgirootsub" ] || ! [ -d "$rcgiroot" ] || cp -pR "$rcgiroot" "$cgiroot" >/dev/null 2>&1 || :
880 mkdir -p "$webroot" "$cgiroot"
883 cd git.git &&
884 "$MAKE" --no-print-directory --silent NO_SUBDIR=: bindir="$(dirname "$cfg_git_bin")" \
885 GITWEB_CONFIG_COMMON="" GITWEB_CONFIG_SYSTEM="" \
886 GITWEB_CONFIG="$cfg_basedir/gitweb/gitweb_config.perl" SHELL_PATH="$shbin" gitweb &&
887 chown_make gitweb &&
888 PERLBIN="$perlbin" && export PERLBIN &&
889 perl -p -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
890 -e 's/^(\s*use\s+warnings\s*;.*)$/#$1/;' gitweb/gitweb.cgi >"$cgiroot"/gitweb.cgi.$$ &&
891 chmod a+x "$cgiroot"/gitweb.cgi.$$ &&
892 chown_make "$cgiroot"/gitweb.cgi.$$ &&
893 mv -f "$cgiroot"/gitweb.cgi.$$ "$cgiroot"/gitweb.cgi &&
894 cp gitweb/static/*.png gitweb/static/*.css gitweb/static/*.js "$webroot"
896 test $? -eq 0
899 echo "*** Setting up git-browser from git-browser.git..."
900 if ! [ -f git-browser.git/git-browser.cgi ]; then
901 echo "ERROR: git-browser.git is not checked out! Did you _REALLY_ read INSTALL?" >&2
902 exit 1
904 mkdir -p "$webroot"/git-browser "$cgiroot"
906 cd git-browser.git &&
907 CFG="$cfg_basedir/gitweb/git-browser.conf" && export CFG &&
908 PERLBIN="$perlbin" && export PERLBIN && perl -p \
909 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
910 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-browser.cgi >"$cgiroot"/git-browser.cgi.$$ &&
911 chmod a+x "$cgiroot"/git-browser.cgi.$$ &&
912 chown_make "$cgiroot"/git-browser.cgi.$$ &&
913 perl -p \
914 -e 's/^#!.*perl/#!$ENV{PERLBIN}/ if $. == 1;' \
915 -e 's/"git-browser\.conf"/"$ENV{"CFG"}"/' git-diff.cgi >"$cgiroot"/git-diff.cgi.$$ &&
916 chmod a+x "$cgiroot"/git-diff.cgi.$$ &&
917 chown_make "$cgiroot"/git-diff.cgi.$$ &&
918 mv -f "$cgiroot"/git-browser.cgi.$$ "$cgiroot"/git-browser.cgi &&
919 mv -f "$cgiroot"/git-diff.cgi.$$ "$cgiroot"/git-diff.cgi &&
920 for h in *.html; do
921 [ "$h" != "index.html" ] || continue
922 if [ "$h" = "by-commit.html" ] || [ "$h" = "by-date.html" ]; then
923 FAVLINE='<link rel="shortcut icon" href="/git-favicon.png" type="image/png" />' &&
924 export FAVLINE && perl -p -e 'print "$ENV{FAVLINE}\n" if m{</head>};' "$h" \
925 >"$webroot/git-browser/$h.$$" &&
926 chmod a+r "$webroot/git-browser/$h.$$" &&
927 mv -f "$webroot/git-browser/$h.$$" "$webroot/git-browser/$h"
928 else
929 cp -p "$h" "$webroot/git-browser/"
931 done
932 cp -pR *.js *.css js.lib "$webroot/git-browser/" &&
933 cp -pR JSON "$cgiroot/"
935 test $? -eq 0
936 gitwebabs="$cfg_gitweburl"
937 case "$gitwebabs" in "http://"[!/]*|"https://"[!/]*)
938 gitwebabs="${gitwebabs#*://}"
939 case "$gitwebabs" in
940 *"/"*) gitwebabs="/${gitwebabs#*/}";;
941 *) gitwebabs="";;
942 esac
943 esac
944 case "$gitwebabs" in */);;*) gitwebabs="$gitwebabs/"; esac
945 cat >"$basedir/gitweb"/git-browser.conf.$$ <<-EOT
946 gitbin: $cfg_git_bin
947 gitweb: $gitwebabs
948 warehouse: $cfg_reporoot
949 doconfig: $cfg_basedir/gitweb/gitbrowser_config.perl
951 chown_make "$basedir/gitweb"/git-browser.conf.$$
952 mv -f "$basedir/gitweb"/git-browser.conf.$$ "$basedir/gitweb"/git-browser.conf
953 esctitle="$(printf '%s\n' "$cfg_title" | LC_ALL=C sed 's/\\/\\\\/g;s/"/\\"/g;')" || :
954 cat >"$webroot"/git-browser/GitConfig.js.$$ <<-EOT
955 cfg_gitweb_url="$cfg_gitweburl/"
956 cfg_browsercgi_url="$cfg_webadmurl/git-browser.cgi"
957 cfg_home_url="$cfg_gitweburl/%n"
958 cfg_home_text="summary"
959 cfg_bycommit_title="$esctitle - %n/graphiclog1"
960 cfg_bydate_title="$esctitle - %n/graphiclog2"
962 chown_make "$webroot"/git-browser/GitConfig.js.$$
963 mv -f "$webroot"/git-browser/GitConfig.js.$$ "$webroot"/git-browser/GitConfig.js
966 echo "*** Setting up our part of the website..."
967 mkdir -p "$webroot" "$cgiroot"
968 cp "$basedir"/bin/snapshot.cgi "$basedir/cgi"
969 cp "$basedir"/bin/authrequired.cgi "$basedir/cgi"
970 [ -n "$cfg_httpspushurl" ] || rm -f "$basedir/cgi"/usercert.cgi "$cgiroot"/usercert.cgi
971 cp "$basedir/cgi"/*.cgi "$cgiroot"
972 rm -rf "$basedir/cgi"
973 [ -z "$webreporoot" ] || { rm -f "$webreporoot" && ln -s "$cfg_reporoot" "$webreporoot"; }
974 if [ -z "$cfg_httpspushurl" ] || [ -n "$cfg_pretrustedroot" ]; then
975 grep -v 'rootcert[.]html' gitweb/indextext.html >"$basedir/gitweb/indextext.html"
976 else
977 cp gitweb/indextext.html "$basedir/gitweb"
979 mv "$basedir"/html/*.css "$basedir"/html/*.js "$webroot"
980 cp mootools.js "$webroot"
981 cp htaccess "$webroot/.htaccess"
982 cp cgi/htaccess "$cgiroot/.htaccess"
983 cp git-favicon.ico "$webroot/favicon.ico"
984 cp robots.txt "$webroot"
985 cat gitweb/gitweb.css >>"$webroot"/gitweb.css
988 if [ -n "$cfg_httpspushurl" ]; then
989 echo "*** Setting up SSL certificates..."
990 openssl="${var_openssl_bin:-openssl}"
991 createcert() { PATH="$basedir/bin:$PATH" "$basedir/bin/CACreateCert" "$@"; }
992 bits=2048
993 if [ "$cfg_rsakeylength" -gt "$bits" ] 2>/dev/null; then
994 bits="$cfg_rsakeylength"
996 mkdir -p "$cfg_certsdir"
997 [ -d "$cfg_certsdir" ]
998 wwwcertcn=
999 if [ -e "$cfg_certsdir/girocco_www_crt.pem" ]; then
1000 wwwcertcn="$(
1001 "$openssl" x509 -in "$cfg_certsdir/girocco_www_crt.pem" -noout -subject |
1002 sed -e 's,[^/]*,,'
1005 wwwcertdns=
1006 if [ -n "$cfg_wwwcertaltnames" ]; then
1007 for dnsopt in $cfg_wwwcertaltnames; do
1008 wwwcertdns="${wwwcertdns:+$wwwcertdns }--dns $dnsopt"
1009 done
1011 wwwcertdnsfile=
1012 if [ -r "$cfg_certsdir/girocco_www_crt.dns" ]; then
1013 wwwcertdnsfile="$(cat "$cfg_certsdir/girocco_www_crt.dns")"
1015 needroot=
1016 [ -e "$cfg_certsdir/girocco_client_crt.pem" ] &&
1017 [ -e "$cfg_certsdir/girocco_client_key.pem" ] &&
1018 [ -e "$cfg_certsdir/girocco_www_key.pem" ] &&
1019 [ -e "$cfg_certsdir/girocco_www_crt.pem" ] && [ "$wwwcertcn" = "/CN=$cfg_httpsdnsname" ] &&
1020 [ -e "$cfg_certsdir/girocco_root_crt.pem" ] || needroot=1
1021 if [ -n "$needroot" ] && ! [ -e "$cfg_certsdir/girocco_root_key.pem" ]; then
1022 rm -f "$cfg_certsdir/girocco_root_crt.pem" "$cfg_certsdir/girocco_root_key.pem"
1023 umask 0077
1024 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_root_key.pem" $bits
1025 chmod 0600 "$cfg_certsdir/girocco_root_key.pem"
1026 rm -f "$cfg_certsdir/girocco_root_crt.pem"
1027 umask 0022
1028 echo "Created new root key"
1030 if ! [ -e "$cfg_certsdir/girocco_root_crt.pem" ]; then
1031 createcert --root --key "$cfg_certsdir/girocco_root_key.pem" \
1032 --out "$cfg_certsdir/girocco_root_crt.pem" "girocco $cfg_nickname root certificate"
1033 rm -f "$cfg_certsdir/girocco_www_crt.pem" "$cfg_certsdir/girocco_www_chain.pem"
1034 rm -f "$cfg_certsdir/girocco_client_crt.pem" "$cfg_certsdir/girocco_client_suffix.pem"
1035 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1036 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1037 echo "Created new root certificate"
1039 if ! [ -e "$cfg_certsdir/girocco_www_key.pem" ]; then
1040 umask 0077
1041 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_www_key.pem" $bits
1042 chmod 0600 "$cfg_certsdir/girocco_www_key.pem"
1043 rm -f "$cfg_certsdir/girocco_www_crt.pem"
1044 umask 0022
1045 echo "Created new www key"
1047 if ! [ -e "$cfg_certsdir/girocco_www_crt.pem" ] ||
1048 [ "$wwwcertcn" != "/CN=$cfg_httpsdnsname" ] || [ "$wwwcertdns" != "$wwwcertdnsfile" ]; then
1049 "$openssl" rsa -in "$cfg_certsdir/girocco_www_key.pem" -pubout |
1050 createcert --server --key "$cfg_certsdir/girocco_root_key.pem" \
1051 --cert "$cfg_certsdir/girocco_root_crt.pem" $wwwcertdns \
1052 --out "$cfg_certsdir/girocco_www_crt.pem" "$cfg_httpsdnsname"
1053 printf '%s\n' "$wwwcertdns" >"$cfg_certsdir/girocco_www_crt.dns"
1054 echo "Created www certificate"
1056 if ! [ -e "$cfg_certsdir/girocco_www_chain.pem" ]; then
1057 cat "$cfg_certsdir/girocco_root_crt.pem" >"$cfg_certsdir/girocco_www_chain.pem"
1058 echo "Created www certificate chain file"
1060 if ! [ -e "$cfg_certsdir/girocco_client_key.pem" ]; then
1061 umask 0037
1062 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_client_key.pem" $bits
1063 chmod 0640 "$cfg_certsdir/girocco_client_key.pem"
1064 rm -f "$cfg_certsdir/girocco_client_crt.pem"
1065 umask 0022
1066 echo "Created new client key"
1068 if ! [ -e "$cfg_certsdir/girocco_client_crt.pem" ]; then
1069 "$openssl" rsa -in "$cfg_certsdir/girocco_client_key.pem" -pubout |
1070 createcert --subca --key "$cfg_certsdir/girocco_root_key.pem" \
1071 --cert "$cfg_certsdir/girocco_root_crt.pem" \
1072 --out "$cfg_certsdir/girocco_client_crt.pem" "girocco $cfg_nickname client authority"
1073 rm -f "$cfg_certsdir/girocco_client_suffix.pem"
1074 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1075 rm -f "$cfg_chroot/etc/sshcerts"/*.pem
1076 echo "Created client certificate"
1078 if ! [ -e "$cfg_certsdir/girocco_client_suffix.pem" ]; then
1079 cat "$cfg_certsdir/girocco_client_crt.pem" >"$cfg_certsdir/girocco_client_suffix.pem"
1080 echo "Created client certificate suffix file"
1082 if [ -z "$cfg_pretrustedroot" ]; then
1083 cat "$cfg_rootcert" >"$webroot/${cfg_nickname}_root_cert.pem"
1084 else
1085 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1087 if [ -n "$cfg_mob" ]; then
1088 if ! [ -e "$cfg_certsdir/girocco_mob_user_key.pem" ]; then
1089 "$openssl" genrsa -f4 -out "$cfg_certsdir/girocco_mob_user_key.pem" $bits
1090 chmod 0644 "$cfg_certsdir/girocco_mob_user_key.pem"
1091 rm -f "$cfg_certsdir/girocco_mob_user_crt.pem"
1092 echo "Created new mob user key"
1094 if ! [ -e "$cfg_certsdir/girocco_mob_user_crt.pem" ]; then
1095 "$openssl" rsa -in "$cfg_mobuserkey" -pubout |
1096 createcert --client --key "$cfg_clientkey" \
1097 --cert "$cfg_clientcert" \
1098 --out "$cfg_certsdir/girocco_mob_user_crt.pem" 'mob'
1099 echo "Created mob user client certificate"
1101 cat "$cfg_mobuserkey" >"$webroot/${cfg_nickname}_mob_key.pem"
1102 cat "$cfg_mobusercert" "$cfg_clientcertsuffix" >"$webroot/${cfg_nickname}_mob_user.pem"
1103 else
1104 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1106 else
1107 rm -f "$webroot/${cfg_nickname}_root_cert.pem"
1108 rm -f "$webroot/${cfg_nickname}_mob_key.pem" "$webroot/${cfg_nickname}_mob_user.pem"
1112 echo "*** Processing website html templates..."
1113 rm -f "$cgiroot/html.cgi"
1114 rm -rf "$cgiroot/html"
1115 mkdir -p "$cgiroot/html"
1116 for tf in "$basedir/html"/*.html; do
1117 tfb="${tf##*/}"
1118 "$perlbin" -I"$basedir" cgi/html.cgi "$webroot" "$tfb" "$basedir" >"$cgiroot/html/$tfb"
1119 rm -f "$tf"
1120 done
1122 echo "*** Formatting markdown documentation..."
1123 mkdir -p "$cgiroot/html/gfm"
1124 for d in basics.md syntax.md; do
1126 cat <<-HEADER
1127 <!DOCTYPE html>
1128 <html xmlns="http://www.w3.org/1999/xhtml">
1129 <head>
1130 <meta charset="utf-8" />
1131 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1132 <title>$d</title>
1133 </head>
1134 <body><pre>
1135 HEADER
1136 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1137 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1138 -e 's/ by adding `.md` to the URL//' \
1139 -e 's/&/\&amp;/g' -e 's/</\&lt;/g' <"markdown.git/$d"
1140 cat <<-FOOTER
1141 </pre></body>
1142 </html>
1143 FOOTER
1144 } >"$cgiroot/html/gfm/$d.html"
1146 title="Markdown: $(echo "${d%.md}" | "$perlbin" -pe '$_=ucfirst')"
1147 gwfpath="$cfg_gitwebfiles"
1148 case "$gwfpath" in *"//"*)
1149 case "$gwfpath" in *"/");;*) gwfpath="$gwfpath/"; esac
1150 gwfpath="${gwfpath#*//}"; gwfpath="${gwfpath#*/}"
1151 esac
1152 case "$gwfpath" in "/"*);;*) gwfpath="/$gwfpath"; esac
1153 gwfpath="${gwfpath%/}"
1154 cat <<-HEADER
1155 <!DOCTYPE html>
1156 <html xmlns="http://www.w3.org/1999/xhtml">
1157 <head>
1158 <meta charset="utf-8" />
1159 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
1160 <title>$title</title>
1161 <link rel="stylesheet" type="text/css" href="$gwfpath/gitweb.css" />
1162 <link rel="stylesheet" type="text/css" href="$gwfpath/girocco.css" />
1163 <link rel="shortcut icon" href="$gwfpath/git-favicon.png" type="image/png" />
1164 </head>
1165 <body style="text-align:center">
1166 <div class="readme" style="overflow:inherit;display:inline-block;text-align:left;max-width:42pc">
1167 HEADER
1168 <"markdown.git/$d" LC_ALL=C sed -e '/\[[Ll]icense\]/d' \
1169 -e 's, \([a-z][a-z]*\)\.md, \1.md.html,' \
1170 -e 's/ by adding `.md` to the URL//' |
1171 "$perlbin" "markdown.git/Markdown.pl"
1172 cat <<-FOOTER
1173 </div>
1174 </body>
1175 </html>
1176 FOOTER
1177 } >"$cgiroot/html/gfm/${d%.md}.html"
1178 done
1181 echo "*** Finalizing permissions and moving into place..."
1182 chown -R -h "$cfg_mirror_user""$owngroup" "$basedir" "$webroot" "$cgiroot"
1183 [ -z "$cfg_httpspushurl" ] || chown -R -h "$cfg_mirror_user""$owngroup" "$cfg_certsdir"
1185 # This should always be the very last thing install.sh does
1186 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1187 quick_move "$basedir" "$rbasedir" "$rbasedir-old"
1188 [ -n "$webrootsub" ] || quick_move "$webroot" "$rwebroot" "$rwebroot-old"
1189 [ -n "$cgirootsub" ] || quick_move "$cgiroot" "$rcgiroot" "$rcgiroot-old"
1190 rm -rf "$rbasedir-old" "$rwebroot-old" "$rcgiroot-old"
1191 echo "--- Update hooks and config with $cfg_basedir/toolbox/update-all-projects.sh"
1192 ! [ -S "$cfg_chroot/etc/taskd.socket" ] || {
1193 echo "*** Requesting graceful restart of running taskd (and, if running, jobd)..."
1194 touch "$cfg_chroot/etc/taskd.restart"
1195 chown_make "$cfg_chroot/etc/taskd.restart"
1196 trap ':' PIPE
1197 echo "nop" | nc_openbsd -w 5 -U "$cfg_chroot/etc/taskd.socket" || :
1198 trap - PIPE