Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

etcupdate: beta version #790

Merged
merged 17 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion usr/local/bin/bastille
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Available Commands:
create Create a new thin container or a thick container if -T|--thick option specified.
destroy Destroy a stopped container or a FreeBSD release.
edit Edit container configuration files (advanced).
etcupdate Update /etc directory to specified release.
export Exports a specified container.
help Help about any command.
htop Interactive process viewer (requires htop).
Expand Down Expand Up @@ -157,7 +158,7 @@ version|-v|--version)
help|-h|--help)
usage
;;
bootstrap|create|destroy|export|htop|import|list|mount|rdr|restart|setup|start|top|umount|update|upgrade|verify)
bootstrap|create|destroy|etcupdate|export|htop|import|list|mount|rdr|restart|setup|start|top|umount|update|upgrade|verify)
# Nothing "extra" to do for these commands. -- cwells
;;
clone|config|cmd|console|convert|cp|edit|limits|pkg|rcp|rename|service|stop|sysrc|tags|template|zfs)
Expand Down
27 changes: 21 additions & 6 deletions usr/local/share/bastille/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,28 @@ set_target_single() {
local _TARGET="${1}"
if [ "${_TARGET}" = ALL ] || [ "${_TARGET}" = all ]; then
error_exit "[all|ALL] not supported with this command."
else
check_target_exists "${_TARGET}" || error_exit "Jail not found \"${_TARGET}\""
JAILS="${_TARGET}"
TARGET="${_TARGET}"
export JAILS
export TARGET
elif [ "$(echo ${_TARGET} | wc -w)" -gt 1 ]; then
error_exit "Error: Command only supports a single TARGET."
elif echo "${_TARGET}" | grep -Eq '^[0-9]+$'; then
if get_jail_name "${_TARGET}" > /dev/null; then
_TARGET="$(get_jail_name ${_TARGET})"
else
error_exit "Error: JID \"${_TARGET}\" not found. Is jail running?"
fi
elif
! check_target_exists "${_TARGET}"; then
if jail_autocomplete "${_TARGET}" > /dev/null; then
_TARGET="$(jail_autocomplete ${_TARGET})"
elif [ $? -eq 2 ]; then
error_exit "Jail not found \"${_TARGET}\""
else
exit 1
fi
fi
TARGET="${_TARGET}"
JAILS="${_TARGET}"
export TARGET
export JAILS
}

target_all_jails() {
Expand Down
193 changes: 193 additions & 0 deletions usr/local/share/bastille/etcupdate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
#!/bin/sh
# Copyright (c) 2018-2024, Christer Edwards <[email protected]>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

. /usr/local/share/bastille/common.sh
. /usr/local/etc/bastille/bastille.conf

usage() {
error_notify "Usage: bastille etcupdate [option(s)] [bootstrap|TARGET] [diff|resolve|update RELEASE]"
cat << EOF
Options:

-d | --dry-run Show output, but do not apply.
-f | --force Force a re-bootstrap of a RELEASE.
-x | --debug Enable debug mode.

EOF
exit 1
}

bootstrap_etc_release() {
local _release="${1}"
local _current="$(sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives | awk -F': ' '{print $2}')"
if ! ls -A "${bastille_releasesdir}/${_release}/usr/src" 2>/dev/null; then
sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives=src
if ! bastille bootstrap "${_release}" > /dev/null; then
sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}"
error_exit "Failed to bootstrap etcupdate: ${_release}"
else
sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}"
fi
fi
}

bootstrap_etc_tarball() {
local _release="${1}"
if [ ! -f ${bastille_cachedir}/${_release}.tbz2 ]; then
echo "Building tarball, please wait..."
if ! etcupdate build -d /tmp/etcupdate -s ${bastille_releasesdir}/${_release}/usr/src ${bastille_cachedir}/${_release}.tbz2; then
error_exit "Failed to build etcupdate tarball \"${_release}.tbz2\""
else
info "Etcupdate bootstrap complete: ${_release}"
fi
elif [ -f ${bastille_cachedir}/${_release}.tbz2 ] && [ "${FORCE}" -eq 1 ]; then
rm -f "${bastille_cachedir}/${_release}.tbz2"
echo "Building tarball, please wait..."
if ! etcupdate build -d /tmp/etcupdate -s ${bastille_releasesdir}/${_release}/usr/src ${bastille_cachedir}/${_release}.tbz2; then
error_exit "Failed to build etcupdate tarball: ${_release}.tbz2"
else
info "Etcupdate bootstrap complete: ${_release}"
fi
else
info "Etcupdate release has already been prepared for application: ${_release}"
fi
}

diff_review() {
local _jail="${1}"
info "[_jail]: diff"
etcupdate diff -D "${bastille_jailsdir}/${_jail}/root"
}

resolve_conflicts() {
local _jail="${1}"
if [ "${DRY_RUN}" -eq 1 ]; then
info "[_jail]: resolve --dry-run"
etcupdate resolve -n -D "${bastille_jailsdir}/${_jail}/root"
else
info "[_jail]: resolve"
etcupdate resolve -D "${bastille_jailsdir}/${_jail}/root"
fi
}

update_jail_etc() {
local _jail="${1}"
local _release="${2}"
if [ "${DRY_RUN}" -eq 1 ]; then
info "[_jail]: update --dry-run"
etcupdate -n -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2
else
info "[_jail]: update"
etcupdate -D "${bastille_jailsdir}/${_jail}/root" -t ${bastille_cachedir}/${_release}.tbz2
fi
}

if [ "$#" -lt 2 ] || [ "$#" -gt 4 ]; then
usage
fi

# Handle options.
DRY_RUN=0
FORCE=0
while [ "$#" -gt 0 ]; do
case "${1}" in
-h|--help|help)
usage
;;
-d|--dry-run)
DRY_RUN=1
shift
;;
-f|--force)
FORCE=1
shift
;;
-x|--debug)
enable_debug
shift
;;
-*)
for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do
case ${_opt} in
d) DRY_RUN=1 ;;
f) FORCE=1 ;;
x) enable_debug ;;
*) error_exit "Unknown Option: \"${1}\"" ;;
esac
done
shift
;;
*)
break
;;
esac
done

# Main commands
while [ "$#" -gt 0 ]; do
case "${1}" in
bootstrap)
if [ -z "${2}" ]; then
usage
else
RELEASE="${2}"
bootstrap_etc_release "${RELEASE}"
bootstrap_etc_tarball "${RELEASE}"
shift $#
fi
;;
*)
if [ -z "${2}" ]; then
usage
else
TARGET="${1}"
ACTION="${2}"
RELEASE="${3}"
set_target_single "${TARGET}"
case "${ACTION}" in
diff)
diff_review "${TARGET}"
shift "$#"
;;
resolve)
resolve_conflicts "${TARGET}"
shift "$#"
;;
update)
update_jail_etc "${TARGET}" "${RELEASE}"
tschettervictor marked this conversation as resolved.
Show resolved Hide resolved
shift "$#"
;;
*)
error_exit "Unknown action: \"${ACTION}\""
;;
esac
fi
;;
esac
done