Merge pull request #995 from BastilleBSD/final-blank-line

Refactor line spacing on all commands
This commit is contained in:
tschettervictor
2025-05-01 17:41:22 -06:00
committed by GitHub
37 changed files with 761 additions and 590 deletions

View File

@@ -45,13 +45,19 @@ EOF
}
validate_release_url() {
info "\nBootstrapping release: ${RELEASE}..."
## check upstream url, else warn user
if [ -n "${NAME_VERIFY}" ]; then
RELEASE="${NAME_VERIFY}"
info "\nFetching ${PLATFORM_OS} distfiles..."
if ! fetch -qo /dev/null "${UPSTREAM_URL}/MANIFEST" 2>/dev/null; then
error_exit "Unable to fetch MANIFEST. See 'bootstrap urls'."
fi
info "Bootstrapping ${PLATFORM_OS} distfiles..."
# Alternate RELEASE/ARCH fetch support
if [ "${OPTION}" = "--i386" ] || [ "${OPTION}" = "--32bit" ]; then
@@ -61,13 +67,15 @@ validate_release_url() {
bootstrap_directories
bootstrap_release
else
usage
fi
}
bootstrap_directories() {
## ensure required directories are in place
# Ensure required directories are in place
## ${bastille_prefix}
if [ ! -d "${bastille_prefix}" ]; then
@@ -81,7 +89,7 @@ bootstrap_directories() {
chmod 0750 "${bastille_prefix}"
# Make sure the dataset is mounted in the proper place
elif [ -d "${bastille_prefix}" ]; then
if ! zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" 2>/dev/null; then
if ! zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" >/dev/null; then
zfs create ${bastille_zfs_options} -o mountpoint="${bastille_prefix}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}"
elif [ "$(zfs get -H -o value mountpoint ${bastille_zfs_zpool}/${bastille_zfs_prefix})" != "${bastille_prefix}" ]; then
zfs set mountpoint="${bastille_prefix}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}"
@@ -188,6 +196,7 @@ bootstrap_directories() {
}
bootstrap_release() {
## if release exists quit, else bootstrap additional distfiles
if [ -f "${bastille_releasesdir}/${RELEASE}/COPYRIGHT" ]; then
## check distfiles list and skip existing cached files
@@ -201,9 +210,9 @@ bootstrap_release() {
## check if release already bootstrapped, else continue bootstrapping
if [ -z "${bastille_bootstrap_archives}" ]; then
error_notify "Bootstrap appears complete."
error_exit "Bootstrap appears complete."
else
info "Bootstrapping additional distfiles..."
info "\nFetching additional distfiles..."
fi
fi
@@ -211,13 +220,13 @@ bootstrap_release() {
## check if the dist files already exists then extract
FETCH_VALIDATION="0"
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
info "Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz."
info "Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz..."
if /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
## silence motd at container login
touch "${bastille_releasesdir}/${RELEASE}/root/.hushlogin"
touch "${bastille_releasesdir}/${RELEASE}/usr/share/skel/dot.hushlogin"
else
error_exit "Failed to extract ${_archive}.txz."
error_exit "[ERROR]: Failed to extract ${_archive}.txz."
fi
else
## get the manifest for dist files checksum validation
@@ -247,14 +256,14 @@ bootstrap_release() {
rm -rf "${bastille_releasesdir:?}/${RELEASE}"
fi
fi
error_exit "Bootstrap failed."
error_exit "[ERROR]: Bootstrap failed."
fi
## fetch for missing dist files
if [ ! -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
if ! fetch "${UPSTREAM_URL}/${_archive}.txz" -o "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
## alert only if unable to fetch additional dist files
error_notify "Failed to fetch ${_archive}.txz."
error_exit "[ERROR]: Failed to fetch ${_archive}.txz"
fi
fi
@@ -264,31 +273,30 @@ bootstrap_release() {
SHA256_FILE=$(sha256 -q "${bastille_cachedir}/${RELEASE}/${_archive}.txz")
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
rm "${bastille_cachedir}/${RELEASE}/${_archive}.txz"
error_exit "Failed validation for ${_archive}.txz. Please retry bootstrap!"
error_exit "[ERROR]: Failed validation for ${_archive}.txz. Please retry bootstrap!"
else
info "Validated checksum for ${RELEASE}: ${_archive}.txz"
info "MANIFEST: ${SHA256_DIST}"
info "DOWNLOAD: ${SHA256_FILE}"
info "\nValidated checksum for ${RELEASE}: ${_archive}.txz"
echo "MANIFEST: ${SHA256_DIST}"
echo "DOWNLOAD: ${SHA256_FILE}"
fi
fi
## extract the fetched dist files
if [ -f "${bastille_cachedir}/${RELEASE}/${_archive}.txz" ]; then
info "Extracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz."
info "\nExtracting ${PLATFORM_OS} ${RELEASE} ${_archive}.txz..."
if /usr/bin/tar -C "${bastille_releasesdir}/${RELEASE}" -xf "${bastille_cachedir}/${RELEASE}/${_archive}.txz"; then
## silence motd at container login
touch "${bastille_releasesdir}/${RELEASE}/root/.hushlogin"
touch "${bastille_releasesdir}/${RELEASE}/usr/share/skel/dot.hushlogin"
else
error_exit "Failed to extract ${_archive}.txz."
error_exit "[ERROR]: Failed to extract ${_archive}.txz."
fi
fi
fi
done
echo
info "Bootstrap successful."
info "See 'bastille --help' for available commands."
info "\nBootstrap successful."
echo "See 'bastille --help' for available commands."
}
@@ -311,22 +319,22 @@ debootstrap_release() {
read answer
case "${answer}" in
[Nn][Oo]|[Nn]|"")
error_exit "Exiting."
error_exit "Cancelled, Exiting."
;;
[Yy][Ee][Ss]|[Yy])
# Skip already loaded known modules.
if ! kldstat -m ${_req_kmod} >/dev/null 2>&1; then
info "Loading kernel module: ${_req_kmod}"
info "\nLoading kernel module: ${_req_kmod}"
kldload -v ${_req_kmod}
fi
info "Persisting module: ${_req_kmod}"
info "\nPersisting module: ${_req_kmod}"
sysrc -f /boot/loader.conf ${_req_kmod}_load=YES
;;
esac
else
# If already set in /boot/loader.conf, check and try to load the module.
if ! kldstat -m ${_req_kmod} >/dev/null 2>&1; then
info "Loading kernel module: ${_req_kmod}"
info "\nLoading kernel module: ${_req_kmod}"
kldload -v ${_req_kmod}
fi
fi
@@ -335,10 +343,11 @@ debootstrap_release() {
# Mandatory Linux modules/rc.
for _lin_kmod in ${linuxarc_mods}; do
if ! kldstat -n ${_lin_kmod} >/dev/null 2>&1; then
info "Loading kernel module: ${_lin_kmod}"
info "\nLoading kernel module: ${_lin_kmod}"
kldload -v ${_lin_kmod}
fi
done
if [ ! "$(sysrc -qn linux_enable)" = "YES" ] && \
[ ! "$(sysrc -f /etc/rc.conf.local -qn linux_enable)" = "YES" ]; then
sysrc linux_enable=YES
@@ -349,7 +358,7 @@ debootstrap_release() {
read answer
case $answer in
[Nn][Oo]|[Nn]|"")
error_exit "Exiting. You need to install debootstap before boostrapping a Linux jail."
error_exit "[ERROR]: debootstrap is required for boostrapping a Linux jail."
;;
[Yy][Ee][Ss]|[Yy])
pkg install -y debootstrap
@@ -358,8 +367,9 @@ debootstrap_release() {
fi
# Fetch the Linux flavor
info "Bootstrapping ${PLATFORM_OS} distfiles..."
info "\nFetching ${PLATFORM_OS} distfiles..."
if ! debootstrap --foreign --arch=${ARCH_BOOTSTRAP} --no-check-gpg ${LINUX_FLAVOR} "${bastille_releasesdir}"/${DIR_BOOTSTRAP}; then
## perform cleanup only for stale/empty directories on failure
if checkyesno bastille_zfs_enable; then
if [ -n "${bastille_zfs_zpool}" ]; then
@@ -368,12 +378,13 @@ debootstrap_release() {
fi
fi
fi
if [ -d "${bastille_releasesdir}/${DIR_BOOTSTRAP}" ]; then
if [ ! "$(ls -A "${bastille_releasesdir}/${DIR_BOOTSTRAP}")" ]; then
rm -rf "${bastille_releasesdir:?}/${DIR_BOOTSTRAP}"
fi
fi
error_exit "Bootstrap failed."
error_exit "[ERROR]: Bootstrap failed."
fi
case "${LINUX_FLAVOR}" in
@@ -383,8 +394,8 @@ debootstrap_release() {
;;
esac
info "Bootstrap successful."
info "See 'bastille --help' for available commands."
info "\nBootstrap successful."
info "\nSee 'bastille --help' for available commands."
}
bootstrap_template() {
@@ -455,7 +466,7 @@ while [ "$#" -gt 0 ]; do
shift
;;
-*)
error_exit "Unknown Option: \"${1}\""
error_exit "[ERROR]: Unknown Option: \"${1}\""
;;
*)
break
@@ -477,27 +488,27 @@ if [ "$(sysrc -n zfs_enable)" = "YES" ] && ! checkyesno bastille_zfs_enable; the
read answer
case $answer in
no|No|n|N|"")
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_enable."
error_exit "[ERROR]: Missing ZFS parameters. See bastille_zfs_enable."
;;
yes|Yes|y|Y) ;;
esac
fi
# Validate ZFS parameters.
# Validate ZFS parameters
if checkyesno bastille_zfs_enable; then
## check for the ZFS pool and bastille prefix
if [ -z "${bastille_zfs_zpool}" ]; then
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_zpool."
error_exit "[ERROR]: Missing ZFS parameters. See bastille_zfs_zpool."
elif [ -z "${bastille_zfs_prefix}" ]; then
error_exit "ERROR: Missing ZFS parameters. See bastille_zfs_prefix."
error_exit "[ERROR]: Missing ZFS parameters. See bastille_zfs_prefix."
elif ! zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then
error_exit "ERROR: ${bastille_zfs_zpool} is not a ZFS pool."
error_exit "[ERROR]: ${bastille_zfs_zpool} is not a ZFS pool."
fi
## check for the ZFS dataset prefix if already exist
if [ -d "/${bastille_zfs_zpool}/${bastille_zfs_prefix}" ]; then
if ! zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" > /dev/null 2>&1; then
error_exit "ERROR: ${bastille_zfs_zpool}/${bastille_zfs_prefix} is not a ZFS dataset."
error_exit "[ERROR]: ${bastille_zfs_zpool}/${bastille_zfs_prefix} is not a ZFS dataset."
fi
fi
fi
@@ -517,7 +528,7 @@ if [ -n "${OPTION}" ] && [ "${OPTION}" != "${HW_MACHINE}" ] && [ "${OPTION}" !=
HW_MACHINE="i386"
HW_MACHINE_ARCH="i386"
else
error_exit "Unsupported architecture."
error_exit "[ERROR]: Unsupported architecture."
fi
fi

View File

@@ -76,7 +76,7 @@ while [ "$#" -gt 0 ]; do
a) AUTO=1 ;;
l) LIVE=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\""
*) error_exit "[ERROR]: Unknown Option: \"${1}\""
esac
done
shift
@@ -104,18 +104,26 @@ set_target_single "${TARGET}"
## don't allow for dots(.) in container names
if echo "${NEWNAME}" | grep -q "[.]"; then
error_exit "Container names may not contain a dot(.)!"
error_exit "[ERROR]: Jail names may not contain a dot(.)!"
fi
validate_ip() {
local IP="${1}"
IP6_MODE="disable"
ip6=$(echo "${IP}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))')
if [ -n "${ip6}" ]; then
info "Valid: (${ip6})."
info "\nValid: (${ip6})."
IP6_MODE="new"
elif { [ "${IP}" = "0.0.0.0" ] || [ "${IP}" = "DHCP" ]; } && [ "$(bastille config ${TARGET} get vnet)" = "enabled" ]; then
info "Valid: (${IP})."
info "\nValid: (${IP})."
else
local IFS
if echo "${IP}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then
TEST_IP=$(echo "${IP}" | cut -d / -f1)
@@ -126,11 +134,13 @@ validate_ip() {
error_exit "Invalid: (${TEST_IP})"
fi
done
if ifconfig | grep -qwF "${TEST_IP}"; then
warn "Warning: IP address already in use (${TEST_IP})."
warn "\nWarning: IP address already in use (${TEST_IP})."
else
info "Valid: (${IP})."
info "\nValid: (${IP})."
fi
else
error_exit "Invalid: (${IP})."
fi
@@ -138,8 +148,10 @@ validate_ip() {
}
update_jailconf() {
# Update jail.conf
JAIL_CONFIG="${bastille_jailsdir}/${NEWNAME}/jail.conf"
if [ -f "${JAIL_CONFIG}" ]; then
if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${JAIL_CONFIG}"; then
sed -i '' "s|host.hostname = ${TARGET};|host.hostname = ${NEWNAME};|" "${JAIL_CONFIG}"
@@ -161,6 +173,7 @@ update_jailconf() {
if [ "${_interface}" != "not set" ]; then
sed -i '' "/.*interface = .*/d" "${JAIL_CONFIG}"
fi
# IP4
if [ "${_ip4}" != "not set" ]; then
for _ip in ${_ip4}; do
@@ -175,6 +188,7 @@ update_jailconf() {
sed -i '' "/ip4.addr += .*/ s/${_ip}/127.0.0.1/" "${JAIL_CONFIG}"
done
fi
# IP6
if [ "${_ip6}" != "not set" ]; then
for _ip in ${_ip6}; do
@@ -216,6 +230,7 @@ update_jailconf_vnet() {
if echo ${_if} | grep -Eoq 'epair[0-9]+'; then
for _num in $(seq 0 "${_bastille_if_num_range}"); do
if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then
# Generate new epair name
if [ "$(echo -n "e${_num}a_${NEWNAME}" | awk '{print length}')" -lt 16 ]; then
local _new_host_epair="e${_num}a_${NEWNAME}"
@@ -224,6 +239,7 @@ update_jailconf_vnet() {
local _new_host_epair="epair${_num}a"
local _new_jail_epair="epair${_num}b"
fi
# Get epair name from TARGET
if grep -Eoq "e[0-9]+a_${TARGET}" "${_jail_conf}"; then
_target_host_epair="$(grep -Eo -m 1 "e[0-9]+a_${TARGET}" "${_jail_conf}")"
@@ -232,18 +248,22 @@ update_jailconf_vnet() {
_target_host_epair="${_if}a"
_target_jail_epair="${_if}b"
fi
# Replace host epair name in jail.conf
sed -i '' "s|up name ${_target_host_epair}|up name ${_new_host_epair}|g" "${_jail_conf}"
sed -i '' "s|${_target_host_epair} ether|${_new_host_epair} ether|g" "${_jail_conf}"
sed -i '' "s|deletem ${_target_host_epair}|deletem ${_new_host_epair}|g" "${_jail_conf}"
sed -i '' "s|${_target_host_epair} destroy|${_new_host_epair} destroy|g" "${_jail_conf}"
sed -i '' "s|${_target_host_epair} description|${_new_host_epair} description|g" "${_jail_conf}"
# Replace jail epair name in jail.conf
sed -i '' "s|= ${_target_jail_epair};|= ${_new_jail_epair};|g" "${_jail_conf}"
sed -i '' "s|up name ${_target_jail_epair}|up name ${_new_jail_epair}|g" "${_jail_conf}"
sed -i '' "s|${_target_jail_epair} ether|${_new_jail_epair} ether|g" "${_jail_conf}"
# Replace epair name in jail.conf
sed -i '' "s|${_if}|epair${_num}|g" "${_jail_conf}"
# If jail had a static MAC, generate one for clone
if grep -q ether ${_jail_conf}; then
local external_interface="$(grep "epair${_num}a" ${_jail_conf} | grep -o '[^ ]* addm' | awk '{print $1}')"
@@ -251,8 +271,10 @@ update_jailconf_vnet() {
sed -i '' "s|${_new_host_epair} ether.*:.*:.*:.*:.*:.*a\";|${_new_host_epair} ether ${macaddr}a\";|" "${_jail_conf}"
sed -i '' "s|${_new_jail_epair} ether.*:.*:.*:.*:.*:.*b\";|${_new_jail_epair} ether ${macaddr}b\";|" "${_jail_conf}"
fi
# Replace epair description
sed -i '' "/${_new_host_epair}/ s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${_jail_conf}"
# Update /etc/rc.conf
local _jail_vnet="$(grep ${_target_jail_epair} "${_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")"
local _jail_vnet_vlan="$(grep "vlans_${_jail_vnet}" "${_rc_conf}" | sed 's/.*=//g')"
@@ -281,17 +303,21 @@ update_jailconf_vnet() {
break
fi
done
# Update VNET (non-bridged) config
elif echo ${_if} | grep -Eoq 'e[0-9]+b_bastille[0-9]+'; then
# Update VNET config
_if="$(echo ${_if} | grep -Eo 'bastille[0-9]+')"
for _num in $(seq 0 "${_bastille_if_num_range}"); do
if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then
# Update jail.conf epair name
local _jail_if="bastille${_num}"
local _jail_vnet="$(grep ${_if} "${_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")"
local _jail_vnet_vlan="$(grep "vlans_${_jail_vnet}" "${_rc_conf}" | sed 's/.*=//g')"
sed -i '' "s|${_if}|${_jail_if}|g" "${_jail_conf}"
# If jail had a static MAC, generate one for clone
if grep ether ${_jail_conf} | grep -qoc ${_jail_if}; then
local external_interface="$(grep ${_jail_if} ${_jail_conf} | grep -o 'addm.*' | awk '{print $3}' | sed 's/["|;]//g')"
@@ -300,6 +326,7 @@ update_jailconf_vnet() {
sed -i '' "s|${_jail_if} ether.*:.*:.*:.*:.*:.*b\";|${_jail_if} ether ${macaddr}b\";|" "${_jail_conf}"
fi
sed -i '' "/${_jail_if}/ s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${_jail_conf}"
# Update /etc/rc.conf
sed -i '' "s|ifconfig_e0b_${_if}_name|ifconfig_e0b_${_jail_if}_name|" "${_rc_conf}"
if grep "vnet0" "${_rc_conf}" | grep -q ${_jail_if}; then
@@ -325,23 +352,27 @@ update_jailconf_vnet() {
fi
break
fi
done
done
# Update netgraph VNET (non-bridged) config
elif echo ${_if} | grep -Eoq 'ng[0-9]+_bastille[0-9]+'; then
_if="$(echo ${_if} | grep -Eo 'bastille[0-9]+')"
for _num in $(seq 0 "${_bastille_if_num_range}"); do
if ! echo "${_bastille_if_list}" | grep -oqswx "${_num}"; then
# Update jail.conf epair name
local _jail_if="bastille${_num}"
local _jail_vnet="$(grep ${_if} "${_rc_conf}" | grep -Eo -m 1 "vnet[0-9]+")"
local _jail_vnet_vlan="$(grep "vlans_${_jail_vnet}" "${_rc_conf}" | sed 's/.*=//g')"
sed -i '' "s|${_if}|${_jail_if}|g" "${_jail_conf}"
# If jail had a static MAC, generate one for clone
if grep ether ${_jail_conf} | grep -qoc ${_jail_if}; then
local external_interface="$(grep ${_jail_if} ${_jail_conf} | grep -o 'jng bridge.*' | awk '{print $4}' | sed 's/["|;]//g')"
generate_static_mac "${NEWNAME}" "${external_interface}"
sed -i '' "s|${_jail_if} ether.*:.*:.*:.*:.*:.*a\";|${_jail_if} ether ${macaddr}a\";|" "${_jail_conf}"
fi
# Update /etc/rc.conf
sed -i '' "s|ifconfig_ng0_${_if}_name|ifconfig_ng0_${_jail_if}_name|" "${_rc_conf}"
if grep "vnet0" "${_rc_conf}" | grep -q ${_jail_if}; then
@@ -374,22 +405,31 @@ update_jailconf_vnet() {
clone_jail() {
info "\n[${TARGET}]:"
echo "Attempting clone to ${NEWNAME}..."
if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
if checkyesno bastille_zfs_enable; then
# Validate jail state
if [ "${LIVE}" -eq 1 ]; then
check_target_is_running "${TARGET}" || error_exit "[-l|--live] can only be used with a running jail."
else check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-stopping ${TARGET}..."
if ! check_target_is_running "${TARGET}"; then
error_exit "[ERROR]: [-l|--live] can only be used with a running jail."
fi
elif ! check_target_is_stopped "${TARGET}"; then
if [ "${AUTO}" -eq 1 ]; then
bastille stop "${TARGET}"
else
info "\n[${TARGET}]:"
error_notify "Jail is running."
error_exit "Use [-a|--auto] to force stop the jail, or [-l|--live] (ZFS only) to clone a running jail."
fi
fi
if [ -n "${IP}" ]; then
validate_ip "${IP}"
else
usage
fi
if [ -n "${bastille_zfs_zpool}" ]; then
# Replicate the existing container
DATE=$(date +%F-%H%M%S)
@@ -404,12 +444,13 @@ clone_jail() {
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}/root@bastille_clone_${DATE}"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NEWNAME}@bastille_clone_${DATE}"
fi
else
check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-stopping ${TARGET}..."
bastille stop "${TARGET}"
else
info "\n[${TARGET}]:"
error_notify "Jail is running."
error_exit "Use [-a|--auto] to force stop the jail."
fi
@@ -419,7 +460,7 @@ clone_jail() {
fi
else
error_exit "${NEWNAME} already exists."
error_exit "[ERROR]: ${NEWNAME} already exists."
fi
# Generate jail configuration files
@@ -428,9 +469,9 @@ clone_jail() {
# Display exit status
if [ "$?" -ne 0 ]; then
error_exit "An error has occurred while attempting to clone '${TARGET}'."
error_exit "[ERROR]: An error has occurred while attempting to clone '${TARGET}'."
else
info "Cloned '${TARGET}' to '${NEWNAME}' successfully."
info "\nCloned '${TARGET}' to '${NEWNAME}' successfully."
fi
# Start jails if AUTO=1 or LIVE=1
@@ -442,12 +483,7 @@ clone_jail() {
fi
}
# Check if IP address is valid.
if [ -n "${IP}" ]; then
validate_ip
else
usage
fi
info "\nAttempting to clone '${TARGET}' to '${NEWNAME}'..."
clone_jail

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -76,7 +76,7 @@ while [ "$#" -gt 0 ]; do
esac
done
if [ $# -eq 0 ]; then
if [ "$#" -eq 0 ]; then
usage
fi
@@ -91,27 +91,32 @@ set_target "${TARGET}"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# Validate jail state
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${_jail}]:"
COUNT=$(($COUNT+1))
# Allow executing commands on linux jails
if grep -qw "linsysfs" "${bastille_jailsdir}/${_jail}/fstab"; then
# Allow executing commands on Linux jails.
jexec -l -u root "${_jail}" "$@"
else
jexec -l -U root "${_jail}" "$@"
fi
ERROR_CODE=$?
if [ "${ERROR_CODE}" -ne 0 ]; then
warn "[${_jail}]: ${ERROR_CODE}"
fi
if [ "$COUNT" -eq 1 ]; then
RETURN=${ERROR_CODE}
else
@@ -124,6 +129,4 @@ done
if [ "${COUNT}" -gt 1 ] && [ "${RETURN}" -gt 0 ]; then
RETURN=1
return "${RETURN}"
fi
echo
fi

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
shift
;;
-*)
error_notify "Unknown Option: \"${1}\""
error_notify "[ERROR]: Unknown Option: \"${1}\""
usage
;;
*)
@@ -115,12 +115,13 @@ print_jail_conf() {
}
for _jail in ${JAILS}; do
# Handle Bastille specific properties
# Currently only 'priority' and 'boot'
if [ "${PROPERTY}" = "priority" ] || [ "${PROPERTY}" = "prio" ]; then
PROPERTY="priority"
BASTILLE_PROPERTY=1
FILE="${bastille_jailsdir}/${_jail}/boot.conf"
info "[${_jail}]:"
if [ "${ACTION}" = "set" ]; then
if echo "${VALUE}" | grep -Eq '^[0-9]+$'; then
sysrc -f "${FILE}" "${PROPERTY}=${VALUE}"
@@ -133,7 +134,6 @@ for _jail in ${JAILS}; do
elif [ "${PROPERTY}" = "boot" ]; then
BASTILLE_PROPERTY=1
FILE="${bastille_jailsdir}/${_jail}/boot.conf"
info "[${_jail}]:"
if [ "${ACTION}" = "set" ]; then
if [ "${VALUE}" = "on" ] || [ "${VALUE}" = "off" ]; then
sysrc -f "${FILE}" "${PROPERTY}=${VALUE}"
@@ -244,4 +244,4 @@ if { [ "${ACTION}" = "set" ] || [ "${ACTION}" = "remove" ]; } && [ -z "${BASTILL
info "A restart is required for the changes to be applied. See 'bastille restart'."
fi
exit 0
exit 0

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
x) enable_debug ;;
a) AUTO=1 ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -87,8 +87,10 @@ bastille_root_check
set_target "${TARGET}"
validate_user() {
local _jail="${1}"
local _user="${2}"
if jexec -l "${_jail}" id "${_user}" >/dev/null 2>&1; then
USER_SHELL="$(jexec -l "${_jail}" getent passwd "${_user}}" | cut -d: -f7)"
if [ -n "${USER_SHELL}" ]; then
@@ -106,27 +108,33 @@ validate_user() {
}
check_fib() {
local _jail="${1}"
fib=$(grep 'exec.fib' "${bastille_jailsdir}/${_jail}/jail.conf" | awk '{print $3}' | sed 's/\;//g')
if [ -n "${fib}" ]; then
_setfib="setfib -F ${fib}"
else
_setfib=""
fi
if [ -n "${fib}" ]; then
_setfib="setfib -F ${fib}"
else
_setfib=""
fi
}
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# Validate jail state
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${_jail}]:"
LOGIN="$(jexec -l "${_jail}" which login)"
if [ -n "${USER}" ]; then
validate_user "${_jail}" "${USER}"
else
@@ -135,6 +143,4 @@ for _jail in ${JAILS}; do
${_setfib} jexec -l "${_jail}" $LOGIN -f root
fi
done
echo
done

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -82,24 +82,26 @@ CONVERT_RELEASE="${2}"
bastille_root_check
set_target_single "${TARGET}"
info "\n[${TARGET}]:"
# Validate jail state
check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-stopping ${TARGET}..."
bastille stop "${TARGET}"
else
else
info "\n[${TARGET}]:"
error_notify "Jail is running."
error_exit "Use [-a|--auto] to auto-stop the jail."
fi
validate_release_name() {
local _name=${1}
local _sanity="$(echo "${_name}" | tr -c -d 'a-zA-Z0-9-_')"
if [ -n "$(echo "${_sanity}" | awk "/^[-_].*$/" )" ]; then
error_exit "Release names may not begin with (-|_) characters!"
error_exit "[ERROR]: Release names may not begin with (-|_) characters!"
elif [ "${_name}" != "${_sanity}" ]; then
error_exit "Release names may not contain special characters!"
error_exit "[ERROR]: Release names may not contain special characters!"
fi
}
convert_jail_to_release() {
@@ -107,7 +109,7 @@ convert_jail_to_release() {
_jailname="${1}"
_release="${2}"
echo "Creating ${_release} from ${_jailname}..."
info "\nAttempting to create '${_release}' from '${_jailname}'..."
if checkyesno bastille_zfs_enable; then
if [ -n "${bastille_zfs_zpool}" ]; then
@@ -140,7 +142,7 @@ convert_jail_to_release() {
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${_release}"
error_exit "Failed to create release. Please retry!"
else
info "Created ${_release} from ${_jailname}"
info "\nCreated '${_release}' from '${_jailname}'\n"
fi
else
## copy all files for thick jails
@@ -148,14 +150,15 @@ convert_jail_to_release() {
if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories
bastille destroy -af "${NAME}"
error_exit "Failed to create release. Please retry!"
error_exit "[ERROR]: Failed to create release. Please retry!"
else
info "Created ${_release} from ${_jailname}"
info "\nCreated '${_release}' from '${_jailname}'\n"
fi
fi
}
convert_symlinks() {
# Work with the symlinks, revert on first cp error
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
# Retrieve old symlinks temporarily
@@ -166,7 +169,7 @@ convert_symlinks() {
done
# Copy new files to destination jail
echo "Copying required base files to container..."
info "\nCopying required base files to container..."
for _link in ${SYMLINKS}; do
if [ ! -d "${_link}" ]; then
if [ -d "${bastille_releasesdir}/${RELEASE}/${_link}" ]; then
@@ -185,13 +188,13 @@ convert_symlinks() {
fi
done
else
error_exit "Release must be bootstrapped first. See 'bastille bootstrap'."
error_exit "[ERROR]: Release must be bootstrapped first. See 'bastille bootstrap'."
fi
}
revert_convert() {
# Revert the conversion on first cp error
error_notify "A problem has occurred while copying the files. Reverting changes..."
error_notify "[ERROR]: A problem has occurred while copying the files. Reverting changes..."
for _link in ${SYMLINKS}; do
if [ -d "${_link}" ]; then
chflags -R noschg "${bastille_jailsdir}/${TARGET}/root/${_link}"
@@ -209,10 +212,13 @@ revert_convert() {
}
start_convert() {
# Attempt container conversion and handle some errors
DATE=$(date)
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
info "Converting '${TARGET}' into a thickjail. This may take a while..."
info "\nConverting '${TARGET}' into a thickjail. This may take a while..."
# Set some variables
RELEASE=$(grep -w "${bastille_releasesdir}/.* ${bastille_jailsdir}/${TARGET}/root/.bastille" ${bastille_jailsdir}/${TARGET}/fstab | sed "s|${bastille_releasesdir}/||;s| .*||")
@@ -230,53 +236,56 @@ start_convert() {
sed -i '' -E "s|${FSTABMOD}|# Converted from thin to thick container on ${DATE}|g" "${bastille_jailsdir}/${TARGET}/fstab"
if [ -n "${HASPORTS}" ]; then
sed -i '' -E "s|${HASPORTS}|# Ports copied from base to container on ${DATE}|g" "${bastille_jailsdir}/${TARGET}/fstab"
info "Copying ports to container..."
info "\nCopying ports to container..."
cp -a "${bastille_releasesdir}/${RELEASE}/usr/ports" "${bastille_jailsdir}/${TARGET}/root/usr"
fi
mv "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/root/.bastille.old"
info "Conversion of '${TARGET}' completed successfully!"
info "\nConversion of '${TARGET}' completed successfully!\n"
exit 0
else
error_exit "Can't determine release version. See 'bastille bootstrap'."
error_exit "[ERROR]: Can't determine release version. See 'bastille bootstrap'."
fi
else
error_exit "${TARGET} not found. See 'bastille create'."
error_exit "[ERROR]: ${TARGET} not found. See 'bastille create'."
fi
}
# Convert thin jail to thick jail if only one arg
# Convert jail to release if two args
if [ "$#" -eq 1 ]; then
# Check if jail is a thin jail
if [ ! -d "${bastille_jailsdir}/${TARGET}/root/.bastille" ]; then
error_exit "${TARGET} is not a thin container."
error_exit "[ERROR]: ${TARGET} is not a thin container."
elif ! grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
error_exit "${TARGET} is not a thin container."
error_exit "[ERROR]: ${TARGET} is not a thin container."
fi
# Make sure the user agree with the conversion
# Be interactive here since this cannot be easily undone
while :; do
error_notify "Warning: container conversion from thin to thick can't be undone!"
warn "\n[WARNING]: Jail conversion from thin to thick can't be undone!\n"
# shellcheck disable=SC2162
# shellcheck disable=SC3045
read -p "Do you really wish to convert '${TARGET}' into a thick container? [y/N]:" yn
case ${yn} in
[Yy]) start_convert;;
[Nn]) exit 0;;
[Yy]) start_convert;;
[Nn]) exit 0;;
esac
done
elif [ "$#" -eq 2 ]; then
# Check if jail is a thick jail
if [ -d "${bastille_jailsdir}/${TARGET}/root/.bastille" ]; then
error_exit "${TARGET} is not a thick jail."
error_exit "[ERROR]: ${TARGET} is not a thick jail."
elif grep -qw ".bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
error_exit "${TARGET} is not a thick jail."
error_exit "[ERROR]: ${TARGET} is not a thick jail."
fi
validate_release_name "${CONVERT_RELEASE}"
convert_jail_to_release "${TARGET}" "${CONVERT_RELEASE}"
else
usage
fi
echo
fi

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
q) OPTION="-a" ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -95,7 +95,7 @@ for _jail in ${JAILS}; do
jail_path="$(echo ${bastille_jailsdir}/${_jail}/root/${JAIL_PATH} | sed 's#//#/#g')"
if ! cp "${OPTION}" "${host_path}" "${jail_path}"; then
error_continue "CP failed: ${host_path} -> ${jail_path}"
error_continue "[ERROR]: CP failed: ${host_path} -> ${jail_path}"
fi
done

View File

@@ -37,6 +37,7 @@ usage() {
# If no option specified, will create a thin container by default
error_notify "Usage: bastille create [option(s)] NAME RELEASE IP_ADDRESS [INTERFACE]"
cat << EOF
Options:
-B | --bridge Enables VNET, VNET containers are attached to a specified, already existing external bridge.
@@ -59,26 +60,35 @@ EOF
}
validate_name() {
local NAME_VERIFY=${NAME}
local NAME_SANITY="$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')"
if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then
error_exit "Container names may not begin with (-|_) characters!"
error_exit "[ERROR]: Jail names may not begin with (-|_) characters!"
elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
error_exit "Container names may not contain special characters!"
error_exit "[ERROR]: Jail names may not contain special characters!"
elif echo "${NAME_VERIFY}" | grep -qE '^[0-9]+$'; then
error_exit "Container names may not contain only digits."
error_exit "[ERROR]: Jail names may not contain only digits."
fi
}
validate_ip() {
_ip="${1}"
_ip6=$(echo "${_ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)')
if [ -n "${_ip6}" ]; then
info "Valid: (${_ip6})."
info "\nValid: (${_ip6})."
ipx_addr="ip6.addr"
else
if [ "${_ip}" = "inherit" ] || [ "${_ip}" = "ip_hostname" ] || [ "${_ip}" = "DHCP" ] || [ "${_ip}" = "SYNCDHCP" ]; then
info "Valid: (${_ip})."
info "\nValid: (${_ip})."
else
local IFS
if echo "${_ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then
@@ -90,16 +100,19 @@ validate_ip() {
error_continue "Invalid: (${TEST_IP})"
fi
done
if ifconfig | grep -qwF "${TEST_IP}"; then
warn "Warning: IP address already in use (${TEST_IP})."
fi
ipx_addr="ip4.addr"
info "Valid: (${_ip})."
info "\nValid: (${_ip})."
else
error_continue "Invalid: (${_ip})."
fi
fi
fi
# Warn if IP is in use
if ifconfig | grep -qwF "${TEST_IP}"; then
warn "[WARNING]: IP address in use (${TEST_IP})."
fi
# Set interface value
if [ ! -f "${bastille_jail_conf}" ]; then
if [ -z "${bastille_network_loopback}" ] && [ -n "${bastille_network_shared}" ]; then
@@ -112,6 +125,7 @@ validate_ip() {
local bastille_jail_conf_interface=${INTERFACE}
fi
fi
# Determine IP/Interface mode
if [ "${_ip}" = "inherit" ]; then
if [ -n "${DUAL_STACK}" ]; then
@@ -148,27 +162,32 @@ validate_ip() {
}
validate_ips() {
IP6_MODE="disable"
IP4_DEFINITION=""
IP6_DEFINITION=""
IP4_ADDR=""
IP6_ADDR=""
IP_HOSTNAME=""
for ip in ${IP}; do
validate_ip "${ip}"
done
}
validate_netif() {
local LIST_INTERFACES="$(ifconfig -l)"
if echo "${LIST_INTERFACES} VNET" | grep -qwo "${INTERFACE}"; then
info "Valid: (${INTERFACE})."
info "\nValid: (${INTERFACE})."
else
error_exit "Invalid: (${INTERFACE})."
error_exit "[ERROR]: Invalid: (${INTERFACE})."
fi
}
validate_release() {
## ensure the user set the Linux(experimental) option explicitly
if [ -n "${UBUNTU}" ]; then
if [ -z "${LINUX_JAIL}" ]; then
@@ -185,6 +204,7 @@ validate_release() {
}
generate_minimal_conf() {
cat << EOF > "${bastille_jail_conf}"
${NAME} {
host.hostname = ${NAME};
@@ -196,6 +216,7 @@ EOF
}
generate_jail_conf() {
if [ "$(sysctl -n security.jail.jailed)" -eq 1 ]; then
devfs_ruleset_value=0
else
@@ -224,6 +245,7 @@ EOF
}
generate_linux_jail_conf() {
cat << EOF > "${bastille_jail_conf}"
${NAME} {
host.hostname = ${NAME};
@@ -247,12 +269,15 @@ EOF
}
generate_vnet_jail_conf() {
if [ "$(sysctl -n security.jail.jailed)" -eq 1 ]; then
devfs_ruleset_value=0
else
devfs_ruleset_value=13
fi
NETBLOCK=$(generate_vnet_jail_netblock "${NAME}" "${VNET_JAIL_BRIDGE}" "${bastille_jail_conf_interface}" "${STATIC_MAC}")
cat << EOF > "${bastille_jail_conf}"
${NAME} {
enforce_statfs = 2;
@@ -274,6 +299,7 @@ EOF
}
post_create_jail() {
# Common config checks and settings.
# Using relative paths here.
@@ -310,6 +336,7 @@ post_create_jail() {
}
create_jail() {
bastille_jail_base="${bastille_jailsdir}/${NAME}/root/.bastille" ## dir
bastille_jail_template="${bastille_jailsdir}/${NAME}/root/.template" ## dir
bastille_jail_path="${bastille_jailsdir}/${NAME}/root" ## dir
@@ -424,7 +451,7 @@ create_jail() {
if ! cp -a "${bastille_releasesdir}/${RELEASE}/${files}" "${bastille_jail_path}/${files}"; then
## notify and clean stale files/directories
bastille destroy -af "${NAME}"
error_exit "Failed to copy release files. Please retry create!"
error_exit "[ERROR]: Failed to copy release files. Please retry create!"
fi
fi
done
@@ -444,9 +471,10 @@ create_jail() {
# Check and apply required settings.
post_create_jail
elif [ -n "${THICK_JAIL}" ]; then
info "\nCreating a thickjail. This may take a while...\n"
## perform release base replication
info "\nCreating a thickjail. This may take a while..."
## perform release base replication
## sane bastille zfs options
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
## send without -R if encryption is enabled
@@ -478,7 +506,7 @@ create_jail() {
if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories
bastille destroy -af "${NAME}"
error_exit "Failed release base replication. Please retry create!"
error_exit "[ERROR]: Failed release base replication. Please retry create!"
fi
fi
else
@@ -487,7 +515,7 @@ create_jail() {
if [ "$?" -ne 0 ]; then
## notify and clean stale files/directories
bastille destroy -af "${NAME}"
error_exit "Failed to copy release files. Please retry create!"
error_exit "[ERROR]: Failed to copy release files. Please retry create!"
fi
fi
fi
@@ -549,8 +577,8 @@ create_jail() {
chmod 0700 "${bastille_jailsdir}/${NAME}"
# Apply priority and boot settings before starting jail
sysrc -f "${bastille_jailsdir}/${NAME}/boot.conf" boot=${BOOT}
sysrc -f "${bastille_jailsdir}/${NAME}/boot.conf" priority="${PRIORITY}"
sysrc -f "${bastille_jailsdir}/${NAME}/boot.conf" boot=${BOOT} >/dev/null
sysrc -f "${bastille_jailsdir}/${NAME}/boot.conf" priority="${PRIORITY}" >/dev/null
# Jail must be started before applying the default template. -- cwells
if [ -z "${EMPTY_JAIL}" ]; then
@@ -566,7 +594,7 @@ create_jail() {
if [ -z "${EMPTY_JAIL}" ]; then
if ! check_target_is_running "${NAME}"; then
bastille destroy -af "${NAME}"
error_exit "[${NAME}]: Failed to create jail..."
error_exit "[ERROR]: Failed to create jail: ${NAME}"
fi
fi
@@ -579,6 +607,7 @@ create_jail() {
_gateway6=''
_ifconfig_inet=''
_ifconfig_inet6=''
if echo "${IP}" | grep -qE '(0[.]0[.]0[.]0|DHCP)'; then
# Enable DHCP if requested
_ifconfig_inet=SYNCDHCP
@@ -637,7 +666,7 @@ create_jail() {
fi
## Using templating function to fetch necessary packges @hackacad
elif [ -n "${LINUX_JAIL}" ]; then
info "Fetching packages..."
info "\nFetching packages..."
jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive rm /var/cache/apt/archives/rsyslog*.deb"
jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive dpkg --force-depends --force-confdef --force-confold -i /var/cache/apt/archives/*.deb"
jexec -l "${NAME}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive dpkg --force-depends --force-confdef --force-confold -i /var/cache/apt/archives/*.deb"
@@ -764,7 +793,7 @@ while [ $# -gt 0 ]; do
T) THICK_JAIL=1 ;;
V) VNET_JAIL=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -778,16 +807,16 @@ done
# Validate options
if [ -n "${EMPTY_JAIL}" ]; then
if [ -n "${CLONE_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${LINUX_JAIL}" ]; then
error_exit "Error: Empty jail option can't be used with other options."
error_exit "[ERROR]: Empty jail option can't be used with other options."
fi
elif [ -n "${LINUX_JAIL}" ]; then
if [ -n "${EMPTY_JAIL}" ] || [ -n "${VNET_JAIL}" ] || [ -n "${THICK_JAIL}" ] || [ -n "${CLONE_JAIL}" ]; then
error_exit "Error: Linux jail option can't be used with other options."
error_exit "[ERROR]: Linux jail option can't be used with other options."
fi
elif [ -n "${CLONE_JAIL}" ] && [ -n "${THICK_JAIL}" ]; then
error_exit "Error: Clonejail and Thickjail can't be used together."
error_exit "[ERROR]: Clonejail and Thickjail can't be used together."
elif [ -z "${VNET_JAIL}" ] && [ -z "${VNET_JAIL_BRIDGE}" ] && [ -n "${VLAN_ID}" ]; then
error_exit "Error: VLANs can only be used with VNET and bridged VNET jails."
error_exit "[ERROR]: VLANs can only be used with VNET and bridged VNET jails."
fi
NAME="$1"
@@ -795,6 +824,8 @@ RELEASE="$2"
IP="$3"
INTERFACE="$4"
info "\nAttempting to create jail: ${NAME}"
if [ -n "${EMPTY_JAIL}" ]; then
if [ $# -ne 1 ]; then
usage
@@ -805,7 +836,7 @@ else
fi
fi
## validate jail name
# Validate jail name
if [ -n "${NAME}" ]; then
validate_name
fi
@@ -813,11 +844,11 @@ fi
# Validate interface type
if [ -n "${VNET_JAIL}" ] && [ -n "${VNET_JAIL_BRIDGE}" ]; then
if ! ifconfig -g bridge | grep -owq "${INTERFACE}"; then
error_exit "Interface is not a bridge: ${INTERFACE}"
error_exit "[ERROR]: Interface is not a bridge: ${INTERFACE}"
fi
elif [ -n "${VNET_JAIL}" ] && [ -z "${VNET_JAIL_BRIDGE}" ]; then
if ifconfig -g bridge | grep -owq "${INTERFACE}"; then
error_exit "Interface is a bridge: ${INTERFACE}"
error_exit "[ERROR]: Interface is a bridge: ${INTERFACE}"
fi
fi
@@ -853,7 +884,7 @@ if [ -n "${LINUX_JAIL}" ] && [ -n "${VALIDATE_RELEASE}" ]; then
NAME_VERIFY=bookworm
;;
*)
error_notify "Unknown Linux."
error_notify "[ERROR]: Unknown linux release."
usage
;;
esac
@@ -937,24 +968,25 @@ if [ -z "${EMPTY_JAIL}" ]; then
esac
fi
## check for name/root/.bastille
# Check for name/root/.bastille
if [ -d "${bastille_jailsdir}/${NAME}/root/.bastille" ]; then
error_exit "Jail: ${NAME} already created. ${NAME}/root/.bastille exists."
error_exit "[ERROR]: ${NAME} already exists. ${NAME}/root/.bastille exists."
fi
## check for required release
# Check for required release
if [ ! -d "${bastille_releasesdir}/${RELEASE}" ]; then
error_exit "Release must be bootstrapped first; see 'bastille bootstrap'."
error_notify "[ERROR]: Release must be bootstrapped first."
error_exit "See 'bastille bootstrap'."
fi
## check if ip address is valid
# Validate IP address
if [ -n "${IP}" ]; then
validate_ips
else
usage
fi
## check if interface is valid
# Validate interface
if [ -n "${INTERFACE}" ]; then
validate_netif
validate_netconf
@@ -962,7 +994,7 @@ if [ -z "${EMPTY_JAIL}" ]; then
if [ -z "${INTERFACE}" ]; then
if [ -z "${bastille_network_shared}" ]; then
# User must specify interface on vnet jails.
error_exit "Error: Network interface not defined."
error_exit "[ERROR]: Network interface not defined."
else
validate_netconf
fi
@@ -1004,7 +1036,7 @@ if [ -z ${bastille_template_vnet+x} ]; then
fi
if check_target_exists "${NAME}"; then
error_exit "Error: Existing jail found: ${NAME}"
error_exit "[ERROR]: Jail already exists: ${NAME}"
fi
create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}"

View File

@@ -53,27 +53,32 @@ destroy_jail() {
for _jail in ${JAILS}; do
info "[${_jail}]:"
bastille_jail_base="${bastille_jailsdir}/${_jail}"
bastille_jail_log="${bastille_logsdir}/${_jail}_console.log"
# Validate jail state before continuing
check_target_is_stopped "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-stopping ${_jail}..."
bastille stop "${_jail}"
else
info "\n[${_jail}]:"
error_notify "Jail is running."
error_continue "Use [-a|--auto] to auto-stop the jail."
fi
info "\n[${_jail}]:"
if [ -d "${bastille_jail_base}" ]; then
# Make sure no filesystem is currently mounted
mount_points="$(mount | cut -d ' ' -f 3 | grep ${bastille_jail_base}/root/)"
if [ -n "${mount_points}" ]; then
error_notify "Failed to destroy jail: ${_jail}"
error_continue_next_jail "Jail has mounted filesystems:\n$mount_points"
error_notify "[ERROR]: Failed to destroy jail: ${_jail}"
error_continue "Jail has mounted filesystems:\n$mount_points"
fi
info "Deleting Jail: ${_jail}."
echo "Destroying jail..."
if checkyesno bastille_zfs_enable; then
if [ -n "${bastille_zfs_zpool}" ]; then
if [ -n "${_jail}" ]; then
@@ -85,7 +90,7 @@ destroy_jail() {
# This will deal with the common "cannot unmount 'XYZ': pool or dataset is busy"
# unless the force option is defined by the user, otherwise will have a partially deleted jail.
if ! zfs destroy "${OPTIONS}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"; then
error_continue_next_jail "[ERROR]: Jail dataset(s) appears to be busy, exiting."
error_continue "[ERROR]: Jail dataset(s) appears to be busy, exiting."
fi
fi
fi
@@ -102,13 +107,13 @@ destroy_jail() {
# Archive jail log
if [ -f "${bastille_jail_log}" ]; then
mv "${bastille_jail_log}" "${bastille_jail_log}"-"$(date +%F)"
info "Note: jail console logs archived."
info "${bastille_jail_log}-$(date +%F)"
echo "Note: jail console logs archived."
echo "${bastille_jail_log}-$(date +%F)"
fi
# Clear any active rdr rules
if [ ! -z "$(pfctl -a "rdr/${_jail}" -Psn 2>/dev/null)" ]; then
info "Clearing RDR rules:"
echo "Clearing RDR rules..."
pfctl -a "rdr/${_jail}" -Fn
fi
fi
@@ -129,13 +134,18 @@ destroy_rel() {
bastille_rel_base="${bastille_releasesdir}/${TARGET}" ## dir
info "\nAttempting to destroy release: ${TARGET}"
## check if this release have containers child
BASE_HASCHILD="0"
if [ -d "${bastille_jailsdir}" ]; then
JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g")
for _jail in ${JAIL_LIST}; do
if grep -qwo "${TARGET}" "${bastille_jailsdir}/${_jail}/fstab" 2>/dev/null; then
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
error_notify "[ERROR]: (${_jail}) depends on ${TARGET} base."
BASE_HASCHILD="1"
elif checkyesno bastille_zfs_enable; then
if [ -n "${bastille_zfs_zpool}" ]; then
@@ -147,7 +157,7 @@ destroy_rel() {
CLONE_JAIL=$(zfs list -H -o clones "${_snap_clone}" | tr ',' '\n')
CLONE_CHECK="${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}/root"
if echo "${CLONE_JAIL}" | grep -qw "${CLONE_CHECK}"; then
error_notify "Notice: (${_jail}) depends on ${TARGET} base."
error_notify "[ERROR]: (${_jail}) depends on ${TARGET} base."
BASE_HASCHILD="1"
fi
fi
@@ -159,10 +169,10 @@ destroy_rel() {
fi
if [ ! -d "${bastille_rel_base}" ]; then
error_exit "Release base not found."
error_exit "[ERROR]: Release base not found."
else
if [ "${BASE_HASCHILD}" -eq "0" ]; then
info "Deleting base: ${TARGET}"
echo "Deleting release base..."
if checkyesno bastille_zfs_enable; then
if [ -n "${bastille_zfs_zpool}" ]; then
if [ -n "${TARGET}" ]; then
@@ -195,7 +205,7 @@ destroy_rel() {
fi
fi
else
error_notify "Cannot destroy base with child containers."
error_notify "[ERROR]: Cannot destroy base with child containers."
fi
fi
}
@@ -232,7 +242,7 @@ while [ "$#" -gt 0 ]; do
c) NO_CACHE=1 ;;
f) FORCE=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -305,4 +315,4 @@ case "${TARGET}" in
;;
esac
echo
echo

View File

@@ -55,7 +55,7 @@ while [ "$#" -gt 0 ]; do
shift
;;
-*)
error_notify "Unknown Option: \"${1}\""
error_notify "[ERROR]: Unknown Option: \"${1}\""
usage
;;
*)
@@ -82,4 +82,4 @@ if [ -z "${EDITOR}" ]; then
EDITOR=edit
fi
"${EDITOR}" "${bastille_jailsdir}/${TARGET}/${TARGET_FILENAME}"
"${EDITOR}" "${bastille_jailsdir}/${TARGET}/${TARGET_FILENAME}"

View File

@@ -44,13 +44,15 @@ EOF
}
bootstrap_etc_release() {
local _release="${1}"
local _current="$(sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives | awk -F': ' '{print $2}')"
if [ -z "$(ls -A "${bastille_releasesdir}/${_release}/usr/src")" ]; then
sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives=src
if ! bastille bootstrap "${_release}" > /dev/null; then
sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}"
error_exit "Failed to bootstrap etcupdate: ${_release}"
error_exit "[ERROR]: Failed to bootstrap etcupdate: ${_release}"
else
sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}"
fi
@@ -58,17 +60,19 @@ bootstrap_etc_release() {
}
bootstrap_etc_tarball() {
local _release="${1}"
if [ ! -f ${bastille_cachedir}/${_release}.tbz2 ]; then
echo "\nBuilding tarball, please wait..."
info "\nBuilding tarball, please wait..."
if ! etcupdate build -d /tmp/etcupdate -s ${bastille_releasesdir}/${_release}/usr/src ${bastille_cachedir}/${_release}.tbz2; then
error_exit "Failed to build etcupdate tarball \"${_release}.tbz2\""
error_exit "[ERROR]: Failed to build etcupdate tarball \"${_release}.tbz2\""
else
info "\nEtcupdate bootstrap complete: ${_release}"
fi
elif [ -f ${bastille_cachedir}/${_release}.tbz2 ] && [ "${FORCE}" -eq 1 ]; then
rm -f "${bastille_cachedir}/${_release}.tbz2"
echo "Building tarball, please wait..."
info "\nBuilding tarball, please wait..."
if ! etcupdate build -d /tmp/etcupdate -s ${bastille_releasesdir}/${_release}/usr/src ${bastille_cachedir}/${_release}.tbz2; then
error_exit "[ERROR]: Failed to build etcupdate tarball: ${_release}.tbz2"
else
@@ -80,34 +84,42 @@ bootstrap_etc_tarball() {
}
diff_review() {
local _jail="${1}"
if [ "${DRY_RUN}" -eq 1 ]; then
error_exit "[ERROR]: diff mode does not support [-d|--dryrun]"
fi
info "\n[${_jail}]: etcupdate --diff mode"
echo "Running: etcupdate --diff mode"
etcupdate diff -D "${bastille_jailsdir}/${_jail}/root"
}
resolve_conflicts() {
local _jail="${1}"
if [ "${DRY_RUN}" -eq 1 ]; then
error_exit "[ERROR]: resolve mode does not support [-d|--dryrun]"
fi
info "\n[${_jail}]: etcupdate resolve"
echo "Running: etcupdate resolve"
etcupdate resolve -D "${bastille_jailsdir}/${_jail}/root"
}
update_jail_etc() {
local _jail="${1}"
local _release="${2}"
if [ ! -f ${bastille_cachedir}/${_release}.tbz2 ]; then
error_exit "Error: Please run \"bastille etcupdate bootstrap RELEASE\" first."
error_exit "[ERROR]: Please run 'bastille etcupdate bootstrap RELEASE' first."
fi
if [ "${DRY_RUN}" -eq 1 ]; then
info "\n[${_jail}]: etcupdate update --dry-run"
echo "Running: etcupdate update --dry-run"
etcupdate -n -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2
else
info "\n[${_jail}]: etcupdate update"
echo "Running: etcupdate update"
etcupdate -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2
fi
}
@@ -161,6 +173,7 @@ while [ "$#" -gt 0 ]; do
usage
else
RELEASE="${2}"
info "\nAttempting to bootstrap etcupdate release: ${RELEASE}..."
bootstrap_etc_release "${RELEASE}"
bootstrap_etc_tarball "${RELEASE}"
shift "$#"
@@ -170,7 +183,11 @@ while [ "$#" -gt 0 ]; do
TARGET="${1}"
ACTION="${2}"
RELEASE="${3}"
set_target_single "${TARGET}"
info "\n[${TARGET}]:"
case "${ACTION}" in
diff)
diff_review "${TARGET}"
@@ -189,11 +206,11 @@ while [ "$#" -gt 0 ]; do
fi
;;
*)
error_exit "Unknown action: \"${ACTION}\""
error_exit "[ERROR]: Unknown action: \"${ACTION}\""
;;
esac
;;
esac
done
echo
echo

View File

@@ -119,7 +119,7 @@ if [ -n "${bastille_export_options}" ]; then
-v|--verbose)
OPT_ZSEND="-Rv"
shift;;
-*) error_notify "Unknown Option: \"${1}\""
-*) error_notify "[ERROR]: Unknown Option: \"${1}\""
usage;;
esac
done
@@ -170,7 +170,7 @@ else
shift
;;
-*)
error_notify "Unknown Option: \"${1}\""
error_notify "[ERROR]: Unknown Option: \"${1}\""
usage
;;
*)
@@ -194,13 +194,15 @@ fi
bastille_root_check
set_target_single "${TARGET}"
info "\n[${_jail}]:"
# Validate for combined options
if [ "${COMP_OPTION}" -gt "1" ]; then
error_exit "Error: Only one compression format can be used during export."
error_exit "[ERROR]: Only one compression format can be used during export."
fi
if { [ -n "${TXZ_EXPORT}" ] || [ -n "${TGZ_EXPORT}" ]; } && [ -n "${SAFE_EXPORT}" ]; then
error_exit "Error: Simple archive modes with safe ZFS export can't be used together."
error_exit "[ERROR]: Simple archive modes with safe ZFS export can't be used together."
fi
if ! checkyesno bastille_zfs_enable; then
@@ -209,7 +211,7 @@ if ! checkyesno bastille_zfs_enable; then
[ -n "${RAW_EXPORT}" ] ||
[ -n "${SAFE_EXPORT}" ] ||
[ "${OPT_ZSEND}" = "-Rv" ]; then
error_exit "Options --xz, --gz, --raw, --safe, and --verbose are valid for ZFS configured systems only."
error_exit "[ERROR]: Options --xz, --gz, --raw, --safe, and --verbose are valid for ZFS configured systems only."
fi
fi
@@ -226,7 +228,7 @@ if [ -n "${DIR_EXPORT}" ]; then
# Set the user defined export directory
bastille_backupsdir="${DIR_EXPORT}"
else
error_exit "Error: Path not found."
error_exit "[ERROR]: Path not found."
fi
fi
@@ -241,7 +243,7 @@ fi
create_zfs_snap() {
# Take a recursive temporary snapshot
if [ -z "${USER_EXPORT}" ]; then
echo "Creating temporary ZFS snapshot for export..."
info "\nCreating temporary ZFS snapshot for export..."
fi
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}"
}
@@ -277,7 +279,7 @@ export_check() {
EXPORT_INFO="to a compressed ${FILE_EXT} ${EXPORT_TYPE}"
fi
info "${EXPORT_AS} '${TARGET}' ${EXPORT_INFO}..."
info "\n${EXPORT_AS} '${TARGET}' ${EXPORT_INFO}..."
fi
# Safely stop and snapshot the jail
@@ -291,15 +293,13 @@ export_check() {
if checkyesno bastille_zfs_enable; then
if [ -z "${USER_EXPORT}" ]; then
info "Sending ZFS data stream..."
info "\nSending ZFS data stream..."
fi
fi
}
jail_export() {
info "\n[${_jail}]:"
# Attempt to export the container
DATE=$(date +%F-%H%M%S)
if checkyesno bastille_zfs_enable; then
@@ -336,7 +336,7 @@ jail_export() {
# Quietly export the container recursively, user must redirect standard output
if ! zfs send ${OPT_ZSEND} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}"; then
clean_zfs_snap
error_notify "\nError: An export option is required, see 'bastille export, otherwise the user must redirect to standard output."
error_exit "[ERROR]: An export option is required, see 'bastille export, otherwise the user must redirect to standard output."
fi
fi
fi
@@ -345,28 +345,28 @@ jail_export() {
FILE_EXT=".tgz"
# Create standard tgz backup archive
info "Exporting '${TARGET}' to a compressed ${FILE_EXT} archive..."
info "\nExporting '${TARGET}' to a compressed ${FILE_EXT} archive..."
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | gzip ${bastille_compress_gz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}"
elif [ -n "${TXZ_EXPORT}" ]; then
FILE_EXT=".txz"
# Create standard txz backup archive
info "Exporting '${TARGET}' to a compressed ${FILE_EXT} archive..."
info "\nExporting '${TARGET}' to a compressed ${FILE_EXT} archive..."
cd "${bastille_jailsdir}" && tar -cf - "${TARGET}" | xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}"
else
error_exit "Error: export option required"
error_exit "[ERROR]: export option required"
fi
fi
# shellcheck disable=SC2181
if [ "$?" -ne 0 ]; then
error_exit "Failed to export '${TARGET}' container."
error_exit "[ERROR]: Failed to export '${TARGET}' container."
else
if [ -z "${USER_EXPORT}" ]; then
# Generate container checksum file
cd "${bastille_backupsdir}" || error_exit "Failed to change directory."
sha256 -q "${TARGET}_${DATE}${FILE_EXT}" > "${TARGET}_${DATE}.sha256"
info "Exported '${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}' successfully."
info "\nExported '${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}' successfully."
fi
exit 0
fi
@@ -374,19 +374,20 @@ jail_export() {
# Check if backups directory/dataset exist
if [ ! -d "${bastille_backupsdir}" ]; then
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
error_exit "[ERROR]: Backups directory/dataset does not exist. See 'bastille bootstrap'."
fi
if [ -n "${TARGET}" ]; then
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
error_exit "[${TARGET}]: Not found."
error_exit "[ERROR]: Jail not found: ${TARGET}"
fi
# Check if is a ZFS system
if ! checkyesno bastille_zfs_enable; then
# Check if container is running and ask for stop in non ZFS systems
if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
error_exit "${TARGET} is running. See 'bastille stop'."
error_exit "[ERROR]: ${TARGET} is running. See 'bastille stop'."
fi
fi
jail_export

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\""
*) error_exit "[ERROR]: Unknown Option: \"${1}\""
esac
done
shift
@@ -85,18 +85,18 @@ TARGET="${1}"
bastille_root_check
set_target_single "${TARGET}"
info "[${TARGET}]:"
check_target_is_running "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${TARGET}..."
bastille start "${TARGET}"
else
else
info "\n[${TARGET}]:"
error_notify "Jail is not running."
error_continue_next_jail "Use [-a|--auto] to auto-start the jail."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${TARGET}]:"
if [ ! -x "${bastille_jailsdir}/${TARGET}/root/usr/local/bin/htop" ]; then
error_notify "htop not found on ${TARGET}."
error_exit "[ERROR]: htop not found on ${TARGET}."
elif [ -x "${bastille_jailsdir}/${TARGET}/root/usr/local/bin/htop" ]; then
jexec -l ${TARGET} /usr/local/bin/htop
fi
fi

View File

@@ -84,7 +84,7 @@ while [ "$#" -gt 0 ]; do
M) OPT_STATIC_MAC=1 ;;
v) OPT_ZRECV="-u -v" ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -117,20 +117,20 @@ validate_archive() {
# Skip validation for unsupported archive
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
if [ -f "${bastille_backupsdir}/${FILE_TRIM}.sha256" ]; then
info "Validating file: ${TARGET}..."
info "\nValidating file: ${TARGET}..."
SHA256_DIST=$(cat "${bastille_backupsdir}/${FILE_TRIM}.sha256")
SHA256_FILE=$(sha256 -q "${bastille_backupsdir}/${TARGET}")
if [ "${SHA256_FILE}" != "${SHA256_DIST}" ]; then
error_exit "Failed validation for ${TARGET}."
error_exit "[ERROR]: Failed validation for ${TARGET}."
else
info "File validation successful!"
info "\nFile validation successful!"
fi
else
# Check if user opt to force import
if [ "${OPT_FORCE}" -eq 1 ]; then
warn "Warning: Skipping archive validation!"
warn "[WARNING]: Skipping archive validation!"
else
error_exit "Checksum file not found. See 'bastille import [option(s)] FILE'."
error_exit "[ERROR]: Checksum file not found. See 'bastille import [option(s)] FILE'."
fi
fi
fi
@@ -141,7 +141,7 @@ update_zfsmount() {
OLD_ZFS_MOUNTPOINT=$(zfs get -H mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" | awk '{print $3}')
NEW_ZFS_MOUNTPOINT="${bastille_jailsdir}/${TARGET_TRIM}/root"
if [ "${NEW_ZFS_MOUNTPOINT}" != "${OLD_ZFS_MOUNTPOINT}" ]; then
info "Updating ZFS mountpoint..."
info "\nUpdating ZFS mountpoint..."
zfs set mountpoint="${bastille_jailsdir}/${TARGET_TRIM}/root" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
fi
@@ -155,11 +155,13 @@ update_zfsmount() {
}
update_jailconf() {
# Update jail.conf paths
JAIL_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/jail.conf"
if [ -f "${JAIL_CONFIG}" ]; then
if ! grep -qw "path = ${bastille_jailsdir}/${TARGET_TRIM}/root;" "${JAIL_CONFIG}"; then
info "Updating jail.conf..."
info "\nUpdating jail.conf..."
sed -i '' "s|exec.consolelog.*=.*;|exec.consolelog = ${bastille_logsdir}/${TARGET_TRIM}_console.log;|" "${JAIL_CONFIG}"
sed -i '' "s|path.*=.*;|path = ${bastille_jailsdir}/${TARGET_TRIM}/root;|" "${JAIL_CONFIG}"
sed -i '' "s|mount.fstab.*=.*;|mount.fstab = ${bastille_jailsdir}/${TARGET_TRIM}/fstab;|" "${JAIL_CONFIG}"
@@ -173,16 +175,18 @@ update_jailconf() {
}
update_fstab_import() {
# Update fstab .bastille mountpoint on thin containers only
# Set some variables
FSTAB_CONFIG="${bastille_jailsdir}/${TARGET_TRIM}/fstab"
FSTAB_RELEASE=$(grep -owE '([1-9]{2,2})\.[0-9](-RELEASE|-RELEASE-i386|-RC[1-9])|([0-9]{1,2}-stable-build-[0-9]{1,3})|(current-build)-([0-9]{1,3})|(current-BUILD-LATEST)|([0-9]{1,2}-stable-BUILD-LATEST)|(current-BUILD-LATEST)' "${FSTAB_CONFIG}")
FSTAB_CURRENT=$(grep -w ".*/releases/.*/jails/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}")
FSTAB_NEWCONF="${bastille_releasesdir}/${FSTAB_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0"
if [ -n "${FSTAB_CURRENT}" ] && [ -n "${FSTAB_NEWCONF}" ]; then
# If both variables are set, compare and update as needed
if ! grep -qw "${bastille_releasesdir}/${FSTAB_RELEASE}.*${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille" "${FSTAB_CONFIG}"; then
info "Updating fstab..."
info "\nUpdating fstab..."
if [ -n "${RELEASE}" ]; then
FSTAB_NEWCONF="${RELEASE}"
fi
@@ -192,9 +196,10 @@ update_fstab_import() {
}
generate_config() {
# Attempt to read previous config file and set required variables accordingly
# If we can't get a valid interface, fallback to lo1 and warn user
info "Generating jail.conf..."
info "\nGenerating jail.conf..."
DEVFS_RULESET=4
if [ "${FILE_EXT}" = ".zip" ]; then
@@ -241,43 +246,43 @@ generate_config() {
else
# If there are multiple IP/NIC let the user configure network
IP4_DEFINITION=""
IP6_DEFINITION=""
IP6_DEFINITION=""
IP6_MODE="disable"
# IP4 set, but not IP6
# IP4 set, but not IP6
if [ -n "${IP4_CONFIG}" ] && [ -z "${IP6_CONFIG}" ]; then
if ! echo "${IP4_CONFIG}" | grep -q '.*,.*'; then
IP4_IF=$(echo "${IP4_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${IP4_IF}" ]; then
config_netif
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};"
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};"
IP6_MODE="disable"
else
IP4_DEFINITION="ip4.addr = ${IP4_CONFIG};"
IP6_MODE="disable"
fi
IP6_MODE="disable"
fi
else
IP4_IF=$(echo "${IP4_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${IP4_IF}" ]; then
config_netif
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};"
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};"
IP6_MODE="disable"
else
IP4_DEFINITION="ip4.addr = ${IP4_CONFIG};"
IP6_MODE="disable"
fi
IP6_MODE="disable"
fi
fi
# IP6 set, but not IP4
# IP6 set, but not IP4
elif [ -z "${IP4_CONFIG}" ] && [ -z "${IP6_CONFIG}" ]; then
if ! echo "${IP6_CONFIG}" | grep -q '.*,.*'; then
IP6_IF=$(echo "${IP6_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${IP6_IF}" ]; then
config_netif
IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};"
IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};"
IP6_MODE="new"
else
IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};"
IP6_MODE="new"
fi
IP6_MODE="new"
fi
else
IP6_IF=$(echo "${IP6_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${IP6_IF}" ]; then
@@ -286,48 +291,48 @@ generate_config() {
IP6_MODE="new"
else
IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};"
IP6_MODE="new"
fi
IP6_MODE="new"
fi
fi
# IP4 and IP6 both set
elif [ -n "${IP4_CONFIG}" ] && [ -n "${IP6_CONFIG}" ]; then
elif [ -n "${IP4_CONFIG}" ] && [ -n "${IP6_CONFIG}" ]; then
if ! echo "${IP4_CONFIG}" | grep -q '.*,.*'; then
IP4_IF=$(echo "${IP4_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${IP4_IF}" ]; then
config_netif
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};"
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};"
else
IP4_DEFINITION="ip4.addr = ${IP4_CONFIG};"
fi
fi
else
IP4_IF=$(echo "${IP4_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${IP4_IF}" ]; then
config_netif
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};"
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IP4_CONFIG};"
else
IP4_DEFINITION="ip4.addr = ${IP4_CONFIG};"
fi
fi
fi
if ! echo "${IP6_CONFIG}" | grep -q '.*,.*'; then
IP6_IF=$(echo "${IP6_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${IP6_IF}" ]; then
config_netif
IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};"
IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};"
IP6_MODE="new"
else
IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};"
IP6_MODE="new"
fi
IP6_MODE="new"
fi
else
IP6_IF=$(echo "${IP6_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${IP6_IF}" ]; then
config_netif
IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};"
IP6_DEFINITION="ip6.addr = ${NETIF_CONFIG}|${IP6_CONFIG};"
IP6_MODE="new"
else
IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};"
else
IP6_DEFINITION="ip6.addr = ${IP6_CONFIG};"
IP6_MODE="new"
fi
fi
fi
# ezjail import
elif [ -n "${IPVX_CONFIG}" ]; then
@@ -335,14 +340,14 @@ generate_config() {
NETIF_CONFIG=$(echo "${IPVX_CONFIG}" | grep '.*|' | sed 's/|.*//g')
if [ -z "${NETIF_CONFIG}" ]; then
config_netif
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IPVX_CONFIG};"
IP4_DEFINITION="ip4.addr = ${NETIF_CONFIG}|${IPVX_CONFIG};"
IP6_MODE="disable"
else
IP4_DEFINITION="ip4.addr = ${IPVX_CONFIG};"
IP6_MODE="disable"
fi
IP6_MODE="disable"
fi
if echo "${IPVX_CONFIG}" | sed 's/.*|//' | grep -Eq '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$))'; then
IP4_DEFINITION=""
IP4_DEFINITION=""
IP6_DEFINITION="ip6.addr = ${IPVX_CONFIG};"
IP6_MODE="new"
fi
@@ -369,7 +374,7 @@ EOF
if [ -z "${CONFIG_RELEASE}" ]; then
# Fallback to host version
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
warn "Warning: ${CONFIG_RELEASE} was set by default!"
warn "[WARNING]: ${CONFIG_RELEASE} was set by default!"
fi
mkdir "${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille"
echo "${bastille_releasesdir}/${CONFIG_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" \
@@ -405,6 +410,7 @@ EOF
}
update_config() {
# Update an existing jail configuration
# The config on select archives does not provide a clear way to determine
# the base release, so lets try to get it from the base/COPYRIGHT file,
@@ -414,11 +420,13 @@ update_config() {
else
CONFIG_RELEASE="${RELEASE}"
fi
if [ -z "${CONFIG_RELEASE}" ]; then
# Fallback to host version
CONFIG_RELEASE=$(freebsd-version | sed 's/\-[pP].*//')
warn "Warning: ${CONFIG_RELEASE} was set by default!"
warn "[WARNING]: ${CONFIG_RELEASE} was set by default!"
fi
mkdir "${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille"
echo "${bastille_releasesdir}/${CONFIG_RELEASE} ${bastille_jailsdir}/${TARGET_TRIM}/root/.bastille nullfs ro 0 0" \
>> "${bastille_jailsdir}/${TARGET_TRIM}/fstab"
@@ -448,7 +456,7 @@ vnet_requirements() {
if [ -f "/usr/share/examples/jails/jib" ] && [ ! -f "/usr/local/bin/jib" ]; then
install -m 0544 /usr/share/examples/jails/jib /usr/local/bin/jib
else
warn "Warning: Unable to locate/install jib script required by VNET jails."
warn "[WARNING]: Unable to locate/install jib script required by VNET jails."
fi
fi
elif [ "${bastille_network_vnet_type}" = "netgraph" ]; then
@@ -456,7 +464,7 @@ vnet_requirements() {
if [ -f "/usr/share/examples/jails/jng" ] && [ ! -f "/usr/local/bin/jng" ]; then
install -m 0544 /usr/share/examples/jails/jng /usr/local/bin/jng
else
warn "Warning: Unable to locate/install jng script required by VNET jails."
warn "[WARNING]: Unable to locate/install jng script required by VNET jails."
fi
fi
fi
@@ -474,16 +482,17 @@ config_netif() {
}
update_symlinks() {
# Work with the symlinks
SYMLINKS="bin boot lib libexec rescue sbin usr/bin usr/include usr/lib usr/lib32 usr/libdata usr/libexec usr/ports usr/sbin usr/share usr/src"
# Just warn user to bootstrap the release if missing
if [ ! -d "${bastille_releasesdir}/${CONFIG_RELEASE}" ]; then
warn "Warning: ${CONFIG_RELEASE} must be bootstrapped. See 'bastille bootstrap'."
warn "[WARNING]: ${CONFIG_RELEASE} must be bootstrapped. See 'bastille bootstrap'."
fi
# Update old symlinks
info "Updating symlinks..."
info "\nUpdating symlinks..."
for _link in ${SYMLINKS}; do
if [ -L "${_link}" ]; then
ln -sf /.bastille/${_link} ${_link}
@@ -492,7 +501,7 @@ update_symlinks() {
ln -sfF /.bastille/${_link} ${_link} || EXIT_CODE=$?
if [ "${EXIT_CODE:-0}" != "0" ]; then
# Assume that the failure was due to the directory not being empty and explain the problem in friendlier terms
warn "Warning: directory ${_link} on imported jail was not empty and will not be updated by Bastille"
warn "[WARNING]: directory ${_link} on imported jail was not empty and will not be updated by Bastille"
fi
fi
done
@@ -500,8 +509,8 @@ update_symlinks() {
create_zfs_datasets() {
# Prepare the ZFS environment and restore from file
info "Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
info "Preparing ZFS environment..."
info "\nImporting '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
echo "Preparing ZFS environment..."
# Create required ZFS datasets, mountpoint inherited from system
zfs create ${bastille_zfs_options} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
@@ -512,7 +521,7 @@ remove_zfs_datasets() {
# Perform cleanup on failure
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root"
zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
error_exit "Failed to extract files from '${TARGET}' archive."
error_exit "[ERROR]: Failed to extract files from '${TARGET}' archive."
}
jail_import() {
@@ -525,8 +534,8 @@ jail_import() {
if [ "${FILE_EXT}" = ".xz" ]; then
validate_archive
# Import from compressed xz on ZFS systems
info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} image."
info "Receiving ZFS data stream..."
info "\nImporting '${TARGET_TRIM}' from compressed ${FILE_EXT} image."
echo "Receiving ZFS data stream..."
xz ${bastille_decompress_xz_options} "${bastille_backupsdir}/${TARGET}" | \
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
@@ -535,8 +544,8 @@ jail_import() {
elif [ "${FILE_EXT}" = ".gz" ]; then
validate_archive
# Import from compressed xz on ZFS systems
info "Importing '${TARGET_TRIM}' from compressed ${FILE_EXT} image."
info "Receiving ZFS data stream..."
info "\nImporting '${TARGET_TRIM}' from compressed ${FILE_EXT} image."
echo "Receiving ZFS data stream..."
gzip ${bastille_decompress_gz_options} "${bastille_backupsdir}/${TARGET}" | \
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
@@ -549,7 +558,7 @@ jail_import() {
create_zfs_datasets
# Extract required files to the new datasets
info "Extracting files from '${TARGET}' archive..."
info "\nExtracting files from '${TARGET}' archive..."
tar --exclude='root' -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
tar -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 2 -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${TARGET_TRIM}/root"
if [ "$?" -ne 0 ]; then
@@ -561,7 +570,7 @@ jail_import() {
create_zfs_datasets
# Extract required files to the new datasets
info "Extracting files from '${TARGET}' archive..."
info "\nExtracting files from '${TARGET}' archive..."
tar --exclude='root' -xf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components 2 -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${TARGET_TRIM}/root"
if [ "$?" -ne 0 ]; then
@@ -570,7 +579,7 @@ jail_import() {
elif [ "${FILE_EXT}" = ".zip" ]; then
validate_archive
# Attempt to import a foreign/iocage container
info "Importing '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
info "\nImporting '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
# Sane bastille ZFS options
ZFS_OPTIONS=$(echo ${bastille_zfs_options} | sed 's/-o//g')
@@ -580,7 +589,7 @@ jail_import() {
error_exit "Failed to extract files from '${TARGET}' archive."
rm -f "${FILE_TRIM}" "${FILE_TRIM}_root"
fi
info "Receiving ZFS data stream..."
echo "Receiving ZFS data stream..."
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${FILE_TRIM}"
zfs set ${ZFS_OPTIONS} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}/root" < "${FILE_TRIM}_root"
@@ -604,7 +613,7 @@ jail_import() {
create_zfs_datasets
# Extract required files to the new datasets
info "Extracting files from '${TARGET}' archive..."
info "\nExtracting files from '${TARGET}' archive..."
tar --exclude='ezjail/' -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}/root"
if [ "$?" -ne 0 ]; then
@@ -619,7 +628,7 @@ jail_import() {
workout_components
# Extract required files to the new datasets
info "Extracting files from '${TARGET}' archive..."
info "\nExtracting files from '${TARGET}' archive..."
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${DIRS_PLUS}" -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${JAIL_PATH}"
if [ -f "${bastille_jailsdir}/${TARGET_TRIM}/${TARGET_TRIM}" ]; then
@@ -636,8 +645,8 @@ jail_import() {
validate_archive
# Based on the file name, looks like we are importing a raw bastille image
# Import from uncompressed image file
info "Importing '${TARGET_TRIM}' from uncompressed image archive."
info "Receiving ZFS data stream..."
info "\nImporting '${TARGET_TRIM}' from uncompressed image archive."
echo "Receiving ZFS data stream..."
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}" < "${bastille_backupsdir}/${TARGET}"
# Update ZFS mountpoint property if required
@@ -653,27 +662,27 @@ jail_import() {
fi
fi
else
error_exit "Unknown archive format."
error_exit "[ERROR]: Unknown archive format."
fi
fi
else
# Import from standard supported archives on UFS systems
if [ "${FILE_EXT}" = ".txz" ]; then
info "Extracting files from '${TARGET}' archive..."
info "\nExtracting files from '${TARGET}' archive..."
tar -Jxf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
elif [ "${FILE_EXT}" = ".tgz" ]; then
info "Extracting files from '${TARGET}' archive..."
info "\nExtracting files from '${TARGET}' archive..."
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
# Attempt to import/configure foreign/ezjail container
info "Extracting files from '${TARGET}' archive..."
info "\nExtracting files from '${TARGET}' archive..."
mkdir "${bastille_jailsdir}/${TARGET_TRIM}"
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
mv "${bastille_jailsdir}/${TARGET_TRIM}/ezjail" "${bastille_jailsdir}/${TARGET_TRIM}/root"
generate_config
elif [ "${FILE_EXT}" = ".tar" ]; then
# Attempt to import/configure foreign/qjail container
info "Extracting files from '${TARGET}' archive..."
info "\nExtracting files from '${TARGET}' archive..."
mkdir -p "${bastille_jailsdir}/${TARGET_TRIM}/root"
workout_components
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
@@ -683,24 +692,24 @@ jail_import() {
fi
update_config
else
error_exit "Unsupported archive format."
error_exit "[ERROR]: Unsupported archive format."
fi
fi
if [ "$?" -ne 0 ]; then
error_exit "Failed to import from '${TARGET}' archive."
error_exit "[ERROR]: Failed to import from '${TARGET}' archive."
else
# Update the jail.conf and fstab if required
# This is required on foreign imports only
update_jailconf
update_fstab_import
if [ -z "${USER_IMPORT}" ]; then
info "Container '${TARGET_TRIM}' imported successfully."
info "\nJail: '${TARGET_TRIM}' imported successfully."
fi
exit 0
fi
else
error_exit "Jails directory/dataset does not exist. See 'bastille bootstrap'."
error_exit "[ERROR]: Jails directory/dataset does not exist. See 'bastille bootstrap'."
fi
}
@@ -713,7 +722,7 @@ fi
# Check if backups directory/dataset exist
if [ ! -d "${bastille_backupsdir}" ]; then
error_exit "Backups directory/dataset does not exist. See 'bastille bootstrap'."
error_exit "[ERROR]: Backups directory/dataset does not exist. See 'bastille bootstrap'."
fi
# Check if archive exist then trim archive name
@@ -724,11 +733,11 @@ if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
TARGET_TRIM=$(echo "${TARGET}" | sed "s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.xz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.gz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.tgz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.txz//;s/_[0-9]*-[0-9]*-[0-9]*.zip//;s/-[0-9]\{12\}.[0-9]\{2\}.tar.gz//;s/@[0-9]\{12\}.[0-9]\{2\}.tar//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*//")
fi
else
error_exit "Unrecognized archive name."
error_exit "[ERROR]: Unrecognized archive name."
fi
else
if echo "${TARGET}" | grep -q '_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.*$'; then
error_exit "Archive '${TARGET}' not found."
error_exit "[ERROR]: Archive '${TARGET}' not found."
else
# Assume user will import from standard input
TARGET_TRIM=${TARGET}
@@ -737,16 +746,9 @@ else
fi
# Check if a running jail matches name or already exist
if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET_TRIM}$/")" ]; then
error_exit "A running jail matches name."
elif [ -n "${TARGET_TRIM}" ]; then
if [ -d "${bastille_jailsdir}/${TARGET_TRIM}" ]; then
error_exit "Container: ${TARGET_TRIM} already exists."
fi
fi
check_target_exists || error_exit "[ERROR]: Jail: ${TARGET_TRIM} already exists."
if [ -n "${TARGET}" ]; then
info "\nAttempting to import jail: ${TARGET}..."
jail_import
fi
echo
fi

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
q) OPTION="-a" ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -95,13 +95,13 @@ for _jail in ${DEST_TARGET}; do
continue
else
info "\n[${_jail}]:"
source_path="$(echo ${bastille_jailsdir}/${SOURCE_TARGET}/root/${SOURCE_PATH} | sed 's#//#/#g')"
info "\n[${_jail}]:"
source_path="$(echo ${bastille_jailsdir}/${SOURCE_TARGET}/root/${SOURCE_PATH} | sed 's#//#/#g')"
dest_path="$(echo ${bastille_jailsdir}/${_jail}/root/${DEST_PATH} | sed 's#//#/#g')"
if ! cp "${OPTION}" "${source_path}" "${dest_path}"; then
error_continue "JCP failed: ${source_path} -> ${dest_path}"
error_continue "[ERROR]: JCP failed: ${source_path} -> ${dest_path}"
fi
fi

View File

@@ -51,9 +51,9 @@ EOF
AUTO=0
while [ "$#" -gt 0 ]; do
case "${1}" in
-h|--help|help)
usage
;;
-h|--help|help)
usage
;;
-a|--auto)
AUTO=1
shift
@@ -67,7 +67,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -95,7 +95,7 @@ fi
RACCT_ENABLE="$(sysctl -n kern.racct.enable)"
if [ "${RACCT_ENABLE}" != '1' ]; then
error_exit "Racct not enabled. Append 'kern.racct.enable=1' to /boot/loader.conf and reboot"
error_exit "[ERROR]: Racct not enabled. Append 'kern.racct.enable=1' to /boot/loader.conf and reboot"
fi
bastille_root_check
@@ -103,16 +103,15 @@ set_target "${TARGET}"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
info "[${_jail}]:"
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${_jail}]:"
case "${ACTION}" in
add)
@@ -186,11 +185,8 @@ for _jail in ${JAILS}; do
rm -f "${bastille_jailsdir}/${_jail}/rctl.conf"
echo "rctl.conf removed."
else
error_continue "rctl.conf not found."
error_continue "[ERROR]: rctl.conf not found."
fi
;;
esac
done
echo
done

View File

@@ -512,7 +512,7 @@ while [ "$#" -gt 0 ]; do
a) ;;
j) OPT_JSON=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\""
*) error_exit "[ERROR]: Unknown Option: \"${1}\""
esac
done
shift
@@ -609,4 +609,4 @@ if [ "$#" -eq 1 ]; then
fi
;;
esac
fi
fi

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\""
*) error_exit "[ERROR]: Unknown Option: \"${1}\""
esac
done
shift
@@ -106,7 +106,6 @@ if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z "
error_notify "FSTAB format not recognized."
warn "Format: /host/path /jail/path nullfs ro 0 0"
warn "Read: ${_fstab}"
usage
fi
# Exit if host path doesn't exist, type is not "nullfs", or mount is an advanced mount type "tmpfs,linprocfs,linsysfs,fdescfs,procfs"
@@ -122,7 +121,6 @@ elif [ ! -e "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then
error_notify "Invalid host path or incorrect mount type in FSTAB."
warn "Format: /host/path /jail/path nullfs ro 0 0"
warn "Read: ${_fstab}"
usage
fi
# Mount permissions,options must include one of "ro, rw, rq, sw, xx"
@@ -130,7 +128,6 @@ if ! echo "${_perms}" | grep -Eq '(ro|rw|rq|sw|xx)(,.*)?$'; then
error_notify "Detected invalid mount permissions in FSTAB."
warn "Format: /host/path /jail/path nullfs ro 0 0"
warn "Read: ${_fstab}"
usage
fi
# Dump and pass need to be "0 0 - 1 1"
@@ -138,21 +135,20 @@ if [ "${_checks}" != "0 0" ] && [ "${_checks}" != "1 0" ] && [ "${_checks}" != "
error_notify "Detected invalid fstab options in FSTAB."
warn "Format: /host/path /jail/path nullfs ro 0 0"
warn "Read: ${_fstab}"
usage
fi
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${_jail}]:"
_fullpath_fstab="$( echo "${bastille_jailsdir}/${_jail}/root/${_jailpath_fstab}" 2>/dev/null | sed 's#//#/#' )"
_fullpath="$( echo "${bastille_jailsdir}/${_jail}/root/${_jailpath}" 2>/dev/null | sed 's#//#/#' )"
_fstab_entry="${_hostpath_fstab} ${_fullpath_fstab} ${_type} ${_perms} ${_checks}"
@@ -199,7 +195,5 @@ for _jail in ${JAILS}; do
echo "${_fstab_entry}" >> "${bastille_jailsdir}/${_jail}/fstab" || error_continue "Failed to create fstab entry: ${_fstab_entry}"
mount -F "${bastille_jailsdir}/${_jail}/fstab" -a || error_continue "Failed to mount volume: ${_fullpath}"
echo "Added: ${_fstab_entry}"
done
echo
done

View File

@@ -118,7 +118,7 @@ while [ "$#" -gt 0 ]; do
P) PASSTHROUGH=1 ;;
V) VNET=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -135,7 +135,7 @@ INTERFACE="${3}"
if [ "${ACTION}" = "add" ] && [ "${NO_IP}" -eq 0 ] && [ -n "${4}" ]; then
IP="${4}"
elif [ "${NO_IP}" -eq 1 ] && [ -n "${4}" ]; then
error_notify "IP should not be present when using -n|--no-ip."
error_exit "[ERROR]: IP should not be present when using -n|--no-ip."
else
IP=""
fi
@@ -147,15 +147,15 @@ if [ "${ACTION}" = "add" ]; then
{ [ "${BRIDGE}" -eq 1 ] && [ "${CLASSIC}" -eq 1 ]; } || \
{ [ "${BRIDGE}" -eq 1 ] && [ "${PASSTHROUGH}" -eq 1 ]; } || \
{ [ "${CLASSIC}" -eq 1 ] && [ "${PASSTHROUGH}" -eq 1 ]; } then
error_notify "Error: Only one of [-B|--bridge], [-C|--classic], [-P|--passthrough] or [-V|--vnet] should be set."
error_exit "[ERROR]: Only one of [-B|--bridge], [-C|--classic], [-P|--passthrough] or [-V|--vnet] should be set."
elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${CLASSIC}" -eq 0 ] && [ "${PASSTHROUGH}" -eq 0 ]; then
error_notify "Error: [-B|--bridge], [-C|--classic], [-P|--passthrough] or [-V|--vnet] must be set."
error_exit "[ERROR]: [-B|--bridge], [-C|--classic], [-P|--passthrough] or [-V|--vnet] must be set."
elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${PASSTHROUGH}" -eq 0 ] && [ -n "${VLAN_ID}" ]; then
error_notify "VLANs can only be used with VNET interfaces."
error_exit "[ERROR]: VLANs can only be used with VNET interfaces."
elif [ "${VNET}" -eq 0 ] && [ "${BRIDGE}" -eq 0 ] && [ "${NO_IP}" -eq 1 ]; then
error_notify "[-n|--no-ip] can only be used with VNET jails."
error_exit "[ERROR]: [-n|--no-ip] can only be used with VNET jails."
elif [ "${bastille_network_vnet_type}" = "netgraph" ] && [ "${BRIDGE}" -eq 1 ]; then
error_notify "[-B|--bridge] cannot be used with Netgraph."
error_exit "[ERROR]: [-B|--bridge] cannot be used with Netgraph."
fi
fi
@@ -166,23 +166,26 @@ fi
bastille_root_check
set_target_single "${TARGET}"
# Validate jail state
check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-stopping ${TARGET}..."
bastille stop "${TARGET}"
else
else
info "\n[${_jail}]:"
error_notify "Jail is running."
error_exit "Use [-a|--auto] to auto-stop the jail."
fi
validate_ip() {
IP6_ENABLE=0
local ip="${1}"
local ip6="$( echo "${ip}" 2>/dev/null | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )"
if [ -n "${ip6}" ]; then
info "Valid: (${ip6})."
info "\nValid: (${ip6})."
IP6_ENABLE=1
elif [ "${ip}" = "0.0.0.0" ] || [ "${ip}" = "DHCP" ]; then
info "Valid: (${ip})."
info "\nValid: (${ip})."
else
local IFS
if echo "${ip}" 2>/dev/null | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then
@@ -194,7 +197,7 @@ validate_ip() {
error_exit "Invalid: (${TEST_IP})"
fi
done
info "Valid: (${ip})."
info "\nValid: (${ip})."
else
error_exit "Invalid: (${ip})."
fi
@@ -202,18 +205,22 @@ validate_ip() {
}
validate_netif() {
local _interface="${1}"
if ifconfig -l | grep -qwo ${_interface}; then
info "Valid: (${_interface})."
info "\nValid: (${_interface})."
else
error_exit "Invalid: (${_interface})."
fi
}
check_interface_added() {
local _jailname="${1}"
local _if="${2}"
local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf"
if grep -qo "${_if}" "${_jail_config}"; then
return 0
else
@@ -222,6 +229,7 @@ check_interface_added() {
}
add_interface() {
local _jailname="${1}"
local _if="${2}"
local _ip="${3}"
@@ -232,6 +240,7 @@ add_interface() {
local _vnet_if_count="$(grep -Eo 'vnet[1-9]+' ${_jail_rc_config} | sort -u | wc -l | awk '{print $1}')"
local _if_vnet="vnet$((_vnet_if_count + 1))"
local _bastille_if_num_range=$((_bastille_if_count + 1))
if [ "${BRIDGE}" -eq 1 ]; then
if [ "${_bastille_if_count}" -gt 0 ]; then
for _num in $(seq 0 "${_bastille_if_num_range}"); do
@@ -426,9 +435,11 @@ EOF
}
remove_interface() {
local _jailname="${1}"
local _if="${2}"
local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf"
# Skip next block in case of classic jail
if [ "$(bastille config ${TARGET} get vnet)" != "not set" ]; then
local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf"
@@ -452,31 +463,31 @@ remove_interface() {
local _if_jail="${_if}"
_if_type="passthrough"
else
error_exit "Could not find interface inside jail: \"${_if_jail}\""
error_exit "[ERROR]: Could not find interface inside jail: \"${_if_jail}\""
fi
if [ "${_if_type}" = "bastille" ] || [ "${_if_type}" = "epair" ]; then
if grep -oq "${_if_jail}" ${_jail_config}; then
local _if_vnet="$(grep ${_if_jail} ${_jail_rc_config} | grep -Eo 'vnet[0-9]+')"
else
error_exit "Interface not found: ${_if_jail}"
error_exit "[ERROR]: Interface not found: ${_if_jail}"
fi
elif [ "${_if_type}" = "passthrough" ]; then
if grep -oq "${_if_jail}" ${_jail_config}; then
local _if_vnet="${_if_jail}"
else
error_exit "Interface not found: ${_if_jail}"
error_exit "[ERROR]: Interface not found: ${_if_jail}"
fi
fi
# Do not allow removing default vnet0 interface
if [ "${_if_vnet}" = "vnet0" ]; then
error_exit "Default interface cannot be removed."
error_exit "[ERROR]: Default interface cannot be removed."
fi
# Avoid removing entire file contents if variables aren't set for some reason
if [ -z "${_if_jail}" ]; then
error_exit "Error: Could not find specifed interface."
error_exit "[ERROR]: Could not find specifed interface."
fi
# Remove interface from /etc/rc.conf
@@ -484,13 +495,13 @@ remove_interface() {
if [ -n "${_if_vnet}" ] && echo ${_if_vnet} 2>/dev/null | grep -Eoq 'vnet[0-9]+'; then
sed -i '' "/.*${_if_vnet}.*/d" "${_jail_rc_config}"
else
error_exit "Failed to remove interface from /etc/rc.conf"
error_exit "[ERROR]: Failed to remove interface from /etc/rc.conf"
fi
elif [ "${_if_type}" = "passthrough" ]; then
if [ -n "${_if_vnet}" ]; then
sed -i '' "/.*${_if_vnet}.*/d" "${_jail_rc_config}"
else
error_exit "Failed to remove interface from /etc/rc.conf"
error_exit "[ERROR]: Failed to remove interface from /etc/rc.conf"
fi
fi
@@ -507,18 +518,18 @@ remove_interface() {
sed -i '' "/.*${_if_jail}.*/d" "${_jail_config}"
fi
else
error_exit "Failed to remove interface from jail.conf"
error_exit "[ERROR]: Failed to remove interface from jail.conf"
fi
else
# Remove interface from jail.conf (non-VNET)
if [ -n "${_if}" ]; then
if grep ${_if} ${_jail_config} 2>/dev/null | grep -qo " = "; then
error_exit "Default interface cannot be removed."
error_exit "[ERROR]: Default interface cannot be removed."
else
sed -i '' "/.*${_if}.*/d" "${_jail_config}"
fi
else
error_exit "Failed to remove interface from jail.conf"
error_exit "[ERROR]: Failed to remove interface from jail.conf"
fi
fi
@@ -526,12 +537,14 @@ remove_interface() {
}
add_vlan() {
local _jailname="${1}"
local _interface="${2}"
local _ip="${3}"
local _vlan_id="${4}"
local _jail_config="${bastille_jailsdir}/${_jailname}/jail.conf"
local _jail_rc_config="${bastille_jailsdir}/${_jailname}/root/etc/rc.conf"
if [ "${VNET}" -eq 1 ]; then
local _jail_epair_num="$(grep ${_interface} ${_jail_config} | grep -Eo -m 1 "bastille[0-9]+" | grep -Eo "[0-9]+")"
local _jail_vnet="$(grep "e0b_bastille${_jail_epair_num}_name" ${_jail_rc_config} | grep -Eo "vnet[0-9]+")"
@@ -542,7 +555,7 @@ add_vlan() {
local _jail_vnet="${_interface}"
fi
if grep -Eq "ifconfig_${_jail_vnet}_${_vlan_id}" "${bastille_jailsdir}/${_jailname}/root/etc/rc.conf"; then
error_exit "VLAN has already been added: VLAN ${_vlan_id}"
error_exit "[ERROR]: VLAN has already been added: VLAN ${_vlan_id}"
else
bastille start "${_jailname}"
bastille template "${_jailname}" ${bastille_template_vlan} --arg VLANID="${_vlan_id}" --arg IFCONFIG="inet ${_ip}" --arg JAIL_VNET="${_jail_vnet}"
@@ -571,9 +584,9 @@ case "${ACTION}" in
fi
if [ "${VNET}" -eq 1 ]; then
if [ "$(bastille config ${TARGET} get vnet)" = "not set" ]; then
error_exit "Error: ${TARGET} is not a VNET jail."
error_exit "[ERROR]: ${TARGET} is not a VNET jail."
elif ifconfig -g bridge | grep -owq "${INTERFACE}"; then
error_exit "\"${INTERFACE}\" is a bridge interface."
error_exit "[ERROR]: '${INTERFACE}' is a bridge interface."
else
add_interface "${TARGET}" "${INTERFACE}" "${IP}"
if [ -n "${VLAN_ID}" ]; then
@@ -585,13 +598,13 @@ case "${ACTION}" in
fi
elif [ "${BRIDGE}" -eq 1 ]; then
if [ "$(bastille config ${TARGET} get vnet)" = "not set" ]; then
error_exit "Error: ${TARGET} is not a VNET jail."
error_exit "[ERROR]: ${TARGET} is not a VNET jail."
elif ! ifconfig -g bridge | grep -owq "${INTERFACE}"; then
error_exit "\"${INTERFACE}\" is not a bridge interface."
error_exit "[ERROR]: '${INTERFACE}' is not a bridge interface."
else
add_interface "${TARGET}" "${INTERFACE}" "${IP}"
if [ -n "${VLAN_ID}" ]; then
add_vlan "${TARGET}" "${INTERFACE}" "${IP}" "${VLAN_ID}"
if [ -n "${VLAN_ID}" ]; then
add_vlan "${TARGET}" "${INTERFACE}" "${IP}" "${VLAN_ID}"
fi
if [ "${AUTO}" -eq 1 ]; then
bastille start "${TARGET}"
@@ -599,7 +612,7 @@ case "${ACTION}" in
fi
elif [ "${PASSTHROUGH}" -eq 1 ]; then
if [ "$(bastille config ${TARGET} get vnet)" = "not set" ]; then
error_exit "Error: ${TARGET} is not a VNET jail."
error_exit "[ERROR]: ${TARGET} is not a VNET jail."
else
add_interface "${TARGET}" "${INTERFACE}" "${IP}"
fi
@@ -611,7 +624,7 @@ case "${ACTION}" in
fi
elif [ "${CLASSIC}" -eq 1 ]; then
if [ "$(bastille config ${TARGET} get vnet)" != "not set" ]; then
error_exit "Error: ${TARGET} is a VNET jail."
error_exit "[ERROR]: ${TARGET} is a VNET jail."
else
add_interface "${TARGET}" "${INTERFACE}" "${IP}"
if [ "${AUTO}" -eq 1 ]; then
@@ -624,7 +637,7 @@ case "${ACTION}" in
check_interface_added "${TARGET}" "${INTERFACE}" || error_exit "Interface not found in jail.conf: \"${INTERFACE}\""
validate_netif "${INTERFACE}"
if ! grep -q "${INTERFACE}" ${bastille_jailsdir}/${TARGET}/jail.conf; then
error_exit "Interface not found in jail.conf: \"${INTERFACE}\""
error_exit "[ERROR]: Interface not found in jail.conf: \"${INTERFACE}\""
else
remove_interface "${TARGET}" "${INTERFACE}"
if [ "${AUTO}" -eq 1 ]; then
@@ -633,6 +646,6 @@ case "${ACTION}" in
fi
;;
*)
error_exit "Only [add|remove] are supported."
error_exit "[ERROR]: Only [add|remove] are supported."
;;
esac
esac

View File

@@ -72,7 +72,7 @@ while [ "$#" -gt 0 ]; do
a) AUTO=1 ;;
H) USE_HOST_PKG=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -97,17 +97,19 @@ errors=0
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# Validate jail state
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
else
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_continue_next_jail "Use [-a|--auto] to auto-start the jail."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${_jail}]:"
bastille_jail_path="${bastille_jailsdir}/${_jail}/root"
if [ -f "/usr/sbin/mport" ]; then
if ! jexec -l -U root "${_jail}" /usr/sbin/mport "$@"; then
errors=1
@@ -129,7 +131,7 @@ for _jail in ${JAILS}; do
done
if [ $errors -ne 0 ]; then
error_exit "Failed to apply on some jails, please check logs"
fi
echo
error_exit "[ERROR]: Failed to apply on some jails, please check logs"
else
echo
fi

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
q) OPTION="-a" ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -93,5 +93,7 @@ host_path="${HOST_PATH}"
jail_path="$(echo ${bastille_jailsdir}/${TARGET}/root/${JAIL_PATH} | sed 's#//#/#g')"
if ! cp "${OPTION}" "${jail_path}" "${host_path}"; then
error_exit "RCP failed: ${jail_path} -> ${host_path}"
fi
error_exit "[ERROR]: RCP failed: ${jail_path} -> ${host_path}"
else
echo
fi

View File

@@ -49,10 +49,13 @@ EOF
}
check_jail_validity() {
# Validate jail network type and set IP4/6
if [ "$( bastille config ${TARGET} get vnet )" != 'enabled' ]; then
_ip4_interfaces="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')"
_ip6_interfaces="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')"
# Check if jail ip4.addr is valid (non-VNET only)
if [ "${_ip4_interfaces}" != "not set" ] && [ "${_ip4_interfaces}" != "disable" ]; then
if echo "${_ip4_interfaces}" | grep -q "|"; then
@@ -61,6 +64,7 @@ check_jail_validity() {
JAIL_IP="$(echo ${_ip4_interfaces} | sed -E 's#/[0-9]+$##g')"
fi
fi
# Check if jail ip6.addr is valid (non-VNET only)
if [ "${_ip6_interfaces}" != "not set" ] && [ "${_ip6_interfaces}" != "disable" ]; then
if echo "${_ip6_interfaces}" | grep -q "|"; then
@@ -70,20 +74,22 @@ check_jail_validity() {
fi
fi
else
error_exit "VNET jails do not support rdr."
error_exit "[ERROR]: VNET jails do not support rdr."
fi
# Check if rdr-anchor is defined in pf.conf
if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then
error_exit "rdr-anchor not found in pf.conf"
error_exit "[ERROR]: rdr-anchor not found in pf.conf"
fi
}
check_rdr_ip_validity() {
local ip="${1}"
local ip6="$( echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )"
if [ -n "${ip6}" ]; then
info "Valid: (${ip6})."
info "\nValid: (${ip6})."
else
local IFS
if echo "${ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then
@@ -95,7 +101,7 @@ check_rdr_ip_validity() {
error_exit "Invalid: (${TEST_IP})"
fi
done
info "Valid: (${ip})."
info "\nValid: (${ip})."
else
error_exit "Invalid: (${ip})."
fi
@@ -103,19 +109,22 @@ check_rdr_ip_validity() {
}
validate_rdr_rule() {
local if="${1}"
local src="${2}"
local dst="${3}"
local proto="${4}"
local host_port="${5}"
local jail_port="${6}"
if grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then
error_notify "Error: Ports already in use on this interface."
error_notify "[ERROR]: Ports already in use on this interface."
error_exit "See 'bastille list ports' or 'bastille rdr TARGET reset'."
fi
}
persist_rdr_rule() {
local inet="${1}"
local if="${2}"
local src="${3}"
@@ -123,12 +132,14 @@ persist_rdr_rule() {
local proto="${5}"
local host_port="${6}"
local jail_port="${7}"
if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then
echo "$inet $if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${TARGET}/rdr.conf"
fi
}
persist_rdr_log_rule() {
local inet="${1}"
local if="${2}"
local src="${3}"
@@ -138,12 +149,14 @@ persist_rdr_log_rule() {
local jail_port="${7}"
shift 7;
log=$@;
if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then
echo "$inet $if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${TARGET}/rdr.conf"
fi
}
load_rdr_rule() {
local inet="${1}"
local if_name="${2}"
local if=ext_if=\"${2}\"
@@ -152,13 +165,14 @@ load_rdr_rule() {
local proto="${5}"
local host_port="${6}"
local jail_port="${7}"
# Create IPv4 rdr rule
# shellcheck disable=SC2193
if { [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; } then
if ! ( pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null;
printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \
| pfctl -a "rdr/${TARGET}" -f-; then
error_exit "Failed to create IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\""
error_exit "[ERROR]: Failed to create IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\""
else
echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}"
fi
@@ -169,7 +183,7 @@ load_rdr_rule() {
if ! ( pfctl -a "rdr/${TARGET}" -Psn;
printf '%s\nrdr pass on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \
| pfctl -a "rdr/${TARGET}" -f-; then
error_exit "Failed to create IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\""
error_exit "[ERROR]: Failed to create IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\""
else
echo "IPv6 ${proto}/${host_port}:${jail_port} on ${if_name}"
fi
@@ -177,6 +191,7 @@ load_rdr_rule() {
}
load_rdr_log_rule() {
local inet="${1}"
local if_name="${2}"
local if=ext_if=\"${2}\"
@@ -187,24 +202,26 @@ load_rdr_log_rule() {
local jail_port="${7}"
shift 7;
log=$@
# Create IPv4 rule with log
# shellcheck disable=SC2193
if { [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; } then
if ! ( pfctl -a "rdr/${TARGET}" -Psn;
printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \
| pfctl -a "rdr/${TARGET}" -f-; then
error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\""
error_exit "[ERROR]: Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\""
else
echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}"
fi
fi
# Create IPv6 rdr rule with log (if ip6.addr is enabled)
# shellcheck disable=SC2193
if [ -n "${JAIL_IP6}" ] && { [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; } then
if ! ( pfctl -a "rdr/${TARGET}" -Psn;
printf '%s\nrdr pass %s on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \
| pfctl -a "rdr/${TARGET}" -f-; then
error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\""
error_exit "[ERROR]: Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\""
else
echo "IPv6 ${proto}/${host_port}:${jail_port} on ${if_name}"
fi
@@ -231,7 +248,7 @@ while [ "$#" -gt 0 ]; do
RDR_DST="${2}"
shift 2
else
error_exit "${2} is not an IP on this system."
error_exit "[ERROR]: '${2}' is not an IP on this system."
fi
;;
-i|--interface)
@@ -240,7 +257,7 @@ while [ "$#" -gt 0 ]; do
RDR_IF="${2}"
shift 2
else
error_exit "${2} is not a valid interface."
error_exit "[ERROR]: '${2}' is not a valid interface."
fi
;;
-s|--source)
@@ -251,7 +268,7 @@ while [ "$#" -gt 0 ]; do
;;
-t|--type)
if [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then
error_exit "[-t|--type] must be [ipv4|ipv6]"
error_exit "[ERROR]: [-t|--type] must be [ipv4|ipv6]"
else
OPTION_INET_TYPE=1
RDR_INET="${2}"
@@ -263,7 +280,7 @@ while [ "$#" -gt 0 ]; do
shift
;;
-*)
error_exit "Unknown option: \"${1}\""
error_exit "[ERROR]: Unknown option: \"${1}\""
;;
*)
break
@@ -283,13 +300,11 @@ shift
bastille_root_check
set_target_single "${TARGET}"
info "\n[${TARGET}]:"
while [ "$#" -gt 0 ]; do
case "${1}" in
list)
if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then
error_exit "Command \"${1}\" cannot be used with options."
error_exit "[ERROR]: Command \"${1}\" cannot be used with options."
elif [ -n "${2}" ]; then
usage
else
@@ -300,28 +315,26 @@ while [ "$#" -gt 0 ]; do
;;
clear)
if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then
error_exit "Command \"${1}\" cannot be used with options."
error_exit "[ERROR]: Command \"${1}\" cannot be used with options."
elif [ -n "${2}" ]; then
usage
else
check_jail_validity
echo "${TARGET} redirects:"
pfctl -a "rdr/${TARGET}" -Fn
fi
shift
;;
reset)
if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then
error_exit "Command \"${1}\" cannot be used with options."
error_exit "[ERROR]: Command \"${1}\" cannot be used with options."
elif [ -n "${2}" ]; then
usage
else
check_jail_validity
echo "${TARGET} redirects:"
pfctl -a "rdr/${TARGET}" -Fn
if rm -f "${bastille_jailsdir}/${TARGET}/rdr.conf"; then
if rm -f "${bastille_jailsdir}/${TARGET}/rdr.conf"; then
echo "rdr.conf removed"
fi
fi
fi
shift
;;
@@ -329,7 +342,7 @@ while [ "$#" -gt 0 ]; do
if [ "$#" -lt 3 ]; then
usage
elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_INET_TYPE}" -ne 1 ];then
error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]"
error_exit "[ERROR]: [-t|--type] must be set when using [-s|--source] or [-d|--destination]"
elif [ "$#" -eq 3 ]; then
check_jail_validity
validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3
@@ -401,6 +414,4 @@ while [ "$#" -gt 0 ]; do
fi
;;
esac
done
echo
done

View File

@@ -79,28 +79,33 @@ NEWNAME="${2}"
bastille_root_check
set_target_single "${TARGET}"
# Validate jail state
check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-stopping ${TARGET}..."
bastille stop "${TARGET}"
else
else
info "\n[${TARGET}]:"
error_notify "Jail is running."
error_exit "Use [-a|--auto] to auto-stop the jail."
fi
validate_name() {
local NAME_VERIFY="${NEWNAME}"
local NAME_SANITY="$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_')"
if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then
error_exit "Container names may not begin with (-|_) characters!"
error_exit "[ERROR]: Jail names may not begin with (-|_) characters!"
elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
error_exit "Container names may not contain special characters!"
error_exit "[ERROR]: Jail names may not contain special characters!"
fi
}
update_jailconf() {
# Update jail.conf
local _jail_conf="${bastille_jailsdir}/${NEWNAME}/jail.conf"
local _rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf"
if [ -f "${_jail_conf}" ]; then
if ! grep -qw "path = ${bastille_jailsdir}/${NEWNAME}/root;" "${_jail_conf}"; then
sed -i '' "s|host.hostname.*=.*${TARGET};|host.hostname = ${NEWNAME};|" "${_jail_conf}"
@@ -130,6 +135,7 @@ update_jailconf_vnet() {
for _if in ${_if_list}; do
if echo ${_if} | grep -Eoq 'epair[0-9]+'; then
# Check if epair name = jail name
local _epair_num="$(grep -Eo -m 1 "epair[0-9]+" "${_jail_conf}" | grep -Eo "[0-9]+")"
if grep -E "epair[0-9]+a" "${_jail_conf}" | grep -Eo "e[0-9]+a_${TARGET}"; then
@@ -139,6 +145,7 @@ update_jailconf_vnet() {
local _target_host_epair="$(grep -Eo -m 1 "epair[0-9]+a" "${_jail_conf}")"
local _target_jail_epair="$(grep -Eo -m 1 "epair[0-9]+b" "${_jail_conf}")"
fi
if [ "$(echo -n "e${_epair_num}a_${NEWNAME}" | awk '{print length}')" -lt 16 ]; then
# Generate new epair name
local _new_host_epair="e${_epair_num}a_${NEWNAME}"
@@ -147,18 +154,22 @@ update_jailconf_vnet() {
local _new_host_epair="epair${_epair_num}a"
local _new_jail_epair="epair${_epair_num}b"
fi
# Replace host epair name in jail.conf
sed -i '' "s|up name ${_target_host_epair}|up name ${_new_host_epair}|g" "${_jail_conf}"
sed -i '' "s|${_target_host_epair} ether|${_new_host_epair} ether|g" "${_jail_conf}"
sed -i '' "s|deletem ${_target_host_epair}|deletem ${_new_host_epair}|g" "${_jail_conf}"
sed -i '' "s|${_target_host_epair} destroy|${_new_host_epair} destroy|g" "${_jail_conf}"
sed -i '' "s|${_target_host_epair} description|${_new_host_epair} description|g" "${_jail_conf}"
# Replace jail epair name in jail.conf
sed -i '' "s|= ${_target_jail_epair};|= ${_new_jail_epair};|g" "${_jail_conf}"
sed -i '' "s|up name ${_target_jail_epair}|up name ${_new_jail_epair}|g" "${_jail_conf}"
sed -i '' "s|${_target_jail_epair} ether|${_new_jail_epair} ether|g" "${_jail_conf}"
# Replace epair description
sed -i '' "s|vnet host interface for Bastille jail ${TARGET}|vnet host interface for Bastille jail ${NEWNAME}|g" "${_jail_conf}"
# Replace epair name in /etc/rc.conf
sed -i '' "/ifconfig/ s|${_target_jail_epair}|${_new_jail_epair}|g" "${_rc_conf}"
fi
@@ -166,8 +177,8 @@ update_jailconf_vnet() {
}
change_name() {
# Attempt container name change
info "Attempting to rename '${TARGET}' to ${NEWNAME}..."
if checkyesno bastille_zfs_enable; then
if [ -n "${bastille_zfs_zpool}" ] && [ -n "${bastille_zfs_prefix}" ]; then
# Check and rename container ZFS dataset accordingly
@@ -191,10 +202,10 @@ change_name() {
ZFS_DATASET_TARGET=$(echo "${ZFS_DATASET_ORIGIN}" | sed "s|\/${TARGET}||")
if [ -n "${ZFS_DATASET_ORIGIN}" ] && [ -n "${ZFS_DATASET_TARGET}" ]; then
if ! zfs rename -f "${ZFS_DATASET_ORIGIN}" "${ZFS_DATASET_TARGET}/${NEWNAME}"; then
error_exit "Can't rename '${TARGET}' dataset."
error_exit "[ERROR]: Can't rename '${TARGET}' dataset."
fi
else
error_exit "Can't determine the ZFS origin path of '${TARGET}'."
error_exit "[ERROR]: Can't determine the ZFS origin path of '${TARGET}'."
fi
else
# Just rename the jail directory
@@ -208,9 +219,9 @@ change_name() {
# Check exit status and notify
if [ "$?" -ne 0 ]; then
error_exit "An error has occurred while attempting to rename '${TARGET}'."
error_exit "[ERROR]: An error has occurred while attempting to rename '${TARGET}'."
else
info "Renamed '${TARGET}' to '${NEWNAME}' successfully."
echo "Renamed '${TARGET}' to '${NEWNAME}' successfully."
if [ "${AUTO}" -eq 1 ]; then
bastille start "${NEWNAME}"
fi
@@ -224,9 +235,11 @@ fi
# Check if a jail already exists with NEW_NAME
if [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
error_exit "Jail: ${NEWNAME} already exists."
error_exit "[ERROR]: Jail: ${NEWNAME} already exists."
fi
info "\nAttempting to rename '${TARGET}' to ${NEWNAME}..."
change_name
echo
info "\nRenamed '${TARGET}' to '${NEWNAME}' successfully.\n"

View File

@@ -89,7 +89,7 @@ while [ "$#" -gt 0 ]; do
_stop_options="${_stop_options} -x"
;;
*)
error_exit "Unknown Option: \"${1}\""
error_exit "[ERROR]: Unknown Option: \"${1}\""
;;
esac
done
@@ -118,4 +118,4 @@ for _jail in ${JAILS}; do
bastille start ${_start_options} ${_jail}
fi
done
done

View File

@@ -49,7 +49,7 @@ EOF
AUTO=0
while [ "$#" -gt 0 ]; do
case "${1}" in
-h|--help|help)
-h|--help|help)
usage
;;
-a|--auto)
@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -88,18 +88,17 @@ set_target "${TARGET}"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# Validate jail state
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
else
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_continue_next_jail "Use [-a|--auto] to auto-start the jail."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${_jail}]:"
jexec -l "${_jail}" /usr/sbin/service "$@"
done
echo
done

View File

@@ -250,7 +250,7 @@ case "$1" in
configure_pf
;;
-n|netgraph)
warn "[WARNING] Bastille only allows using either 'if_bridge' or 'netgraph'"
warn "[WARNING]: Bastille only allows using either 'if_bridge' or 'netgraph'"
warn "as VNET network options. You CANNOT use both on the same system. If you have"
warn "already started using bastille with 'if_bridge' do not continue."
# shellcheck disable=SC3045
@@ -270,7 +270,7 @@ case "$1" in
;;
-l|loopback)
warn "[WARNING] Bastille only allows using either the 'loopback' or 'shared'"
warn "[WARNING]: Bastille only allows using either the 'loopback' or 'shared'"
warn "interface to be configured ant one time. If you continue, the 'shared'"
warn "interface will be disabled, and the 'loopback' interface will be used as default."
# shellcheck disable=SC3045
@@ -288,7 +288,7 @@ case "$1" in
esac
;;
-s|shared)
warn "[WARNING] Bastille only allows using either the 'loopback' or 'shared'"
warn "[WARNING]: Bastille only allows using either the 'loopback' or 'shared'"
warn "interface to be configured at one time. If you continue, the 'loopback'"
warn "interface will be disabled, and the shared interface will be used as default."
# shellcheck disable=SC3045
@@ -315,4 +315,7 @@ case "$1" in
configure_vnet
configure_bridge
;;
*)
error_exit "[ERROR]: Unknown option: \"${1}\""
;;
esac

View File

@@ -82,7 +82,7 @@ while [ "$#" -gt 0 ]; do
b) BOOT=1 ;;
v) OPTION="-v" ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -134,14 +134,14 @@ for _jail in ${JAILS}; do
fi
if ifconfig | grep "^${_if}:" >/dev/null; then
if ifconfig | grep -qwF "${_ip}"; then
warn "Warning: IP address (${_ip}) already in use, continuing..."
warn "[WARNING]: IP address (${_ip}) already in use, continuing..."
fi
## add ip to firewall table if it is not reachable through local interface (assumes NAT/rdr is needed)
if route -n get ${_ip} | grep "gateway" >/dev/null; then
pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}"
fi
else
error_continue "Error: ${_if} interface does not exist."
error_continue "[ERROR]: ${_if} interface does not exist."
fi
done
fi
@@ -157,14 +157,14 @@ for _jail in ${JAILS}; do
fi
if ifconfig | grep "^${_if}:" >/dev/null; then
if ifconfig | grep -qwF "${_ip}"; then
warn "Warning: IP address (${_ip}) already in use, continuing..."
warn "[WARNING]: IP address (${_ip}) already in use, continuing..."
fi
## add ip to firewall table if it is not reachable through local interface (assumes NAT/rdr is needed)
if route -n get ${_ip} | grep "gateway" >/dev/null; then
pfctl -q -t "${bastille_network_pf_table}" -T add "${_ip}"
fi
else
error_continue "Error: ${_if} interface does not exist."
error_continue "[ERROR]: ${_if} interface does not exist."
fi
done
fi
@@ -190,6 +190,4 @@ for _jail in ${JAILS}; do
# Delay between jail action
sleep "${DELAY_TIME}"
done
echo
done

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
v) OPTION="-v" ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -136,6 +136,4 @@ for _jail in ${JAILS}; do
done
fi
done
echo
done

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -88,16 +88,17 @@ set_target "${TARGET}"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# Validate jail state
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
else
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${_jail}]:"
jexec -l "${_jail}" /usr/sbin/sysrc "$@"
done
done

View File

@@ -56,7 +56,7 @@ while [ "$#" -gt 0 ]; do
shift
;;
-*)
error_exit "Unknown Option: \"${1}\""
error_exit "[ERROR]: Unknown Option: \"${1}\""
;;
*)
break
@@ -118,5 +118,4 @@ for _jail in ${JAILS}; do
;;
esac
done
done

View File

@@ -35,6 +35,7 @@
usage() {
error_notify "Usage: bastille template [option(s)] TARGET [--convert|project/template]"
cat << EOF
Options:
-a | --auto Auto mode. Start/stop jail(s) if required.
@@ -45,6 +46,7 @@ EOF
}
post_command_hook() {
_jail=$1
_cmd=$2
_args=$3
@@ -110,7 +112,7 @@ render() {
echo "Rendering File: ${_file_path}"
eval "sed -i '' ${ARG_REPLACEMENTS} '${_file_path}'"
else
warn "Path not found for render: ${2}"
warn "[WARNING]: Path not found for render: ${2}"
fi
}
@@ -123,7 +125,7 @@ line_in_file() {
echo "${_line}" >> "${_jailpath}/${_filepath}"
fi
else
warn "Path not found for line_in_file: ${_filepath}"
warn "[WARNING]: Path not found for line_in_file: ${_filepath}"
fi
}
@@ -131,13 +133,13 @@ line_in_file() {
AUTO=0
while [ "$#" -gt 0 ]; do
case "${1}" in
-h|--help|help)
usage
;;
-a|--auto)
AUTO=1
shift
;;
-h|--help|help)
usage
;;
-a|--auto)
AUTO=1
shift
;;
-x|--debug)
enable_debug
shift
@@ -147,7 +149,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -158,7 +160,7 @@ while [ "$#" -gt 0 ]; do
esac
done
if [ $# -lt 2 ]; then
if [ "$#" -lt 2 ]; then
usage
fi
@@ -175,11 +177,11 @@ bastille_root_check
# Special case conversion of hook-style template files into a Bastillefile. -- cwells
if [ "${TARGET}" = '--convert' ]; then
if [ -d "${TEMPLATE}" ]; then # A relative path was provided. -- cwells
cd "${TEMPLATE}" || error_exit "Failed to change to directory: ${TEMPLATE}"
cd "${TEMPLATE}" || error_exit "[ERROR]: Failed to change to directory: ${TEMPLATE}"
elif [ -d "${bastille_template}" ]; then
cd "${bastille_template}" || error_exit "Failed to change to directory: ${TEMPLATE}"
cd "${bastille_template}" || error_exit "[ERROR]: Failed to change to directory: ${TEMPLATE}"
else
error_exit "Template not found: ${TEMPLATE}"
error_exit "[ERROR]: Template not found: ${TEMPLATE}"
fi
echo "Converting template: ${TEMPLATE}"
@@ -217,7 +219,7 @@ if [ "${TARGET}" = '--convert' ]; then
fi
done
info "Template converted: ${TEMPLATE}"
info "\nTemplate converted: ${TEMPLATE}"
exit 0
else
set_target "${TARGET}"
@@ -229,7 +231,7 @@ case ${TEMPLATE} in
if [ ! -d "${bastille_templatesdir}/${TEMPLATE_DIR}" ]; then
info "Bootstrapping ${TEMPLATE}..."
if ! bastille bootstrap "${TEMPLATE}"; then
error_exit "Failed to bootstrap template: ${TEMPLATE}"
error_exit "[ERROR]: Failed to bootstrap template: ${TEMPLATE}"
fi
fi
TEMPLATE="${TEMPLATE_DIR}"
@@ -238,14 +240,14 @@ case ${TEMPLATE} in
*/*)
if [ ! -d "${bastille_templatesdir}/${TEMPLATE}" ]; then
if [ ! -d ${TEMPLATE} ]; then
error_exit "${TEMPLATE} not found."
error_exit "[ERROR]: ${TEMPLATE} not found."
else
bastille_template=${TEMPLATE}
fi
fi
;;
*)
error_exit "Template name/URL not recognized."
error_exit "[ERROR]: Template name/URL not recognized."
esac
# Check for an --arg-file parameter. -- cwells
@@ -265,22 +267,22 @@ for _script_arg in "$@"; do
done
if [ -n "${ARG_FILE}" ] && [ ! -f "${ARG_FILE}" ]; then
error_exit "File not found: ${ARG_FILE}"
error_exit "[ERROR]: File not found: ${ARG_FILE}"
fi
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
else
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${_jail}]:"
info "Applying template: ${TEMPLATE}..."
echo "Applying template: ${TEMPLATE}..."
## get jail ip4 and ip6 values
bastille_jail_path=$(/usr/sbin/jls -j "${_jail}" path)
@@ -406,7 +408,7 @@ for _jail in ${JAILS}; do
if ! eval "bastille ${_cmd} ${_jail} ${_args}"; then
set +f
unset IFS
error_exit "Failed to execute command: ${_cmd}"
error_exit "[ERROR]: Failed to execute command: ${_cmd}"
fi
post_command_hook "${_jail}" "${_cmd}" "${_args}"
@@ -450,9 +452,9 @@ for _jail in ${JAILS}; do
info "[${_jail}]:${_hook} -- START"
if [ "${_hook}" = 'CMD' ] || [ "${_hook}" = 'PRE' ]; then
bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || error_exit "Failed to execute command."
bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || error_exit "[ERROR]: Failed to execute command."
elif [ "${_hook}" = 'PKG' ]; then
bastille pkg "${_jail}" install -y "$(cat "${bastille_template}/PKG")" || error_exit "Failed to install packages."
bastille pkg "${_jail}" install -y "$(cat "${bastille_template}/PKG")" || error_exit "[ERROR]: Failed to install packages."
bastille pkg "${_jail}" audit -F
else
while read _line; do
@@ -462,7 +464,7 @@ for _jail in ${JAILS}; do
# Replace "arg" variables in this line with the provided values. -- cwells
_line=$(echo "${_line}" | eval "sed ${ARG_REPLACEMENTS}")
eval "_args=\"${_args_template}\""
bastille "${_cmd}" "${_jail}" "${_args}" || error_exit "Failed to execute command."
bastille "${_cmd}" "${_jail}" "${_args}" || error_exit "[ERROR]: Failed to execute command."
done < "${bastille_template}/${_hook}"
fi
info "[${_jail}]:${_hook} -- END"
@@ -470,8 +472,6 @@ for _jail in ${JAILS}; do
fi
done
info "Template applied: ${TEMPLATE}"
info "\nTemplate applied: ${TEMPLATE}"
done
echo
done

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\""
*) error_exit "[ERROR]: Unknown Option: \"${1}\""
esac
done
shift
@@ -85,16 +85,14 @@ TARGET="${1}"
bastille_root_check
set_target_single "${TARGET}"
info "\n[${TARGET}]:"
check_target_is_running "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${TARGET}..."
bastille start "${TARGET}"
else
else
info "\n[${TARGET}]:"
error_notify "Jail is not running."
error_exit "Use [-a|--auto] to auto-start the jail."
fi
jexec -l "${TARGET}" /usr/bin/top
info "\n[${TARGET}]:"
echo
jexec -l "${TARGET}" /usr/bin/top

View File

@@ -65,7 +65,7 @@ while [ "$#" -gt 0 ]; do
case ${_opt} in
a) AUTO=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\""
*) error_exit "[ERROR]: Unknown Option: \"${1}\""
esac
done
shift
@@ -88,17 +88,16 @@ set_target "${TARGET}"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# Validate jail state
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
info "\n[${TARGET}]:"
error_notify "Jail is not running."
error_continue "Use [-a|--auto] to auto-start the jail."
fi
info "[${_jail}]:"
info "\n[${_jail}]:"
_jailpath="$( echo "${bastille_jailsdir}/${_jail}/root/${MOUNT_PATH}" 2>/dev/null | sed 's#//#/#' | sed 's#\\##g')"
_mount="$( mount | grep -Eo "[[:blank:]]${_jailpath}[[:blank:]]" )"
@@ -107,18 +106,18 @@ for _jail in ${JAILS}; do
# Exit if mount point non-existent
if [ -z "${_mount}" ] && [ -z "${_fstab_entry}" ]; then
error_continue "The specified mount point does not exist."
error_continue "[ERROR]: The specified mount point does not exist."
fi
# Unmount
if [ -n "${_mount}" ]; then
umount "${_jailpath}" || error_continue "Failed to unmount volume: ${MOUNT_PATH}"
umount "${_jailpath}" || error_continue "[ERROR]: Failed to unmount volume: ${MOUNT_PATH}"
fi
# Remove entry from fstab
if [ -n "${_fstab_entry}" ]; then
if ! sed -E -i '' "\, +${_jailpath_fstab} +,d" "${bastille_jailsdir}/${_jail}/fstab"; then
error_continue "Failed to delete fstab entry: ${MOUNT_PATH}"
error_continue "[ERROR]: Failed to delete fstab entry: ${MOUNT_PATH}"
fi
fi
@@ -129,6 +128,4 @@ for _jail in ${JAILS}; do
echo "Unmounted: ${_jailpath}"
done
echo
done

View File

@@ -75,7 +75,7 @@ while [ "$#" -gt 0 ]; do
a) AUTO=1 ;;
f) OPTION="-F" ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -91,12 +91,11 @@ TARGET="${1}"
bastille_root_check
if [ -f "/bin/midnightbsd-version" ]; then
echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}"
exit 1
error_exit "[ERROR]: Not yet supported on MidnightBSD."
fi
if freebsd-version | grep -qi HBSD; then
error_exit "Not yet supported on HardenedBSD."
error_exit "[ERROR]: Not yet supported on HardenedBSD."
fi
# Check for alternate/unsupported archs
@@ -107,31 +106,38 @@ arch_check() {
}
jail_check() {
# Check if the jail is thick and is running
set_target_single "${TARGET}"
check_target_is_running "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${TARGET}..."
bastille start "${TARGET}"
else
info "\n[${TARGET}]:"
error_notify "Jail is not running."
error_exit "Use [-a|--auto] to auto-start the jail."
fi
info "\n[${TARGET}]:"
if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir}/${TARGET}/fstab"; then
error_notify "${TARGET} is not a thick container."
error_notify "[ERROR]: ${TARGET} is not a thick container."
error_exit "See 'bastille update RELEASE' to update thin jails."
fi
}
jail_update() {
local _jailname="${1}"
local _jailpath="${bastille_jailsdir}/${TARGET}/root"
local _freebsd_update_conf="${_jailpath}/etc/freebsd-update.conf"
local _workdir="${_jailpath}/var/db/freebsd-update"
# Update a thick container
if [ -d "${bastille_jailsdir}/${TARGET}" ]; then
CURRENT_VERSION=$(/usr/sbin/jexec -l "${TARGET}" freebsd-version 2>/dev/null)
if [ -z "${CURRENT_VERSION}" ]; then
error_exit "Can't determine '${TARGET}' version."
error_exit "[ERROR]: Can't determine '${TARGET}' version."
else
env PAGER="/bin/cat" freebsd-update ${OPTION} \
--not-running-from-cron \
@@ -144,9 +150,11 @@ jail_update() {
}
release_update() {
local _releasepath="${bastille_releasesdir}/${TARGET}"
local _freebsd_update_conf="${_releasepath}/etc/freebsd-update.conf"
local _workdir="${_releasepath}/var/db/freebsd-update"
# Update a release base(affects child containers)
if [ -d "${_releasepath}" ]; then
TARGET_TRIM="${TARGET}"
@@ -166,29 +174,32 @@ release_update() {
-f "${_freebsd_update_conf}" \
install --currently-running "${TARGET_TRIM}"
else
error_exit "${TARGET} not found. See 'bastille bootstrap RELEASE'."
error_exit "[ERROR]: ${TARGET} not found. See 'bastille bootstrap RELEASE'."
fi
}
template_update() {
# Update a template
_template_path=${bastille_templatesdir}/${BASTILLE_TEMPLATE}
if [ -d $_template_path ]; then
info "[${BASTILLE_TEMPLATE}]:"
git -C $_template_path pull ||\
error_notify "${BASTILLE_TEMPLATE} update unsuccessful."
if [ -d $_template_path ]; then
info "\n[${BASTILLE_TEMPLATE}]:"
if ! git -C $_template_path pull; then
error_exit "[ERROR]: ${BASTILLE_TEMPLATE} update unsuccessful."
fi
bastille verify "${BASTILLE_TEMPLATE}"
else
error_exit "${BASTILLE_TEMPLATE} not found. See 'bastille bootstrap'."
error_exit "[ERROR]: ${BASTILLE_TEMPLATE} not found. See 'bastille bootstrap'."
fi
}
templates_update() {
# Update all templates
_updated_templates=0
if [ -d ${bastille_templatesdir} ]; then
# shellcheck disable=SC2045
# shellcheck disable=SC2045
for _template_path in $(ls -d ${bastille_templatesdir}/*/*); do
if [ -d $_template_path/.git ]; then
BASTILLE_TEMPLATE=$(echo "$_template_path" | awk -F / '{ print $(NF-1) "/" $NF }')
@@ -200,9 +211,9 @@ templates_update() {
fi
if [ "$_updated_templates" -ne "0" ]; then
info "$_updated_templates templates updated."
info "\n$_updated_templates templates updated."
else
error_exit "no templates found. See 'bastille bootstrap'."
error_exit "[ERROR]: No templates found. See 'bastille bootstrap'."
fi
}
@@ -216,9 +227,6 @@ elif echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then
arch_check
release_update
else
info "\n[${TARGET}]:"
jail_check
jail_update "${TARGET}"
fi
echo
fi

View File

@@ -72,7 +72,7 @@ while [ "$#" -gt 0 ]; do
a) AUTO=1 ;;
f) OPTION="-F" ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
esac
done
shift
@@ -95,55 +95,63 @@ set_target_single "${TARGET}"
# Check for unsupported actions
if [ -f "/bin/midnightbsd-version" ]; then
echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}"
exit 1
error_exit "[ERROR]: Not yet supported on MidnightBSD."
fi
if freebsd-version | grep -qi HBSD; then
error_exit "Not yet supported on HardenedBSD."
error_exit "[ERROR]: Not yet supported on HardenedBSD."
fi
thick_jail_check() {
local _jail="${1}"
# Check if the jail is thick and is running
# Validate jail state
check_target_is_running "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-starting ${_jail}..."
bastille start "${_jail}"
else
info "\n[${_jail}]:"
error_notify "Jail is not running."
error_exit "Use [-a|--auto] to auto-start the jail."
fi
}
thin_jail_check() {
local _jail="${1}"
# Check if the jail is thick and is running
# Validate jail state
check_target_is_stopped "${_jail}" || if [ "${AUTO}" -eq 1 ]; then
echo "Auto-stopping ${_jail}..."
bastille stop "${_jail}"
else
info "\n[${_jail}]:"
error_notify "Jail is running."
error_exit "Use [-a|--auto] to auto-stop the jail."
fi
}
release_check() {
local _release="${1}"
# Validate the release
if ! echo "${_release}" | grep -q "[0-9]\{2\}.[0-9]-[RELEASE,BETA,RC]"; then
error_exit "${_release} is not a valid release."
error_exit "[ERROR]: ${_release} is not a valid release."
fi
# Exit if NEWRELEASE doesn't exist
if [ "${THIN_JAIL}" -eq 1 ]; then
if [ ! -d "${bastille_releasesdir}/${_release}" ]; then
error_notify "Release not found: ${_release}"
error_notify "[ERROR]: Release not found: ${_release}"
error_exit "See 'bastille bootstrap ${_release} to bootstrap the release."
fi
fi
}
jail_upgrade() {
local _jailname="${1}"
if [ "${THIN_JAIL}" -eq 1 ]; then
local _oldrelease="$(bastille config ${_jailname} get osrelease)"
else
@@ -166,8 +174,8 @@ jail_upgrade() {
if [ "${AUTO}" -eq 1 ]; then
bastille start "${_jailname}"
fi
info "Upgraded ${_jailname}: ${_oldrelease} -> ${_newrelease}"
info "See 'bastille etcupdate TARGET' to update /etc/rc.conf"
info "\nUpgraded ${_jailname}: ${_oldrelease} -> ${_newrelease}"
echo "See 'bastille etcupdate TARGET' to update /etc/rc.conf"
else
# Upgrade a thick jail
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron \
@@ -179,16 +187,17 @@ jail_upgrade() {
# Update "osrelease" entry inside jail.conf
sed -i '' "/osrelease/ s|${_oldrelease}|${_newrelease}|g" "${bastille_jailsdir}/${_jailname}/jail.conf"
echo
echo -e "${COLOR_YELLOW}Please run 'bastille upgrade ${_jailname} install', restart the jail, then run 'bastille upgrade ${_jailname} install' again to finish installing updates.${COLOR_RESET}"
warn "Please run 'bastille upgrade ${_jailname} install', restart the jail, then run 'bastille upgrade ${_jailname} install' again to finish installing updates."
fi
}
jail_updates_install() {
local _jailname="${1}"
local _jailpath="${bastille_jailsdir}/${_jailname}/root"
local _workdir="${_jailpath}/var/db/freebsd-update"
local _freebsd_update_conf="${_jailpath}/etc/freebsd-update.conf"
# Finish installing upgrade on a thick container
if [ -d "${bastille_jailsdir}/${_jailname}" ]; then
env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron \
@@ -197,7 +206,7 @@ jail_updates_install() {
-f "${_freebsd_update_conf}" \
install
else
error_exit "${TARGET} not found. See 'bastille bootstrap RELEASE'."
error_exit "[ERROR]: ${_jailname} not found. See 'bastille bootstrap RELEASE'."
fi
}
@@ -207,8 +216,6 @@ if grep -qw "${bastille_jailsdir}/${TARGET}/root/.bastille" "${bastille_jailsdir
THIN_JAIL=1
fi
info "\n[${TARGET}]:"
# Check what we should upgrade
if [ "${NEWRELEASE}" = "install" ]; then
if [ "${THIN_JAIL}" -eq 1 ]; then
@@ -216,6 +223,7 @@ if [ "${NEWRELEASE}" = "install" ]; then
else
thick_jail_check "${TARGET}"
fi
info "\n[${TARGET}]:"
jail_updates_install "${TARGET}"
else
release_check "${NEWRELEASE}"
@@ -224,7 +232,6 @@ else
else
thick_jail_check "${TARGET}"
fi
info "\n[${TARGET}]:"
jail_upgrade "${TARGET}" "${NEWRELEASE}"
fi
echo
fi

View File

@@ -45,22 +45,24 @@ EOF
}
verify_release() {
if [ -f "/bin/midnightbsd-version" ]; then
echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}"
exit 1
error_exit "[ERROR]: Not yet supported on MidnightBSD."
fi
if freebsd-version | grep -qi HBSD; then
error_exit "Not yet supported on HardenedBSD."
error_exit "[ERROR]: Not yet supported on HardenedBSD."
fi
if [ -d "${bastille_releasesdir}/${RELEASE}" ]; then
freebsd-update -b "${bastille_releasesdir}/${RELEASE}" --currently-running "${RELEASE}" IDS
else
error_exit "${RELEASE} not found. See 'bastille bootstrap'."
error_exit "[ERROR]: ${RELEASE} not found. See 'bastille bootstrap'."
fi
}
handle_template_include() {
case ${TEMPLATE_INCLUDE} in
http?://*/*/*)
bastille bootstrap "${TEMPLATE_INCLUDE}"
@@ -71,12 +73,13 @@ handle_template_include() {
bastille verify "${BASTILLE_TEMPLATE_USER}/${BASTILLE_TEMPLATE_REPO}"
;;
*)
error_exit "Template INCLUDE content not recognized."
error_exit "[ERROR]: Template INCLUDE content not recognized."
;;
esac
}
verify_template() {
_template_path=${bastille_templatesdir}/${BASTILLE_TEMPLATE}
_hook_validate=0
@@ -84,22 +87,20 @@ verify_template() {
_path=${_template_path}/${_hook}
if [ -s "${_path}" ]; then
_hook_validate=$((_hook_validate+1))
info "Detected ${_hook} hook."
info "\nDetected ${_hook} hook."
## line count must match newline count
# shellcheck disable=SC2046
# shellcheck disable=SC3003
if [ $(wc -l "${_path}" | awk '{print $1}') -ne "$(tr -d -c '\n' < "${_path}" | wc -c)" ]; then
info "[${_hook}]:"
error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]."
error_notify "[ERROR]: ${BASTILLE_TEMPLATE}:${_hook} [failed]."
error_notify "Line numbers don't match line breaks."
echo
error_exit "Template validation failed."
## if INCLUDE; recursive verify
elif [ "${_hook}" = 'INCLUDE' ]; then
info "[${_hook}]:"
cat "${_path}"
echo
while read _include; do
info "[${_hook}]:[${_include}]:"
TEMPLATE_INCLUDE="${_include}"
@@ -110,7 +111,6 @@ verify_template() {
elif [ "${_hook}" = 'OVERLAY' ]; then
info "[${_hook}]:"
cat "${_path}"
echo
while read _dir; do
info "[${_hook}]:[${_dir}]:"
if [ -x "/usr/local/bin/tree" ]; then
@@ -118,7 +118,6 @@ verify_template() {
else
find "${_template_path}/${_dir}" -print | sed -e 's;[^/]*/;|___;g;s;___|; |;g'
fi
echo
done < "${_path}"
elif [ "${_hook}" = 'Bastillefile' ]; then
info "[${_hook}]:"
@@ -131,41 +130,38 @@ verify_template() {
handle_template_include
fi
done < "${_path}"
echo
else
info "[${_hook}]:"
cat "${_path}"
echo
fi
fi
done
## remove bad templates
# Remove bad templates
if [ "${_hook_validate}" -lt 1 ]; then
error_notify "No valid template hooks found."
error_notify "Template discarded."
rm -rf "${_template_path}"
exit 1
error_notify "[ERROR]: No valid template hooks found."
error_exit "Template discarded."
fi
## if validated; ready to use
if [ "${_hook_validate}" -gt 0 ]; then
info "Template ready to use."
info "\nTemplate ready to use."
fi
}
# Handle options.
while [ "$#" -gt 0 ]; do
case "${1}" in
-h|--help|help)
usage
;;
-h|--help|help)
usage
;;
-x|--debug)
enable_debug
shift
;;
-*)
error_exit "Unknown Option: \"${1}\""
error_exit "[ERROR]: Unknown Option: \"${1}\""
;;
*)
break
@@ -200,4 +196,4 @@ case "${1}" in
;;
esac
echo
echo

View File

@@ -45,54 +45,65 @@ EOF
}
zfs_snapshot() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# shellcheck disable=SC2140
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
# shellcheck disable=SC2140
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
done
done
}
zfs_destroy_snapshot() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# shellcheck disable=SC2140
zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
# shellcheck disable=SC2140
zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
done
done
}
zfs_set_value() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
done
done
}
zfs_get_value() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
zfs get "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
zfs get "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
done
done
}
zfs_disk_usage() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
done
done
}
@@ -107,7 +118,7 @@ while [ "$#" -gt 0 ]; do
shift
;;
-*)
error_notify "Unknown Option: \"${1}\""
error_notify "[ERROR]: Unknown Option: \"${1}\""
usage
;;
*)
@@ -128,12 +139,12 @@ set_target "${TARGET}"
# Check if ZFS is enabled
if ! checkyesno bastille_zfs_enable; then
error_exit "ZFS not enabled."
error_exit "[ERROR]: ZFS not enabled."
fi
# Check if zpool is defined
if [ -z "${bastille_zfs_zpool}" ]; then
error_exit "ZFS zpool not defined."
error_exit "[ERROR]: ZFS zpool not defined."
fi
case "${ACTION}" in
@@ -159,6 +170,4 @@ case "${ACTION}" in
*)
usage
;;
esac
echo
esac