From 933438dde801ac13171a0fe83020dd83bc66701a Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 19:34:29 -0500 Subject: [PATCH 01/21] updates version on README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd72b4cb..21746469 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ Use "bastille command -h|--help" for more information about a command. ``` -## 0.10-beta +## 0.12-beta This document outlines the basic usage of the Bastille container management framework. This release is still considered beta. From 50fd86aede7f30587d963029914a2e654813aaa3 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 19:39:19 -0500 Subject: [PATCH 02/21] github: fix typo --- .github/workflows/shellcheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index b3f26bba..07a3dc0c 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -3,7 +3,7 @@ name: ShellCheck Linting on: pull_request: branches: - - main + - master jobs: lint: From 5dbb196baaa12934eb2fdaa21de3a685d3e5a7f8 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 19:41:15 -0500 Subject: [PATCH 03/21] github: fix typo in shellcheck action --- .github/workflows/shellcheck.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 07a3dc0c..e10fe6ab 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -15,7 +15,7 @@ jobs: uses: actions/checkout@v4 - name: Run ShellCheck - uses: ludeeus/action-shellcheckudeeus/action-shellcheck@2.0.0 + uses: ludeeus/action-shellcheck@2.0.0 with: scandir: "./usr/local/share/bastille" additional_files: "./usr/local/bin/bastille" From 2be5238a57a8b1b936b619b3bd93c9692870942f Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 19:44:30 -0500 Subject: [PATCH 04/21] github: shellcheck severity to warning --- .github/workflows/shellcheck.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index e10fe6ab..c92bf931 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -17,6 +17,7 @@ jobs: - name: Run ShellCheck uses: ludeeus/action-shellcheck@2.0.0 with: + severity: warning scandir: "./usr/local/share/bastille" additional_files: "./usr/local/bin/bastille" ignore_paths: "./usr/local/share/bastille/templates" From 302dfb972078fd8af15818d5c7e7d12a2e0fd2c0 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 19:56:36 -0500 Subject: [PATCH 05/21] github: shellcheck exclude some rules --- .github/workflows/shellcheck.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index c92bf931..721e7cdc 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -16,8 +16,12 @@ jobs: - name: Run ShellCheck uses: ludeeus/action-shellcheck@2.0.0 + env: + # Excluding SC3043: In POSIX sh, 'local' is undefined. Ignoring because local is a built-in command in FreeBSD + # Excluding SC2154: Variable is referenced but not assigned. Because we include files in the scripts + SHELLCHECK_OPTS: -e SC3043 -e SC2154 with: severity: warning scandir: "./usr/local/share/bastille" additional_files: "./usr/local/bin/bastille" - ignore_paths: "./usr/local/share/bastille/templates" + ignore_paths: "./usr/local/share/bastille/templates ./usr/local/share/bastille/colors.pre.sh" From 7c02c91e5c37ddcb66d04e0e2fa768eaa11b29fd Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 20:00:26 -0500 Subject: [PATCH 06/21] github: shellcheck exclude SC3037 --- .github/workflows/shellcheck.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index 721e7cdc..ac17c63a 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -19,7 +19,9 @@ jobs: env: # Excluding SC3043: In POSIX sh, 'local' is undefined. Ignoring because local is a built-in command in FreeBSD # Excluding SC2154: Variable is referenced but not assigned. Because we include files in the scripts - SHELLCHECK_OPTS: -e SC3043 -e SC2154 + # Excluding SC3037: In POSIX sh, echo flags are undefined. Ignoring temporarily until we decide to keep it or + # use printf instead + SHELLCHECK_OPTS: -e SC3043 -e SC2154 -e SC3037 with: severity: warning scandir: "./usr/local/share/bastille" From 7e6a9fa896ade4c24866fc4883ca21b44b563860 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 20:37:02 -0500 Subject: [PATCH 07/21] [WIP] shellcheck linting --- .github/workflows/shellcheck.yml | 3 ++- usr/local/share/bastille/common.sh | 6 +++--- usr/local/share/bastille/mount.sh | 11 +++++++++-- usr/local/share/bastille/template.sh | 18 +++++++++--------- usr/local/share/bastille/verify.sh | 2 +- usr/local/share/bastille/zfs.sh | 4 ++-- 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index ac17c63a..c183dd37 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -21,7 +21,8 @@ jobs: # Excluding SC2154: Variable is referenced but not assigned. Because we include files in the scripts # Excluding SC3037: In POSIX sh, echo flags are undefined. Ignoring temporarily until we decide to keep it or # use printf instead - SHELLCHECK_OPTS: -e SC3043 -e SC2154 -e SC3037 + # Excluding SC2155: Declare and assign separately to avoid masking return values. + SHELLCHECK_OPTS: -e SC3043 -e SC2154 -e SC3037 -e SC2155 with: severity: warning scandir: "./usr/local/share/bastille" diff --git a/usr/local/share/bastille/common.sh b/usr/local/share/bastille/common.sh index 74c12e67..9940d9e6 100644 --- a/usr/local/share/bastille/common.sh +++ b/usr/local/share/bastille/common.sh @@ -47,7 +47,7 @@ enable_color() { # If "NO_COLOR" environment variable is present, or we aren't speaking to a # tty, disable output colors. -if [ -z "${NO_COLOR}" -a -t 1 ]; then +if [ -z "${NO_COLOR}" ] && [ -t 1 ]; then enable_color fi @@ -77,9 +77,9 @@ generate_vnet_jail_netblock() { ## determine number of containers + 1 ## iterate num and grep all jail configs ## define uniq_epair - local jail_list=$(bastille list jails) + local jail_list="$(bastille list jails)" if [ -n "${jail_list}" ]; then - local list_jails_num=$(echo "${jail_list}" | wc -l | awk '{print $1}') + local list_jails_num="$(echo "${jail_list}" | wc -l | awk '{print $1}')" local num_range=$((list_jails_num + 1)) for _num in $(seq 0 "${num_range}"); do if ! grep -q "e[0-9]b_bastille${_num}" "${bastille_jailsdir}"/*/jail.conf; then diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index a2ab85fc..7ccb3813 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -45,8 +45,10 @@ esac if [ $# -lt 2 ]; then usage elif [ $# -eq 2 ]; then + # shellcheck disable=SC2124 _fstab="$@ nullfs ro 0 0" else + # shellcheck disable=SC2124 _fstab="$@" fi @@ -67,8 +69,13 @@ if [ -z "${_hostpath}" ] || [ -z "${_jailpath}" ] || [ -z "${_type}" ] || [ -z " exit 1 fi -## if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, procfs" -if [ "${_hostpath}" == "tmpfs" -a "$_type" == "tmpfs" ] || [ "${_hostpath}" == "linprocfs" -a "${_type}" == "linprocfs" ] || [ "${_hostpath}" == "linsysfs" -a "${_type}" == "linsysfs" ] || [ "${_hostpath}" == "proc" -a "${_type}" == "procfs" ] || [ "${_hostpath}" == "fdesc" -a "${_type}" == "fdescfs" ] ; then +# if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, +# procfs" +if [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ] || + [ "${_hostpath}" = "linprocfs" ] && [ "${_type}" = "linprocfs" ] || + [ "${_hostpath}" = "linsysfs" ] && [ "${_type}" = "linsysfs" ] || + [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ] || + [ "${_hostpath}" = "fdesc" ] && [ "${_type}" = "fdescfs" ]; then warn "Detected advanced mount type ${_hostpath}" elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then error_notify "Detected invalid host path or incorrect mount type in FSTAB." diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index d9634f5a..1ab68364 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -96,7 +96,7 @@ render() { if [ -d "${_file_path}" ]; then # Recursively render every file in this directory. -- cwells echo "Rendering Directory: ${_file_path}" find "${_file_path}" \( -type d -name .git -prune \) -o -type f - find "${_file_path}" \( -type d -name .git -prune \) -o -type f -print0 | $(eval "xargs -0 sed -i '' ${ARG_REPLACEMENTS}") + find "${_file_path}" \( -type d -name .git -prune \) -o -type f -print0 | eval "xargs -0 sed -i '' ${ARG_REPLACEMENTS}" elif [ -f "${_file_path}" ]; then echo "Rendering File: ${_file_path}" eval "sed -i '' ${ARG_REPLACEMENTS} '${_file_path}'" @@ -128,9 +128,9 @@ fi # 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}" + cd "${TEMPLATE}" || error_exit "Failed to change to directory: ${TEMPLATE}" elif [ -d "${bastille_template}" ]; then - cd "${bastille_template}" + cd "${bastille_template}" || error_exit "Failed to change to directory: ${TEMPLATE}" else error_exit "Template not found: ${TEMPLATE}" fi @@ -232,7 +232,7 @@ for _jail in ${JAILS}; do if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then _jail_ip=$(/usr/sbin/jls -j "${_jail}" ip4.addr 2>/dev/null) _jail_ip6=$(/usr/sbin/jls -j "${_jail}" ip6.addr 2>/dev/null) - if [ -z "${_jail_ip}" -o "${_jail_ip}" = "-" ]; then + if [ -z "${_jail_ip}" ] || [ "${_jail_ip}" = "-" ]; then error_notify "Jail IP not found: ${_jail}" _jail_ip='' # In case it was -. -- cwells fi @@ -299,12 +299,12 @@ for _jail in ${JAILS}; do # Escape single-quotes in the command being executed. -- cwells _args=$(echo "${_args}" | sed "s/'/'\\\\''/g") # Allow redirection within the jail. -- cwells - _args="sh -c '${_args}'" + _args="sh -c ${_args}" ;; cp|copy) _cmd='cp' # Convert relative "from" path into absolute path inside the template directory. -- cwells - if [ "${_args%${_args#?}}" != '/' ] && [ "${_args%${_args#??}}" != '"/' ]; then + if [ "${_args%"${_args#?}"}" != '/' ] && [ "${_args%"${_args#??}"}" != '"/' ]; then _args="${bastille_template}/${_args}" fi ;; @@ -368,9 +368,9 @@ for _jail in ${JAILS}; do info "[${_jail}]:${_hook} -- START" if [ "${_hook}" = 'CMD' ] || [ "${_hook}" = 'PRE' ]; then - bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || exit 1 + bastille cmd "${_jail}" /bin/sh < "${bastille_template}/${_hook}" || error_exit "Failed to execute command." elif [ "${_hook}" = 'PKG' ]; then - bastille pkg "${_jail}" install -y $(cat "${bastille_template}/PKG") || exit 1 + bastille pkg "${_jail}" install -y "$(cat "${bastille_template}/PKG")" || error_exit "Failed to install packages." bastille pkg "${_jail}" audit -F else while read _line; do @@ -380,7 +380,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} || exit 1 + bastille "${_cmd} ${_jail} ${_args}" || error_exit "Failed to execute command." done < "${bastille_template}/${_hook}" fi info "[${_jail}]:${_hook} -- END" diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index cffb9f0b..87b0d07b 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -78,7 +78,7 @@ verify_template() { info "Detected ${_hook} hook." ## line count must match newline count - if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then + if [ "$(wc -l "${_path}" | awk '{print $1}')" -ne "$(grep -c printf '\n' "${_path}")" ]; then info "[${_hook}]:" error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]." error_notify "Line numbers don't match line breaks." diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index ab6f45eb..0c771d3b 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -38,7 +38,7 @@ usage() { zfs_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" - zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" + zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG}" echo done } @@ -46,7 +46,7 @@ done zfs_destroy_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" - zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}"@"${TAG}" + zfs destroy -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${_jail}@${TAG}" echo done } From 8808e8a5a434dcc868b4db3a1e9712a8010a4a62 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 20:57:43 -0500 Subject: [PATCH 08/21] [WIP] shellcheck linting --- usr/local/share/bastille/bootstrap.sh | 4 +++- usr/local/share/bastille/clone.sh | 7 ++++--- usr/local/share/bastille/destroy.sh | 2 +- usr/local/share/bastille/import.sh | 8 ++++---- usr/local/share/bastille/service.sh | 2 +- usr/local/share/bastille/tags.sh | 2 +- usr/local/share/bastille/update.sh | 7 ++++--- 7 files changed, 18 insertions(+), 14 deletions(-) diff --git a/usr/local/share/bastille/bootstrap.sh b/usr/local/share/bastille/bootstrap.sh index bfad535e..295ebf67 100644 --- a/usr/local/share/bastille/bootstrap.sh +++ b/usr/local/share/bastille/bootstrap.sh @@ -216,6 +216,8 @@ bootstrap_release() { if [ -f "${bastille_releasesdir}/${RELEASE}/COPYRIGHT" ]; then ## check distfiles list and skip existing cached files bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/base//") + # TODO check how to handle this + # shellcheck disable=SC2010 bastille_cached_files=$(ls "${bastille_cachedir}/${RELEASE}" | grep -v "MANIFEST" | tr -d ".txz") for distfile in ${bastille_cached_files}; do bastille_bootstrap_archives=$(echo "${bastille_bootstrap_archives}" | sed "s/${distfile}//") @@ -452,7 +454,7 @@ HW_MACHINE_ARCH=$(sysctl hw.machine_arch | awk '{ print $2 }') # bootstrapping from aarch64/arm64 Debian or Ubuntu require a different value for ARCH # create a new variable -if [ "${HW_MACHINE_ARCH}" == "aarch64" ]; then +if [ "${HW_MACHINE_ARCH}" = "aarch64" ]; then HW_MACHINE_ARCH_LINUX="arm64" else HW_MACHINE_ARCH_LINUX=${HW_MACHINE_ARCH} diff --git a/usr/local/share/bastille/clone.sh b/usr/local/share/bastille/clone.sh index 48a4417d..fee55737 100644 --- a/usr/local/share/bastille/clone.sh +++ b/usr/local/share/bastille/clone.sh @@ -58,6 +58,7 @@ validate_ip() { if [ -n "${ip6}" ]; then info "Valid: (${ip6})." IPX_ADDR="ip6.addr" + # shellcheck disable=SC2034 IP6_MODE="new" else local IFS @@ -104,8 +105,8 @@ update_jailconf_vnet() { bastille_jail_rc_conf="${bastille_jailsdir}/${NEWNAME}/root/etc/rc.conf" # Determine number of containers and define an uniq_epair - local list_jails_num=$(bastille list jails | wc -l | awk '{print $1}') - local num_range=$(expr "${list_jails_num}" + 1) + local list_jails_num="$(bastille list jails | wc -l | awk '{print $1}')" + local num_range="$(expr "${list_jails_num}" + 1)" jail_list=$(bastille list jail) for _num in $(seq 0 "${num_range}"); do if [ -n "${jail_list}" ]; then @@ -125,7 +126,7 @@ update_jailconf_vnet() { sed -i '' "s|ifconfig_e0b_bastille.*_name|ifconfig_e0b_${uniq_epair}_name|" "${bastille_jail_rc_conf}" # If 0.0.0.0 set DHCP, else set static IP address - if [ "${IP}" == "0.0.0.0" ]; then + if [ "${IP}" = "0.0.0.0" ]; then sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="SYNCDHCP" else sysrc -f "${bastille_jail_rc_conf}" ifconfig_vnet0="inet ${IP}" diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index 9d9e9996..9bdb6057 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -172,7 +172,7 @@ destroy_rel() { if [ "${FORCE}" = "1" ]; then ## remove cache on force if [ -d "${bastille_cachedir}/${TARGET}" ]; then - rm -rf "${bastille_cachedir}/${TARGET}" + rm -rf "${bastille_cachedir:?}/${TARGET}" fi fi echo diff --git a/usr/local/share/bastille/import.sh b/usr/local/share/bastille/import.sh index 391dfc9d..34cda5fc 100644 --- a/usr/local/share/bastille/import.sh +++ b/usr/local/share/bastille/import.sh @@ -79,7 +79,7 @@ while [ $# -gt 0 ]; do TARGET="${2}" shift ;; - -*|--*) + --*|-*) error_notify "Unknown Option." usage ;; @@ -281,7 +281,7 @@ EOF >> "${bastille_jailsdir}/${TARGET_TRIM}/fstab" # Work with the symlinks - cd "${bastille_jailsdir}/${TARGET_TRIM}/root" + cd "${bastille_jailsdir}/${TARGET_TRIM}/root" || error_exit "Failed to change directory." update_symlinks else # Generate new empty fstab file @@ -324,7 +324,7 @@ update_config() { >> "${bastille_jailsdir}/${TARGET_TRIM}/fstab" # Work with the symlinks - cd "${bastille_jailsdir}/${TARGET_TRIM}/root" + cd "${bastille_jailsdir}/${TARGET_TRIM}/root" || error_exit "Failed to change directory." update_symlinks } @@ -377,7 +377,7 @@ update_symlinks() { for _link in ${SYMLINKS}; do if [ -L "${_link}" ]; then ln -sf /.bastille/${_link} ${_link} - elif [ "${ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED:-0}" = "1" -a -d "${_link}" ]; then + elif [ "${ALLOW_EMPTY_DIRS_TO_BE_SYMLINKED:-0}" = "1" ] && [ -d "${_link}" ]; then # -F will enforce that the directory is empty and replaced by the symlink ln -sfF /.bastille/${_link} ${_link} || EXIT_CODE=$? if [ "${EXIT_CODE:-0}" != "0" ]; then diff --git a/usr/local/share/bastille/service.sh b/usr/local/share/bastille/service.sh index 23b8e589..92fa4f27 100644 --- a/usr/local/share/bastille/service.sh +++ b/usr/local/share/bastille/service.sh @@ -41,7 +41,7 @@ help|-h|--help) ;; esac -if [ $# -lt 1 -o $# -gt 2 ]; then +if [ $# -lt 1 ] || [ $# -gt 2 ]; then usage fi diff --git a/usr/local/share/bastille/tags.sh b/usr/local/share/bastille/tags.sh index de24044c..65ed802f 100644 --- a/usr/local/share/bastille/tags.sh +++ b/usr/local/share/bastille/tags.sh @@ -50,7 +50,7 @@ help|-h|--help) ;; esac -if [ $# -lt 1 -o $# -gt 2 ]; then +if [ $# -lt 1 ] || [ $# -gt 2 ]; then usage fi diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index 3bd033f8..4304a73a 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -143,9 +143,10 @@ template_update() { templates_update() { # Update all templates _updated_templates=0 - if [ -d ${bastille_templatesdir} ]; then - for _template_path in $(ls -d ${bastille_templatesdir}/*/*); do - if [ -d $_template_path/.git ]; then + if [ -d "${bastille_templatesdir}" ]; then + # 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 }') template_update From b6bf75a4ef9eaebe14a8019314d918d566a5006e Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 21:05:45 -0500 Subject: [PATCH 09/21] [WIP] shellcheck linting --- usr/local/share/bastille/create.sh | 24 ++++++++++++++---------- usr/local/share/bastille/rename.sh | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 674bdc19..488fa559 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -60,7 +60,7 @@ running_jail() { validate_name() { local NAME_VERIFY=${NAME} - local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_') + 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 @@ -123,7 +123,7 @@ validate_ips() { } validate_netif() { - local LIST_INTERFACES=$(ifconfig -l) + local LIST_INTERFACES="$(ifconfig -l)" if echo "${LIST_INTERFACES} VNET" | grep -qwo "${INTERFACE}"; then info "Valid: (${INTERFACE})." else @@ -253,7 +253,7 @@ post_create_jail() { # Using relative paths here. # MAKE SURE WE'RE IN THE RIGHT PLACE. - cd "${bastille_jail_path}" + cd "${bastille_jail_path}" || error_exit "Failed to change directory." echo if [ ! -f "${bastille_jail_conf}" ]; then @@ -292,7 +292,9 @@ create_jail() { bastille_jail_fstab="${bastille_jailsdir}/${NAME}/fstab" ## file bastille_jail_conf="${bastille_jailsdir}/${NAME}/jail.conf" ## file bastille_jail_log="${bastille_logsdir}/${NAME}_console.log" ## file + # shellcheck disable=SC2034 bastille_jail_rc_conf="${bastille_jailsdir}/${NAME}/root/etc/rc.conf" ## file + # shellcheck disable=SC2034 bastille_jail_resolv_conf="${bastille_jailsdir}/${NAME}/root/etc/resolv.conf" ## file if [ ! -d "${bastille_jailsdir}/${NAME}" ]; then @@ -409,9 +411,9 @@ create_jail() { info "Creating a clonejail...\n" ## clone the release base to the new basejail SNAP_NAME="bastille-clone-$(date +%Y-%m-%d-%H%M%S)" - zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" + zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" - zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" \ + zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" \ "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" # Check and apply required settings. @@ -425,17 +427,17 @@ create_jail() { ## take a temp snapshot of the base release SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)" - zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" + zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" ## replicate the release base to the new thickjail and set the default mountpoint - zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" | \ + zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" | \ zfs receive "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" zfs set ${ZFS_OPTIONS} mountpoint=none "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" zfs inherit mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" ## cleanup temp snapshots initially - zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" - zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}" + zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" + zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root@${SNAP_NAME}" fi if [ "$?" -ne 0 ]; then @@ -608,7 +610,9 @@ esac bastille_root_check if echo "$3" | grep '@'; then + # shellcheck disable=SC2034 BASTILLE_JAIL_IP=$(echo "$3" | awk -F@ '{print $2}') + # shellcheck disable=SC2034 BASTILLE_JAIL_INTERFACES=$( echo "$3" | awk -F@ '{print $1}') fi @@ -691,7 +695,7 @@ while [ $# -gt 0 ]; do VNET_JAIL_BRIDGE="1" shift ;; - -*|--*) + --*|-*) error_notify "Unknown Option." usage ;; diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index bbcdfedf..b9197bc5 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -37,7 +37,7 @@ usage() { validate_name() { local NAME_VERIFY=${NEWNAME} - local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_') + 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 From 7927385458e4fb33c408711fa0ca140dc93ecf19 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 21:34:36 -0500 Subject: [PATCH 10/21] [WIP] shellcheck linting --- .github/workflows/shellcheck.yml | 4 +++- usr/local/share/bastille/convert.sh | 4 +++- usr/local/share/bastille/edit.sh | 1 + usr/local/share/bastille/export.sh | 16 +++++++++++----- usr/local/share/bastille/list.sh | 28 ++++++++++++++++------------ usr/local/share/bastille/mount.sh | 2 -- usr/local/share/bastille/rdr.sh | 8 ++++---- usr/local/share/bastille/stop.sh | 2 +- 8 files changed, 39 insertions(+), 26 deletions(-) diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index c183dd37..4851b20f 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -22,7 +22,9 @@ jobs: # Excluding SC3037: In POSIX sh, echo flags are undefined. Ignoring temporarily until we decide to keep it or # use printf instead # Excluding SC2155: Declare and assign separately to avoid masking return values. - SHELLCHECK_OPTS: -e SC3043 -e SC2154 -e SC3037 -e SC2155 + # Excluding SC2124: Assigning an array to a string! Check instead if this is a false positive or if there is + # a better way to do it. + SHELLCHECK_OPTS: -e SC3043 -e SC2154 -e SC3037 -e SC2155 -e SC2124 with: severity: warning scandir: "./usr/local/share/bastille" diff --git a/usr/local/share/bastille/convert.sh b/usr/local/share/bastille/convert.sh index f26e9191..0290f355 100644 --- a/usr/local/share/bastille/convert.sh +++ b/usr/local/share/bastille/convert.sh @@ -114,7 +114,7 @@ start_convert() { HASPORTS=$(grep -w ${bastille_releasesdir}/${RELEASE}/usr/ports ${bastille_jailsdir}/${TARGET}/fstab) if [ -n "${RELEASE}" ]; then - cd "${bastille_jailsdir}/${TARGET}/root" + cd "${bastille_jailsdir}/${TARGET}/root" || error_exit "Failed to change directory to ${bastille_jailsdir}/${TARGET}/root" # Work with the symlinks convert_symlinks @@ -149,6 +149,8 @@ fi # Be interactive here since this cannot be easily undone while :; do error_notify "Warning: container conversion from thin to thick can't be undone!" + # 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;; diff --git a/usr/local/share/bastille/edit.sh b/usr/local/share/bastille/edit.sh index 78e678bf..79677e5b 100644 --- a/usr/local/share/bastille/edit.sh +++ b/usr/local/share/bastille/edit.sh @@ -51,6 +51,7 @@ fi bastille_root_check if [ -z "${EDITOR}" ]; then + # shellcheck disable=SC2209 EDITOR=vi fi diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 3c14e962..d0d6ea27 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -76,6 +76,7 @@ bastille_root_check zfs_enable_check() { # Temporarily disable ZFS so we can create a standard backup archive if checkyesno bastille_zfs_enable; then + # shellcheck disable=SC2034 bastille_zfs_enable="NO" fi } @@ -135,7 +136,7 @@ if [ -n "${bastille_export_options}" ]; then --verbose) OPT_ZSEND="-Rv" shift;; - -*|--*) error_notify "Unknown Option." + --*|-*) error_notify "Unknown Option." usage;; esac done @@ -185,7 +186,7 @@ else TARGET="${2}" shift ;; - -*|--*) + --*|-*) error_notify "Unknown Option." usage ;; @@ -208,12 +209,16 @@ if [ "${COMP_OPTION}" -gt "1" ]; then error_exit "Error: Only one compression format can be used during export." fi -if [ -n "${TXZ_EXPORT}" -o -n "${TGZ_EXPORT}" ] && [ -n "${SAFE_EXPORT}" ]; then +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." fi if ! checkyesno bastille_zfs_enable; then - if [ -n "${XZ_EXPORT}" -o -n "${GZIP_EXPORT}" -o -n "${RAW_EXPORT}" -o -n "${SAFE_EXPORT}" -o "${OPT_ZSEND}" = "-Rv" ]; then + if [ -n "${XZ_EXPORT}" ] || + [ -n "${GZIP_EXPORT}" ] || + [ -n "${RAW_EXPORT}" ] || + [ -n "${SAFE_EXPORT}" ] || + [ "${OPT_ZSEND}" = "-Rv" ]; then error_exit "Options --xz, --gz, --raw, --safe, --verbose are valid for ZFS configured systems only." fi fi @@ -270,7 +275,7 @@ export_check() { EXPORT_AS="Exporting" fi - if [ "${FILE_EXT}" = ".xz" -o "${FILE_EXT}" = ".gz" -o "${FILE_EXT}" = "" ]; then + if [ "${FILE_EXT}" = ".xz" ] || [ "${FILE_EXT}" = ".gz" ] || [ "${FILE_EXT}" = "" ]; then EXPORT_TYPE="image" else EXPORT_TYPE="archive" @@ -360,6 +365,7 @@ jail_export() { fi fi + # shellcheck disable=SC2181 if [ "$?" -ne 0 ]; then error_exit "Failed to export '${TARGET}' container." else diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index ebb28cc4..2732ca4d 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -35,7 +35,7 @@ usage() { error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]" } -if [ "${1}" = help -o "${1}" = "-h" -o "${1}" = "--help" ]; then +if [ "${1}" = help ] || [ "${1}" = "-h" ] || [ "${1}" = "--help" ]; then usage fi @@ -45,7 +45,7 @@ if [ $# -eq 0 ]; then /usr/sbin/jls fi -if [ "${1}" == "-j" ]; then +if [ "${1}" = "-j" ]; then /usr/sbin/jls -N --libxo json exit 0 fi @@ -61,7 +61,7 @@ list_all(){ if [ "${MAX_LENGTH_JAIL_NAME}" -lt 3 ]; then MAX_LENGTH_JAIL_NAME=3; fi MAX_LENGTH_JAIL_IP=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 sed -n "s/^[ ]*ip[4,6].addr[ ]*=[ ]*\(.*\);$/\1 /p" | sed 's/\// /g' | awk '{ print length($1) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_IP:-10} - MAX_LENGTH_JAIL_VNET_IP=$(find ""${bastille_jailsdir}/*/jail.conf"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -h "ifconfig_vnet0=" $(sed -n "s/\(.*\)jail.conf$/\1root\/etc\/rc.conf/p") | sed -n "s/^ifconfig_vnet0=\"\(.*\)\"$/\1/p"| sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print length($2); else print 15 }' | sort -nr | head -n 1) + MAX_LENGTH_JAIL_VNET_IP=$(find "${bastille_jailsdir}/*/jail.conf" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -l "vnet;" | grep -h "ifconfig_vnet0=" "$(sed -n "s/\(.*\)jail.conf$/\1root\/etc\/rc.conf/p")" | sed -n "s/^ifconfig_vnet0=\"\(.*\)\"$/\1/p"| sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print length($2); else print 15 }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_VNET_IP=${MAX_LENGTH_JAIL_VNET_IP:-10} if [ "${MAX_LENGTH_JAIL_VNET_IP}" -gt "${MAX_LENGTH_JAIL_IP}" ]; then MAX_LENGTH_JAIL_IP=${MAX_LENGTH_JAIL_VNET_IP}; fi if [ "${MAX_LENGTH_JAIL_IP}" -lt 10 ]; then MAX_LENGTH_JAIL_IP=10; fi @@ -72,11 +72,11 @@ list_all(){ MAX_LENGTH_JAIL_PORTS=${MAX_LENGTH_JAIL_PORTS:-15} if [ "${MAX_LENGTH_JAIL_PORTS}" -lt 15 ]; then MAX_LENGTH_JAIL_PORTS=15; fi if [ "${MAX_LENGTH_JAIL_PORTS}" -gt 30 ]; then MAX_LENGTH_JAIL_PORTS=30; fi - MAX_LENGTH_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/fstab"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1) + MAX_LENGTH_JAIL_RELEASE=$(find "${bastille_jailsdir}/*/fstab" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/releases/.*/root/.bastille.*nullfs" | grep -hE "^USERLAND_VERSION=" "$(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++')" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1) MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_JAIL_RELEASE:-7} - MAX_LENGTH_THICK_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/root/bin/freebsd-version"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -hE "^USERLAND_VERSION=" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1) + MAX_LENGTH_THICK_JAIL_RELEASE=$(find "${bastille_jailsdir}/*/root/bin/freebsd-version" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -hE "^USERLAND_VERSION=" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p" | awk '{ print length($0) }' | sort -nr | head -n 1) MAX_LENGTH_THICK_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE:-7} - MAX_LENGTH_LINUX_JAIL_RELEASE=$(find ""${bastille_jailsdir}/*/fstab"" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hE "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" $(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p") 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | sed "N;N;s/\n/;/g" | sed -n "s/^NAME=\(.*\);VERSION_ID=\(.*\);VERSION_CODENAME=\(.*\)$/\1 \2 (\3)/p" | awk '{ print length($0) }' | sort -nr | head -n 1) + MAX_LENGTH_LINUX_JAIL_RELEASE=$(find "${bastille_jailsdir}/*/fstab" -maxdepth 1 -type f -print0 2> /dev/null | xargs -r0 -P0 grep -h "/jails/.*/root/proc.*linprocfs" | grep -hE "^NAME=|^VERSION_ID=|^VERSION_CODENAME=" "$(sed -n "s/^linprocfs *\(.*\)\/.*$/\1\/etc\/os-release/p")" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | sed "N;N;s/\n/;/g" | sed -n "s/^NAME=\(.*\);VERSION_ID=\(.*\);VERSION_CODENAME=\(.*\)$/\1 \2 (\3)/p" | awk '{ print length($0) }' | sort -nr | head -n 1) MAX_LENGTH_LINUX_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE:-7} if [ "${MAX_LENGTH_THICK_JAIL_RELEASE}" -gt "${MAX_LENGTH_JAIL_RELEASE}" ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_THICK_JAIL_RELEASE}; fi if [ "${MAX_LENGTH_LINUX_JAIL_RELEASE}" -gt "${MAX_LENGTH_JAIL_RELEASE}" ]; then MAX_LENGTH_JAIL_RELEASE=${MAX_LENGTH_LINUX_JAIL_RELEASE}; fi @@ -93,7 +93,7 @@ list_all(){ if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then JAIL_NAME=$(grep -h -m 1 -e "^.* {$" "${bastille_jailsdir}/${_JAIL}/jail.conf" 2> /dev/null | awk '{ print $1 }') IS_FREEBSD_JAIL=0 - if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" -o -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" -o "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi + if [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/bin/freebsd-version" ] || [ -f "${bastille_jailsdir}/${JAIL_NAME}/root/.bastille/bin/freebsd-version" ] || [ "$(grep -c "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_FREEBSD_JAIL=1; fi IS_FREEBSD_JAIL=${IS_FREEBSD_JAIL:-0} IS_LINUX_JAIL=0 if [ "$(grep -c "^linprocfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null)" -gt 0 ]; then IS_LINUX_JAIL=1; fi @@ -117,7 +117,7 @@ list_all(){ JAIL_RELEASE=$(grep -hE "^NAME=.*$|^VERSION_ID=.*$|^VERSION_CODENAME=.*$" "${JAIL_PATH}/etc/os-release" 2> /dev/null | sed "s/\"//g" | sed "s/ GNU\/Linux//g" | awk -F'=' '{ a[$1] = $2; o++ } o%3 == 0 { print a["VERSION_CODENAME"] " (" a["NAME"] " " a["VERSION_ID"] ")" }') fi else - JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" == "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) + JAIL_STATE=$(if [ "$(sed -n "/^${JAIL_NAME} {$/,/^}$/p" "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null | awk '$0 ~ /^'${JAIL_NAME}' \{|\}/ { printf "%s",$0 }')" = "${JAIL_NAME} {}" ]; then echo "Down"; else echo "n/a"; fi) if [ "$(awk '$1 == "vnet;" { print $1 }' "${bastille_jailsdir}/${JAIL_NAME}/jail.conf" 2> /dev/null)" ]; then JAIL_IP=$(sed -n 's/^ifconfig_vnet0="\(.*\)"$/\1/p' "${bastille_jailsdir}/${JAIL_NAME}/root/etc/rc.conf" 2> /dev/null | sed "s/\// /g" | awk '{ if ($1 ~ /^[inet|inet6]/) print $2; else print $1 }') else @@ -131,7 +131,7 @@ list_all(){ if [ -f "${JAIL_PATH}/bin/freebsd-version" ]; then JAIL_RELEASE=$(grep -hE "^USERLAND_VERSION=" "${JAIL_PATH}/bin/freebsd-version" 2> /dev/null | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") else - JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | grep -hE "^USERLAND_VERSION=" $(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++') | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") + JAIL_RELEASE=$(grep -h "/releases/.*/root/.bastille.*nullfs" "${bastille_jailsdir}/${JAIL_NAME}/fstab" 2> /dev/null | grep -hE "^USERLAND_VERSION=" "$(sed -n "s/^\(.*\) \/.*$/\1\/bin\/freebsd-version/p" | awk '!_[$0]++')" | sed "s/[\"\'\^]//g;s/ .*$//g" | sed -n "s/^USERLAND_VERSION=\(.*\)$/\1/p") fi fi if [ "${IS_LINUX_JAIL}" -eq 1 ]; then @@ -158,12 +158,16 @@ list_all(){ fi } +# TODO: Check the correct usage or arguments here. See SC2120. +# shellcheck disable=SC2120 list_release(){ if [ -d "${bastille_releasesdir}" ]; then - REL_LIST=$(ls "${bastille_releasesdir}" | sed "s/\n//g") + # TODO: Check if this can be changed to `find` as SC2012 suggests. + # shellcheck disable=SC2012 + REL_LIST="$(ls "${bastille_releasesdir}" | sed "s/\n//g")" for _REL in ${REL_LIST}; do - if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" -o -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then - if [ "${2}" == "-p" -a -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then + if [ -f "${bastille_releasesdir}/${_REL}/root/.profile" ] || [ -d "${bastille_releasesdir}/${_REL}/debootstrap" ]; then + if [ "${2}" = "-p" ] && [ -f "${bastille_releasesdir}/${_REL}/bin/freebsd-version" ]; then REL_PATCH_LEVEL=$(sed -n "s/^USERLAND_VERSION=\"\(.*\)\"$/\1/p" "${bastille_releasesdir}/${_REL}/bin/freebsd-version" 2> /dev/null) REL_PATCH_LEVEL=${REL_PATCH_LEVEL:-${_REL}} echo "${REL_PATCH_LEVEL}" diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index 7ccb3813..b530b039 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -45,10 +45,8 @@ esac if [ $# -lt 2 ]; then usage elif [ $# -eq 2 ]; then - # shellcheck disable=SC2124 _fstab="$@ nullfs ro 0 0" else - # shellcheck disable=SC2124 _fstab="$@" fi diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 6bd7fbcd..74279304 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -70,7 +70,7 @@ check_jail_validity() { # Check if jail ip4 address (ip4.addr) is valid (non-VNET only) if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then JAIL_IP=$(/usr/sbin/jls -j "${TARGET}" ip4.addr 2>/dev/null) - if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then + if [ -z "${JAIL_IP}" ] || [ "${JAIL_IP}" = "-" ]; then error_exit "Jail IP not found: ${TARGET}" fi fi @@ -186,10 +186,10 @@ while [ $# -gt 0 ]; do for last in "$@"; do true done - if [ $2 == "(" ] && [ $last == ")" ] ; then + if [ "$2" = "(" ] && [ "$last" = ")" ] ; then check_jail_validity - persist_rdr_log_rule $proto $host_port $jail_port "$@" - load_rdr_log_rule $proto $host_port $jail_port "$@" + persist_rdr_log_rule "$proto" "$host_port" "$jail_port" "$@" + load_rdr_log_rule "$proto" "$host_port" "$jail_port" "$@" shift $# else usage diff --git a/usr/local/share/bastille/stop.sh b/usr/local/share/bastille/stop.sh index a3a8dfbe..49cec54d 100644 --- a/usr/local/share/bastille/stop.sh +++ b/usr/local/share/bastille/stop.sh @@ -73,7 +73,7 @@ for _jail in ${JAILS}; do jail -f "${bastille_jailsdir}/${_jail}/jail.conf" -r "${_jail}" ## remove (captured above) ip4.addr from firewall table - if [ -n "${bastille_network_loopback}" -a ! -z "${_ip}" ]; then + if [ -n "${bastille_network_loopback}" ] && [ ! -z "${_ip}" ]; then if grep -qw "interface.*=.*${bastille_network_loopback}" "${bastille_jailsdir}/${_jail}/jail.conf"; then pfctl -q -t "${bastille_network_pf_table}" -T delete "${_ip}" fi From 7c000a07d839bd1e19aec003e5b80b32c9f2b1b6 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 8 Dec 2024 21:37:26 -0500 Subject: [PATCH 11/21] [WIP] shellcheck linting --- usr/local/share/bastille/export.sh | 2 +- usr/local/share/bastille/list.sh | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index d0d6ea27..1ef540db 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -371,7 +371,7 @@ jail_export() { else if [ -z "${USER_EXPORT}" ]; then # Generate container checksum file - cd "${bastille_backupsdir}" + 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." fi diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 2732ca4d..25190642 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -203,6 +203,7 @@ list_limit(){ } list_import(){ + # shellcheck disable=SC2010 ls "${bastille_backupsdir}" | grep -v ".sha256$" } From d708a3460de3b182d3b60043c7b4fc13dddb08f2 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Mon, 9 Dec 2024 07:53:56 -0500 Subject: [PATCH 12/21] shellcheck: template, fix quotes --- usr/local/share/bastille/template.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 1ab68364..f984b1ff 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -380,7 +380,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 "Failed to execute command." done < "${bastille_template}/${_hook}" fi info "[${_jail}]:${_hook} -- END" From 097ad8e2696924adaedb4549db4bd636b069d2a9 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Mon, 9 Dec 2024 19:43:04 -0500 Subject: [PATCH 13/21] shellcheck: template, revert single quotes --- usr/local/share/bastille/template.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index f984b1ff..53f50bc0 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -299,7 +299,7 @@ for _jail in ${JAILS}; do # Escape single-quotes in the command being executed. -- cwells _args=$(echo "${_args}" | sed "s/'/'\\\\''/g") # Allow redirection within the jail. -- cwells - _args="sh -c ${_args}" + _args="sh -c '${_args}'" ;; cp|copy) _cmd='cp' From 7bad37c2508d58788ce3e9fc326094cf73bcf794 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Tue, 10 Dec 2024 14:14:07 -0500 Subject: [PATCH 14/21] shellcheck: export, mount. Logic syntax --- usr/local/share/bastille/export.sh | 2 +- usr/local/share/bastille/mount.sh | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 1ef540db..123db04b 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -209,7 +209,7 @@ if [ "${COMP_OPTION}" -gt "1" ]; then error_exit "Error: Only one compression format can be used during export." fi -if [ -n "${TXZ_EXPORT}" ] || [ -n "${TGZ_EXPORT}" ] && [ -n "${SAFE_EXPORT}" ]; then +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." fi diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index b530b039..f9723509 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -69,11 +69,11 @@ fi # if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, # procfs" -if [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ] || - [ "${_hostpath}" = "linprocfs" ] && [ "${_type}" = "linprocfs" ] || - [ "${_hostpath}" = "linsysfs" ] && [ "${_type}" = "linsysfs" ] || - [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ] || - [ "${_hostpath}" = "fdesc" ] && [ "${_type}" = "fdescfs" ]; then +if { [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ]; } || + { [ "${_hostpath}" = "linprocfs" ] && [ "${_type}" = "linprocfs" ]; } || + { [ "${_hostpath}" = "linsysfs" ] && [ "${_type}" = "linsysfs" ]; } || + { [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ]; } || + { [ "${_hostpath}" = "fdesc" ] && [ "${_type}" = "fdescfs" ]; } then warn "Detected advanced mount type ${_hostpath}" elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then error_notify "Detected invalid host path or incorrect mount type in FSTAB." From 763184ad5269a8efcf75b100149d2d19740a0452 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 15 Dec 2024 09:43:24 -0500 Subject: [PATCH 15/21] shellcheck: disable=SC2046 on verify.sh --- usr/local/share/bastille/verify.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 87b0d07b..178e06cc 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -78,7 +78,8 @@ verify_template() { info "Detected ${_hook} hook." ## line count must match newline count - if [ "$(wc -l "${_path}" | awk '{print $1}')" -ne "$(grep -c printf '\n' "${_path}")" ]; then + # shellcheck disable=SC2046 + if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c printf '\n' "${_path}") ]; then info "[${_hook}]:" error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]." error_notify "Line numbers don't match line breaks." From fd175fddca97d7618bff2bb75350b5999f1da538 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 15 Dec 2024 09:57:30 -0500 Subject: [PATCH 16/21] shellcheck: disable=SC2046 on verify.sh pt2 --- usr/local/share/bastille/verify.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 178e06cc..4ae5c48e 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -79,7 +79,7 @@ verify_template() { ## line count must match newline count # shellcheck disable=SC2046 - if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c printf '\n' "${_path}") ]; then + if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then info "[${_hook}]:" error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]." error_notify "Line numbers don't match line breaks." From 63964b107dc882d5eea8b2b0451efe3a0cd7123d Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 15 Dec 2024 09:58:05 -0500 Subject: [PATCH 17/21] shellcheck: disable=SC3003 on verify.sh --- usr/local/share/bastille/verify.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/usr/local/share/bastille/verify.sh b/usr/local/share/bastille/verify.sh index 4ae5c48e..8f50dffa 100644 --- a/usr/local/share/bastille/verify.sh +++ b/usr/local/share/bastille/verify.sh @@ -79,6 +79,7 @@ verify_template() { ## line count must match newline count # shellcheck disable=SC2046 + # shellcheck disable=SC3003 if [ $(wc -l "${_path}" | awk '{print $1}') -ne $(grep -c $'\n' "${_path}") ]; then info "[${_hook}]:" error_notify "${BASTILLE_TEMPLATE}:${_hook} [failed]." From a906f14ce8ebcb8f513080e8306ba14e02a9ce3d Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 15 Dec 2024 10:51:30 -0500 Subject: [PATCH 18/21] shellcheck: fix double quote on `update TEMPLATES` --- usr/local/share/bastille/update.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/update.sh b/usr/local/share/bastille/update.sh index 4304a73a..60458a81 100644 --- a/usr/local/share/bastille/update.sh +++ b/usr/local/share/bastille/update.sh @@ -145,8 +145,8 @@ templates_update() { _updated_templates=0 if [ -d "${bastille_templatesdir}" ]; then # shellcheck disable=SC2045 - for _template_path in $(ls -d "${bastille_templatesdir}/*/*"); do - if [ -d "$_template_path/.git" ]; then + 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 }') template_update From 124e968b652178be0e39c73367f8b6e9e50c8485 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 15 Dec 2024 10:59:30 -0500 Subject: [PATCH 19/21] shellcheck: fix zfs intentional '@' and disable SC2140 --- usr/local/share/bastille/zfs.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/zfs.sh b/usr/local/share/bastille/zfs.sh index 0c771d3b..0bcedbec 100644 --- a/usr/local/share/bastille/zfs.sh +++ b/usr/local/share/bastille/zfs.sh @@ -38,7 +38,8 @@ usage() { zfs_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" - 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}" echo done } @@ -46,7 +47,8 @@ done zfs_destroy_snapshot() { for _jail in ${JAILS}; do info "[${_jail}]:" - 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}" echo done } From 78d2ae9b2c7064ab65a1e20857134434502cbca8 Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 15 Dec 2024 11:02:28 -0500 Subject: [PATCH 20/21] shellcheck: fix create intentional '@' and disable SC2140 --- usr/local/share/bastille/create.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 488fa559..f0a1250f 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -411,9 +411,11 @@ create_jail() { info "Creating a clonejail...\n" ## clone the release base to the new basejail SNAP_NAME="bastille-clone-$(date +%Y-%m-%d-%H%M%S)" - zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" + # shellcheck disable=SC2140 + zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" - zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" \ + # shellcheck disable=SC2140 + zfs clone -p "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" \ "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" # Check and apply required settings. @@ -427,17 +429,21 @@ create_jail() { ## take a temp snapshot of the base release SNAP_NAME="bastille-$(date +%Y-%m-%d-%H%M%S)" - zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" + # shellcheck disable=SC2140 + zfs snapshot "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" ## replicate the release base to the new thickjail and set the default mountpoint - zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" | \ + # shellcheck disable=SC2140 + zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" | \ zfs receive "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" zfs set ${ZFS_OPTIONS} mountpoint=none "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" zfs inherit mountpoint "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root" ## cleanup temp snapshots initially - zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}@${SNAP_NAME}" - zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root@${SNAP_NAME}" + # shellcheck disable=SC2140 + zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/releases/${RELEASE}"@"${SNAP_NAME}" + # shellcheck disable=SC2140 + zfs destroy "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${NAME}/root"@"${SNAP_NAME}" fi if [ "$?" -ne 0 ]; then From 889308465f85205358db9ae91d53c6952233183e Mon Sep 17 00:00:00 2001 From: Juan David Hurtado G Date: Sun, 15 Dec 2024 21:06:59 -0500 Subject: [PATCH 21/21] shellcheck: mount. Style: indication of line continuation --- usr/local/share/bastille/mount.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usr/local/share/bastille/mount.sh b/usr/local/share/bastille/mount.sh index f9723509..bb0e6615 100644 --- a/usr/local/share/bastille/mount.sh +++ b/usr/local/share/bastille/mount.sh @@ -69,10 +69,10 @@ fi # if host path doesn't exist, type is not "nullfs" or are using advanced mount type "tmpfs,linprocfs,linsysfs, fdescfs, # procfs" -if { [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ]; } || - { [ "${_hostpath}" = "linprocfs" ] && [ "${_type}" = "linprocfs" ]; } || - { [ "${_hostpath}" = "linsysfs" ] && [ "${_type}" = "linsysfs" ]; } || - { [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ]; } || +if { [ "${_hostpath}" = "tmpfs" ] && [ "$_type" = "tmpfs" ]; } || \ + { [ "${_hostpath}" = "linprocfs" ] && [ "${_type}" = "linprocfs" ]; } || \ + { [ "${_hostpath}" = "linsysfs" ] && [ "${_type}" = "linsysfs" ]; } || \ + { [ "${_hostpath}" = "proc" ] && [ "${_type}" = "procfs" ]; } || \ { [ "${_hostpath}" = "fdesc" ] && [ "${_type}" = "fdescfs" ]; } then warn "Detected advanced mount type ${_hostpath}" elif [ ! -d "${_hostpath}" ] || [ "${_type}" != "nullfs" ]; then