mirror of
https://github.com/hackacad/bastille.git
synced 2025-12-29 08:50:34 +01:00
Merge pull request #995 from BastilleBSD/final-blank-line
Refactor line spacing on all commands
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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}"
|
||||
|
||||
@@ -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
|
||||
@@ -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}"
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user