From 837c77ee73a60ae646dc3e803a92fdb1727cfa13 Mon Sep 17 00:00:00 2001 From: JRGTH Date: Fri, 27 Jun 2025 03:07:49 -0400 Subject: [PATCH 01/12] [Enhancement] 'Bastille zfs command' [Enhancement] 'Bastille zfs command' Here is the proposed `zfs` comand enhancement proposed here: https://github.com/BastilleBSD/bastille/pull/1163 --- usr/local/bin/bastille | 4 +- usr/local/share/bastille/list.sh | 20 +++- usr/local/share/bastille/zfs.sh | 153 ++++++++++++++++++++++++++++--- 3 files changed, 163 insertions(+), 14 deletions(-) mode change 100755 => 100644 usr/local/bin/bastille diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille old mode 100755 new mode 100644 index 5acdf342..f6d09ad8 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -32,7 +32,7 @@ PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin -BASTILLE_VERSION=0.14.20250420 +BASTILLE_VERSION="0.14.20250420" # Validate config file # Copy default when 'setup' is called @@ -114,7 +114,7 @@ Available Commands: update Update container base -pX release. upgrade Upgrade container release to X.Y-RELEASE. verify Compare release against a "known good" index. - zfs Manage (get|set) ZFS attributes on targeted container(s). + zfs Manage (get|set) ZFS attributes or snapshots on targeted container(s). Use "bastille -v|--version" for version information. Use "bastille command -h|--help" for more information about a command. diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 387c420e..25c1ddb4 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -34,7 +34,7 @@ usage() { error_notify "Usage: bastille list [option(s)] [RELEASE (-p)] [all] [backup(s)] [export(s)] [import(s)] [ip(s)] [jail(s)] [limit(s)] [log(s)]" - error_notify " [path(s)] [port(s)] [prio|priority] [release(s)] [state(s)] [template(s)]" + error_notify " [path(s)] [port(s)] [prio|priority] [release(s)] [snapshot(s)] [state(s)] [template(s)]" cat << EOF Options: @@ -606,6 +606,20 @@ list_release(){ fi } +list_snapshot(){ + # TODO: Avility to list snapshot data for a single target. + # List snapshots with its usage data for valid bastille jails only. + if [ -d "${bastille_jailsdir}" ]; then + JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") + for _JAIL in ${JAIL_LIST}; do + if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then + info "\n[${_JAIL}]:" + zfs list -r -t snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_JAIL}" + fi + done + fi +} + list_template(){ find "${bastille_templatesdir}" -type d -maxdepth 2 | sed "s#${bastille_templatesdir}/##g" } @@ -767,6 +781,10 @@ if [ "$#" -eq 1 ]; then release|releases) list_release "${2}" ;; + snapshot|snapshots) + list_snapshot + exit 0 + ;; template|templates) list_template ;; diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index bcf69dcb..26015dc7 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -33,20 +33,33 @@ . /usr/local/share/bastille/common.sh usage() { - error_notify "Usage: bastille zfs [option(s)] TARGET [destroy_snap|(df|usage)|get|set|(snap|snapshot)] [key=value|date]" + + error_notify "Usage: bastille zfs [option(s)] TARGET [destroy|(df|usage)|get|set|(snap|snapshot)] [key=value|date]" error_notify " [jail pool/dataset /jail/path]" error_notify " [unjail pool/dataset]" cat << EOF - Options: - -x | --debug Enable debug mode. + snapshot Create a ZFS snapshot for the specified container. + rollback Rollback a ZFS snapshot on the specified container. + destroy Destroy a ZFS snapshot on the specified container. + -a | --auto Auto mode. Start/stop jail(s) if required. + -v | --verbose Be more verbose during the snapshot destroy operation. + -n | --dryrun Do a dry-run(no actual deletion) to determine what data would be deleted. + -x | --debug Enable debug mode. EOF exit 1 } +AUTO="0" +SNAP_NAME_GEN= +SNAP_CREATE= +SNAP_ROLLBACK= +SNAP_DESTROY= +SNAP_VERBOSE= + zfs_jail_dataset() { info "\n[${_jail}]:" @@ -121,17 +134,26 @@ zfs_snapshot() { info "\n[${_jail}]:" # shellcheck disable=SC2140 zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" + _return=$? +} + +zfs_rollback() { + info "\n[${_jail}]:" + # shellcheck disable=SC2140 + zfs rollback -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}"@"${TAG}" + _return=$? } zfs_destroy_snapshot() { info "\n[${_jail}]:" # shellcheck disable=SC2140 - zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" + zfs destroy ${_opts} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" + _return=$? } zfs_set_value() { info "\n[${_jail}]:" - zfs "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}" + zfs set "${ATTRIBUTE}" "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}" } zfs_get_value() { @@ -144,8 +166,7 @@ zfs_disk_usage() { zfs list -t all -o name,used,avail,refer,mountpoint,compress,ratio -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}" } -# Handle options. -AUTO=0 +# Handle some options. while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) @@ -155,6 +176,10 @@ while [ "$#" -gt 0 ]; do AUTO=1 shift ;; + -v|--verbose) + SNAP_VERBOSE="1" + shift + ;; -x|--debug) enable_debug shift @@ -195,14 +220,116 @@ if [ -z "${bastille_zfs_zpool}" ]; then error_exit "[ERROR]: ZFS zpool not defined." fi +snapshot_checks() { + # Check if jail is running and stop if requested. + if [ -z "${SNAP_DESTROY}" ]; then + check_target_is_stopped "${_jail}" || \ + if [ "${AUTO}" -eq 1 ]; then + bastille stop "${_jail}" + fi + fi + + # Check existence for the given snapshot. + if [ -n "${SNAP_ROLLBACK}" ] || [ -n "${SNAP_DESTROY}" ]; then + if [ -n "${TAG}" ]; then + # Early warning about missing snapshot parent dataset for reference, this may happen when + # more recent snapshots were deleted by either, intentional or automatically. + if ! zfs list -t snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG}" >/dev/null 2>&1; then + info "\n[${_jail}]:" + warn "[WARNING]: Either snapshot '${TAG}' not exist or parent dataset appears to be missing." + fi + fi + elif [ -n "${SNAP_CREATE}" ]; then + if zfs list -t snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG}" >/dev/null 2>&1; then + info "\n[${_jail}]:" + warn "[WARNING]: Looks like the snapshot '${TAG}' already exist, See 'bastille list snapshot'." + fi + fi + + # Generate a relatively short but unique name for the snapshots based on the current date/jail name. + if [ -n "${SNAP_NAME_GEN}" ]; then + DATE=$(date +%F-%H%M%S) + NAME_MD5X6=$(echo "${DATE} ${TARGET}" | md5 | cut -b -6) + SNAPSHOT_NAME="Bastille_${NAME_MD5X6}_${TARGET}_${DATE}" + TAG="${SNAPSHOT_NAME}" + fi +} + +snapshot_create() { + # Attempt to snapshot the container. + # Thiw will create a ZFS snapshot for the specified container with an auto-generated name with the + # following format "Bastille_XXXXXX_JAILNAME_YYYY-MM-DD-HHMMSS" unless a name tag is manually entered. + SNAP_CREATE="1" + if [ -z "${TAG}" ]; then + SNAP_NAME_GEN="1" + fi + + snapshot_checks + zfs_snapshot + + # Check for exit status and notify only for user reference. + if [ "${_return}" -ne 0 ]; then + error_notify "[ERROR]: Failed to snapshot jail: '${_jail}'" + else + info "Snapshot for ${_jail} successfully created as '${TAG}'." + fi + + # Start the jail after snapshot if requested. + if [ "${AUTO}" -eq 1 ]; then + bastille start "${_jail}" + fi +} + +snapshot_rollback() { + # This feature is intended work with snapshots created by either, bastille or manually created byu the user. + # An error about "more recent snapshots or bookmarks exist" will appears if the '-r' flag is not specified. + SNAP_ROLLBACK="1" + snapshot_checks + zfs_rollback + + # Check for exit status and just notify. + if [ "${_return}" -ne 0 ]; then + error_notify "[ERROR]: Failed to restore '${TAG}' snapshot for '${_jail}'." + else + info "Snapshot '${TAG}' successfully rolled back for '${_jail}'." + fi + + # Start the jail after rollback if requested. + if [ "${AUTO}" -eq 1 ]; then + bastille start "${_jail}" + fi +} + +snapshot_destroy() { + # Destroy the user specifier bastille snapshot. + SNAP_DESTROY="1" + snapshot_checks + + # Set some options. + if [ -n "${SNAP_VERBOSE}" ]; then + _opts="-v -r" + else + _opts="-r" + fi + zfs_destroy_snapshot + + # Check for exit status and just notify. + if [ "${_return}" -ne 0 ]; then + error_notify "[ERROR]: Failed to destroy '${TAG}' snapshot for '${_jail}'" + else + info "Snapshot '${TAG}' destroyed successfully." + exit 0 + fi +} + for _jail in ${JAILS}; do ( case "${ACTION}" in - destroy_snap|destroy_snapshot) + destroy|destroy_snap|destroy_snapshot) TAG="${3}" - zfs_destroy_snapshot + snapshot_destroy ;; df|usage) zfs_disk_usage @@ -216,6 +343,10 @@ for _jail in ${JAILS}; do MOUNT="${4}" zfs_jail_dataset ;; + rollback) + TAG="${3}" + snapshot_rollback + ;; unjail) DATASET="${3}" zfs_unjail_dataset @@ -226,7 +357,7 @@ for _jail in ${JAILS}; do ;; snap|snapshot) TAG="${3}" - zfs_snapshot + snapshot_create ;; *) usage @@ -236,6 +367,6 @@ for _jail in ${JAILS}; do ) & bastille_running_jobs "${bastille_process_limit}" - + done wait From d6a9848354d9071dc158c0038f1937258ea5de0f Mon Sep 17 00:00:00 2001 From: JRGTH Date: Fri, 27 Jun 2025 03:54:52 -0400 Subject: [PATCH 02/12] Remove dryrun, user can see snap data with list Remove dryrun as user can see snap usage data with `list` cmd instead. --- usr/local/share/bastille/zfs.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 26015dc7..02f61251 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -46,7 +46,6 @@ usage() { destroy Destroy a ZFS snapshot on the specified container. -a | --auto Auto mode. Start/stop jail(s) if required. -v | --verbose Be more verbose during the snapshot destroy operation. - -n | --dryrun Do a dry-run(no actual deletion) to determine what data would be deleted. -x | --debug Enable debug mode. EOF @@ -232,8 +231,8 @@ snapshot_checks() { # Check existence for the given snapshot. if [ -n "${SNAP_ROLLBACK}" ] || [ -n "${SNAP_DESTROY}" ]; then if [ -n "${TAG}" ]; then - # Early warning about missing snapshot parent dataset for reference, this may happen when - # more recent snapshots were deleted by either, intentional or automatically. + # Early warning about missing required snapshot/parent dataset for reference, this may happen when + # more recent snapshots were deleted by either, intentional or automatically when rollback older snapshots. if ! zfs list -t snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG}" >/dev/null 2>&1; then info "\n[${_jail}]:" warn "[WARNING]: Either snapshot '${TAG}' not exist or parent dataset appears to be missing." From e953aea373ffe9d4e45fc3a7fe0826a6e2cf7ae9 Mon Sep 17 00:00:00 2001 From: JRGTH Date: Fri, 27 Jun 2025 04:54:57 -0400 Subject: [PATCH 03/12] Add one sec for creating snaps in batch mode --- usr/local/share/bastille/zfs.sh | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 02f61251..5a409c7a 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -58,6 +58,7 @@ SNAP_CREATE= SNAP_ROLLBACK= SNAP_DESTROY= SNAP_VERBOSE= +SNAP_BATCH= zfs_jail_dataset() { @@ -206,6 +207,10 @@ fi TARGET="${1}" ACTION="${2}" +if [ "${TARGET}" = "ALL" -o "${TARGET}" = "all" ]; then + SNAP_BATCH="1" +fi + bastille_root_check set_target "${TARGET}" @@ -247,10 +252,12 @@ snapshot_checks() { # Generate a relatively short but unique name for the snapshots based on the current date/jail name. if [ -n "${SNAP_NAME_GEN}" ]; then - DATE=$(date +%F-%H%M%S) - NAME_MD5X6=$(echo "${DATE} ${TARGET}" | md5 | cut -b -6) - SNAPSHOT_NAME="Bastille_${NAME_MD5X6}_${TARGET}_${DATE}" - TAG="${SNAPSHOT_NAME}" + for _JAIL in ${_jail}; do + DATE=$(date +%F-%H%M%S) + NAME_MD5X6=$(echo "${DATE} ${TARGET}" | md5 | cut -b -6) + SNAPSHOT_NAME="Bastille_${NAME_MD5X6}_${_JAIL}_${DATE}" + TAG="${SNAPSHOT_NAME}" + done fi } @@ -277,6 +284,11 @@ snapshot_create() { if [ "${AUTO}" -eq 1 ]; then bastille start "${_jail}" fi + + # Delay a sec for batch snapshot creation safety. + if [ -n "${SNAP_BATCH}" ]; then + sleep 1 + fi } snapshot_rollback() { From 3d5c76c1469187135830654591546b67b4311f25 Mon Sep 17 00:00:00 2001 From: JRGTH Date: Fri, 27 Jun 2025 05:04:02 -0400 Subject: [PATCH 04/12] Remove early warning, seems redundant with zfs Remove early warning, seems redundant with zfs error handling output. --- usr/local/share/bastille/zfs.sh | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 5a409c7a..392bd4fb 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -233,28 +233,11 @@ snapshot_checks() { fi fi - # Check existence for the given snapshot. - if [ -n "${SNAP_ROLLBACK}" ] || [ -n "${SNAP_DESTROY}" ]; then - if [ -n "${TAG}" ]; then - # Early warning about missing required snapshot/parent dataset for reference, this may happen when - # more recent snapshots were deleted by either, intentional or automatically when rollback older snapshots. - if ! zfs list -t snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG}" >/dev/null 2>&1; then - info "\n[${_jail}]:" - warn "[WARNING]: Either snapshot '${TAG}' not exist or parent dataset appears to be missing." - fi - fi - elif [ -n "${SNAP_CREATE}" ]; then - if zfs list -t snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG}" >/dev/null 2>&1; then - info "\n[${_jail}]:" - warn "[WARNING]: Looks like the snapshot '${TAG}' already exist, See 'bastille list snapshot'." - fi - fi - # Generate a relatively short but unique name for the snapshots based on the current date/jail name. if [ -n "${SNAP_NAME_GEN}" ]; then for _JAIL in ${_jail}; do DATE=$(date +%F-%H%M%S) - NAME_MD5X6=$(echo "${DATE} ${TARGET}" | md5 | cut -b -6) + NAME_MD5X6=$(echo "${DATE} ${_JAIL}" | md5 | cut -b -6) SNAPSHOT_NAME="Bastille_${NAME_MD5X6}_${_JAIL}_${DATE}" TAG="${SNAPSHOT_NAME}" done From 72e9bae7f258530d6088e1369bb6276466c20eb7 Mon Sep 17 00:00:00 2001 From: JRGTH Date: Fri, 27 Jun 2025 11:35:28 -0400 Subject: [PATCH 05/12] Add some checks wen handling batch snapshots Add some checks and delay only wen handling batch snapshots with generated names. --- usr/local/share/bastille/zfs.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 392bd4fb..c3e3ce6c 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -58,6 +58,7 @@ SNAP_CREATE= SNAP_ROLLBACK= SNAP_DESTROY= SNAP_VERBOSE= +SNAP_CHECK= SNAP_BATCH= zfs_jail_dataset() { @@ -241,6 +242,13 @@ snapshot_checks() { SNAPSHOT_NAME="Bastille_${NAME_MD5X6}_${_JAIL}_${DATE}" TAG="${SNAPSHOT_NAME}" done + + # Check for the generated snapshot name. + SNAP_CHECK=$(echo ${TAG} | grep -wo "Bastille_[0-9a-fA-F]\{6\}_${_jail}_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}") + if [ -z "${SNAP_CHECK}" ]; then + info "\n[${_jail}]:" + error_notify "[ERROR]: Failed validation for the generated snapshot name." + fi fi } @@ -268,8 +276,8 @@ snapshot_create() { bastille start "${_jail}" fi - # Delay a sec for batch snapshot creation safety. - if [ -n "${SNAP_BATCH}" ]; then + # Delay a sec only for batch snapshot creation when using md5 to generate names. + if [ -n "${SNAP_BATCH}" ] && [ -n "${SNAP_CHECK}" ]; then sleep 1 fi } From 9503df28fbd530ca8933ef39c5eea83485147d0e Mon Sep 17 00:00:00 2001 From: JRGTH Date: Wed, 2 Jul 2025 23:59:41 -0400 Subject: [PATCH 06/12] Add snapshot batch rollback and simplify code Add snapshot batch rollback ability and simplify/maintenance code. --- usr/local/share/bastille/zfs.sh | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index c3e3ce6c..8dbb728a 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -58,7 +58,8 @@ SNAP_CREATE= SNAP_ROLLBACK= SNAP_DESTROY= SNAP_VERBOSE= -SNAP_CHECK= +SNAP_TAGCHECK= +SNAP_GENCHECK= SNAP_BATCH= zfs_jail_dataset() { @@ -226,6 +227,20 @@ if [ -z "${bastille_zfs_zpool}" ]; then fi snapshot_checks() { + # Check if we requested ALL jails. + if [ -n "${SNAP_ROLLBACK}" ]; then + if [ -n "${SNAP_BATCH}" ]; then + TARGET="${_jail}" + + # Check if is a bastille created snapshot with a unique name and warn about unwanted errors. + # Just warn here and don't exit, as a user may copy/use that unique name for other targets manually. + SNAP_TAGCHECK=$(echo ${TAG} | grep -wo "Bastille_[0-9a-fA-F]\{6\}_${_jail}_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}") + if [ -n "${SNAP_TAGCHECK}" ]; then + warn "\n[WARNING]: A snapshot with unique name was given for ALL targets, ignore unwanted errors." + fi + fi + fi + # Check if jail is running and stop if requested. if [ -z "${SNAP_DESTROY}" ]; then check_target_is_stopped "${_jail}" || \ @@ -241,11 +256,12 @@ snapshot_checks() { NAME_MD5X6=$(echo "${DATE} ${_JAIL}" | md5 | cut -b -6) SNAPSHOT_NAME="Bastille_${NAME_MD5X6}_${_JAIL}_${DATE}" TAG="${SNAPSHOT_NAME}" + SNAPSHOT_NAME= done # Check for the generated snapshot name. - SNAP_CHECK=$(echo ${TAG} | grep -wo "Bastille_[0-9a-fA-F]\{6\}_${_jail}_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}") - if [ -z "${SNAP_CHECK}" ]; then + SNAP_GENCHECK=$(echo ${TAG} | grep -wo "Bastille_[0-9a-fA-F]\{6\}_${_jail}_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}") + if [ -z "${SNAP_GENCHECK}" ]; then info "\n[${_jail}]:" error_notify "[ERROR]: Failed validation for the generated snapshot name." fi @@ -275,15 +291,10 @@ snapshot_create() { if [ "${AUTO}" -eq 1 ]; then bastille start "${_jail}" fi - - # Delay a sec only for batch snapshot creation when using md5 to generate names. - if [ -n "${SNAP_BATCH}" ] && [ -n "${SNAP_CHECK}" ]; then - sleep 1 - fi } snapshot_rollback() { - # This feature is intended work with snapshots created by either, bastille or manually created byu the user. + # This feature is intended work with snapshots created by either, bastille or manually created by the user. # An error about "more recent snapshots or bookmarks exist" will appears if the '-r' flag is not specified. SNAP_ROLLBACK="1" snapshot_checks From 9561f83edf480027ca57915039cd9ecf5a0ee35b Mon Sep 17 00:00:00 2001 From: JRGTH Date: Thu, 3 Jul 2025 00:10:24 -0400 Subject: [PATCH 07/12] Make shellcheck happy. Just make shellcheck happy and code maintenance. --- usr/local/share/bastille/zfs.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 8dbb728a..5080e1cd 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -54,7 +54,6 @@ EOF AUTO="0" SNAP_NAME_GEN= -SNAP_CREATE= SNAP_ROLLBACK= SNAP_DESTROY= SNAP_VERBOSE= @@ -209,7 +208,7 @@ fi TARGET="${1}" ACTION="${2}" -if [ "${TARGET}" = "ALL" -o "${TARGET}" = "all" ]; then +if [ "${TARGET}" = "ALL" ] || [ "${TARGET}" = "all" ]; then SNAP_BATCH="1" fi @@ -272,7 +271,6 @@ snapshot_create() { # Attempt to snapshot the container. # Thiw will create a ZFS snapshot for the specified container with an auto-generated name with the # following format "Bastille_XXXXXX_JAILNAME_YYYY-MM-DD-HHMMSS" unless a name tag is manually entered. - SNAP_CREATE="1" if [ -z "${TAG}" ]; then SNAP_NAME_GEN="1" fi From c52e55953399657ecc50e873b01394aa3ac1e316 Mon Sep 17 00:00:00 2001 From: JRGTH Date: Tue, 8 Jul 2025 19:25:06 -0400 Subject: [PATCH 08/12] Solve later PR conflict for list cmd This PR will solve the later PR conflict for the list cmd. --- usr/local/share/bastille/list.sh | 197 ++++++++++++++++++------------- 1 file changed, 112 insertions(+), 85 deletions(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 25c1ddb4..b3450fd6 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -34,20 +34,30 @@ usage() { error_notify "Usage: bastille list [option(s)] [RELEASE (-p)] [all] [backup(s)] [export(s)] [import(s)] [ip(s)] [jail(s)] [limit(s)] [log(s)]" - error_notify " [path(s)] [port(s)] [prio|priority] [release(s)] [snapshot(s)] [state(s)] [template(s)]" + error_notify " [path(s)] [port(s)] [prio|priority] [release(s)] [snapshot(s)] [state(s)] [template(s)] [type]" cat << EOF Options: - -d | --down List stopped jails only. - -j | --json List jails or sub-arg(s) in json format. - -p | --pretty Print JSON in columns. - -u | --up List running jails only. - -x | --debug Enable debug mode. + -d | --down List stopped jails only. + -j | --json List jails or sub-arg(s) in json format. + -p | --pretty Print JSON in columns. + -s | --sort VALUE Print info in VALUE order. + -u | --up List running jails only. + -x | --debug Enable debug mode. EOF exit 1 } +print_info() { + + # Print jails in given order + for _file in $(echo ${_tmp_list}); do + cat ${_file} + rm -f ${_file} + done | sort ${OPT_SORT} +} + pretty_json() { sed -e 's/^ {/ {\n /g' \ -e 's/,"/,\n "/g' \ @@ -56,6 +66,16 @@ pretty_json() { -e 's/^\[\(.*\)\]$/[\n\1\n]/' } +get_jail_list() { + + # Check if we want only a single jail, or all jails + if [ -n "${TARGET}" ]; then + JAIL_LIST="${TARGET}" + else + JAIL_LIST="$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g")" + fi +} + get_max_lengths() { if [ -d "${bastille_jailsdir}" ]; then @@ -279,13 +299,7 @@ list_bastille(){ _tmp_list= get_max_lengths - - # Check if we want only a single jail, or all jails - if [ -n "${TARGET}" ]; then - JAIL_LIST="${TARGET}" - else - JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") - fi + get_jail_list # Print header printf " JID%*sName%*sBoot%*sPrio%*sState%*sType%*sIP Address%*sPublished Ports%*sRelease%*sTags\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 4))" "" "$((${SPACER}))" "" "$((${SPACER}))" "" "$((${SPACER}))" "" "$((${MAX_LENGTH_JAIL_TYPE} + ${SPACER} - 4))" "" "$((${MAX_LENGTH_JAIL_IP} + ${SPACER} - 10))" "" "$((${MAX_LENGTH_JAIL_PORTS} + ${SPACER} - 15))" "" "$((${MAX_LENGTH_JAIL_RELEASE} + ${SPACER} - 7))" "" @@ -330,11 +344,7 @@ list_bastille(){ done wait - # Print jails in order - for _file in $(echo ${_tmp_list} | sort); do - cat ${_file} - rm -f ${_file} - done + print_info } list_all(){ @@ -342,13 +352,7 @@ list_all(){ _tmp_list= get_max_lengths - - # Check if we want only a single jail, or all jails - if [ -n "${TARGET}" ]; then - JAIL_LIST="${TARGET}" - else - JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") - fi + get_jail_list # Print header printf " JID%*sBoot%*sPrio%*sState%*sIP Address%*sPublished Ports%*sHostname%*sRelease%*sPath\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${SPACER}))" "" "$((${SPACER}))" "" "$((${SPACER}))" "" "$((${MAX_LENGTH_JAIL_IP} + ${SPACER} - 10))" "" "$((${MAX_LENGTH_JAIL_PORTS} + ${SPACER} - 15))" "" "$((${MAX_LENGTH_JAIL_HOSTNAME} + ${SPACER} - 8))" "" "$((${MAX_LENGTH_JAIL_RELEASE} + ${SPACER} - 7))" "" @@ -393,11 +397,7 @@ list_all(){ done wait - # Print jails in order - for _file in $(echo ${_tmp_list} | sort); do - cat ${_file} - rm -f ${_file} - done + print_info } list_ips() { @@ -405,13 +405,7 @@ list_ips() { _tmp_list= get_max_lengths - - # Check if we want only a single jail, or all jails - if [ -n "${TARGET}" ]; then - JAIL_LIST="${TARGET}" - else - JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") - fi + get_jail_list # Print header printf " JID%*sName%*sIP Address\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 4))" "" @@ -438,27 +432,15 @@ list_ips() { done wait - # Print jails in order - for _file in $(echo ${_tmp_list} | sort); do - cat ${_file} - rm -f ${_file} - done - + print_info } - list_paths() { _tmp_list= get_max_lengths - - # Check if we want only a single jail, or all jails - if [ -n "${TARGET}" ]; then - JAIL_LIST="${TARGET}" - else - JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") - fi + get_jail_list # Print header printf " JID%*sName%*sPath\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 4))" "" @@ -485,12 +467,7 @@ list_paths() { done wait - # Print jails in order - for _file in $(echo ${_tmp_list} | sort); do - cat ${_file} - rm -f ${_file} - done - + print_info } list_ports() { @@ -498,13 +475,7 @@ list_ports() { _tmp_list= get_max_lengths - - # Check if we want only a single jail, or all jails - if [ -n "${TARGET}" ]; then - JAIL_LIST="${TARGET}" - else - JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") - fi + get_jail_list # Print header printf " JID%*sName%*sPublished Ports\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 4))" "" @@ -531,12 +502,7 @@ list_ports() { done wait - # Print jails in order - for _file in $(echo ${_tmp_list} | sort); do - cat ${_file} - rm -f ${_file} - done - + print_info } list_state() { @@ -544,13 +510,7 @@ list_state() { _tmp_list= get_max_lengths - - # Check if we want only a single jail, or all jails - if [ -n "${TARGET}" ]; then - JAIL_LIST="${TARGET}" - else - JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") - fi + get_jail_list # Print header printf " JID%*sName%*sState\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 4))" "" @@ -577,12 +537,42 @@ list_state() { done wait - # Print jails in order - for _file in $(echo ${_tmp_list} | sort); do - cat ${_file} - rm -f ${_file} - done + print_info +} +list_type() { + + _tmp_list= + + get_max_lengths + get_jail_list + + # Print header + printf " JID%*sName%*sType\n" "$((${MAX_LENGTH_JID} + ${SPACER} - 3))" "" "$((${MAX_LENGTH_JAIL_NAME} + ${SPACER} - 4))" "" + + for _jail in ${JAIL_LIST}; do + + # Validate jail.conf existence + if [ -f "${bastille_jailsdir}/${_jail}/jail.conf" ]; then + _tmp_jail=$(mktemp /tmp/bastille-list-${_jail}) + else + continue + fi + + ( + + get_jail_info "${_jail}" + + printf " ${JID}%*s${JAIL_NAME}%*s${JAIL_TYPE}\n" "$((${MAX_LENGTH_JID} - ${#JID} + ${SPACER}))" "" "$((${MAX_LENGTH_JAIL_NAME} - ${#JAIL_NAME} + ${SPACER}))" "" + + ) > "${_tmp_jail}" & + + _tmp_list="$(printf "%s\n%s" "${_tmp_list}" "${_tmp_jail}")" + + done + wait + + print_info } # TODO: Check the correct usage or arguments here. See SC2120. @@ -607,7 +597,7 @@ list_release(){ } list_snapshot(){ - # TODO: Avility to list snapshot data for a single target. + # TODO: Ability to list snapshot data for a single target. # List snapshots with its usage data for valid bastille jails only. if [ -d "${bastille_jailsdir}" ]; then JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") @@ -656,6 +646,7 @@ TARGET="" OPT_JSON=0 OPT_PRETTY=0 OPT_STATE="all" +OPT_SORT="-k2" while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) @@ -673,13 +664,32 @@ while [ "$#" -gt 0 ]; do OPT_PRETTY=1 shift ;; + -s|--sort) + if [ -n "${3}" ]; then + error_exit "[ERROR]: [-s|--sort] can only be used with 'bastille list'." + fi + case "${2}" in + jid) OPT_SORT="-k1 -n" ;; + name) OPT_SORT="-k2" ;; + boot) OPT_SORT="-k3" ;; + prio|priority) OPT_SORT="-k4 -n" ;; + state) OPT_SORT="-k5" ;; + type|jailtype) OPT_SORT="-k6" ;; + ip) OPT_SORT="-k7 -n" ;; + ports) OPT_SORT="-k8 -n" ;; + release) OPT_SORT="-k9" ;; + tags) OPT_SORT="-k10" ;; + *) error_exit "Invalid sort option: \"${2}\"" ;; + esac + shift 2 + ;; -u|--up) OPT_STATE="Up" shift ;; -x|--debug) enable_debug - shift + shift ;; -*) for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do @@ -724,6 +734,7 @@ fi if [ "$#" -eq 1 ]; then case "${1}" in -a|--all|all) + OPT_SORT="-k2" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_all | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Boot\":\"%s\",\"Prio\":\"%s\",\"State\":\"%s\",\"IP Address\":\"%s\",\"Published Ports\":\"%s\",\"Hostname\":\"%s\",\"Release\":\"%s\",\"Path\":\"%s\"}",$1,$2,$3,$4,$5,$6,$7,$8,$9} END{print "\n]"}' | pretty_json @@ -735,6 +746,7 @@ if [ "$#" -eq 1 ]; then fi ;; ip|ips) + OPT_SORT="-k3 -n" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_ips | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"IP Address\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json @@ -746,6 +758,7 @@ if [ "$#" -eq 1 ]; then fi ;; path|paths) + OPT_SORT="-k3" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_paths | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"Path\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json @@ -757,6 +770,7 @@ if [ "$#" -eq 1 ]; then fi ;; rdr|port|ports) + OPT_SORT="-k3 -n" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_ports | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"Published Ports\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json @@ -768,6 +782,7 @@ if [ "$#" -eq 1 ]; then fi ;; state|status) + OPT_SORT="-k3" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_state | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"State\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json @@ -778,10 +793,22 @@ if [ "$#" -eq 1 ]; then list_state fi ;; + type|jailtype) + OPT_SORT="-k3" + if [ "${OPT_JSON}" -eq 1 ]; then + if [ "${OPT_PRETTY}" -eq 1 ]; then + list_type | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"Type\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json + else + list_type | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"Type\":\"%s\"}",$1,$2,$3} END{print "\n]"}' + fi + else + list_type + fi + ;; release|releases) list_release "${2}" ;; - snapshot|snapshots) + snap|snapshot|snapshots) list_snapshot exit 0 ;; From b32d32f64e842b5a232c7c98cc7a2c241729cbfa Mon Sep 17 00:00:00 2001 From: JRGTH Date: Tue, 8 Jul 2025 19:43:33 -0400 Subject: [PATCH 09/12] Solve one more conflict for list cmd This will solve one more conflict for list command, we will later add the `[snapshot(s)]` to the usage banner. --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index b3450fd6..326f7031 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -34,7 +34,7 @@ usage() { error_notify "Usage: bastille list [option(s)] [RELEASE (-p)] [all] [backup(s)] [export(s)] [import(s)] [ip(s)] [jail(s)] [limit(s)] [log(s)]" - error_notify " [path(s)] [port(s)] [prio|priority] [release(s)] [snapshot(s)] [state(s)] [template(s)] [type]" + error_notify " [path(s)] [port(s)] [prio|priority] [release(s)] [state(s)] [template(s)] [type]" cat << EOF Options: From 5580c9d0d357b5cafc188879cb6f92716922bcba Mon Sep 17 00:00:00 2001 From: JRGTH Date: Wed, 9 Jul 2025 00:25:36 -0400 Subject: [PATCH 10/12] Solver more conflicts due later updates Updated this PR and added the later changes to solve some conflicts to the `bastille` bin cmd, this is now ready for review. Between I would double quote the bastille version to: ``` BASTILLE_VERSION="1.0.20250714" ``` But I leave that as that just in case. --- usr/local/bin/bastille | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index f6d09ad8..1f05106d 100644 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -32,7 +32,7 @@ PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin -BASTILLE_VERSION="0.14.20250420" +BASTILLE_VERSION=1.0.20250714 # Validate config file # Copy default when 'setup' is called From 678886f6191a1e12fde0f359569ce624bfadc009 Mon Sep 17 00:00:00 2001 From: JRGTH Date: Wed, 16 Jul 2025 00:05:14 -0400 Subject: [PATCH 11/12] Remove sort option to fix recent conflicts Remove the sort option to fix the recent conflicts. --- usr/local/bin/bastille | 10 ++++----- usr/local/share/bastille/list.sh | 35 ++++---------------------------- 2 files changed, 9 insertions(+), 36 deletions(-) mode change 100644 => 100755 usr/local/bin/bastille diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille old mode 100644 new mode 100755 index 1f05106d..96ab6793 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -203,9 +203,11 @@ case "${CMD}" in # Commands that don't allow parallel mode bootstrap| \ clone| \ + cmd| \ console| \ convert| \ create| \ + destroy| \ edit| \ etcupdate| \ export| \ @@ -213,10 +215,13 @@ case "${CMD}" in import| \ limits| \ list| \ + migrate| \ network| \ + pkg| \ rcp| \ rdr| \ rename| \ + service| \ setup| \ top| \ update| \ @@ -227,17 +232,12 @@ case "${CMD}" in fi ;; # Commands that allow parallel mode - cmd| \ config| \ cp| \ - destroy| \ jcp| \ limits| \ - migrate| \ mount| \ - pkg| \ restart| \ - service| \ start| \ stop| \ sysrc| \ diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 326f7031..d02d78f5 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -41,7 +41,6 @@ usage() { -d | --down List stopped jails only. -j | --json List jails or sub-arg(s) in json format. -p | --pretty Print JSON in columns. - -s | --sort VALUE Print info in VALUE order. -u | --up List running jails only. -x | --debug Enable debug mode. @@ -52,10 +51,10 @@ EOF print_info() { # Print jails in given order - for _file in $(echo ${_tmp_list}); do + for _file in $(echo ${_tmp_list} | sort); do cat ${_file} rm -f ${_file} - done | sort ${OPT_SORT} + done } pretty_json() { @@ -194,8 +193,8 @@ get_jail_info() { # Get info if jail is UP if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then # Get IP for VNET jails - JAIL_IP4="$(jexec -l ${JAIL_NAME} ifconfig -an | grep "inet " | grep -v "127.0.0.1" | awk '{print $2}')" - JAIL_IP6="$(jexec -l ${JAIL_NAME} ifconfig -an | grep "inet6" | grep -Ev 'lo[0-9]+| ::1 | fe80::' | awk '{print $2}' | sed 's/%.*//g')" + JAIL_IP4="$(jexec -l ${JAIL_NAME} ifconfig -an | grep "^[[:space:]]*inet " | grep -v "127.0.0.1" | awk '{print $2}')" + JAIL_IP6="$(jexec -l ${JAIL_NAME} ifconfig -an | grep "^[[:space:]]*inet6" | grep -Ev 'lo[0-9]+| ::1 | fe80::' | awk '{print $2}' | sed 's/%.*//g')" else # Get IP for standard jails JAIL_IP4=$(jls -j ${JAIL_NAME} ip4.addr | sed 's/,/\n/g') @@ -646,7 +645,6 @@ TARGET="" OPT_JSON=0 OPT_PRETTY=0 OPT_STATE="all" -OPT_SORT="-k2" while [ "$#" -gt 0 ]; do case "${1}" in -h|--help|help) @@ -664,25 +662,6 @@ while [ "$#" -gt 0 ]; do OPT_PRETTY=1 shift ;; - -s|--sort) - if [ -n "${3}" ]; then - error_exit "[ERROR]: [-s|--sort] can only be used with 'bastille list'." - fi - case "${2}" in - jid) OPT_SORT="-k1 -n" ;; - name) OPT_SORT="-k2" ;; - boot) OPT_SORT="-k3" ;; - prio|priority) OPT_SORT="-k4 -n" ;; - state) OPT_SORT="-k5" ;; - type|jailtype) OPT_SORT="-k6" ;; - ip) OPT_SORT="-k7 -n" ;; - ports) OPT_SORT="-k8 -n" ;; - release) OPT_SORT="-k9" ;; - tags) OPT_SORT="-k10" ;; - *) error_exit "Invalid sort option: \"${2}\"" ;; - esac - shift 2 - ;; -u|--up) OPT_STATE="Up" shift @@ -734,7 +713,6 @@ fi if [ "$#" -eq 1 ]; then case "${1}" in -a|--all|all) - OPT_SORT="-k2" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_all | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Boot\":\"%s\",\"Prio\":\"%s\",\"State\":\"%s\",\"IP Address\":\"%s\",\"Published Ports\":\"%s\",\"Hostname\":\"%s\",\"Release\":\"%s\",\"Path\":\"%s\"}",$1,$2,$3,$4,$5,$6,$7,$8,$9} END{print "\n]"}' | pretty_json @@ -746,7 +724,6 @@ if [ "$#" -eq 1 ]; then fi ;; ip|ips) - OPT_SORT="-k3 -n" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_ips | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"IP Address\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json @@ -758,7 +735,6 @@ if [ "$#" -eq 1 ]; then fi ;; path|paths) - OPT_SORT="-k3" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_paths | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"Path\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json @@ -770,7 +746,6 @@ if [ "$#" -eq 1 ]; then fi ;; rdr|port|ports) - OPT_SORT="-k3 -n" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_ports | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"Published Ports\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json @@ -782,7 +757,6 @@ if [ "$#" -eq 1 ]; then fi ;; state|status) - OPT_SORT="-k3" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_state | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"State\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json @@ -794,7 +768,6 @@ if [ "$#" -eq 1 ]; then fi ;; type|jailtype) - OPT_SORT="-k3" if [ "${OPT_JSON}" -eq 1 ]; then if [ "${OPT_PRETTY}" -eq 1 ]; then list_type | awk 'BEGIN{print "["} NR>1{if(NR>2)print ","; printf " {\"JID\":\"%s\",\"Name\":\"%s\",\"Type\":\"%s\"}",$1,$2,$3} END{print "\n]"}' | pretty_json From b5e16816dba4af3429d59f40a28933f7ef185695 Mon Sep 17 00:00:00 2001 From: JRGTH Date: Wed, 16 Jul 2025 00:07:41 -0400 Subject: [PATCH 12/12] Update bastille bin version --- usr/local/bin/bastille | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/bin/bastille b/usr/local/bin/bastille index 96ab6793..e2ca31dc 100755 --- a/usr/local/bin/bastille +++ b/usr/local/bin/bastille @@ -32,7 +32,7 @@ PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin -BASTILLE_VERSION=1.0.20250714 +BASTILLE_VERSION=1.0.1.250714 # Validate config file # Copy default when 'setup' is called