chiark / gitweb /
Automate installation of the CGI at last.
[disorder] / scripts / setup.in
1 #! /bin/bash
2 #
3 # This file is part of DisOrder
4 # Copyright (C) 2008 Richard Kettlewell
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 # USA
20 #
21
22 set -e
23
24 while [ $# -gt 0 ]; do
25   opt="$1"
26   shift
27   case "$opt" in
28   -h | --help )
29     cat  <<EOF
30
31 Usage:
32   scripts/setup [OPTIONS]
33
34 Options:
35   --root ROOT             Add a root (can be used multiple times)
36   --encoding ENCODING     Filename encoding
37   --port PORT             TCP port to listen on or 'none'
38   --smtp-server HOSTNAME  SMTP server
39   --email ADDRESS         Origin email address
40   --register y|n          Enable/disable online registration
41   --play local|network    Choose local or network play
42   --mcast ADDRESS PORT    Set multicast address and port for --play network
43   -h, --help              Display this message
44
45 Sets up a basic DisOrder installation.  You must have run 'make install'
46 first.  Use scripts/teardown to stop the server and deconfigure.
47
48 EOF
49     exit 0
50     ;;
51   --version | -V )
52     echo "DisOrder scripts/setup _version_"
53     exit 0
54     ;;
55   --root )
56     roots="$roots $1"
57     shift
58     ;;
59   --encoding )
60     encoding="$1"
61     shift
62     ;;
63   --port )
64     port="$1"
65     shift
66     ;;
67   --smtp-server )
68     smtp_server="$1"
69     shift
70     ;;
71   --email )
72     mail_sender="$1"
73     shift
74     ;;
75   --register )
76     register="$1"
77     shift
78     ;;
79   --play )
80     play="$1"
81     shift
82     ;;
83   --mcast )
84     play=network
85     mcast_address="$1"
86     shift
87     mcast_port="$1"
88     shift
89     ;;
90   * )
91     echo >&2 "ERROR: unknown option '$opt'"
92     exit 1
93     ;;
94   esac
95 done
96
97 echo
98 echo ------------------------------------------------------------------------
99 echo "DisOrder setup script"
100
101 case $(uname -s) in
102 Darwin )
103   echo "Mac OS X detected"
104   os=Mac
105   user=jukebox
106   group=jukebox
107   ;;
108 FreeBSD )
109   echo "FreeBSD detected"
110   os=FreeBSD
111   user=jukebox
112   group=jukebox
113   ;;
114 Linux )
115   if grep Debian /etc/issue >/dev/null 2>&1; then
116     echo "You appear to be running Debian - please use .debs instead"
117     echo
118   elif grep Ubuntu /etc/issue >/dev/null 2>&1; then
119     echo "You appear to be running Ubuntu - please use .debs instead"
120     echo
121   fi
122   echo "Linux detected"
123   os=Linux
124   user=jukebox
125   group=jukebox
126   ;;
127 * )
128   echo 
129   echo "WARNING: unknown operating system '$(uname -s)'"
130   echo "This script won't be able to do all setup on this platform"
131   os=unknown
132   user=daemon
133   group=daemon
134   ;;
135 esac
136
137 echo
138 echo "This script will:"
139 echo " - overwrite any existing configuration"
140 echo " - set the server up to be run at boot time"
141 echo " - start the server"
142 echo " - set up the web interface"
143 echo
144 echo "If this is not what you want, press ^C."
145 echo ------------------------------------------------------------------------
146
147 if [ -z "$roots" ]; then
148   while :; do
149     echo
150     echo "What directory or directories contain your music files:"
151     echo "(enter one or more directories separated by spaces)"
152     read -r roots
153     ok=true
154     for root in $roots; do
155       if [ ! -d $root ]; then
156         echo "'$root' does not exist"
157         ok=false
158       fi
159     done
160     if $ok; then
161       break
162     fi
163   done
164 fi
165
166 if [ -z "$encoding" ]; then
167   echo 
168   echo "What filesystem encoding should I assume for track names?"
169   echo "(e.g. UTF-8, ISO-8859-1, ...)"
170   read -r encoding
171 fi
172
173 if [ -z "$port" ]; then
174   while :; do
175     echo
176     echo "What TCP port should DisOrder listen on?"
177     echo "(enter 'none' for none)"
178     read -r port
179     case $port in
180     none )
181       break
182       ;;
183     [^0-9] )
184       echo "'$port' is not a valid port number"
185       continue
186       ;;
187     * )
188       break
189       ;;
190     esac
191   done
192 fi
193
194 if [ -z "$play" ]; then
195   while :; do
196     echo
197     echo "How do you want to play sound?  Enter 'local' to use a local sound"
198     echo "device or 'network' to multicast sound across your network."
199     read -r play
200     case $play in
201     'local' | network )
202       break
203       ;;
204     * )
205       echo "Enter 'local' or 'network'"
206       continue
207       ;;
208     esac
209   done
210 fi
211
212 if [ "x$play" = xnetwork ]; then
213   if [ -z "$mcast_address" ]; then
214     echo
215     echo "Enter destination address for network transmission"
216     echo "(e.g. a multicast address)"
217     read -r mcast_address
218   fi
219   if [ -z "$mcast_port" ]; then
220     while :; do
221       echo
222       echo "Enter destination port for network transmission"
223       read -r mcast_port
224       case $mcast_port in
225       none )
226         break
227         ;;
228       [^0-9] )
229         echo "'$mcast_port' is not a valid port number"
230         continue
231         ;;
232       * )
233         break
234         ;;
235       esac
236     done
237   fi
238 fi
239
240 if [ -z "$mail_sender" ]; then
241   while :; do
242     echo
243     echo "What address should mail from DisOrder come from?"
244     read -r mail_sender
245     case "$mail_sender" in
246     *@* )
247       break
248       ;;
249     * )
250       echo "Email address must contain an '@' sign"
251       ;;
252     esac
253   done
254 fi
255
256 if [ -z "$register" ]; then
257   while :; do
258     echo
259     echo "Do you want to enable online registration?  (Enter 'y' or 'n')"
260     read -r register
261     case $register in
262     y | n )
263       break
264       ;;
265     esac
266   done
267 fi
268
269 echo
270 echo "Proposed DisOrder setup:"
271 echo " Music directory:       $roots"
272 if [ $port = none ]; then
273   echo " Do not listen on a TCP port"
274 else
275   echo " TCP port to listen on: $port"
276 fi
277 if [ ! -z "$smtp_server" ]; then
278   echo " SMTP Server:           $smtp_server"
279 fi
280 echo " Sender address:        $mail_sender"
281 echo " Online registration:   $register"
282 if [ $play = network ]; then
283   echo " Send sound to:         $mcast_address port $mcast_port"
284 fi
285
286 echo "Is this OK?  (Enter 'y' or 'n')"
287 read -r ok
288 case $ok in
289 y )
290   ;;
291 * )
292   echo
293   echo "OK, didn't change anything."
294   exit 0
295   ;;
296 esac
297
298 mkdir -p pkgconfdir
299
300 rm -f pkgconfdir/config.new
301 for root in $roots; do
302   echo "collection fs $encoding $root" >> pkgconfdir/config.new
303 done
304 for scratch in slap.ogg scratch.ogg; do
305   echo "scratch pkgdatadir/$scratch" >> pkgconfdir/config.new
306 done
307 echo "user $user" >> pkgconfdir/config.new
308 if [ $port != none ]; then
309   echo "listen 0.0.0.0 $port" >> pkgconfdir/config.new
310 fi
311 if [ $play = network ]; then
312   echo "broadcast $mcast_address $mcast_port" >> pkgconfdir/config.new
313 fi
314 if [ ! -z "$smtp_server" ]; then
315   echo "smtp_server $smtp_server" >> pkgconfdir/config.new
316 fi
317 echo "mail_sender $mail_sender" >> pkgconfdir/config.new
318
319 echo
320 echo "Proposed pkgconfdir/config:"
321 sed < pkgconfdir/config.new 's/^/  /'
322 echo
323 echo "Is this OK?  (Enter 'y' or 'n')"
324 read -r ok
325 case $ok in
326 y )
327   ;;
328 * )
329   echo
330   echo "OK, not installing it."
331   rm -f pkgconfdir/config.new
332   exit 0
333   ;;
334 esac
335 echo
336 echo "Installing pkgconfdir/config"
337 mv pkgconfdir/config.new pkgconfdir/config
338
339 if [ ! -f pkgconfdir/options.user ]; then
340   echo "Making sure pkgconfdir/options.user exists"
341   touch pkgconfdir/options.user
342 fi
343
344 # pick ID1 ID2 ... IDn
345 # Echoes an ID matching none of ID1..IDn
346 pick() {
347   local n
348   n=250                         # better not choose 0!
349   while :; do
350     ok=true
351     for k in "$@"; do
352       if [ $n = $k ]; then
353         ok=false
354         break
355       fi
356     done
357     if $ok; then
358       echo $n
359       return
360     fi
361     n=$((1+$n))
362   done
363 }
364
365 case $os in
366 Mac )
367   # Apple don't seem to believe in creating a user as a discrete operation
368   if dscl . -read /Groups/$group >/dev/null 2>&1; then
369     echo "$group group already exists"
370   else
371     echo "Creating $group group"
372     gids=$(dscl . -list /Groups PrimaryGroupID|awk '{print $2}')
373     gid=$(pick $gids)
374     echo "(picked gid $gid)"
375     dscl . -create /Groups/$group
376     dscl . -create /Groups/$group PrimaryGroupID $gid
377     dscl . -create /Groups/$group Password \*
378   fi
379   if dscl . -read /Users/$user >/dev/null 2>&1; then
380     echo "$user user already exists"
381   else
382     echo "Creating $user user"
383     uids=$(dscl . -list /Users UniqueID|awk '{print $2}')
384     uid=$(pick $uids)
385     echo "(picked uid $uid)"
386     gid=$(dscl . -read /Groups/$group PrimaryGroupID | awk '{print $2}')
387     dscl . -create /Users/$user
388     dscl . -create /Users/$user UniqueID $uid
389     dscl . -create /Users/$user UserShell /usr/bin/false
390     dscl . -create /Users/$user RealName 'DisOrder server'
391     dscl . -create /Users/$user NFSHomeDirectory pkgstatedir
392     dscl . -create /Users/$user PrimaryGroupID $gid
393     dscl . -create /Users/$user Password \*
394   fi
395   ;;
396 FreeBSD )
397   # FreeBSD has a simple well-documented interface
398   if pw groupshow $group >/dev/null 2>&1; then
399     echo "$group group already exists"
400   else
401     echo "Creating $group group"
402     pw groupadd $group
403   fi
404   if pw usershow $user >/dev/null 2>&1; then
405     echo "$user user already exists"
406   else
407     echo "Creating $user user"
408     pw useradd $user -w no -d pkgstatedir -g $group -c 'DisOrder user'
409   fi
410   ;;
411 Linux )
412   if grep ^$group: /etc/group >/dev/null; then
413     echo "$group group already exists"
414   else
415     echo "Creating $group group"
416     groupadd $group
417   fi
418   if grep ^$user: /etc/passwd >/dev/null; then
419     echo "$user user already exists"
420   else
421     echo "Creating $user user"
422     useradd -d pkgstatedir -g $group $user -c 'DisOrder user'
423   fi
424   ;;
425 esac
426
427 echo "Making sure that pkgstatedir exists"
428 mkdir -p pkgstatedir
429 chown $user:$group pkgstatedir
430 chmod 2755 pkgstatedir
431
432 case $os in
433 Mac )
434   echo "Installing the plist into /Library/LaunchDaemons"
435   cp examples/uk.org.greenend.rjk.disorder.plist /Library/LaunchDaemons/.
436   echo "Reloading launchd"
437   launchctl load /Library/LaunchDaemons
438   echo "Starting DisOrder server"
439   launchctl start uk.org.greenend.rjk.disorder
440   DOCROOT=/Library/WebServer/Documents
441   sever_running=true
442   ;;
443 FreeBSD )
444   echo "Installing startup script into /etc/rc.d"
445   install -m 555 examples/disorder.rc /etc/rc.d/disorder
446   echo "Starting DisOrder server"
447   /etc/rc.d/disorder start
448   echo "Identifying web server"
449   set /usr/local/www/*
450   case $# in
451   0 )
452     echo
453     echo "Could not find a web server"
454     exit 1
455     ;;
456   1 )
457     ;;
458   * )
459     echo
460     echo "Yikes!  There seems to be more than one web server here."
461     echo "Guessing that you want $1."
462     echo
463     ;;
464   esac
465   web=$1
466   echo "Found $web"
467   DOCROOT=$web/data
468   server_running=true
469   ;;
470 Linux )
471   echo "Looking for init scripts directory"
472   for d in /etc/rc.d /etc; do
473     if [ -d $d/init.d ]; then
474       RC_D=$d
475       break
476     fi
477   done
478   if [ -z "$RC_D" ]; then
479     echo "Cannot find your init scripts directory"
480   else
481     echo "Installing init script into $RC_D/init.d"
482     install -m 755 examples/disorder.init $RC_D/init.d/disorder
483     echo "Linking init script into $RC_D/rc*.d"
484     for n in 2 3 4 5; do
485       echo " $RC_D/rc$n.d/S99disorder -> $RC_D/init.d/disorder"
486       rm -f $RC_D/rc$n.d/S99disorder
487       ln -s $RC_D/init.d/disorder $RC_D/rc$n.d/S99disorder
488     done
489     for n in 0 1 6; do
490       echo " $RC_D/rc$n.d/K01disorder -> $RC_D/init.d/disorder"
491       rm -f $RC_D/rc$n.d/K01disorder
492       ln -s $RC_D/init.d/disorder $RC_D/rc$n.d/K01disorder
493     done
494     echo "Starting DisOrder server"
495     $RC_D/init.d/disorder start
496   fi
497   echo "Looking for web server document root"
498   for d in /var/www/html /var/www; do
499     if [ -d $d ]; then
500       DOCROOT=$d
501       break
502     fi
503   done
504   server_running=true
505   ;;
506 * )
507   echo
508   echo "Sorry, I don't know how to install the server on this platform."
509   echo "You will have to do that by hand."
510   server_running=false
511   ;;
512 esac
513
514 echo
515 if [ -z "$DOCROOT" ]; then
516   echo "Cannot find your web server's document root"
517 else
518   echo "Setting up link to CGI's dependencies in $DOCROOT"
519   rm -f $DOCROOT/disorder
520   ln -s pkgdatadir/static $DOCROOT/disorder
521 fi
522
523 if $server_running; then
524   first=true
525   sleep 5
526   while ! disorder version >/dev/null 2>&1; do
527     if $first; then
528       echo "Waiting for server startup to complete..."
529       first=false
530     fi
531     sleep 1
532   done
533   if [ $register = y ]; then
534     echo "Creating guest user with 'register' right"
535     disorder setup-guest
536   else
537     echo "Creating guest user without 'register' right"
538     disorder setup-guest --no-online-registration
539   fi
540 fi
541
542 echo
543 echo Done