#!/bin/bash # default values user=lily loopfile=/home/lily/loopfile size=200000 jaildir=/home/lily/lilymnt # Usage information function USAGE () { echo "" echo "USAGE: " echo " create_lily_jail.sh [-s SIZE] [-p LILYPREFIX] [USER [LOOPFILE [MOUNTPOINT]]]" echo "" echo "Create a proper chroot jail for lilypond, using a loop device with " echo "the LOOPFILE of SIZE, mounted on MOUNTPOINT. Everything is created " echo "in the USER's home directory and set up for use by USER." echo "" echo "ARGUMENTS:" echo " USER The user for which the jail is set up ($user)" echo " LOOPFILE The loopfile for the raw data ($loopfile)" echo " MOUNTPOINT Where LOOPFILE will be mounted for use ($jaildir)" echo "" echo "OPTIONS:" echo " -h This usage information" echo " -p LILYPREFIX Where lilypond was manually installed to (empty)" echo " If not given, lilypond will not be installed." echo " Can be given multiple times." echo " -s SIZE size of the loopfile in bytes ($size)" echo "" echo "EXAMPLE:" echo " create_lily_jail.sh -s 100000 lily /home/lily/lilyloopfile" echo "" exit $E_OPTERROR # Exit and explain usage, if no argument(s) given. } lilyprefixes=() #process options while getopts ":p:s:h" Option do case $Option in s ) size=$OPTARG;; p ) # Remove / from the front/tail of prefix, because we will use it also as relative dir! a=${OPTARG#/}; lilyprefixes+=(${a%/});; h ) USAGE exit 0;; * ) echo "" echo "Unimplemented option chosen." USAGE esac done shift $((OPTIND-1)) if [ "$#" -ge "1" ]; then user=$1; fi loopfile=/home/$user/loopfile jaildir=/home/$user/lilymnt if [ "$#" -ge "2" ]; then loopfile=$2; fi if [ "$#" -ge "3" ]; then jaildir=$3; fi lilyhome=$jaildir/lilyhome echo "user=$user, loopfile=$loopfile, jaildir=$jaildir, size=$size, lilyprefix=${lilyprefixes[@]}" # check if user exists. If not, add it. home=`cut -d: -f1,6 /etc/passwd | grep -e "^$user:" | sed "s/^$user://"` echo "HOME: $home" if [ -d "$home" ]; then echo "User $user already exists"; else home=/home/$user/ echo "Adding user $user with homedir $home"; adduser --gecos "LilyPond Jail user" $user; fi # check if the loopfile is already used. If so, get the loop device and unmount # just in case it is mounted loop=`losetup -j $loopfile 2> /dev/null | cut -d: -f1 ` if [ -e "$loop" ]; then echo "Loop file already used on $loop, reusing it..." umount $loop 2> /dev/null losetup -d $loop else loop=`losetup --find` echo "Finding next free loop device: $loop"; fi # Create a loop file of the appropriate size. If it exists, ask for overwriting. if [ -f $loopfile ]; then echo "Loopfile $loopfile already exists. Do you want to overwrite it? [y/N]" read answer if [ "$answer" != "y" ]; then echo "NOT overwriting the loopfile $loopfile. Exiting..." exit 1 fi fi echo "Writing loopfile $loopfile of size $size" dd if=/dev/zero of=$loopfile bs=1k count=$size # Set up the proper loop devices echo "Setting up $loop for file $loopfile, to be mounted at $jaildir" mkdir -p $jaildir losetup $loop $loopfile mkfs -t ext3 $loop $size mount -t ext3 $loop $jaildir mkdir $lilyhome chown $user $lilyhome # copy all files required for lilypond echo "Setting up all files needed to run lilypond" cd $jaildir mkdir -p bin usr/bin usr/share usr/lib usr/share/fonts/truetype ${lilyprefixes[@]} tmp chmod a+w tmp # build an array of the lilypond and guile binaries in all prefixes lily_use_binaries=(); for i in ${lilyprefixes[@]}; do echo " Copying lilypond distribution from $i"; cp -rL /$i/lilypond $i; lily_use_binaries+=(/$i/lilypond/usr/bin/lilypond /$i/lilypond/usr/bin/guile) done cp -L `which sh rm` bin cp -L `which convert gs` usr/bin # cp -L /usr/share/fonts/truetype/{msttcorefonts,ttf-liberation,ubuntu-font-family} usr/share/fonts/truetype cp -L /usr/share/fonts/truetype usr/share/fonts # Now the library copying magic for i in ${lily_use_binaries[@]} `which sh rm gs convert`; do echo " Finding dependencies for binary $i"; # ldd returns all dependencies, so extract the file name and then copy it # with the same directory path deps=`ldd $i | \ sed 's:.*=> /\(.*/[^(]*\).*:/\1:' | \ sed 's:\t/\(.*/.*\) (.*)$:/\1:' | \ sed '/.*=>.*/d'; ` for i in $deps; do cp -rL --parents "$i" . done done # The shared files for ghostscript and ImageMagick cp -rL /usr/share/ghostscript usr/share cp -rL /usr/lib/ImageMagick* usr/lib # Finally, print out some information for the user how to set up sudo and fstab: echo " /========================================================================\ | Setup of the lilypond chroot jail on $jaildir finished. | Installed LilyPond binaries from prefixes:" for i in ${lilyprefixes[@]}; do echo "\ | $i" done echo "\ | | Please add the following line to /etc/fstab to automatically mount | the loop device: | $lilyloop $jaildir ext3 auto,loop=$loop 0 0 | | To enable a user USER to run 'sudo lilypond -j...' for any of these | lilypond installations, please add the following lines to /etc/sudoers:" for i in ${lilyprefixes[@]}; do echo "\ | USER ALL=NOPASSWD: /$i/lilypond/usr/bin/lilypond -j$user,$user,$jaildir,/lilyhome *" done echo \ "| \========================================================================/ "