the whole bunch of stuff found below flavour dir is being installed into the new jails root, including the flavour config, packages and files. The startup scripts now only creates users, chowns the files it is told to and installs packages.
273 lines
10 KiB
Bash
Executable File
273 lines
10 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# ugly: this variable is set during port install time
|
|
ezjail_prefix=EZJAIL_PREFIX
|
|
ezjail_etc=${ezjail_prefix}/etc
|
|
ezjail_share=${ezjail_prefix}/share/ezjail
|
|
ezjail_examples=${ezjail_prefix}/share/examples/ezjail
|
|
ezjail_jailcfgs=${ezjail_etc}/ezjail
|
|
|
|
if [ -f ${ezjail_etc}/ezjail.conf ]; then
|
|
. ${ezjail_etc}/ezjail.conf;
|
|
fi
|
|
|
|
# set defaults
|
|
ezjail_jaildir=${ezjail_jaildir:-"/usr/jails"}
|
|
ezjail_jailtemplate=${ezjail_jailtemplate:-"$ezjail_jaildir/newjail"}
|
|
ezjail_jailbase=${ezjail_jailbase:-"$ezjail_jaildir/basejail"}
|
|
ezjail_jailfull=${ezjail_jailfull:-"$ezjail_jaildir/fulljail"}
|
|
ezjail_flavours=${ezjail_flavours:-"$ezjail_jaildir/flavours"}
|
|
ezjail_sourcetree=${ezjail_sourcetree:-"/usr/src"}
|
|
|
|
ezjail_mount_enable=${ezjail_mount_enable:-"YES"}
|
|
ezjail_devfs_enable=${ezjail_devfs_enable:-"YES"}
|
|
ezjail_devfs_ruleset=${ezjail_devfs_ruleset:-"devfsrules_jail"}
|
|
ezjail_procfs_enable=${ezjail_procfs_enable:-"YES"}
|
|
ezjail_fdescfs_enable=${ezjail_fdescfs_enable:-"YES"}
|
|
|
|
exerr () { echo $*; exit 1; }
|
|
|
|
# check for command
|
|
[ "$1" ] || exerr "Usage: `basename $0` [create|delete|list|update] {params}"
|
|
|
|
case "$1" in
|
|
######################## ezjail-admin CREATE ########################
|
|
create)
|
|
shift
|
|
args=`getopt xf:r: $*`
|
|
[ $? = 0 ] || exerr 'Usage: ezjail create [-f flavour] [-r jailroot] [-x] jailname jailip';
|
|
|
|
newjail_root=
|
|
newjail_flavour=
|
|
newjail_softlink=
|
|
newjail_fill="YES"
|
|
|
|
set -- $args
|
|
for arg do
|
|
case $arg in
|
|
-x) newjail_fill="NO"; shift;;
|
|
-r) newjail_root="$2"; shift 2;;
|
|
-f) newjail_flavour="$2"; shift 2;;
|
|
--) shift; break;;
|
|
esac
|
|
done;
|
|
newjail_name=$1; newjail_ip=$2;
|
|
|
|
# we need at least a name and an ip for new jail
|
|
[ "$newjail_name" -a "$newjail_ip" -a $# = 2 ] || exerr 'Usage: ezjail create [-f flavour] [-r jailroot] [-x] jailname jailip'
|
|
|
|
# check, whether ezjail-update has been called. existence of
|
|
# ezjail_jailbase is our indicator
|
|
[ -d $ezjail_jailbase ] || exerr "Error: base jail does not exist. Please run 'ezjail-admin update' first"
|
|
|
|
# relative paths don't make sense in rc.scripts
|
|
[ ${ezjail_jaildir#/} = ${ezjail_jaildir} ] && exerr "Error: Need an absolute path in ezjail_jaildir, it currently is set to: $ezjail_jaildir"
|
|
|
|
# jail names must not have names that irritate file systems,
|
|
# excluding dots from this list was done intentionally to
|
|
# allow foo.com style directory names, however, the jail
|
|
# name will be foo_com in most scripts
|
|
newjail_name=`echo $newjail_name | tr /~ __`;
|
|
newjail_root=${newjail_root:-"${ezjail_jaildir}/${newjail_name}"}
|
|
newjail_nname=`echo $newjail_name | tr . _`;
|
|
|
|
# if jail root specified on command line is not absolute,
|
|
# make it absolute inside our jail directory
|
|
[ ${newjail_root#/} = ${newjail_root} ] && newjail_root=$ezjail_jaildir/$newjail_root
|
|
|
|
# if jail root specified on command line does not lie
|
|
# within our jail directory, we need to create a softlink
|
|
if [ ${newjail_root##${ezjail_jaildir}} = $newjail_root ]; then
|
|
newjail_softlink=$ezjail_jaildir/`basename $newjail_root`
|
|
[ -e $newjail_softlink -a $newjail_fill = "YES" ] && exerr "Error: an ezjail already exists at $newjail_softlink"
|
|
fi
|
|
|
|
# do some sanity checks on the selected flavour (if any)
|
|
if [ "${newjail_flavour}" ]; then
|
|
[ -d ${ezjail_flavours}/${newjail_flavour}/ ] || exerr "Error: Flavour config directory ${ezjail_flavours}/${newjail_flavour} not found"
|
|
fi
|
|
|
|
# now take a copy of our template jail
|
|
if [ "$newjail_fill" = "YES" ]; then
|
|
mkdir -p ${newjail_root} && cd ${ezjail_jailtemplate} && \
|
|
find * | cpio -p -v ${newjail_root} > /dev/null
|
|
fi
|
|
|
|
# if a soft link is necessary, create it now
|
|
[ "$newjail_softlink" ] && ln -s $newjail_root $newjail_softlink
|
|
|
|
# if the automount feature is not disabled, create an
|
|
# fstab entry for new jail
|
|
echo $ezjail_jailbase $newjail_root/basejail nullfs ro 0 0 > /etc/fstab.$newjail_nname
|
|
|
|
# now, where everything seems to have gone right,
|
|
# create control file in ezjails config dir
|
|
mkdir -p $ezjail_jailcfgs
|
|
echo export jail_${newjail_nname}_hostname=\"${newjail_name}\" > ${ezjail_jailcfgs}/${newjail_nname}
|
|
echo export jail_${newjail_nname}_ip=\"${newjail_ip}\" >> ${ezjail_jailcfgs}/${newjail_nname}
|
|
echo export jail_${newjail_nname}_rootdir=\"${newjail_root}\" >> ${ezjail_jailcfgs}/${newjail_nname}
|
|
echo export jail_${newjail_nname}_exec=\"/bin/sh /etc/rc\" >> ${ezjail_jailcfgs}/${newjail_nname}
|
|
echo export jail_${newjail_nname}_mount_enable=\"${ezjail_mount_enable}\" >> ${ezjail_jailcfgs}/${newjail_nname}
|
|
echo export jail_${newjail_nname}_devfs_enable=\"${ezjail_devfs_enable}\" >> ${ezjail_jailcfgs}/${newjail_nname}
|
|
echo export jail_${newjail_nname}_devfs_ruleset=\"devfsrules_jail\" >> ${ezjail_jailcfgs}/${newjail_nname}
|
|
echo export jail_${newjail_nname}_procfs_enable=\"${ezjail_procfs_enable}\" >> ${ezjail_jailcfgs}/${newjail_nname}
|
|
echo export jail_${newjail_nname}_fdescfs_enable=\"${ezjail_fdescfs_enable}\" >> ${ezjail_jailcfgs}/${newjail_nname}
|
|
|
|
# check, whether IP is configured on a local interface, warn if it isnt
|
|
ping -c 1 -m 1 -t 1 -q $newjail_ip > /dev/null
|
|
[ $? = 0 ] || echo "Warning: IP $newjail_ip not configured on a local interface"
|
|
|
|
# check, whether some host system services do listen on the Jails IP
|
|
TIFS=$IFS; IFS=_
|
|
newjail_listener=`sockstat -4 -l | grep $newjail_ip:[[:digit:]]`
|
|
if [ $? = 0 ]; then
|
|
echo "Warning: Some services already seem to be listening on IP $newjail_ip"
|
|
echo " This may cause some confusion, here they are:"
|
|
echo $newjail_listener
|
|
fi
|
|
|
|
newjail_listener=`sockstat -4 -l | grep \*:[[:digit:]]`
|
|
if [ $? = 0 ]; then
|
|
echo "Warning: Some services already seem to be listening on all IPs"
|
|
echo " (including $newjail_ip)"
|
|
echo " This may cause some confusion, here they are:"
|
|
echo $newjail_listener
|
|
fi
|
|
IFS=$TIFS
|
|
|
|
# Final steps for flavour installation
|
|
if [ "${newjail_flavour}" ]; then
|
|
# install files, packages and config to new jail
|
|
# user creating, chown and package installation on jails startup
|
|
cd ${ezjail_jaildir}/${newjail_flavour}
|
|
find * | cpio -p -v ${newjail_root} > /dev/null
|
|
|
|
install -o root -g wheel -m 0755 ${ezjail_share}/ezjail-config.sh ${newjail_root}/etc/rc.d/ezjail-config.sh
|
|
echo "Note: Shell scripts installed, flavourizing on jails first startup"
|
|
fi
|
|
|
|
;;
|
|
######################## ezjail-admin DELETE ########################
|
|
delete)
|
|
shift
|
|
args=`getopt w $*`
|
|
[ $? = 0 ] || exerr 'Usage: ezjail delete [-w] jailname';
|
|
|
|
oldjail_wipe="NO"
|
|
|
|
set -- $args
|
|
for arg do
|
|
case $arg in
|
|
-w) oldjail_wipe="YES"; shift;;
|
|
--) shift; break;;
|
|
esac
|
|
done;
|
|
oldjail_name=$1;
|
|
|
|
# we only need name of jail to vanish
|
|
[ "$oldjail_name" -a $# = 1 ] || exerr 'Usage: ezjail delete [-w] jailname'
|
|
|
|
# tidy up jail name the ezjail way
|
|
oldjail_nname=`echo $oldjail_name | tr /~. ___`;
|
|
|
|
# check for existence of jail in our records
|
|
[ -f ${ezjail_jailcfgs}/${oldjail_nname} ] || exerr "Error: Nothing known about jail $oldjail_name"
|
|
|
|
# fetch information about the jail to be gone
|
|
# by parsing our records
|
|
. ${ezjail_jailcfgs}/${oldjail_nname}
|
|
eval oldjail_rootdir=\"\$jail_${oldjail_nname}_rootdir\"
|
|
|
|
# if jail is still running, refuse to go any further
|
|
if [ -f /var/run/jail_${oldjail_nname}.id ]; then
|
|
echo "Error: Jail appears to be still running, stop it first"
|
|
echo "(/var/run/jail_${oldjail_nname}.id exists)"
|
|
exit 1;
|
|
fi
|
|
|
|
# now we know everything we need to let the jail be gone
|
|
# remove entry from ezjail resource structure
|
|
rm -f ${ezjail_jailcfgs}/${oldjail_nname}
|
|
|
|
# delete fstab.JAILNAME
|
|
rm -f /etc/fstab.$oldjail_nname
|
|
|
|
# if there is a soft link pointing to the jail root, remove it
|
|
oldjail_softlink=$ezjail_jaildir/`basename $oldjail_rootdir`
|
|
[ -L $oldjail_softlink ] && rm $oldjail_softlink
|
|
|
|
# if wiping the jail was requested, remove it
|
|
[ $oldjail_wipe = "YES" ] && rm -rf $oldjail_rootdir
|
|
|
|
;;
|
|
######################## ezjail-admin LIST ########################
|
|
list)
|
|
jail_list=`ls $ezjail_jailcfgs`
|
|
for jail in $jail_list; do
|
|
. ${ezjail_jailcfgs}/$jail
|
|
eval jail_ip=\"\$jail_${jail}_ip\"
|
|
eval jail_hostname=\"\$jail_${jail}_hostname\"
|
|
eval jail_rootdir=\"\$jail_${jail}_rootdir\"
|
|
printf "%-15s %-28s %s\\n" $jail_ip $jail_hostname $jail_rootdir
|
|
done
|
|
|
|
;;
|
|
######################## ezjail-admin UPDATE ########################
|
|
setup|update)
|
|
shift
|
|
args=`getopt is: $*`
|
|
[ $? = 0 ] || exerr 'Usage: ezjail update [-s sourcetree] [-i]'
|
|
|
|
updatejail_installaction="world"
|
|
|
|
set -- $args
|
|
for arg do
|
|
case $arg in
|
|
-i) updatejail_installaction="installworld"; shift;;
|
|
-s) ezjail_sourcetree="$2"; shift 2;;
|
|
--) shift; break;;
|
|
esac
|
|
done;
|
|
|
|
# Bump the user for some of the most common errors
|
|
[ -d ${ezjail_sourcetree} ] || exerr "Cannot find your copy of the FreeBSD source tree in $ezjail_sourcetree."
|
|
[ -f ${ezjail_sourcetree}/Makefile ] || exerr "Your source tree in $ezjail_sourcetree seems to be incomplete (Makefile missing)."
|
|
|
|
cd ${ezjail_sourcetree}
|
|
# Normally fulljail should be renamed by past ezjail-admin commands
|
|
# However those may have failed
|
|
rm -rf ${ezjail_jailfull}; mkdir -p ${ezjail_jailfull}
|
|
|
|
# make our world
|
|
make ${updatejail_installaction} DESTDIR=${ezjail_jailfull}
|
|
[ $? = 0 ] || exerr "make ${updatejail_installaction} failed"
|
|
|
|
# setup world
|
|
make distribution DESTDIR=${ezjail_jailfull}
|
|
[ $? = 0 ] || exerr "make distribution failed"
|
|
|
|
cd ${ezjail_jailfull}
|
|
# Fill basejail from installed world
|
|
mkdir -p ${ezjail_jailbase}/usr ${ezjail_jailbase}/config/pkg
|
|
for a in bin lib libexec sbin usr/bin usr/include usr/lib usr/libexec usr/sbin usr/src usr/share; do
|
|
find ${a} | cpio -d -p -v ${ezjail_jailbase};
|
|
chflags -R noschg ${a}; rm -r ${a}; ln -s /basejail/${a} ${a}
|
|
done
|
|
mkdir basejail
|
|
ln -s /basejail/usr/ports usr/ports
|
|
|
|
if [ -d ${ezjail_jailtemplate} ]; then
|
|
rm -rf ${ezjail_jailtemplate}_old
|
|
mv ${ezjail_jailtemplate} ${ezjail_jailtemplate}_old
|
|
fi
|
|
mv ${ezjail_jailfull} ${ezjail_jailtemplate}
|
|
|
|
# If the default flavour example has not yet been copied, do it now
|
|
[ -d ${ezjail_flavours}/default ] || cp -p -r ${ezjail_examples}/default ${ezjail_flavours}
|
|
|
|
;;
|
|
*)
|
|
exerr "Usage: `basename $0` [create|delete|list|update] {params}"
|
|
;;
|
|
esac
|