line refactor clone,config,bootstrap,verify,zfs

This commit is contained in:
tschettervictor
2025-05-01 12:38:14 -06:00
parent ef53f34574
commit 8ffab02c85
5 changed files with 100 additions and 66 deletions

View File

@@ -114,7 +114,7 @@ validate_ip() {
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 "\nValid: (${IP})."
@@ -130,7 +130,7 @@ validate_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 "\nValid: (${IP})."
fi
@@ -382,7 +382,10 @@ update_jailconf_vnet() {
clone_jail() {
if ! [ -d "${bastille_jailsdir}/${NEWNAME}" ]; then
if checkyesno bastille_zfs_enable; then
# Validate jail state
if [ "${LIVE}" -eq 1 ]; then
if ! check_target_is_running "${TARGET}"; then
error_exit "[-l|--live] can only be used with a running jail."

View File

@@ -115,7 +115,9 @@ 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
@@ -242,4 +244,4 @@ if { [ "${ACTION}" = "set" ] || [ "${ACTION}" = "remove" ]; } && [ -z "${BASTILL
info "A restart is required for the changes to be applied. See 'bastille restart'."
fi
exit 0
exit 0

View File

@@ -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,8 +60,10 @@ 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!"
elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then
@@ -71,14 +74,16 @@ validate_name() {
}
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 +95,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 +120,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 +157,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})."
fi
}
validate_release() {
## ensure the user set the Linux(experimental) option explicitly
if [ -n "${UBUNTU}" ]; then
if [ -z "${LINUX_JAIL}" ]; then
@@ -185,6 +199,7 @@ validate_release() {
}
generate_minimal_conf() {
cat << EOF > "${bastille_jail_conf}"
${NAME} {
host.hostname = ${NAME};
@@ -196,6 +211,7 @@ EOF
}
generate_jail_conf() {
if [ "$(sysctl -n security.jail.jailed)" -eq 1 ]; then
devfs_ruleset_value=0
else
@@ -224,6 +240,7 @@ EOF
}
generate_linux_jail_conf() {
cat << EOF > "${bastille_jail_conf}"
${NAME} {
host.hostname = ${NAME};
@@ -247,12 +264,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 +294,7 @@ EOF
}
post_create_jail() {
# Common config checks and settings.
# Using relative paths here.
@@ -310,6 +331,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
@@ -487,7 +509,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 +571,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
@@ -778,16 +800,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."
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 +817,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 +829,7 @@ else
fi
fi
## validate jail name
# Validate jail name
if [ -n "${NAME}" ]; then
validate_name
fi
@@ -813,11 +837,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 +877,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 +961,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 +987,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 +1029,7 @@ if [ -z ${bastille_template_vnet+x} ]; then
fi
if check_target_exists "${NAME}"; then
error_exit "Error: Existing jail found: ${NAME}"
error_exit "[ERROR]: Jail already exists: ${NAME}"
fi
create_jail "${NAME}" "${RELEASE}" "${IP}" "${INTERFACE}"

View File

@@ -47,9 +47,9 @@ EOF
verify_release() {
if [ -f "/bin/midnightbsd-version" ]; then
echo -e "${COLOR_RED}Not yet supported on MidnightBSD.${COLOR_RESET}"
exit 1
error_exit "Not yet supported on MidnightBSD."
fi
if freebsd-version | grep -qi HBSD; then
error_exit "Not yet supported on HardenedBSD."
fi
@@ -96,13 +96,11 @@ verify_template() {
info "[${_hook}]:"
error_notify "${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}"
@@ -113,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
@@ -121,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}]:"
@@ -134,21 +130,18 @@ 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 "No valid template hooks found."
error_exit "Template discarded."
fi
## if validated; ready to use
@@ -160,9 +153,9 @@ verify_template() {
# Handle options.
while [ "$#" -gt 0 ]; do
case "${1}" in
-h|--help|help)
usage
;;
-h|--help|help)
usage
;;
-x|--debug)
enable_debug
shift
@@ -201,4 +194,4 @@ case "${1}" in
*)
usage
;;
esac
esac

View File

@@ -45,54 +45,65 @@ EOF
}
zfs_snapshot() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# shellcheck disable=SC2140
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
# shellcheck disable=SC2140
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
done
done
}
zfs_destroy_snapshot() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
# shellcheck disable=SC2140
zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
# shellcheck disable=SC2140
zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}"
done
done
}
zfs_set_value() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
done
done
}
zfs_get_value() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
zfs get "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
zfs get "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
done
done
}
zfs_disk_usage() {
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
for _jail in ${JAILS}; do
info "\n[${_jail}]:"
zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"
done
done
}