diff --git a/usr/local/etc/bastille/bastille.conf.sample b/usr/local/etc/bastille/bastille.conf.sample index a47da946..344268e1 100644 --- a/usr/local/etc/bastille/bastille.conf.sample +++ b/usr/local/etc/bastille/bastille.conf.sample @@ -51,7 +51,7 @@ bastille_network_gateway="" ## default ## Default Templates bastille_template_base="default/base" ## default: "default/base" -bastille_template_empty="default/empty" ## default: "default/empty" +bastille_template_empty="" ## default: "default/empty" bastille_template_thick="default/thick" ## default: "default/thick" bastille_template_thin="default/thin" ## default: "default/thin" bastille_template_vnet="default/vnet" ## default: "default/vnet" diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index 1be81266..a92b41e6 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2020, Christer Edwards +# Copyright (c) 2018-2021, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -46,7 +46,9 @@ running_jail() { validate_name() { local NAME_VERIFY=${NAME} local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_') - if [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then + if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then + error_exit "Container names may not begin with (-|_) characters!" + elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then error_exit "Container names may not contain special characters!" fi } @@ -174,7 +176,7 @@ ${NAME} { vnet; vnet.interface = e0b_${uniq_epair}; - exec.prestart += "jib addm ${uniq_epair} ${INTERFACE}"; + exec.prestart += "jib addm ${uniq_epair} ${bastille_jail_conf_interface}"; exec.poststop += "jib destroy ${uniq_epair}"; } EOF @@ -261,6 +263,13 @@ create_jail() { for _link in ${LINK_LIST}; do ln -sf /.bastille/${_link} ${_link} done + # Properly link shared ports on thin jails in read-write. + if [ -d "${bastille_releasesdir}/${RELEASE}/usr/ports" ]; then + if [ ! -d "${bastille_jail_path}/usr/ports" ]; then + mkdir ${bastille_jail_path}/usr/ports + fi + echo -e "${bastille_releasesdir}/${RELEASE}/usr/ports ${bastille_jail_path}/usr/ports nullfs rw 0 0" >> "${bastille_jail_fstab}" + fi fi if [ -z "${THICK_JAIL}" ]; then @@ -353,10 +362,17 @@ create_jail() { chmod 0700 "${bastille_jailsdir}/${NAME}" # Jail must be started before applying the default template. -- cwells - bastille start "${NAME}" + if [ -z "${EMPTY_JAIL}" ]; then + bastille start "${NAME}" + elif [ -n "${EMPTY_JAIL}" ]; then + # Don't start empty jails unless a template defined. + if [ -n "${bastille_template_empty}" ]; then + bastille start "${NAME}" + fi + fi if [ -n "${VNET_JAIL}" ]; then - if [ -n ${bastille_template_vnet} ]; then + if [ -n "${bastille_template_vnet}" ]; then ## rename interface to generic vnet0 uniq_epair=$(grep vnet.interface "${bastille_jailsdir}/${NAME}/jail.conf" | awk '{print $3}' | sed 's/;//') @@ -373,21 +389,28 @@ create_jail() { bastille template "${NAME}" ${bastille_template_vnet} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg IFCONFIG="${_ifconfig}" fi elif [ -n "${THICK_JAIL}" ]; then - if [ -n ${bastille_template_thick} ]; then + if [ -n "${bastille_template_thick}" ]; then bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" fi elif [ -n "${EMPTY_JAIL}" ]; then - if [ -n ${bastille_template_empty} ]; then + if [ -n "${bastille_template_empty}" ]; then bastille template "${NAME}" ${bastille_template_empty} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" fi else # Thin jail. - if [ -n ${bastille_template_thin} ]; then + if [ -n "${bastille_template_thin}" ]; then bastille template "${NAME}" ${bastille_template_thin} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" fi fi # Apply values changed by the template. -- cwells - bastille restart "${NAME}" + if [ -z "${EMPTY_JAIL}" ]; then + bastille restart "${NAME}" + elif [ -n "${EMPTY_JAIL}" ]; then + # Don't restart empty jails unless a template defined. + if [ -n "${bastille_template_empty}" ]; then + bastille restart "${NAME}" + fi + fi } # Handle special-case commands first. @@ -520,6 +543,15 @@ if [ -z "${EMPTY_JAIL}" ]; then if [ -n "${INTERFACE}" ]; then validate_netif validate_netconf + elif [ -n "${VNET_JAIL}" ]; then + if [ -z "${INTERFACE}" ]; then + if [ -z "${bastille_network_shared}" ]; then + # User must specify interface on vnet jails. + error_exit "Error: Network interface not defined." + else + validate_netconf + fi + fi else validate_netconf fi diff --git a/usr/local/share/bastille/destroy.sh b/usr/local/share/bastille/destroy.sh index a4bb3c57..a3ff4a68 100644 --- a/usr/local/share/bastille/destroy.sh +++ b/usr/local/share/bastille/destroy.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2020, Christer Edwards +# Copyright (c) 2018-2021, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -76,6 +76,12 @@ destroy_jail() { rm -rf "${bastille_jail_base}" fi + # Remove target from bastille_list if exist + # Mute sysrc output here as it may be undesirable on large startup list + if [ -n "$(sysrc -qn bastille_list | tr -s " " "\n" | awk "/^${TARGET}$/")" ]; then + sysrc bastille_list-="${TARGET}" > /dev/null + fi + ## archive jail log if [ -f "${bastille_jail_log}" ]; then mv "${bastille_jail_log}" "${bastille_jail_log}"-"$(date +%F)" diff --git a/usr/local/share/bastille/export.sh b/usr/local/share/bastille/export.sh index 398c1632..9fad7b78 100644 --- a/usr/local/share/bastille/export.sh +++ b/usr/local/share/bastille/export.sh @@ -53,6 +53,7 @@ fi OPTION="${1}" EXPATH="${2}" +SAFE_EXPORT= # Handle some options if [ -n "${OPTION}" ]; then @@ -61,6 +62,8 @@ if [ -n "${OPTION}" ]; then # Temporarily disable ZFS so we can create a standard backup archive bastille_zfs_enable="NO" fi + elif [ "${OPTION}" = "-s" -o "${OPTION}" = "--safe" ]; then + SAFE_EXPORT="1" elif echo "${OPTION}" | grep -q "\/"; then if [ -d "${OPTION}" ]; then EXPATH="${OPTION}" @@ -83,6 +86,12 @@ if [ -n "${EXPATH}" ]; then fi fi +create_zfs_snap(){ + # Take a recursive temporary snapshot + info "Creating temporary ZFS snapshot for export..." + zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}" +} + jail_export() { # Attempt to export the container @@ -90,11 +99,18 @@ jail_export() if [ "${bastille_zfs_enable}" = "YES" ]; then if [ -n "${bastille_zfs_zpool}" ]; then FILE_EXT="xz" - info "Exporting '${TARGET}' to a compressed .${FILE_EXT} archive." - info "Sending ZFS data stream..." - # Take a recursive temporary snapshot - zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}" + if [ -n "${SAFE_EXPORT}" ]; then + info "Safely exporting '${TARGET}' to a compressed .${FILE_EXT} archive." + bastille stop ${TARGET} + create_zfs_snap + bastille start ${TARGET} + else + info "Hot exporting '${TARGET}' to a compressed .${FILE_EXT} archive." + create_zfs_snap + fi + + info "Sending ZFS data stream..." # Export the container recursively and cleanup temporary snapshots zfs send -R "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_export_${DATE}" | \ xz ${bastille_compress_xz_options} > "${bastille_backupsdir}/${TARGET}_${DATE}.${FILE_EXT}" diff --git a/usr/local/share/bastille/rename.sh b/usr/local/share/bastille/rename.sh index 1fb73d2a..498c4870 100644 --- a/usr/local/share/bastille/rename.sh +++ b/usr/local/share/bastille/rename.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2020, Christer Edwards +# Copyright (c) 2018-2021, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -38,7 +38,9 @@ usage() { validate_name() { local NAME_VERIFY=${NEWNAME} local NAME_SANITY=$(echo "${NAME_VERIFY}" | tr -c -d 'a-zA-Z0-9-_') - if [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then + if [ -n "$(echo "${NAME_SANITY}" | awk "/^[-_].*$/" )" ]; then + error_exit "Container names may not begin with (-|_) characters!" + elif [ "${NAME_VERIFY}" != "${NAME_SANITY}" ]; then error_exit "Container names may not contain special characters!" fi } diff --git a/usr/local/share/bastille/upgrade.sh b/usr/local/share/bastille/upgrade.sh index dbd0ee9b..52c9c295 100644 --- a/usr/local/share/bastille/upgrade.sh +++ b/usr/local/share/bastille/upgrade.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2018-2020, Christer Edwards +# Copyright (c) 2018-2021, Christer Edwards # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -91,7 +91,9 @@ release_upgrade() { # Upgrade a release if [ -d "${bastille_releasesdir}/${TARGET}" ]; then release_check - freebsd-update ${OPTION} -b "${bastille_releasesdir}/${TARGET}" -r "${NEWRELEASE}" upgrade + env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" --currently-running "${TARGET}" -r "${NEWRELEASE}" upgrade + echo + echo -e "${COLOR_YELLOW}Please run 'bastille upgrade ${TARGET} install' to finish installing updates.${COLOR_RESET}" else error_exit "${TARGET} not found. See 'bastille bootstrap'." fi @@ -121,9 +123,22 @@ jail_updates_install() { fi } +release_updates_install() { + # Finish installing upgrade on a release + if [ -d "${bastille_releasesdir}/${TARGET}" ]; then + env PAGER="/bin/cat" freebsd-update ${OPTION} --not-running-from-cron -b "${bastille_releasesdir}/${TARGET}" install + else + error_exit "${TARGET} not found. See 'bastille bootstrap'." + fi +} + # Check what we should upgrade if echo "${TARGET}" | grep -q "[0-9]\{2\}.[0-9]-RELEASE"; then - release_upgrade + if [ "${NEWRELEASE}" = "install" ]; then + release_updates_install + else + release_upgrade + fi elif [ "${NEWRELEASE}" = "install" ]; then jail_updates_install else