chiark / gitweb /
Grey out edit playlists menu item if server does not appear to support
[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     anyroots=false
155     for root in $roots; do
156       if [ ! -d $root ]; then
157         echo "'$root' does not exist"
158         ok=false
159       else
160         anyroots=true
161       fi
162     done
163     if $anyroots && $ok; then
164       break
165     fi
166   done
167 fi
168
169 if [ -z "$encoding" ]; then
170   while :; do
171     echo 
172     echo "What filesystem encoding should I assume for track names?"
173     echo "(e.g. UTF-8, ISO-8859-1, ...)"
174     read -r encoding
175     if [ ! -z "$encoding" ]; then
176       break
177     fi
178   done
179 fi
180
181 if [ -z "$port" ]; then
182   while :; do
183     echo
184     echo "What TCP port should DisOrder listen on?"
185     echo "(enter 'none' for none)"
186     read -r port
187     case $port in
188     none )
189       break
190       ;;
191     [^0-9] | "" )
192       echo "'$port' is not a valid port number"
193       continue
194       ;;
195     * )
196       break
197       ;;
198     esac
199   done
200 fi
201
202 if [ -z "$play" ]; then
203   while :; do
204     echo
205     echo "How do you want to play sound?  Enter 'local' to use a local sound"
206     echo "device or 'network' to multicast sound across your network."
207     read -r play
208     case $play in
209     'local' | network )
210       break
211       ;;
212     * )
213       echo "Enter 'local' or 'network'"
214       continue
215       ;;
216     esac
217   done
218 fi
219
220 if [ "x$play" = xnetwork ]; then
221   if [ -z "$mcast_address" ]; then
222     echo
223     echo "Enter destination address for network transmission"
224     echo "(e.g. a multicast address)"
225     read -r mcast_address
226   fi
227   if [ -z "$mcast_port" ]; then
228     while :; do
229       echo
230       echo "Enter destination port for network transmission"
231       read -r mcast_port
232       case $mcast_port in
233       none )
234         break
235         ;;
236       [^0-9] | "" )
237         echo "'$mcast_port' is not a valid port number"
238         continue
239         ;;
240       * )
241         break
242         ;;
243       esac
244     done
245   fi
246 fi
247
248 if [ -z "$mail_sender" ]; then
249   while :; do
250     echo
251     echo "What address should mail from DisOrder come from?"
252     read -r mail_sender
253     case "$mail_sender" in
254     *@* )
255       break
256       ;;
257     * )
258       echo "Email address must contain an '@' sign"
259       ;;
260     esac
261   done
262 fi
263
264 if [ -z "$register" ]; then
265   while :; do
266     echo
267     echo "Do you want to enable online registration?  (Enter 'y' or 'n')"
268     read -r register
269     case $register in
270     y | n )
271       break
272       ;;
273     esac
274   done
275 fi
276
277 echo
278 echo "Proposed DisOrder setup:"
279 echo " Music directory:       $roots"
280 if [ "$port" = none ]; then
281   echo " Do not listen on a TCP port"
282 else
283   echo " TCP port to listen on: $port"
284 fi
285 if [ ! -z "$smtp_server" ]; then
286   echo " SMTP Server:           $smtp_server"
287 fi
288 echo " Sender address:        $mail_sender"
289 echo " Online registration:   $register"
290 if [ $play = network ]; then
291   echo " Send sound to:         $mcast_address port $mcast_port"
292 fi
293
294 echo "Is this OK?  (Enter 'y' or 'n')"
295 read -r ok
296 case $ok in
297 y )
298   ;;
299 * )
300   echo
301   echo "OK, didn't change anything."
302   exit 0
303   ;;
304 esac
305
306 mkdir -p pkgconfdir
307
308 rm -f pkgconfdir/config.new
309 for root in $roots; do
310   echo "collection fs $encoding $root" >> pkgconfdir/config.new
311 done
312 for scratch in slap.ogg scratch.ogg; do
313   echo "scratch pkgdatadir/$scratch" >> pkgconfdir/config.new
314 done
315 echo "user $user" >> pkgconfdir/config.new
316 if [ $port != none ]; then
317   echo "listen 0.0.0.0 $port" >> pkgconfdir/config.new
318 fi
319 if [ $play = network ]; then
320   echo "broadcast $mcast_address $mcast_port" >> pkgconfdir/config.new
321 fi
322 if [ ! -z "$smtp_server" ]; then
323   echo "smtp_server $smtp_server" >> pkgconfdir/config.new
324 fi
325 echo "mail_sender $mail_sender" >> pkgconfdir/config.new
326
327 echo
328 echo "Proposed pkgconfdir/config:"
329 sed < pkgconfdir/config.new 's/^/  /'
330 echo
331 echo "Is this OK?  (Enter 'y' or 'n')"
332 read -r ok
333 case $ok in
334 y )
335   ;;
336 * )
337   echo
338   echo "OK, not installing it."
339   rm -f pkgconfdir/config.new
340   exit 0
341   ;;
342 esac
343 echo
344 echo "Installing pkgconfdir/config"
345 mv pkgconfdir/config.new pkgconfdir/config
346
347 if [ ! -f pkgconfdir/options.user ]; then
348   echo "Making sure pkgconfdir/options.user exists"
349   touch pkgconfdir/options.user
350 fi
351
352 # pick ID1 ID2 ... IDn
353 # Echoes an ID matching none of ID1..IDn
354 pick() {
355   local n
356   n=250                         # better not choose 0!
357   while :; do
358     ok=true
359     for k in "$@"; do
360       if [ $n = $k ]; then
361         ok=false
362         break
363       fi
364     done
365     if $ok; then
366       echo $n
367       return
368     fi
369     n=$((1+$n))
370   done
371 }
372
373 case $os in
374 Mac )
375   # Apple don't seem to believe in creating a user as a discrete operation
376   if dscl . -read /Groups/$group >/dev/null 2>&1; then
377     echo "$group group already exists"
378   else
379     echo "Creating $group group"
380     gids=$(dscl . -list /Groups PrimaryGroupID|awk '{print $2}')
381     gid=$(pick $gids)
382     echo "(picked gid $gid)"
383     dscl . -create /Groups/$group
384     dscl . -create /Groups/$group PrimaryGroupID $gid
385     dscl . -create /Groups/$group Password \*
386   fi
387   if dscl . -read /Users/$user >/dev/null 2>&1; then
388     echo "$user user already exists"
389   else
390     echo "Creating $user user"
391     uids=$(dscl . -list /Users UniqueID|awk '{print $2}')
392     uid=$(pick $uids)
393     echo "(picked uid $uid)"
394     gid=$(dscl . -read /Groups/$group PrimaryGroupID | awk '{print $2}')
395     dscl . -create /Users/$user
396     dscl . -create /Users/$user UniqueID $uid
397     dscl . -create /Users/$user UserShell /usr/bin/false
398     dscl . -create /Users/$user RealName 'DisOrder server'
399     dscl . -create /Users/$user NFSHomeDirectory pkgstatedir
400     dscl . -create /Users/$user PrimaryGroupID $gid
401     dscl . -create /Users/$user Password \*
402   fi
403   ;;
404 FreeBSD )
405   # FreeBSD has a simple well-documented interface
406   if pw groupshow $group >/dev/null 2>&1; then
407     echo "$group group already exists"
408   else
409     echo "Creating $group group"
410     pw groupadd $group
411   fi
412   if pw usershow $user >/dev/null 2>&1; then
413     echo "$user user already exists"
414   else
415     echo "Creating $user user"
416     pw useradd $user -w no -d pkgstatedir -g $group -c 'DisOrder user'
417   fi
418   ;;
419 Linux )
420   if grep ^$group: /etc/group >/dev/null; then
421     echo "$group group already exists"
422   else
423     echo "Creating $group group"
424     groupadd $group
425   fi
426   if grep ^$user: /etc/passwd >/dev/null; then
427     echo "$user user already exists"
428   else
429     echo "Creating $user user"
430     useradd -d pkgstatedir -g $group $user -c 'DisOrder user'
431   fi
432   ;;
433 esac
434
435 echo "Making sure that pkgstatedir exists"
436 mkdir -p pkgstatedir
437 chown $user:$group pkgstatedir
438 chmod 2755 pkgstatedir
439
440 case $os in
441 Mac )
442   echo "Installing the plist into /Library/LaunchDaemons"
443   cp examples/uk.org.greenend.rjk.disorder.plist /Library/LaunchDaemons/.
444   echo "Reloading launchd"
445   launchctl load /Library/LaunchDaemons
446   echo "Starting DisOrder server"
447   launchctl start uk.org.greenend.rjk.disorder
448   server_running=true
449   ;;
450 FreeBSD )
451   echo "Installing startup script into /etc/rc.d"
452   install -m 555 examples/disorder.rc /etc/rc.d/disorder
453   echo "Starting DisOrder server"
454   /etc/rc.d/disorder start
455   server_running=true
456   ;;
457 Linux )
458   echo "Looking for init scripts directory"
459   for d in /etc/rc.d /etc; do
460     if [ -d $d/init.d ]; then
461       RC_D=$d
462       break
463     fi
464   done
465   if [ -z "$RC_D" ]; then
466     echo "Cannot find your init scripts directory"
467   else
468     echo "Installing init script into $RC_D/init.d"
469     install -m 755 examples/disorder.init $RC_D/init.d/disorder
470     echo "Linking init script into $RC_D/rc*.d"
471     for n in 2 3 4 5; do
472       echo " $RC_D/rc$n.d/S99disorder -> $RC_D/init.d/disorder"
473       rm -f $RC_D/rc$n.d/S99disorder
474       ln -s $RC_D/init.d/disorder $RC_D/rc$n.d/S99disorder
475     done
476     for n in 0 1 6; do
477       echo " $RC_D/rc$n.d/K01disorder -> $RC_D/init.d/disorder"
478       rm -f $RC_D/rc$n.d/K01disorder
479       ln -s $RC_D/init.d/disorder $RC_D/rc$n.d/K01disorder
480     done
481     echo "Starting DisOrder server"
482     $RC_D/init.d/disorder start
483   fi
484   server_running=true
485   ;;
486 * )
487   echo
488   echo "Sorry, I don't know how to install the server on this platform."
489   echo "You will have to do that by hand."
490   server_running=false
491   ;;
492 esac
493
494 if $server_running; then
495   first=true
496   sleep 5
497   while ! disorder version >/dev/null 2>&1; do
498     if $first; then
499       echo "Waiting for server startup to complete..."
500       first=false
501     fi
502     sleep 1
503   done
504   if [ $register = y ]; then
505     echo "Creating guest user with 'register' right"
506     disorder setup-guest
507   else
508     echo "Creating guest user without 'register' right"
509     disorder setup-guest --no-online-registration
510   fi
511 fi
512
513 echo
514 echo Done