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