#!/bin/sh # # 2012 Jake Guffey (jake.guffey at eprotex.com) # # This file is part of cdist. # # cdist is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # cdist is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # # # The __jail type creates, configures, and deletes FreeBSD jails for use as # virtual machines. # # Debug #exec >&2 #set -x if [ -f "$__object/parameter/name" ]; then name="$(cat "$__object/parameter/name")" else name="$__object_id" fi state="$(cat "$__object/parameter/state")" if [ -f "$__object/parameter/started" ]; then started="$(cat "$__object/parameter/started")" else started="true" fi if [ -f "$__object/parameter/ip" ]; then ip="$(cat "$__object/parameter/ip")" else # IP is an optional param when $state=absent, but # when $state=present, it's required. Enforce this. if [ "$state" = "present" ]; then exec >&2 echo "If --state is 'present,' --ip must be given\!" exit 1 fi fi if [ -f "$__object/parameter/hostname" ]; then hostname="$(cat "$__object/parameter/hostname")" else hostname="$name" fi if [ -f "$__object/parameter/interface" ]; then interface="$(cat "$__object/parameter/interface")" fi if [ -f "$__object/parameter/devfs-enable" ]; then devfsenable="$(cat "$__object/parameter/devfs-enable")" else devfsenable="true" fi if [ -f "$__object/parameter/devfs-ruleset" ]; then devfsruleset="$(cat "$__object/parameter/devfs-ruleset")" else devfsruleset="jailrules" fi # devfs_ruleset being defined without devfs_enable being true # is pointless. Treat this as an error. if [ -n "$devfsruleset" -a "$devfsenable" = "false" ]; then exec >&2 echo "Can't have --devfs-ruleset defined without --devfs-enable true." exit 1 fi if [ -f "$__object/parameter/onboot" ]; then onboot="$(cat "$__object/parameter/onboot")" fi jaildir="/usr/jail" present="$(cat "$__object/explorer/present")" status="$(cat "$__object/explorer/status")" # Defining a jail as absent and started at the same time # makes no sense. Treat this as an error. if [ "$started" = "true" -a "$state" = "absent" ]; then exec >&2 echo "Can't have --state absent and --started true together\!" exit 1 fi stopJail() { # Check $status before issuing command [ "$status" = "STARTED" ] && echo "/etc/rc.d/jail stop ${name}" } startJail() { # Check $status before issuing command [ ! "$status" = "STARTED" ] && echo "/etc/rc.d/jail start ${name}" } deleteJail() { # Remove the jail's rw mountpoints echo "rm -rf /usr/jail/rw/${name}" # Remove the jail's fstab echo "rm -f /etc/fstab.${name}" # Remove the jail directory echo "rm -rf /usr/jail/${name}" # Remove jail_$name_* lines from rc.conf echo <<-EOF sed -i '.bak' "/^jail_${name}_/d" /etc/rc.conf EOF # Remove " $name " from jail_list if it's there echo <<-EOF eval $(grep '^jail_list=' /etc/rc.conf) for JAIL in ${jail_list}; do if [ ! "${JAIL}" = "${name}" ]; then new_list="${new_list} ${JAIL}" fi done jail_list="${new_list}" sed -i '.bak' "s/^jail_list=\".*\"/jail_list=\"${jail_list}\"/" /etc/rc.conf unset jail_list rm -f /etc/rc.conf.bak EOF } createJail() { # Create the jail directory echo <<-EOF mkdir -p ${jaildir}/${name} if [ ! -d "${jaildir}/base" ]; then mkdir "${jaildir}/base" tar -xzf "${jaildir}/jailbase.tgz" -C "${jaildir}/base" if [ ! -d "${jaildir}/base/usr/local" ]; then mkdir -p "${jaildir}/base/usr/local" fi if [ ! -d "${jaildir}/base/usr/home" ]; then mkdir -p "${jaildir}/base/usr/home" fi fi if [ ! -d "${jaildir}/rw" ]; then mkdir "${jaildir}/rw" fi mkdir -p "${jaildir}/rw/${name}/etc" cp -r ${jaildir}/base/etc/* "${jaildir}/rw/${name}/etc/" mkdir "${jaildir}/rw/${name}/local" mkdir "${jaildir}/rw/${name}/db" if [ -d "${jaildir}/base/var/db" ]; then cp -r ${jaildir}/base/var/db/* "${jaildir}/rw/${name}/db/" fi mkdir "${jaildir}/rw/${name}/home" if [ -d "${jaildir}/base/usr/home" ]; then cp -r ${jaildir}/base/usr/home/* "${jaildir}/rw/${name}/home/" fi mkdir "${jaildir}/rw/${name}/tmp" EOF # Create the ro+rw mountpoint entries in fstab echo <<-EOF echo >/etc/fstab.${name} <<-END /usr/jail/base /usr/jail/${name} nullfs ro 0 0 /usr/jail/rw/${name}/etc /usr/jail/${name}/etc nullfs rw 0 0 /usr/jail/rw/${name}/local /usr/jail/${name}/usr/local nullfs rw 0 0 /usr/jail/rw/${name}/db /usr/jail/${name}/var/db nullfs rw 0 0 /usr/jail/rw/${name}/home /usr/jail/${name}/usr/home nullfs rw 0 0 /usr/jail/rw/${name}/tmp /usr/jail/${name}/var/tmp nullfs rw 0 0 END EOF # Add the jail_$name_* lines to rc.conf echo <<-EOF echo >>/etc/rc.conf <<-END jail_${name}_rootdir="${jaildir}/${name}" jail_${name}_hostname="${hostname}" jail_${name}_ip="${ip}" jail_${name}_devfs_enable="${devfsenable}" jail_${name}_mount_enable="YES" jail_${name}_fstab="/etc/fstab.$name" END EOF if [ -n "$interface" ]; then echo <<-EOF echo >>/etc/rc.conf <<-END jail_${name}_interface="${interface}" END EOF fi if [ "$devfsenable" = "true" ]; then echo <<-EOF echo >>/etc/rc.conf <<-END jail_${name}_devfs_ruleset="$devfsruleset" END EOF fi # Add $name to jail_list if $onboot=true if [ "$onboot" = "true" ]; then echo <<-EOF eval $(grep '^jail_list=' /etc/rc.conf) jail_list="${jail_list} ${name}" sed -i '.bak' "s/^jail_list=\".*\"/jail_list=\"${jail_list}\"/" /etc/rc.conf unset jail_list rm -f /etc/rc.conf.bak EOF fi # Add the normal entries into the jail's rc.conf echo "echo hostname=\"${hostname}\"" >>"${jaildir}/rw/${name}/etc/rc.conf" echo 'echo sendmail_enable=\"NONE\"' >>"${jaildir}/rw/${name}/etc/rc.conf" echo 'echo syslogd_enable=\"YES\"' >>"${jaildir}/rw/${name}/etc/rc.conf" echo 'echo syslogd_flags=\"-ss\"' >>"${jaildir}/rw/${name}/etc/rc.conf" } if [ "$present" = "EXISTS" ]; then # The jail currently exists if [ "$state" = "present" ]; then # The jail is supposed to exist if [ "$started" = "true" ]; then # The jail is supposed to be started startJail else # The jail is not supposed to be started stopJail fi exit 0 else # The jail is not supposed to exist stopJail deleteJail exit 0 fi else # The jail does not currently exist if [ "$state" = "absent" ]; then # The jail is not supposed to be present exit 0 else # The jail is supposed to exist createJail [ "$started" = "true" ] && startJail exit 0 fi fi # Debug #set +x