diff --git a/CHANGELOG b/CHANGELOG index 1ee20fc..0de422c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ ====================== Version Description +1.2.00......Re-add Linux jail feature, WebGUI fixes and overall improvements. 1.1.53......Code changes, handle osrelease parameter update in bastille-init. 1.1.52......Re-add Thin jail release change and code improvements. 1.1.51......Code update/improvements, update jail config/util pages and bastille-init. diff --git a/LICENSE b/LICENSE index 85f2386..39f2630 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ --------------------------------------------------------- - Copyright (c) 2019, José Rivera + Copyright (c) 2019-2025, Jose Rivera All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/bastille-init b/bastille-init index 79418be..16570cd 100644 --- a/bastille-init +++ b/bastille-init @@ -9,7 +9,7 @@ # Debug script #set -x -# Copyright (c) 2019-2024, José Rivera (joserprg@gmail.com). +# Copyright (c) 2019-2025, Jose Rivera (joserprg@gmail.com). # All rights reserved. # Redistribution and use in source and binary forms, with or without @@ -43,14 +43,11 @@ PATH=${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin CWDIR=$(dirname $(realpath $0)) # Global variables. -CWDIR_TRIM="" -BASTILLE_ZFS_ZPOOL_MOUNTPOINT="" -BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM="" -REQUIRED_UPDATE="" PLATFORM=$(uname -m) PRODUCT=$(uname -i) PRDVERSION=$(uname -r | cut -d '-' -f1 | tr -d '.') HOSTVERSION=$(freebsd-version | cut -d '-' -f1) +BASTILLE_DIR=$(echo "${CWDIR}" | grep -o '[^/]*$') PRDPLATFORM=$(cat /etc/platform) PRDPRODUCT=$(cat /etc/prd.name) SCRIPTNAME=$(basename $0) @@ -58,6 +55,7 @@ CONFIG="/cf/conf/config.xml" PRDNAME="Bastille" APPNAME="bastille" EXTLOGFILE="${CWDIR}/log/bastille_ext.log" +EXTLOCKFILE="/tmp/bastille_ext.lock" FULLAPPNAME="${APPNAME}-dist" WWWPATH="/usr/local/www" PKGCACHE="/var/cache/pkg" @@ -82,27 +80,42 @@ BASTILLE_VERSION="https://raw.githubusercontent.com/BastilleBSD/${APPNAME}/${BRA GITURL="https://github.com/JRGTH/xigmanas-${APPNAME}-extension/archive/${BRANCH}.zip" VERFILE="https://raw.githubusercontent.com/JRGTH/xigmanas-${APPNAME}-extension/${BRANCH}/version" URL_FREEBSD="http://ftp.freebsd.org/pub/FreeBSD/releases/" +URL_FREEBSD_OLD="https://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/" URL_HARDENEDBSD="https://installers.hardenedbsd.org/pub/" URL_MIDNIGHTBSD="https://www.midnightbsd.org/ftp/MidnightBSD/releases/" OPT="${1}" +ARG="${2}" -# Bastille required +# Load bastille configuration file. if [ -f "${BASTILLECONF}" ]; then . /${BASTILLECONF} - if [ "${bastille_zfs_enable}" = "YES" -o "${bastille_zfs_enable}" = "yes" ]; then - if [ -n "${bastille_zfs_prefix}" ] && [ -n "${bastille_zfs_zpool}" ]; then - # Always enforce ZFS activation below "/mnt/" from the extension. - if echo "${CWDIR}" | grep -q '/mnt/'; then - CWDIR_TRIM=$(echo "${CWDIR}" | sed "s|/mnt/||;s|/${bastille_zfs_prefix}||") - fi +else + . /${INSTALLPATH}/${BASTILLECONF} +fi - BASTILLE_ZFS_ZPOOL_MOUNTPOINT=$(zfs get -H -o value mountpoint "${bastille_zfs_zpool}") - BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM="" - if echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT}" | grep -q '/mnt/'; then - BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM=$(echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT}" | sed "s|/mnt/||;s|/${bastille_zfs_prefix}||") - fi +# Unset variables. +REQUIRED_UPDATE= +CWDIR_TRIM= +BASTILLE_ZFS_PREFIX_TRIM= +BASTILLE_ZFS_ZPOOL_MOUNTPOINT= +BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM= + +# Get extension ZFS config info. +if [ "${bastille_zfs_enable}" = "YES" ] || [ "${bastille_zfs_enable}" = "yes" ]; then + if [ -n "${bastille_zfs_prefix}" ] && [ -n "${bastille_zfs_zpool}" ]; then + # Always enforce ZFS activation below "/mnt/" from the extension. + if echo "${CWDIR}" | grep -q '/mnt/'; then + CWDIR_TRIM=$(echo "${CWDIR}" | sed "s|/mnt/||;s|/${bastille_zfs_prefix}||") fi + BASTILLE_ZFS_ZPOOL_MOUNTPOINT=$(zfs get -H -o value mountpoint "${bastille_zfs_zpool}" 2>/dev/null) + if echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT}" | grep -q '/mnt/'; then + BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM=$(echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT}" | sed "s|/mnt/||;s|/${bastille_zfs_prefix}||") + fi + BASTILLE_ZFS_PREFIX_TRIM=$(echo "${bastille_zfs_prefix}" | sed "s|/${BASTILLE_DIR}||") fi + # Check bastille ZFS config match on disk ZFS config. + BASTILLE_CONFIG_DISK=$(zfs list -H "${bastille_prefix}" 2>/dev/null | awk '{print $1}') + BASTILLE_CONFIG_FILE=$(echo "${bastille_zfs_zpool}/${bastille_zfs_prefix}") fi error_notify() @@ -117,7 +130,7 @@ runtime_config() { # Run-time configuration and checks. if [ -f "${INSTALLPATH}/${BASTILLECONF}" ]; then - if ! sysrc -f ${BASTILLECONF} -qn bastille_prefix | grep -q "${CWDIR}"; then + if ! sysrc -f ${BASTILLECONF} -qc bastille_prefix="${CWDIR}"; then sysrc -f ${INSTALLPATH}/${BASTILLECONF} bastille_prefix="${CWDIR}" >/dev/null 2>&1 fi fi @@ -404,19 +417,11 @@ sys_symlinkdir() ln -fhs ${INSTALLPATH}${USRLOCAL}/etc/${APPNAME} ${USRLOCAL}/etc/${APPNAME} fi - # Link bastille config file. - #if [ -f "${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf.sample" ]; then - # cd ${INSTALLPATH}${USRLOCAL}/etc/${APPNAME} - # if [ ! -f "${APPNAME}.conf" ]; then - # cp ${APPNAME}.conf.sample ${APPNAME}.conf - # fi - #else - if [ -f "${BASTILLECONF_EXT}" ]; then - if [ ! -f "${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf" ]; then - cp ${BASTILLECONF_EXT} ${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf - fi + if [ -f "${BASTILLECONF_EXT}" ]; then + if [ ! -f "${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf" ]; then + cp ${BASTILLECONF_EXT} ${INSTALLPATH}${USRLOCAL}/etc/${APPNAME}/${APPNAME}.conf fi - #fi + fi # Copy bastille shared. if [ -d "${INSTALLPATH}${USRLOCAL}/share/${APPNAME}" ]; then @@ -515,16 +520,14 @@ postinit_cmd() touch ${CWDIR}/postinit || error_notify "Error: A problem has occurred while creating the postinit file." chmod +x ${CWDIR}/postinit if [ "${PRDVERSION}" -ge "110" ]; then - # Generate php script for start/stop commands. + # Generate php script only for start command for extension version 1.2 and later. cat << EOF > ${CWDIR}/postinit EOF fi @@ -616,6 +605,8 @@ gui_enable() else error_notify "Error: Extension gui files not found." fi + + exit 0 } gui_disable() @@ -639,13 +630,15 @@ gui_disable() rm -r ${WWWPATH}/ext fi fi + + exit 0 } jail_update() { # Workaround since XigmaNAS does not ship with freebsd-update command. - if [ "${PRDPRODUCT}" = "XigmaNAS" -o "${PRDPRODUCT}" = "NAS4Free" ]; then + if [ "${PRDPRODUCT}" = "XigmaNAS" ] || [ "${PRDPRODUCT}" = "NAS4Free" ]; then if [ ! -d "${FREEBSD_UPDATE}" ]; then echo "Not supported on ${PRDPRODUCT} platform." exit 1 @@ -834,7 +827,7 @@ thickjail_upgrade() { # Workaround since XigmaNAS does not ship with freebsd-update command. - if [ "${PRDPRODUCT}" = "XigmaNAS" -o "${PRDPRODUCT}" = "NAS4Free" ]; then + if [ "${PRDPRODUCT}" = "XigmaNAS" ] || [ "${PRDPRODUCT}" = "NAS4Free" ]; then if [ ! -d "${FREEBSD_UPDATE}" ]; then echo "Not supported on ${PRDPRODUCT} platform." exit 1 @@ -891,7 +884,7 @@ thickjail_install() { # Workaround since XigmaNAS does not ship with freebsd-update command. - if [ "${PRDPRODUCT}" = "XigmaNAS" -o "${PRDPRODUCT}" = "NAS4Free" ]; then + if [ "${PRDPRODUCT}" = "XigmaNAS" ] || [ "${PRDPRODUCT}" = "NAS4Free" ]; then if [ ! -d "${FREEBSD_UPDATE}" ]; then echo "Not supported on ${PRDPRODUCT} platform." exit 1 @@ -937,12 +930,7 @@ zfs_activate() # Check if ZFS is already configured. # Always enforce ZFS activation below "/mnt/" from the extension. if echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM}" | grep -qw "${CWDIR_TRIM}$"; then - - BASTILLE_DIR=$(echo "${CWDIR}" | grep -o '[^/]*$') - if [ "${bastille_zfs_prefix}" != "${BASTILLE_DIR}" ]; then - error_notify "Invalid ZFS configuration." - fi - if zfs list "${bastille_zfs_zpool}/${BASTILLE_DIR}" > /dev/null 2>&1; then + if zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" > /dev/null 2>&1; then echo "Bastille ZFS is already configured." sysrc -f ${CWDIR}${EXTCONF} ZFS_ACTIVATED="YES" >/dev/null 2>&1 exit 0 @@ -958,23 +946,26 @@ zfs_activate() echo "Enabling ZFS on ${PRDNAME} Extension..." # Confirm before conversion. - while : - do - read -p "Do you really wish to enable ZFS for ${PRDNAME} Extension? [y/N]:" yn - case ${yn} in - [Yy]) break;; - [Nn]) exit 0;; - esac - done + while :; do + read -p "Do you really want to enable ZFS for ${PRDNAME} Extension? [y/N]:" _yn + case ${_yn} in + [Yy]) + break + ;; + [Nn]) + exit 0 + ;; + esac + done echo "Proceeding..." if [ "${bastille_zfs_enable}" = "YES" ]; then - if [ ! -z "${bastille_zfs_zpool}" ]; then + if [ -n "${bastille_zfs_zpool}" ]; then if zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then - if ! zfs list "${bastille_zfs_zpool}/${BASTILLE_DIR}" > /dev/null 2>&1; then - echo "Renaming existing '${BASTILLE_DIR}' directory" + if ! zfs list "${bastille_zfs_zpool}/${bastille_zfs_prefix}" > /dev/null 2>&1; then + echo "Renaming existing '${BASTILLE_DIR}' directory..." mv ${CWDIR} ${CWDIR}.old - echo "Creating a new ZFS dataset for '${BASTILLE_DIR}'" + echo "Creating a new ZFS dataset for '${BASTILLE_DIR}'..." zfs create ${bastille_zfs_options} ${bastille_zfs_zpool}/${bastille_zfs_prefix} if [ $? -ne 0 ]; then MSG="Failed to enable ZFS, reverting changes." @@ -990,7 +981,7 @@ zfs_activate() echo "Bastille ZFS is already configured." fi else - error_notify "ERROR: ${bastille_zfs_zpool} is not a ZFS pool/dataset." + error_notify "ERROR: ${bastille_zfs_zpool} is not a ZFS pool." fi else error_notify "Bastille ZPOOL is not set." @@ -1021,11 +1012,40 @@ pkg_upgrade() reset_install() { + # Confirm for addon config reset. + while :; do + read -p "Do you really want to proceed with the ${PRDNAME} Extension config reset? [y/N]:" _yn + case ${_yn} in + [Yy]) + break + ;; + [Nn]) + exit 0 + ;; + esac + done + echo "Proceeding..." + + # Check for running jails before config reset. + for _jail in $(bastille list jail); do + if jls -j ${_jail} >/dev/null 2>&1; then + echo "Looks like there are running bastille jails, aborting." + exit 1 + fi + done + # Reset the extension environment. echo "Removing extension files..." + if [ -f "${CWDIR}/conf/bastille_config" ]; then - rm -rf ${CWDIR}/conf/bastille_config + echo "Backup current extension config file." + if [ -f "${CWDIR}/conf/bastille_config.old" ]; then + # Remove previous backup file. + rm -f ${CWDIR}/conf/bastille_config.old + fi + mv -vf ${CWDIR}/conf/bastille_config ${CWDIR}/conf/bastille_config.old fi + if [ -d "${CWDIR}/${FULLAPPNAME}" ]; then rm -rf ${CWDIR}/${FULLAPPNAME} fi @@ -1036,56 +1056,68 @@ reset_install() rm -f ${CWDIR}/version fi + sleep 3 + # Set default config. - sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE=YES INSTALL_DIR=${CWDIR} >/dev/null 2>&1 + touch ${CWDIR}/conf/bastille_config + sysrc -f ${CWDIR}${EXTCONF} GUI_ENABLE="YES" >/dev/null 2>&1 + sysrc -f ${CWDIR}${EXTCONF} INSTALL_DIR="${CWDIR}" >/dev/null 2>&1 + sysrc -f ${CWDIR}${EXTCONF} BASTILLE_CONFIG="${CWDIR}/${FULLAPPNAME}${BASTILLECONF}" >/dev/null 2>&1 + sysrc -f ${CWDIR}${EXTCONF} BACKUP_DIR="${CWDIR}/backups" >/dev/null 2>&1 + sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="NO" >/dev/null 2>&1 echo "" echo "*************************************************************************************************************" echo "* The configuration was reset, please go to [Extensions > Bastille > Configuration] to configure bastille. *" - echo "* Alternatively you can edit the '/usr/local/etc/bastille/bastille.conf' file manually. *" + echo "* Alternatively you can edit the 'addon/bastille-dist/usr/local/etc/bastille/bastille.conf' file manually. *" echo "*************************************************************************************************************" echo "" - echo "Notice: If Linux Jail support was enabled, please execute the below command to re-enable it:" + echo "Notice: If Linux Jail support was enabled, please execute the below command to manually re-enable it:" echo "==> sysrc -f ${CWDIR}${EXTCONF} LINUX_COMPAT_SUPPORT=\"YES\"" echo "" + + # Tell Bastille Extension that config was reset. + touch ${CWDIR}/conf/config_reset.lock } remove_addon() { # Confirm for addon removal. - while : - do - read -p "Do you wish to proceed with the ${FULLAPPNAME} removal? [y/N]:" yn - case ${yn} in - [Yy]) break;; - [Nn]) exit 0;; - esac - done + while :; do + read -p "Do you want to proceed with the ${FULLAPPNAME} removal? [y/N]:" _yn + case ${_yn} in + [Yy]) break + ;; + [Nn]) exit 0 + ;; + esac + done echo "Proceeding..." - # Check for working platform and remove symlinks. - if [ "${PRDPLATFORM}" = "x64-embedded" ] || [ "${PRDPLATFORM}" = "x64-full" ]; then - if [ -d "${USRLOCAL}/share/licenses/${APPNAME}-*" ]; then - rm -rf ${USRLOCAL}/share/licenses/${APPNAME}-* - fi - if [ -d $"{USRLOCAL}/share/locale-bastille" ]; then - rm -rf ${USRLOCAL}/share/locale-bastille - fi - if [ -f "${USRLOCAL}/etc/rc.d/${APPNAME}" ]; then - rm -f ${USRLOCAL}/etc/rc.d/${APPNAME} - fi - if [ -f "${USRLOCAL}/etc/${APPNAME}.conf" ]; then - rm -f ${USRLOCAL}/etc/${APPNAME}.conf - fi - if [ -f "${BASTILLEPATH}/${APPNAME}" ]; then - rm -f ${BASTILLEPATH}/${APPNAME} - fi - if [ -f "${USRLOCAL}/sbin/${APPNAME}-init" ]; then - rm -rf ${USRLOCAL}/sbin/${APPNAME}-init - fi - if [ -d "${VARLOG}/${APPNAME}" ]; then - rm -rf ${VARLOG}/${APPNAME} - fi + # Check and disable extension unionfs in case it is enabled. + ${CWDIR}/unionfs.sh unionfs_off + + # Check and remove extension files/symlinks. + if [ -d "${USRLOCAL}/share/licenses/${APPNAME}-*" ]; then + rm -rf ${USRLOCAL}/share/licenses/${APPNAME}-* + fi + if [ -d "${USRLOCAL}/share/locale-bastille" ]; then + rm -rf ${USRLOCAL}/share/locale-bastille + fi + if [ -f "${USRLOCAL}/etc/rc.d/${APPNAME}" ]; then + rm -f ${USRLOCAL}/etc/rc.d/${APPNAME} + fi + if [ -f "${USRLOCAL}/etc/${APPNAME}" ]; then + rm -f ${USRLOCAL}/etc/${APPNAME} + fi + if [ -f "${BASTILLEPATH}/${APPNAME}" ]; then + rm -f ${BASTILLEPATH}/${APPNAME} + fi + if [ -f "${BASTILLEPATH}/${APPNAME}-init" ]; then + rm -rf ${BASTILLEPATH}/${APPNAME}-init + fi + if [ -d "${VARLOG}/${APPNAME}" ]; then + rm -rf ${VARLOG}/${APPNAME} fi # Remove extension and GUI components. @@ -1112,21 +1144,22 @@ remove_addon() # Remove addon related files and folders only- # to protect any user-created custom files- # as well as for the containers dirs/files. - FILES="conf download freebsd-update gui locale-bastille log bastille-dist LICENSE README.md postinit CHANGELOG version bastille-init" + FILES="bastille-dist conf download freebsd-update gui locale-bastille log system CHANGELOG LICENSE README.md bastille-init postinit unionfs.sh version" for FILE in ${FILES}; do if [ -f "${CWDIR}/${FILE}" ] || [ -d "${CWDIR}/${FILE}" ]; then rm -rf ${CWDIR}/${FILE} fi done - BIN_FILES="/usr/local/bin/ar /usr/local/bin/jib /usr/sbin/setfib /usr/bin/sum /usr/bin/diff3 /usr/bin/makewhatis" + # Remove this files since they are not part of the base. + BIN_FILES="/usr/bin/ar /usr/local/bin/jib /usr/sbin/setfib /usr/bin/sum /usr/bin/diff3 /usr/bin/makewhatis" for FILE in ${BIN_FILES}; do if [ -f "${FILE}" ]; then rm -rf ${FILE} fi done - # Don't remove this files on 13.x versions since they are part of the base. + # Don't remove this files on 13.x and later versions since they are part of the base. if [ "$(freebsd-version | cut -d '.' -f1)" -le 12 ]; then PF_FILES="/sbin/pfctl /sbin/pfilctl /sbin/pflogd /etc/pf.os" for FILE in ${PF_FILES}; do @@ -1159,31 +1192,27 @@ get_versions() ext_start() { - if sysrc -f ${CWDIR}${EXTCONF} -qn LINUX_COMPAT_SUPPORT | grep -q "YES"; then + if sysrc -f ${CWDIR}${EXTCONF} -qc LINUX_COMPAT_SUPPORT=YES; then ${CWDIR}/unionfs.sh load_kmods - ${CWDIR}/unionfs.sh unionfs_on fi # Start bastille jails. if [ -d "${CWDIR}/jails" ]; then - JAIL_LIST=$(bastille list jail) - # This loop is for backward compatibility only. - for jail in ${JAIL_LIST}; do - if grep -qw "${jail}_AUTO_START=\"YES\"" ${CWDIR}${EXTCONF}; then - if ! jls | sed "1 d" | awk '{print $3}' | grep -qw ${jail}; then - bastille start ${jail} - fi - fi - done - - # Required for embedded platforms. + # Required for embedded platforms due late startup. if [ "${PRDPLATFORM}" = "x64-embedded" ]; then if sysrc -qc bastille_enable=YES; then - service bastille start + if [ ! -f "${EXTLOCKFILE}" ]; then + service bastille start + fi fi fi fi + # Create extension lock file after boot. + if [ ! -f "${EXTLOCKFILE}" ]; then + touch ${EXTLOCKFILE} + fi + if [ $? -eq 0 ]; then MSG="script has been started successfully!" logger -t ${SCRIPTNAME} ${MSG} @@ -1195,12 +1224,37 @@ ext_start() fi } +zfs_support_enabled() +{ + sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="YES" >/dev/null 2>&1 + sysrc -f ${CWDIR}${EXTCONF} ZFS_ACTIVATED="YES" >/dev/null 2>&1 +} + +zfs_support_error() +{ + echo "WARNING: Invalid ZFS configuration." + sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="ERR" >/dev/null 2>&1 + sysrc -f ${CWDIR}${EXTCONF} -x ZFS_ACTIVATED >/dev/null 2>&1 +} + +zfs_support_avail() +{ + echo "WARNING: ZFS support available but not enabled." + sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="AVA" >/dev/null 2>&1 +} + +zfs_support_disabled() +{ + sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="NO" >/dev/null 2>&1 + sysrc -f ${CWDIR}${EXTCONF} -x ZFS_ACTIVATED >/dev/null 2>&1 +} + rc_params() { # Bastille required parameters. # Set bastille prefix. - if ! sysrc -f ${BASTILLECONF} -qn bastille_prefix | grep -q "${CWDIR}"; then + if ! sysrc -f ${BASTILLECONF} -qc bastille_prefix="${CWDIR}"; then sysrc -f ${BASTILLECONF} bastille_prefix="${CWDIR}" >/dev/null 2>&1 fi @@ -1216,13 +1270,13 @@ rc_params() fi # Set bastille.conf location. - if ! sysrc -f ${CWDIR}${EXTCONF} -n BASTILLE_CONFIG 2>/dev/null | grep -q "${CWDIR}/${FULLAPPNAME}${BASTILLECONF}"; then + if ! sysrc -f ${CWDIR}${EXTCONF} -qc BASTILLE_CONFIG="${CWDIR}/${FULLAPPNAME}${BASTILLECONF}"; then sysrc -f ${CWDIR}${EXTCONF} BASTILLE_CONFIG="${CWDIR}/${FULLAPPNAME}${BASTILLECONF}" >/dev/null 2>&1 fi # Default first network interface. ACTIVE_NETIF=$(ifconfig | grep "UP,BROADCAST" | awk -F":" '{print $1}' | sed 1q) - if ! sysrc -f ${BASTILLECONF} -qn bastille_network_shared | grep -q "${ACTIVE_NETIF}" >/dev/null 2>&1; then + if ! sysrc -f ${BASTILLECONF} -qc bastille_network_shared="${ACTIVE_NETIF}" >/dev/null 2>&1; then #echo "" >> ${BASTILLECONF} && echo "## default network interface" >> ${BASTILLECONF} sysrc -f ${BASTILLECONF} bastille_network_shared="${ACTIVE_NETIF}" >/dev/null 2>&1 else @@ -1233,33 +1287,64 @@ rc_params() fi fi - # Do't start containers by default. - #if ! sysrc -qn bastille_enable >/dev/null 2>&1; then - # sysrc bastille_enable="NO" >/dev/null 2>&1 - #fi + # Check if extension config was reset. + if [ -f "${CWDIR}/conf/config_reset.lock" ]; then + zfs_support_error + echo "WARNING: ${PRDNAME} Extension config was reset." + rm ${CWDIR}/conf/config_reset.lock + fi - # Check if sane ZFS is enabled in this setup. + # Check for sane ZFS parameters in this setup. if [ "${bastille_zfs_enable}" = "YES" ]; then if [ -n "${bastille_zfs_zpool}" ]; then - if zfs list "${bastille_zfs_zpool}" > /dev/null 2>&1; then - BASTILLE_DIR=$(echo ${CWDIR} | grep -o '[^/]*$') - if zfs list "${bastille_zfs_zpool}/${BASTILLE_DIR}" > /dev/null 2>&1; then - sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="YES" >/dev/null 2>&1 - else - if echo "${BASTILLE_ZFS_ZPOOL_MOUNTPOINT_TRIM}" | grep -qw "${CWDIR_TRIM}$"; then - sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="AVA" >/dev/null 2>&1 + if zfs list "${bastille_zfs_zpool}" >/dev/null 2>&1; then + + # Check bastille ZFS config match on disk ZFS config if activation is already enabled in the config file. + if sysrc -f ${CWDIR}${EXTCONF} -qc ZFS_SUPPORT=YES && sysrc -f ${CWDIR}${EXTCONF} -qc ZFS_ACTIVATED=YES; then + if [ "${BASTILLE_CONFIG_DISK}" != "${BASTILLE_CONFIG_FILE}" ]; then + zfs_support_error + exit 1 else - sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="ERR" >/dev/null 2>&1 + # Check and don't allow child datasets in bastille_zfs_zpool. + if echo "${bastille_zfs_zpool}" | grep -q '\/'; then + zfs_support_error + exit 1 + fi fi fi + + # Perform some checks against on-disk and file configurations. + if zfs list "${bastille_zfs_zpool}/${BASTILLE_ZFS_PREFIX_TRIM}/${BASTILLE_DIR}" >/dev/null 2>&1; then + # Looks like ZFS support is already configured, then set parameters. + zfs_support_enabled + elif zfs list "${bastille_zfs_zpool}" >/dev/null 2>&1 && \ + [ "${bastille_zfs_prefix}" = "${BASTILLE_ZFS_PREFIX_TRIM}/${BASTILLE_DIR}" ]; then + # Looks like ZFS support is available for activation. + zfs_support_avail + elif zfs list "${bastille_zfs_zpool}/${BASTILLE_DIR}" >/dev/null 2>&1; then + zfs_support_enabled + elif zfs list "${bastille_zfs_zpool}" >/dev/null 2>&1 && \ + [ "${BASTILLE_ZFS_PREFIX_TRIM}" = "${BASTILLE_DIR}" ]; then + # Looks like ZFS support is available for activation. + zfs_support_avail + elif zfs list "${bastille_zfs_zpool}/${BASTILLE_DIR}" >/dev/null 2>&1; then + zfs_support_enabled + else + zfs_support_error + fi else - sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="ERR" >/dev/null 2>&1 + zfs_support_error fi else - sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="ERR" >/dev/null 2>&1 + zfs_support_error fi else - sysrc -f ${CWDIR}${EXTCONF} ZFS_SUPPORT="NO" >/dev/null 2>&1 + # Check for orphaned configuration and/or config reset. + if zfs list -H "${CWDIR}" >/dev/null 2>&1; then + zfs_support_error + else + zfs_support_disabled + fi fi # Enable bastille in /etc/rc.conf @@ -1347,9 +1432,7 @@ bastille_stop() { # Stop all bastille containers. echo "${PRDNAME} Extension: Stopping all containers..." - if ! sysrc -qc bastille_enable=YES; then - bastille stop ALL - fi + bastille stop ALL if [ $? -eq 0 ]; then exit 0 else @@ -1389,21 +1472,19 @@ bastille_init() gui_start rc_params ext_start - } -linux_compat() +linux_compat_enable() { - # Feature temporarily disabled. - echo "This feature is temporarily disabled due incompatibility with later ${PRDPRODUCT} releases." - exit 1 - + # Experimental feature. if ping -c1 -t5 freebsd.org > /dev/null; then # Manually enable Linux compatibility(Experimental). - if ! sysrc -f ${CWDIR}${EXTCONF} -qn LINUX_COMPAT_SUPPORT | grep -q "YES"; then - ${CWDIR}/unionfs.sh fetch_pkg && ${CWDIR}/unionfs.sh load_kmods && ${CWDIR}/unionfs.sh unionfs_on && sysrc -f ${CWDIR}${EXTCONF} LINUX_COMPAT_SUPPORT="YES" >/dev/null 2>&1 + if ! sysrc -f ${CWDIR}${EXTCONF} -qc LINUX_COMPAT_SUPPORT=YES; then + echo "Enabling Linux compatibility support..." + #${CWDIR}/unionfs.sh fetch_pkg && ${CWDIR}/unionfs.sh load_kmods && ${CWDIR}/unionfs.sh unionfs_on && sysrc -f ${CWDIR}${EXTCONF} LINUX_COMPAT_SUPPORT="YES" >/dev/null 2>&1 + ${CWDIR}/unionfs.sh fetch_debootstrap && ${CWDIR}/unionfs.sh load_kmods && sysrc -f ${CWDIR}${EXTCONF} LINUX_COMPAT_SUPPORT="YES" >/dev/null 2>&1 else - echo "Already enabled." + echo "Linux compatibility already enabled." fi exit 0 else @@ -1412,13 +1493,80 @@ linux_compat() fi } +bootstrap_dist() +{ + # Workaround since XigmaNAS does not ship with debootstrap command. + if sysrc -f ${CWDIR}${EXTCONF} -qc LINUX_COMPAT_SUPPORT=YES; then + # List of tested/working Linux distributions on FreeBSD 14.x. + LINUX_FLAVORS="ubuntu-bionic ubuntu-focal ubuntu-jammy" + if [ -n "${LINUX_DIST}" ]; then + for _linux_flavor in ${LINUX_FLAVORS}; do + + if [ "${LINUX_DIST}" = "${_linux_flavor}" ]; then + LINUX_FLAVOR="${_linux_flavor}" + break + fi + + done + fi + + if [ -z "${LINUX_FLAVOR}" ]; then + echo "Available Linux flavors:" + echo "${LINUX_FLAVORS}" + exit 1 + fi + + # Enable debootstrap environment. + ${CWDIR}/unionfs.sh unionfs_on + + # Bootstrap Linux flavor using bastille. + bastille bootstrap ${_linux_flavor} + + # Disable debootstrap environment. + ${CWDIR}/unionfs.sh unionfs_off + + else + echo "Linux compatibility disabled." + exit 1 + fi + + exit 0 +} + +update_debootstrap() +{ + # Update debootstrap and dependencies. + if sysrc -f ${CWDIR}${EXTCONF} -qc LINUX_COMPAT_SUPPORT=YES; then + ${CWDIR}/unionfs.sh update_debootstrap + else + echo "Linux compatibility disabled." + exit 1 + fi + + exit 0 +} + linux_compat_disable() { - if sysrc -f ${CWDIR}${EXTCONF} -qn LINUX_COMPAT_SUPPORT | grep -q "YES"; then - echo "Disabling Linux jail compatibility support..." + if sysrc -f ${CWDIR}${EXTCONF} -qc LINUX_COMPAT_SUPPORT=YES; then + echo "Disabling Linux compatibility support..." sysrc -f ${CWDIR}${EXTCONF} -x LINUX_COMPAT_SUPPORT - echo "Done!, server reboot is recommended." + ${CWDIR}/unionfs.sh unionfs_off + ${CWDIR}/unionfs.sh unload_kmods + + if [ -d "${CWDIR}/system/usr" ]; then + echo "Removing debootstrap environment..." + rm -rf ${CWDIR}/system/usr + if [ -d "${CWDIR}/system/var" ]; then + rm -rf ${CWDIR}/system/var + fi + fi + echo "Done!, please reboot server now." + else + echo "Linux compatibility disabled." + exit 1 fi + exit 0 } @@ -1495,7 +1643,14 @@ clean|--clean) exit 0 ;; linux_compat) - linux_compat + linux_compat_enable + ;; +bootstrap) + LINUX_DIST="${ARG}" + bootstrap_dist + ;; +update_debootstrap) + update_debootstrap ;; linux_compat_disable) linux_compat_disable @@ -1505,7 +1660,7 @@ bastillebsd_update) ;; esac -while getopts ":ospruxUvgtZh" option; do +while getopts "ospruxUvgtZh" option; do case ${option} in [h]) echo "Usage: ${SCRIPTNAME} -[option] | [container] | [path]"; echo "Options:" @@ -1539,6 +1694,8 @@ while getopts ":ospruxUvgtZh" option; do echo "" echo "Support:" echo "To update BastilleBSD core files only to the latest patches and fixes, please execute: \"${SCRIPTNAME} bastillebsd_update\"" + echo "To bootstrap a Linux distribution please execute: \"${SCRIPTNAME} bootstrap linux_flavor\"" + echo "To update debootstrap package and dependencies please execute: \"${SCRIPTNAME} update_debootstrap\"" echo ""; exit 0;; [o]) OBI_INSTALL="ON";; # To prevent nested PHP-CGI call for installation with OBI. [s]) bastille_start;; @@ -1548,8 +1705,8 @@ while getopts ":ospruxUvgtZh" option; do [x]) reset_install;; [U]) remove_addon;; [v]) get_versions;; - [g]) gui_enable; exit 0 ;; # For enable the addon gui. - [t]) gui_disable; exit 0 ;; # For disable the addon gui. + [g]) gui_enable;; # Enable the addon gui. + [t]) gui_disable;; # Disable the addon gui. [Z]) zfs_activate;; #[L]) linux_compat;; [?]) echo "Invalid option, -h for usage."; exit 1;; diff --git a/gui/bastille_manager-lib.inc b/gui/bastille_manager-lib.inc index 256102d..18b292e 100644 --- a/gui/bastille_manager-lib.inc +++ b/gui/bastille_manager-lib.inc @@ -2,7 +2,7 @@ /* bastille_manager-lib.inc - Copyright (c) 2019-2020 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Redistribution and use in source and binary forms, with or without @@ -70,15 +70,17 @@ $linux_compat_support = exec("/usr/bin/grep 'LINUX_COMPAT_SUPPORT=' $configfile $jail_settings = "settings.conf"; // Ensure the root directory is configured. -if ($rootfolder == "") +if ($rootfolder == ""): $input_errors[] = gtext("Extension installed with fault"); -else { +else: // Initialize locales. $textdomain = "/usr/local/share/locale"; $textdomain_bastille = "/usr/local/share/locale-bastille"; - if (!is_link($textdomain_bastille)) { mwexec("ln -s {$rootfolder}/locale-bastille {$textdomain_bastille}", true); } + if (!is_link($textdomain_bastille)): + mwexec("ln -s {$rootfolder}/locale-bastille {$textdomain_bastille}", true); + endif; bindtextdomain("xigmanas", $textdomain_bastille); -} +endif; if (is_file("{$rootfolder}/postinit")) unlink("{$rootfolder}/postinit"); // Check releases dir. @@ -90,18 +92,17 @@ function is_dir_empty($reldir) { // Get bastille version function get_version_bastille() { global $tarballversion, $prdname; - if (is_file("{$tarballversion}")) { + if (is_file("{$tarballversion}")): // For some reason bastille bin version value isn't double quoted anymore so we can't use the old delimiter. // we will keep the old line for reference. //exec("/usr/bin/grep 'BASTILLE_VERSION=' {$tarballversion} | cut -d'\"' -f2", $result); exec("/usr/bin/grep 'BASTILLE_VERSION=' {$tarballversion} | cut -d'=' -f2", $result); return ($result[0] ?? ''); - } - else { + else: exec("/usr/local/bin/{$prdname} version | awk 'NR==1'", $result); return ($result[0] ?? ''); - } + endif; } // Initial install banner @@ -148,7 +149,9 @@ function get_state_zfs() { function get_all_release_list() { global $rootfolder; global $g; - exec("/bin/echo; /bin/ls {$rootfolder}/releases 2>/dev/null | /usr/bin/tr -s ' ' '\n'",$relinfo); + // Don't show Linux base releases under create jail page for now. + #exec("/bin/echo; /bin/ls {$rootfolder}/releases 2>/dev/null | /usr/bin/tr -s ' ' '\n'",$relinfo); + exec("/bin/echo; /bin/ls {$rootfolder}/releases | grep RELEASE 2>/dev/null | /usr/bin/tr -s ' ' '\n'",$relinfo); array_shift($relinfo); $rellist = []; foreach($relinfo as $rel): @@ -223,6 +226,7 @@ function get_jail_infos() { if (!$r['id']): $r['id'] = "-"; endif; + // Set the IP address on the running jails using bastille list command instead. //$r['ip'] = exec("/usr/bin/grep -w 'ip4.addr' {$jail_dir}/{$item}/jail.conf | /usr/bin/awk '{print $3}' | /usr/bin/tr -d ';'"); $r['ip'] = exec("/usr/local/bin/bastille list {$item} | awk '{print $7}' | sed 1d"); @@ -236,11 +240,18 @@ function get_jail_infos() { if (!$r['ip']): $r['ip'] = "-"; endif; + // Display release. $r['rel'] = exec("/usr/sbin/jexec {$item} freebsd-version 2>/dev/null"); if (!$r['rel']): - $r['rel'] = exec("/usr/sbin/jexec {$item} uname -o 2>/dev/null"); - elseif (!$r['rel']): + if(is_file("{$jail_dir}/{$item}/root/etc/os-release")): + $r['rel'] = exec("/bin/cat {$jail_dir}/{$item}/root/etc/os-release | grep 'PRETTY_NAME=' | tr -d 'PRETTY_NAME=\"'"); + else: + $r['rel'] = exec("/usr/sbin/jexec {$item} uname -o 2>/dev/null"); + endif; + endif; + // We can't get release version info or jail stopped. + if (!$r['rel']): $r['rel'] = "-"; endif; @@ -269,16 +280,18 @@ function get_jail_infos() { if (!$r['path']): $r['path'] = "-"; endif; + // Display auto-start settings. //$jail_autostart = exec("/usr/bin/grep -w {$item}_AUTO_START $configfile | cut -d'=' -f2 | tr -d '\"'"); $jail_autostart = exec("/usr/bin/grep -w boot {$jail_dir}/{$item}/settings.conf | cut -d'=' -f2 | tr -d '\"'"); - if ($jail_autostart == 'on') { + if ($jail_autostart == 'on'): $r['boot'] = $img_path['ena']; - } elseif ($jail_autostart == 'off') { + elseif ($jail_autostart == 'off'): $r['boot'] = $img_path['dis']; - } else { + else: $r['boot'] = $img_path['dis']; - } + endif; + // Display running status icons. $jail_running = exec("/usr/sbin/jls name | /usr/bin/awk '/^{$item}\$/'"); if ($jail_running): @@ -286,6 +299,7 @@ function get_jail_infos() { else: $r['stat'] = $img_path['dis']; endif; + // Display custom template icons if available. $template_icon = "{$jail_dir}/{$item}/plugin_icon.png"; if(file_exists($template_icon)): diff --git a/gui/bastille_manager_add.php b/gui/bastille_manager_add.php index bf80cd4..fcf71fc 100644 --- a/gui/bastille_manager_add.php +++ b/gui/bastille_manager_add.php @@ -2,7 +2,7 @@ /* bastille_manager_add.php - Copyright (c) 2019 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Portions of XigmaNAS® (https://www.xigmanas.com). @@ -59,6 +59,12 @@ if(!get_all_release_list()): $prerequisites_ok = false; endif; +$zfs_status = get_state_zfs(); +if($zfs_status == "Invalid ZFS configuration"): + // Warning if invalid ZFS configuration. + $input_errors[] = gtext("WARNING: Invalid ZFS configuration detected."); +endif; + if($_POST): global $jail_dir; global $configfile; @@ -69,6 +75,12 @@ if($_POST): exit; endif; if(isset($_POST['Create']) && $_POST['Create']): + $zfs_status = get_state_zfs(); + if($zfs_status == "Invalid ZFS configuration"): + // Abort jail creation if invalid ZFS configuration. + $input_errors[] = gtext("Cannot create jail with an invalid ZFS configuration."); + else: + $jname = $pconfig['jailname']; $ipaddr = $pconfig['ipaddress']; $release = $pconfig['release']; @@ -142,6 +154,8 @@ if($_POST): $errormsg .= gtext(" <<< Failed to create container."); endif; endif; + + endif; endif; endif; @@ -316,7 +330,7 @@ $document->render(); endif; html_checkbox2('emptyjail',gettext('Create an empty container'),!empty($pconfig['emptyjail']) ? true : false,gettext('This are ideal for custom builds, experimenting with unsupported RELEASES or Linux jails.'),'',false,false,'emptyjail_change()'); if($linux_compat_support == "YES"): - html_checkbox2('linuxjail',gettext('Create a Linux container'),!empty($pconfig['linuxjail']) ? true : false,gettext('This will create a Linux container, this is highly experimental and for testing purposes.'),'',false,false,'linuxjail_change()'); + //html_checkbox2('linuxjail',gettext('Create a Linux container'),!empty($pconfig['linuxjail']) ? true : false,gettext('This will create a Linux container, this is highly experimental and for testing purposes.'),'',false,false,'linuxjail_change()'); endif; endif; //html_checkbox2('nowstart',gettext('Start after creation'),!empty($pconfig['nowstart']) ? true : false,gettext('Start the container after creation(May be overridden by later bastille releases).'),'',false); diff --git a/gui/bastille_manager_config.php b/gui/bastille_manager_config.php index 1f85530..2ea7ed6 100644 --- a/gui/bastille_manager_config.php +++ b/gui/bastille_manager_config.php @@ -2,7 +2,7 @@ /* bastille_manager_config.php - Copyright (c) 2019 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Copyright (c) 2018 Andreas Schmidhuber @@ -64,6 +64,12 @@ if(!initial_install_banner()): $prerequisites_ok = false; endif; +$zfs_status = get_state_zfs(); +if($zfs_status == "Invalid ZFS configuration"): + // Warning if invalid ZFS configuration. + $input_errors[] = gtext("WARNING: Invalid ZFS configuration detected."); +endif; + function htmlInput($name, $title, $value="", $size=80) { $result = ""; return $result; diff --git a/gui/bastille_manager_editor.php b/gui/bastille_manager_editor.php index 616ebbd..4f096f9 100644 --- a/gui/bastille_manager_editor.php +++ b/gui/bastille_manager_editor.php @@ -2,7 +2,7 @@ /* bastille_manager_editor.php - Copyright (c) 2019 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Portions of XigmaNAS® (https://www.xigmanas.com). diff --git a/gui/bastille_manager_gui.php b/gui/bastille_manager_gui.php index fedbbd0..dc5abae 100644 --- a/gui/bastille_manager_gui.php +++ b/gui/bastille_manager_gui.php @@ -2,7 +2,7 @@ /* bastille_manager_gui.php - Copyright (c) 2019-2020 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Portions of XigmaNAS® (https://www.xigmanas.com). @@ -53,11 +53,13 @@ $gt_record_mod = gtext('Utilities'); $gt_selection_start = gtext('Start Selected'); $gt_selection_stop = gtext('Stop Selected'); $gt_selection_restart = gtext('Restart Selected'); +$gt_selection_autoboot = gtext('Auto-boot Selected'); $gt_record_conf = gtext('Jail Configuration'); $gt_record_inf = gtext('Information'); $gt_selection_start_confirm = gtext('Do you really want to start selected jail(s)?'); $gt_selection_stop_confirm = gtext('Do you want to stop the selected jail(s)?'); $gt_selection_restart_confirm = gtext('Do you want to restart the selected jail(s)?'); +$gt_selection_autoboot_confirm = gtext('Do you want to set auto-boot on selected jail(s)?'); $img_path = [ 'add' => 'images/add.png', 'mod' => 'images/edit.png', @@ -90,6 +92,12 @@ if(!initial_install_banner()): $prerequisites_ok = false; endif; +$zfs_status = get_state_zfs(); +if($zfs_status == "Invalid ZFS configuration"): + // Warning if invalid ZFS configuration. + $input_errors[] = gtext("WARNING: Invalid ZFS configuration detected."); +endif; + if($_POST): if(isset($_POST['apply']) && $_POST['apply']): $ret = array('output' => [], 'retval' => 0); @@ -159,6 +167,24 @@ if($_POST): endif; endforeach; endif; + +if(isset($_POST['autoboot_selected_jail']) && $_POST['autoboot_selected_jail']): + $checkbox_member_array = isset($_POST[$checkbox_member_name]) ? $_POST[$checkbox_member_name] : []; + foreach($checkbox_member_array as $checkbox_member_record): + if(false !== ($index = array_search_ex($checkbox_member_record, $sphere_array, 'jailname'))): + if(!isset($sphere_array[$index]['protected'])): + $cmd = ("/usr/local/bin/bastille config {$checkbox_member_record} set boot on"); + $return_val = mwexec($cmd); + if($return_val == 0): + //$savemsg .= gtext("Jail(s) restarted successfully."); + header($sphere_header); + else: + $errormsg .= gtext("Failed to restart jail(s)."); + endif; + endif; + endif; + endforeach; + endif; endif; $pgtitle = [gtext("Extensions"), gtext('Bastille')]; @@ -177,6 +203,9 @@ $(window).on("load", function() { $("#restart_selected_jail").click(function () { return confirm(''); }); + $("#autoboot_selected_jail").click(function () { + return confirm(''); + }); // Disable action buttons. disableactionbuttons(true); @@ -192,6 +221,7 @@ function disableactionbuttons(ab_disable) { $("#start_selected_jail").prop("disabled", ab_disable); $("#stop_selected_jail").prop("disabled", ab_disable); $("#restart_selected_jail").prop("disabled", ab_disable); + $("#autoboot_selected_jail").prop("disabled", ab_disable); } function controlactionbuttons(ego, triggerbyname) { @@ -362,6 +392,7 @@ $document->render(); + &1"; diff --git a/gui/bastille_manager_jconf.php b/gui/bastille_manager_jconf.php index 1180579..97a405f 100644 --- a/gui/bastille_manager_jconf.php +++ b/gui/bastille_manager_jconf.php @@ -2,7 +2,7 @@ /* bastille_manager_jconf.inc - Copyright (c) 2020 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Redistribution and use in source and binary forms, with or without @@ -34,6 +34,12 @@ require_once 'auth.inc'; require_once 'guiconfig.inc'; require_once("bastille_manager-lib.inc"); +$zfs_status = get_state_zfs(); +if($zfs_status == "Invalid ZFS configuration"): + // Warning if invalid ZFS configuration. + $input_errors[] = gtext("WARNING: Invalid ZFS configuration detected."); +endif; + if (isset($_GET['uuid'])) $uuid = $_GET['uuid']; if (isset($_POST['uuid'])) diff --git a/gui/bastille_manager_maintenance.php b/gui/bastille_manager_maintenance.php index c2a8c85..d8748e5 100644 --- a/gui/bastille_manager_maintenance.php +++ b/gui/bastille_manager_maintenance.php @@ -2,7 +2,7 @@ /* bastille_manager_maintenance.php - Copyright (c) 2019-2020 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Copyright (c) 2016 Andreas Schmidhuber @@ -54,6 +54,12 @@ if(!initial_install_banner()): $prerequisites_ok = false; endif; +$zfs_status = get_state_zfs(); +if($zfs_status == "Invalid ZFS configuration"): + // Warning if invalid ZFS configuration. + $input_errors[] = gtext("WARNING: Invalid ZFS configuration detected."); +endif; + // For legacy product versions. $legacy_check = mwexec("/bin/cat /etc/prd.version | cut -d'.' -f1 | /usr/bin/grep '10'", true); if ($legacy_check == 0) { @@ -120,8 +126,8 @@ if ($_POST) { $uninstall_cmd = "echo 'y' | /usr/local/sbin/bastille-init -U"; mwexec($uninstall_cmd, true); if (is_link("/usr/local/share/{$prdname}")) mwexec("rm /usr/local/share/{$prdname}", true); - if (is_link("/var/cache/pkg")) mwexec("rm /var/cache/pkg", true); - if (is_link("/var/db/pkg")) mwexec("rm /var/db/pkg && mkdir /var/db/pkg", true); + //if (is_link("/var/cache/pkg")) mwexec("rm /var/cache/pkg", true); + //if (is_link("/var/db/pkg")) mwexec("rm /var/db/pkg && mkdir /var/db/pkg", true); // Remove start postinit cmd in later product versions. if (is_array($config['rc']) && is_array($config['rc']['param'])) { diff --git a/gui/bastille_manager_tarballs.php b/gui/bastille_manager_tarballs.php index 39edf0a..1dca4c3 100644 --- a/gui/bastille_manager_tarballs.php +++ b/gui/bastille_manager_tarballs.php @@ -2,7 +2,7 @@ /* bastille_manager_tarballs.php - Copyright (c) 2019 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Portions of XigmaNAS® (https://www.xigmanas.com). @@ -67,6 +67,13 @@ function get_rel_list() { endif; return $result; } + +$zfs_status = get_state_zfs(); +if($zfs_status == "Invalid ZFS configuration"): + // Warning if invalid ZFS configuration. + $input_errors[] = gtext("WARNING: Invalid ZFS configuration detected."); +endif; + $rel_list = get_rel_list(); $sphere_array = $rel_list; @@ -76,26 +83,17 @@ if ($linux_compat_support == "YES"): '14.2-RELEASE' => gettext('14.2-RELEASE'), '14.1-RELEASE' => gettext('14.1-RELEASE'), '14.0-RELEASE' => gettext('14.0-RELEASE'), + '13.5-RELEASE' => gettext('13.4-RELEASE'), '13.4-RELEASE' => gettext('13.4-RELEASE'), - '13.3-RELEASE' => gettext('13.3-RELEASE'), - '13.2-RELEASE' => gettext('13.2-RELEASE'), - '13.1-RELEASE' => gettext('13.1-RELEASE'), - '13.0-RELEASE' => gettext('13.0-RELEASE'), - '12.4-RELEASE' => gettext('12.4-RELEASE'), - '12.3-RELEASE' => gettext('12.3-RELEASE'), - '12.2-RELEASE' => gettext('12.2-RELEASE'), - '12.1-RELEASE' => gettext('12.1-RELEASE'), - '12.0-RELEASE' => gettext('12.0-RELEASE'), - '11.4-RELEASE' => gettext('11.4-RELEASE'), - '11.3-RELEASE' => gettext('11.3-RELEASE'), - '11.2-RELEASE' => gettext('11.2-RELEASE'), - 'ubuntu-jammy' => gettext('Ubuntu-Jammy'), - 'ubuntu-focal' => gettext('Ubuntu-Focal'), - 'ubuntu-bionic' => gettext('Ubuntu-Bionic'), - 'debian-bookworm' => gettext('Debian-Bookworm'), - 'debian-bullseye' => gettext('Debian-Bullseye'), - 'debian-buster' => gettext('Debian-Buster'), - //'debian-stretch' => gettext('Debian-Stretch'), -> Obsolete, removed from bastille boostrap. + // Linux base release bootstrap is allowed from command-line. + //'ubuntu-jammy' => gettext('Ubuntu-noble'), + //'ubuntu-jammy' => gettext('Ubuntu-Jammy'), + //'ubuntu-focal' => gettext('Ubuntu-Focal'), + //'ubuntu-bionic' => gettext('Ubuntu-Bionic'), + //'debian-bookworm' => gettext('Debian-Bookworm'), + //'debian-bullseye' => gettext('Debian-Bullseye'), + //'debian-buster' => gettext('Debian-Buster'), + //'debian-stretch' => gettext('Debian-Stretch'), ]; else: $a_action = [ @@ -103,19 +101,8 @@ else: '14.2-RELEASE' => gettext('14.2-RELEASE'), '14.1-RELEASE' => gettext('14.1-RELEASE'), '14.0-RELEASE' => gettext('14.0-RELEASE'), + '13.5-RELEASE' => gettext('13.4-RELEASE'), '13.4-RELEASE' => gettext('13.4-RELEASE'), - '13.3-RELEASE' => gettext('13.3-RELEASE'), - '13.2-RELEASE' => gettext('13.2-RELEASE'), - '13.1-RELEASE' => gettext('13.1-RELEASE'), - '13.0-RELEASE' => gettext('13.0-RELEASE'), - '12.4-RELEASE' => gettext('12.4-RELEASE'), - '12.3-RELEASE' => gettext('12.3-RELEASE'), - '12.2-RELEASE' => gettext('12.2-RELEASE'), - '12.1-RELEASE' => gettext('12.1-RELEASE'), - '12.0-RELEASE' => gettext('12.0-RELEASE'), - '11.4-RELEASE' => gettext('11.4-RELEASE'), - '11.3-RELEASE' => gettext('11.3-RELEASE'), - '11.2-RELEASE' => gettext('11.2-RELEASE'), ]; endif; @@ -137,6 +124,7 @@ if($_POST): $check_release = ("{$rootfolder}/releases/{$get_release}"); $cmd = sprintf('/bin/echo "Y" | /usr/local/bin/bastille bootstrap %1$s > %2$s',$get_release,$logevent); $base_mandatory = "base"; + $zfs_status = get_state_zfs(); //unset($lib32,$ports,$src); if (isset($_POST['lib32'])): @@ -150,12 +138,12 @@ if($_POST): endif; $opt_tarballs = "$lib32 $ports $src"; - // FreeBSD base release check. - //if(file_exists($check_release)): - // $savemsg .= sprintf(gtext('%s base appears to be already extracted.'),$get_release); - //else: - // Download a FreeBSD base release. - if ($_POST['Download']): + // Download a FreeBSD base release. + if ($_POST['Download']): + if($zfs_status == "Invalid ZFS configuration"): + // Abort bootstrap if invalid ZFS configuration. + $input_errors[] = gtext("Cannot bootstrap with an invalid ZFS configuration."); + else: $savemsg = ""; $errormsg = ""; if ($opt_tarballs): @@ -179,8 +167,9 @@ if($_POST): else: $errormsg .= sprintf(gtext('%s Failed to download and/or extract release base.'),$get_release); endif; + endif; - //endif; + endif; endif; if (isset($_POST['Destroy']) && $_POST['Destroy']): diff --git a/gui/bastille_manager_util.php b/gui/bastille_manager_util.php index 0d77c19..2304b29 100644 --- a/gui/bastille_manager_util.php +++ b/gui/bastille_manager_util.php @@ -2,7 +2,7 @@ /* bastille_manager_util.php - Copyright (c) 2019 José Rivera (joserprg@gmail.com). + Copyright (c) 2019-2025 Jose Rivera (joserprg@gmail.com). All rights reserved. Portions of XigmaNAS® (https://www.xigmanas.com). @@ -39,6 +39,12 @@ require_once 'auth.inc'; require_once 'guiconfig.inc'; require_once("bastille_manager-lib.inc"); +$zfs_status = get_state_zfs(); +if($zfs_status == "Invalid ZFS configuration"): + // Warning if invalid ZFS configuration. + $input_errors[] = gtext("WARNING: Invalid ZFS configuration detected."); +endif; + if(isset($_GET['uuid'])): $uuid = $_GET['uuid']; endif; diff --git a/unionfs.sh b/unionfs.sh old mode 100755 new mode 100644 index c719ce9..34df33e --- a/unionfs.sh +++ b/unionfs.sh @@ -10,7 +10,7 @@ # Debug script #set -x -# Copyright (c) 2019-2024, José Rivera (joserprg@gmail.com). +# Copyright (c) 2019-2025, Jose Rivera (joserprg@gmail.com). # All rights reserved. # Redistribution and use in source and binary forms, with or without @@ -51,20 +51,8 @@ error_notify() { # Log/notify message on error and exit. MSG="${*}" logger -t "${SCRIPTNAME}" "${MSG}" - echo -e "${MSG}" >&2; exit 1 -} - -platform_check() -{ - # Check for working platform. - if [ "${PRDPLATFORM}" = "x64-embedded" ]; then - pkg_symlink - else - if [ -d "/var/cache/pkg" ]; then - echo "Cleaning the pkg cache." - pkg clean -y -a - fi - fi + echo -e "${MSG}" >&2 + exit 1 } load_kmods() { @@ -79,7 +67,7 @@ load_kmods() { # Skip already loaded known modules. for _req_kmod in ${required_mods}; do - if ! sysrc -f /boot/loader.conf -qn ${_req_kmod}_load=YES | grep -q "YES"; then + if ! sysrc -f /boot/loader.conf -qc ${_req_kmod}_load=YES; then sysrc -f /boot/loader.conf ${_req_kmod}_load=YES fi if ! kldstat -m ${_req_kmod} >/dev/null 2>&1; then @@ -95,66 +83,45 @@ load_kmods() { kldload -v ${_lin_kmod} fi done - if ! sysrc -qn linux_enable=YES | grep -q "YES"; then + if ! sysrc -qc linux_enable=YES; then sysrc linux_enable=YES fi } -pkg_symlink() { - if ! sysrc -f ${CWDIR}${EXTCONF} -qn LINUX_COMPAT_SUPPORT | grep -q "YES"; then - echo "Creating pkg environment for embedded platforms." +unload_kmods() { + required_mods="fdescfs linprocfs linsysfs tmpfs" + linuxarc_mods="linux linux64" - if [ -d "/var/cache/pkg" ]; then - if [ ! -L "/var/cache/pkg" ]; then - rm -R /var/cache/pkg - mkdir -p ${CWDIR}/system/cache/pkg - ln -vFs ${CWDIR}/system/cache/pkg /var/cache/pkg - fi - else - mkdir -m 0755 -p /var/cache - mkdir -p ${CWDIR}/system/cache/pkg - ln -vFs ${CWDIR}/system/cache/pkg /var/cache/pkg + for _req_kmod in ${required_mods}; do + if sysrc -f /boot/loader.conf -qc ${_req_kmod}_load=YES; then + echo "Unset kernel module: ${_req_kmod}" + sysrc -f /boot/loader.conf -x ${_req_kmod}_load fi + done - if [ -d "/var/db/pkg" ]; then - if [ ! -L "/var/db/pkg" ]; then - rm -R /var/db/pkg - mkdir -p ${CWDIR}/system/pkg/db - ln -vFs ${CWDIR}/system/pkg/db /var/db/pkg - fi - else - mkdir -p ${CWDIR}/system/pkg/db - ln -vFs ${CWDIR}/system/pkg/db /var/db/pkg - fi + if sysrc -qc linux_enable=YES; then + echo "Unset linux_enable" + sysrc -x linux_enable fi } fetch_pkg() { - if ! sysrc -f ${CWDIR}${EXTCONF} -qn LINUX_COMPAT_SUPPORT | grep -q "YES"; then - echo "Fetching required packages." + echo "Fetching required packages." + # Fetch deboostrap and dependency packages. + pkg fetch -y -d -o ${CWDIR}/system/ debootstrap || error_notify "Error while fetching packages, exiting." - # Skip existing packages/ports bundled with XigmaNAS. - #PKGLIST="#bash #ca_root_nss debootstrap #gettext-runtime glib gmp gnugrep gnugpg gnutls #indexinfo libassuan #libedit #libffi libgcrypt libgpg-error #libiconv libidn2 libksba libtasn1 libunistring libxml2 mpdecimal nettle npth p11-kit #pcre perl5 pinentry pinentry-curses #python38 #readline #sqlite3 tpm-emulator #trousers ubuntu-keyring wget" - PKGLIST="debootstrap glib gmp gnugrep gnupg gnutls libassuan libgcrypt libgpg-error libidn2 libksba libtasn1 libunistring libxml2 mpdecimal nettle npth p11-kit perl5 pinentry pinentry-curses tpm-emulator ubuntu-keyring wget" + extract_pkg +} - for pkg in ${PKGLIST}; do - pkg fetch -y "${pkg}" || error_notify "Error while fetching required [${pkg}] package, exiting." - done - - extract_pkg +fetch_debootstrap() { + if ! sysrc -f ${CWDIR}${EXTCONF} -qc LINUX_COMPAT_SUPPORT=YES; then + fetch_pkg fi } extract_pkg() { echo "Extracting required packages." - - if [ "${PRDPLATFORM}" = "x64-embedded" ]; then - FILELIST=$(find "${CWDIR}/system/cache/pkg" -type f) - LINKLIST=$(find "${CWDIR}/system/cache/pkg" -type l) - else - FILELIST=$(find "/var/cache/pkg" -type f) - LINKLIST=$(find "/var/cache/pkg" -type l) - fi + FILELIST=$(find "${CWDIR}/system/All" -type f) for item in ${FILELIST}; do if [ -f "${item}" ]; then @@ -163,59 +130,68 @@ extract_pkg() { fi done - # Clean leftovers pkg symlinks - if [ "${PRDPLATFORM}" = "x64-embedded" ]; then - for item in ${LINKLIST}; do - if [ -L "${item}" ]; then - rm -rf ${item} - fi - done - else - echo "Cleaning the pkg cache." - pkg clean -y -a + if [ -d "${CWDIR}/system/All" ]; then + rm -r ${CWDIR}/system/All fi if [ ! -d "${CWDIR}/templates" ]; then mkdir -p ${CWDIR}/templates fi + + if [ ! -d "${CWDIR}/system/var/run" ]; then + mkdir -p ${CWDIR}/system/var/run + fi + + echo "Done." } unionfs_on() { if ! df | grep -q "${CWDIR}/system/usr/local"; then - echo "Enabling UnionFS mount for ${CWDIR}/system/usr/local." - mount_unionfs -o below ${CWDIR}/system/usr/local /usr/local + echo "Enabling UnionFS for ${CWDIR}/system/usr/local." + mount_unionfs -o above ${CWDIR}/system/usr/local /usr/local fi if ! df | grep -q "${CWDIR}/system/var/run"; then - echo "Enabling UnionFS mount for ${CWDIR}/system/var/run." - mount_unionfs -o below ${CWDIR}/system/var/run /var/run + echo "Enabling UnionFS for ${CWDIR}/system/var/run." + mount_unionfs -o avobe ${CWDIR}/system/var/run /var/run fi } unionfs_off() { if df | grep -q "${CWDIR}/system/usr/local"; then - echo "Disabling UnionFS mounts for ${CWDIR}/system/usr/local." + echo "Disabling UnionFS for ${CWDIR}/system/usr/local." umount -f /usr/local fi if df | grep -q "${CWDIR}/system/var/run"; then - echo "Disabling UnionFS mounts for ${CWDIR}/system/var/run." + echo "Disabling UnionFS for ${CWDIR}/system/var/run." umount -f /var/run fi } +update_debootstrap() { + echo "Updating debootstrap..." + unionfs_off + fetch_pkg +} + case "${1}" in - fetch_pkg) - platform_check - fetch_pkg + fetch_debootstrap) + fetch_debootstrap ;; load_kmods) load_kmods ;; + unload_kmods) + unload_kmods + ;; unionfs_on) unionfs_on ;; unionfs_off) unionfs_off ;; + update_debootstrap) + update_debootstrap + ;; esac diff --git a/version b/version index 36a0393..0abd29d 100644 --- a/version +++ b/version @@ -1 +1 @@ -1.1.53 +1.2.00