mirror of
https://github.com/BastilleBSD/bastille.git
synced 2025-12-11 01:19:52 +01:00
Merge pull request #1305 from BastilleBSD/zstd
Feat: support zstd compression for export/import
This commit is contained in:
@@ -26,14 +26,16 @@ Available options are:
|
||||
|
||||
Options:
|
||||
|
||||
-a | --auto Auto mode. Start/stop jail(s) if required.
|
||||
--gz Export a ZFS jail using GZIP(.gz) compressed image.
|
||||
-r | --raw Export a ZFS jail to an uncompressed RAW image.
|
||||
-s | --safe Safely stop and start a ZFS jail before the exporting process.
|
||||
--tgz Export a jail using simple .tgz compressed archive instead.
|
||||
--txz Export a jail using simple .txz compressed archive instead.
|
||||
-v | --verbose Be more verbose during the ZFS send operation.
|
||||
--xz Export a ZFS jail using XZ(.xz) compressed image.
|
||||
-x | --debug Enable debug mode.
|
||||
-a | --auto Auto mode. Start/stop jail(s) if required.
|
||||
-l | --live Export a running jail (ZFS only).
|
||||
--gz Export to '.gz' compressed image (ZFS only).
|
||||
--xz Export to a '.xz' compressed image (ZFS only).
|
||||
--zst Export to a .zst compressed image (ZFS only).
|
||||
--raw Export to an uncompressed RAW image (ZFS only).
|
||||
--tgz Export to a '.tgz' compressed archive.
|
||||
--txz Export to a '.txz' compressed archive.
|
||||
--tzst Export to a '.tzst' compressed archive.
|
||||
-v | --verbose Enable verbose mode (ZFS only).
|
||||
-x | --debug Enable debug mode.
|
||||
|
||||
Note: If no export option specified, the container should be redirected to standard output.
|
||||
Note: If no export option specified, the container should be redirected to standard output.
|
||||
|
||||
@@ -19,9 +19,9 @@ To import to a specified release, specify it as the last argument.
|
||||
|
||||
Options:
|
||||
|
||||
-f | --force Force an archive import regardless if the checksum file does not match or missing.
|
||||
-M | --static-mac Generate static MAC for jail when importing foreign jails like iocage.
|
||||
-v | --verbose Be more verbose during the ZFS receive operation.
|
||||
-x | --debug Enable debug mode.
|
||||
-f | --force Force an archive import regardless if the checksum file does not match or missing.
|
||||
-M | --static-mac Generate static MAC for jail when importing foreign jails like iocage.
|
||||
-v | --verbose Enable verbose mode (ZFS only).
|
||||
-x | --debug Enable debug mode.
|
||||
|
||||
Tip: If no option specified, container should be imported from standard input.
|
||||
Tip: If no option specified, container should be imported from standard input.
|
||||
@@ -67,7 +67,9 @@ bastille_compress_xz_options="-0 -v" ## default
|
||||
bastille_decompress_xz_options="-c -d -v" ## default "-c -d -v"
|
||||
bastille_compress_gz_options="-1 -v" ## default "-1 -v"
|
||||
bastille_decompress_gz_options="-k -d -c -v" ## default "-k -d -c -v"
|
||||
bastille_export_options="" ## default "" predefined export options, e.g. "--safe --gz"
|
||||
bastille_compress_zst_options="-3 -v" ## default "-3 -v"
|
||||
bastille_decompress_zst_options="-k -d -c -v" ## default "-k -d -c -v"
|
||||
bastille_export_options="" ## default "" predefined export options, e.g. "--live --gz"
|
||||
|
||||
## Networking
|
||||
bastille_network_vnet_type="if_bridge" ## default: "if_bridge"
|
||||
|
||||
@@ -42,15 +42,17 @@ usage() {
|
||||
|
||||
Options:
|
||||
|
||||
-a | --auto Auto mode. Start/stop jail(s) if required.
|
||||
--gz Export a ZFS jail using GZIP(.gz) compressed image.
|
||||
-r | --raw Export a ZFS jail to an uncompressed RAW image.
|
||||
-s | --safe Safely stop and start a ZFS jail before the exporting process.
|
||||
--tgz Export a jail using simple .tgz compressed archive instead.
|
||||
--txz Export a jail using simple .txz compressed archive instead.
|
||||
-v | --verbose Be more verbose during the ZFS send operation.
|
||||
--xz Export a ZFS jail using XZ(.xz) compressed image.
|
||||
-x | --debug Enable debug mode.
|
||||
-a | --auto Auto mode. Start/stop jail(s) if required.
|
||||
-l | --live Export a running jail (ZFS only).
|
||||
--gz Export to '.gz' compressed image (ZFS only).
|
||||
--xz Export to a '.xz' compressed image (ZFS only).
|
||||
--zst Export to a .zst compressed image (ZFS only).
|
||||
--raw Export to an uncompressed RAW image (ZFS only).
|
||||
--tgz Export to a '.tgz' compressed archive.
|
||||
--txz Export to a '.txz' compressed archive.
|
||||
--tzst Export to a '.tzst' compressed archive.
|
||||
-v | --verbose Enable verbose mode (ZFS only).
|
||||
-x | --debug Enable debug mode.
|
||||
|
||||
Note: If no export option specified, the jail should be redirected to standard output.
|
||||
|
||||
@@ -72,17 +74,18 @@ opt_count() {
|
||||
|
||||
# Reset export options
|
||||
AUTO=0
|
||||
GZIP_EXPORT=
|
||||
XZ_EXPORT=
|
||||
SAFE_EXPORT=
|
||||
USER_EXPORT=
|
||||
RAW_EXPORT=
|
||||
DIR_EXPORT=
|
||||
TXZ_EXPORT=
|
||||
TGZ_EXPORT=
|
||||
LIVE=0
|
||||
GZIP_EXPORT=0
|
||||
XZ_EXPORT=0
|
||||
ZST_EXPORT=0
|
||||
RAW_EXPORT=0
|
||||
OPT_ZSEND="-R"
|
||||
COMP_OPTION="0"
|
||||
|
||||
TXZ_EXPORT=0
|
||||
TGZ_EXPORT=0
|
||||
TZST_EXPORT=0
|
||||
USER_EXPORT=0
|
||||
DIR_EXPORT=""
|
||||
COMP_OPTION=0
|
||||
if [ -n "${bastille_export_options}" ]; then
|
||||
# Overrides the case options by the user defined option(s) automatically.
|
||||
# Add bastille_export_options="--optionA --optionB" to bastille.conf, or simply `export bastille_export_options="--optionA --optionB"` environment variable.
|
||||
@@ -99,6 +102,9 @@ if [ -n "${bastille_export_options}" ]; then
|
||||
-a|--auto)
|
||||
AUTO="1"
|
||||
;;
|
||||
-l|--live)
|
||||
LIVE="1"
|
||||
;;
|
||||
--gz)
|
||||
GZIP_EXPORT="1"
|
||||
opt_count
|
||||
@@ -107,6 +113,14 @@ if [ -n "${bastille_export_options}" ]; then
|
||||
XZ_EXPORT="1"
|
||||
opt_count
|
||||
;;
|
||||
--zst)
|
||||
ZST_EXPORT="1"
|
||||
opt_count
|
||||
;;
|
||||
-r|--raw)
|
||||
RAW_EXPORT="1"
|
||||
opt_count
|
||||
;;
|
||||
--tgz)
|
||||
TGZ_EXPORT="1"
|
||||
opt_count
|
||||
@@ -117,21 +131,21 @@ if [ -n "${bastille_export_options}" ]; then
|
||||
opt_count
|
||||
zfs_enable_check
|
||||
;;
|
||||
-s|--safe)
|
||||
SAFE_EXPORT="1"
|
||||
;;
|
||||
-r|--raw)
|
||||
RAW_EXPORT="1"
|
||||
--tzst)
|
||||
TZST_EXPORT="1"
|
||||
opt_count
|
||||
zfs_enable_check
|
||||
;;
|
||||
-v|--verbose)
|
||||
OPT_ZSEND="-Rv"
|
||||
;;
|
||||
-x)
|
||||
enable_debug
|
||||
;;
|
||||
-*) error_notify "[ERROR]: Unknown Option: \"${1}\""
|
||||
usage;;
|
||||
enable_debug
|
||||
;;
|
||||
-*)
|
||||
error_notify "[ERROR]: Unknown Option: \"${1}\""
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
@@ -147,6 +161,10 @@ else
|
||||
AUTO=1
|
||||
shift
|
||||
;;
|
||||
-l|--live)
|
||||
LIVE="1"
|
||||
shift
|
||||
;;
|
||||
--gz)
|
||||
GZIP_EXPORT="1"
|
||||
opt_count
|
||||
@@ -157,6 +175,16 @@ else
|
||||
opt_count
|
||||
shift
|
||||
;;
|
||||
--zst)
|
||||
ZST_EXPORT="1"
|
||||
opt_count
|
||||
shift
|
||||
;;
|
||||
-r|--raw)
|
||||
RAW_EXPORT="1"
|
||||
opt_count
|
||||
shift
|
||||
;;
|
||||
--tgz)
|
||||
TGZ_EXPORT="1"
|
||||
opt_count
|
||||
@@ -169,13 +197,10 @@ else
|
||||
zfs_enable_check
|
||||
shift
|
||||
;;
|
||||
-s|--safe)
|
||||
SAFE_EXPORT="1"
|
||||
shift
|
||||
;;
|
||||
-r|--raw)
|
||||
RAW_EXPORT="1"
|
||||
--tzst)
|
||||
TZST_EXPORT="1"
|
||||
opt_count
|
||||
zfs_enable_check
|
||||
shift
|
||||
;;
|
||||
-v|--verbose)
|
||||
@@ -183,13 +208,14 @@ else
|
||||
shift
|
||||
;;
|
||||
-x)
|
||||
enable_debug
|
||||
shift
|
||||
;;
|
||||
enable_debug
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do
|
||||
case ${_opt} in
|
||||
a) AUTO=1 ;;
|
||||
l) LIVE=1 ;;
|
||||
x) enable_debug ;;
|
||||
*) error_exit "[ERROR]: Unknown Option: \"${1}\""
|
||||
esac
|
||||
@@ -203,12 +229,11 @@ else
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $# -gt 2 ] || [ $# -lt 1 ]; then
|
||||
if [ $# -lt 1 ] || [ $# -gt 2 ]; then
|
||||
usage
|
||||
fi
|
||||
|
||||
TARGET="${1}"
|
||||
|
||||
# Check for directory export
|
||||
if echo "${2}" | grep -q "\/"; then
|
||||
DIR_EXPORT="${2}"
|
||||
@@ -217,39 +242,30 @@ fi
|
||||
bastille_root_check
|
||||
set_target_single "${TARGET}"
|
||||
|
||||
# Validate for combined options
|
||||
# Only allow a single compression option
|
||||
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
|
||||
error_exit "[ERROR]: Simple archive modes with safe ZFS export can't be used together."
|
||||
# Validate AUTO and LIVE
|
||||
if [ "${AUTO}" -eq 1 ] && [ "${LIVE}" -eq 1 ]; then
|
||||
error_exit "[ERROR]: [-a|--auto] cannot be used with [-l|--live]."
|
||||
fi
|
||||
|
||||
# Don't allow LIVE with T*_EXPORT
|
||||
if { [ "${TXZ_EXPORT}" -eq 1 ] || [ "${TGZ_EXPORT}" -eq 1 ] || [ "${TZST_EXPORT}" -eq 1 ]; } && [ "${LIVE}" -eq 1 ]; then
|
||||
error_exit "[ERROR]: [-l|--live] cannot be used with simple archive modes."
|
||||
fi
|
||||
|
||||
# Don't allow ZFS specific options if not enabled
|
||||
if ! checkyesno bastille_zfs_enable; then
|
||||
if [ -n "${XZ_EXPORT}" ] ||
|
||||
[ -n "${GZIP_EXPORT}" ] ||
|
||||
[ -n "${RAW_EXPORT}" ] ||
|
||||
[ -n "${SAFE_EXPORT}" ] ||
|
||||
if [ "${XZ_EXPORT}" -eq 1 ] ||
|
||||
[ "${GZIP_EXPORT}" -eq 1 ] ||
|
||||
[ "${RAW_EXPORT}" -eq 1 ] ||
|
||||
[ "${LIVE}" -eq 1 ] ||
|
||||
[ "${ZST_EXPORT}" -eq 1 ] ||
|
||||
[ "${OPT_ZSEND}" = "-Rv" ]; then
|
||||
error_exit "[ERROR]: Options --xz, --gz, --raw, --safe, and --verbose are valid for ZFS configured systems only."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${SAFE_EXPORT}" ]; then
|
||||
# Check if container is running, otherwise just ignore
|
||||
if [ -z "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
SAFE_EXPORT=
|
||||
fi
|
||||
fi
|
||||
|
||||
# Export directory check
|
||||
if [ -n "${DIR_EXPORT}" ]; then
|
||||
if [ -d "${DIR_EXPORT}" ]; then
|
||||
# Set the user defined export directory
|
||||
bastille_backupsdir="${DIR_EXPORT}"
|
||||
else
|
||||
error_exit "[ERROR]: Path not found."
|
||||
error_exit "[ERROR]: Options --xz, --gz, --raw, -l|--live, --zst and --verbose are only valid for ZFS configured systems."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -260,10 +276,50 @@ fi
|
||||
if [ -z "${bastille_compress_gz_options}" ]; then
|
||||
bastille_compress_gz_options="-1 -v"
|
||||
fi
|
||||
if [ -z "${bastille_compress_zst_options}" ]; then
|
||||
bastille_compress_zst_options="-3 -v"
|
||||
fi
|
||||
|
||||
# Export directory check
|
||||
if [ -n "${DIR_EXPORT}" ]; then
|
||||
if [ -d "${DIR_EXPORT}" ]; then
|
||||
# Set the user defined export directory
|
||||
bastille_backupsdir="${DIR_EXPORT}"
|
||||
else
|
||||
error_exit "[ERROR]: Path not found."
|
||||
fi
|
||||
elif [ ! -d "${bastille_backupsdir}" ]; then
|
||||
error_exit "[ERROR]: Backups directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
# Validate jail state
|
||||
if checkyesno bastille_zfs_enable; then
|
||||
if [ "${LIVE}" -eq 1 ]; then
|
||||
if ! check_target_is_running "${TARGET}"; then
|
||||
error_exit "[ERROR]: [-l|--live] can only be used with a running jail."
|
||||
fi
|
||||
elif check_target_is_running "${TARGET}"; then
|
||||
if [ "${AUTO}" -eq 1 ]; then
|
||||
bastille stop "${TARGET}"
|
||||
else
|
||||
info "\n[${TARGET}]:"
|
||||
error_notify "[ERROR]: Jail is running."
|
||||
error_exit "Use [-a|--auto] to auto-stop the jail, or [-l|--live] (ZFS only) to migrate a running jail."
|
||||
fi
|
||||
fi
|
||||
else
|
||||
check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
|
||||
bastille stop "${TARGET}"
|
||||
else
|
||||
info "\n[${TARGET}]:"
|
||||
error_notify "Jail is running."
|
||||
error_exit "Use [-a|--auto] to auto-stop the jail."
|
||||
fi
|
||||
fi
|
||||
|
||||
create_zfs_snap() {
|
||||
# Take a recursive temporary snapshot
|
||||
if [ -z "${USER_EXPORT}" ]; then
|
||||
if [ "${USER_EXPORT}" -eq 0 ]; then
|
||||
info "\nCreating temporary ZFS snapshot for export..."
|
||||
fi
|
||||
zfs snapshot -r "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}"
|
||||
@@ -276,19 +332,20 @@ clean_zfs_snap() {
|
||||
}
|
||||
|
||||
export_check() {
|
||||
|
||||
# Inform the user about the exporting method
|
||||
if [ -z "${USER_EXPORT}" ]; then
|
||||
if [ -n "$(/usr/sbin/jls name | awk "/^${TARGET}$/")" ]; then
|
||||
if [ -n "${SAFE_EXPORT}" ]; then
|
||||
EXPORT_AS="Safely exporting"
|
||||
else
|
||||
if [ "${USER_EXPORT}" -eq 0 ]; then
|
||||
if check_target_is_running "${TARGET}" 2>/dev/null; then
|
||||
if [ "${LIVE}" -eq 1 ]; then
|
||||
EXPORT_AS="Hot exporting"
|
||||
else
|
||||
EXPORT_AS="Safely exporting"
|
||||
fi
|
||||
else
|
||||
EXPORT_AS="Exporting"
|
||||
fi
|
||||
|
||||
if [ "${FILE_EXT}" = ".xz" ] || [ "${FILE_EXT}" = ".gz" ] || [ "${FILE_EXT}" = "" ]; then
|
||||
if [ "${FILE_EXT}" = ".xz" ] || [ "${FILE_EXT}" = ".gz" ] || [ "${FILE_EXT}" = ".zst" ] || [ "${FILE_EXT}" = "" ]; then
|
||||
EXPORT_TYPE="image"
|
||||
else
|
||||
EXPORT_TYPE="archive"
|
||||
@@ -303,19 +360,15 @@ export_check() {
|
||||
info "\n${EXPORT_AS} '${TARGET}' ${EXPORT_INFO}..."
|
||||
fi
|
||||
|
||||
# Safely stop and snapshot the jail
|
||||
if [ -n "${SAFE_EXPORT}" ]; then
|
||||
bastille stop ${TARGET}
|
||||
create_zfs_snap
|
||||
bastille start ${TARGET}
|
||||
else
|
||||
create_zfs_snap
|
||||
fi
|
||||
|
||||
if checkyesno bastille_zfs_enable; then
|
||||
if [ -z "${USER_EXPORT}" ]; then
|
||||
|
||||
# Create snapshot
|
||||
create_zfs_snap
|
||||
|
||||
if [ "${USER_EXPORT}" -eq 0 ]; then
|
||||
info "\nSending ZFS data stream..."
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -331,7 +384,8 @@ jail_export() {
|
||||
if [ "$(zfs get -H -o value encryption ${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET})" = "on" ]; then
|
||||
error_exit "[ERROR]: Exporting jails in encryoted datasets is not supported."
|
||||
fi
|
||||
if [ -n "${RAW_EXPORT}" ]; then
|
||||
|
||||
if [ "${RAW_EXPORT}" -eq 1 ]; then
|
||||
|
||||
FILE_EXT=""
|
||||
|
||||
@@ -345,7 +399,7 @@ jail_export() {
|
||||
clean_zfs_snap
|
||||
fi
|
||||
|
||||
elif [ -n "${GZIP_EXPORT}" ]; then
|
||||
elif [ "${GZIP_EXPORT}" -eq 1 ]; then
|
||||
|
||||
FILE_EXT=".gz"
|
||||
|
||||
@@ -359,7 +413,7 @@ jail_export() {
|
||||
clean_zfs_snap
|
||||
fi
|
||||
|
||||
elif [ -n "${XZ_EXPORT}" ]; then
|
||||
elif [ "${XZ_EXPORT}" -eq 1 ]; then
|
||||
|
||||
FILE_EXT=".xz"
|
||||
|
||||
@@ -373,6 +427,20 @@ jail_export() {
|
||||
clean_zfs_snap
|
||||
fi
|
||||
|
||||
elif [ "${ZST_EXPORT}" -eq 1 ]; then
|
||||
|
||||
FILE_EXT=".zst"
|
||||
|
||||
export_check
|
||||
|
||||
# Export the container recursively and cleanup temporary snapshots
|
||||
if ! zfs send ${OPT_ZSEND} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET}@bastille_${TARGET}_${DATE}" | zstd ${bastille_compress_zst_options} > "${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}"; then
|
||||
clean_zfs_snap
|
||||
error_exit "[ERROR]: Failed to export jail: ${TARGET}"
|
||||
else
|
||||
clean_zfs_snap
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
FILE_EXT=""
|
||||
@@ -390,7 +458,7 @@ jail_export() {
|
||||
fi
|
||||
fi
|
||||
else
|
||||
if [ -n "${TGZ_EXPORT}" ]; then
|
||||
if [ "${TGZ_EXPORT}" -eq 1 ]; then
|
||||
|
||||
FILE_EXT=".tgz"
|
||||
|
||||
@@ -402,7 +470,7 @@ jail_export() {
|
||||
error_exit "[ERROR]: Failed to export jail: ${TARGET}"
|
||||
fi
|
||||
|
||||
elif [ -n "${TXZ_EXPORT}" ]; then
|
||||
elif [ "${TXZ_EXPORT}" -eq 1 ]; then
|
||||
|
||||
FILE_EXT=".txz"
|
||||
|
||||
@@ -414,6 +482,18 @@ jail_export() {
|
||||
error_exit "[ERROR]: Failed to export jail: ${TARGET}"
|
||||
fi
|
||||
|
||||
elif [ "${TZST_EXPORT}" -eq 1 ]; then
|
||||
|
||||
FILE_EXT=".tzst"
|
||||
|
||||
# Create standard txz backup archive
|
||||
info "\nExporting '${TARGET}' to a compressed ${FILE_EXT} archive..."
|
||||
|
||||
cd "${bastille_jailsdir}" || error_exit "[ERROR]: Failed to change to directory: ${bastille_jailssdir}"
|
||||
if ! tar -cf - "${TARGET}" | zstd ${bastille_compress_zst_options} > "${bastille_backupsdir}/${TARGET}_${DATE}${FILE_EXT}"; then
|
||||
error_exit "[ERROR]: Failed to export jail: ${TARGET}"
|
||||
fi
|
||||
|
||||
else
|
||||
error_exit "[ERROR]: export option required"
|
||||
fi
|
||||
@@ -423,7 +503,7 @@ jail_export() {
|
||||
if [ "$?" -ne 0 ]; then
|
||||
error_exit "[ERROR]: Failed to export jail: ${TARGET}"
|
||||
else
|
||||
if [ -z "${USER_EXPORT}" ]; then
|
||||
if [ "${USER_EXPORT}" -eq 0 ]; then
|
||||
# Generate container checksum file
|
||||
cd "${bastille_backupsdir}" || error_exit "[ERROR]: Failed to change to directory: ${bastille_backupsdir}"
|
||||
if ! sha256 -q "${TARGET}_${DATE}${FILE_EXT}" > "${TARGET}_${DATE}.sha256"; then
|
||||
@@ -435,29 +515,4 @@ jail_export() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if backups directory/dataset exist
|
||||
if [ ! -d "${bastille_backupsdir}" ]; then
|
||||
error_exit "[ERROR]: Backups directory/dataset does not exist. See 'bastille bootstrap'."
|
||||
fi
|
||||
|
||||
if [ -n "${TARGET}" ]; then
|
||||
|
||||
# Validate jail existence
|
||||
if [ ! -d "${bastille_jailsdir}/${TARGET}" ]; then
|
||||
error_exit "[ERROR]: Jail not found: ${TARGET}"
|
||||
fi
|
||||
|
||||
# Jail needs to be stopped on non-ZFS systems
|
||||
if ! checkyesno bastille_zfs_enable; then
|
||||
# Validate jail state
|
||||
check_target_is_stopped "${TARGET}" || if [ "${AUTO}" -eq 1 ]; then
|
||||
bastille stop "${TARGET}"
|
||||
else
|
||||
info "\n[${TARGET}]:"
|
||||
error_notify "Jail is running."
|
||||
error_exit "Use [-a|--auto] to auto-stop the jail."
|
||||
fi
|
||||
fi
|
||||
|
||||
jail_export
|
||||
fi
|
||||
jail_export
|
||||
|
||||
@@ -40,12 +40,12 @@ usage() {
|
||||
|
||||
Options:
|
||||
|
||||
-f | --force Force an archive import regardless if the checksum file does not match or missing.
|
||||
-M | --static-mac Generate static MAC for jail when importing foreign jails like iocage.
|
||||
-v | --verbose Be more verbose during the ZFS receive operation.
|
||||
-x | --debug Enable debug mode.
|
||||
-f | --force Force an archive import regardless if the checksum file does not match or missing.
|
||||
-M | --static-mac Generate static MAC for jail when importing foreign jails like iocage.
|
||||
-v | --verbose Enable verbose mode (ZFS only).
|
||||
-x | --debug Enable debug mode.
|
||||
|
||||
Tip: If no option specified, container should be imported from standard input.
|
||||
Tip: If no option specified, container should be imported from standard input.
|
||||
|
||||
EOF
|
||||
exit 1
|
||||
@@ -58,9 +58,9 @@ OPT_STATIC_MAC=""
|
||||
USER_IMPORT=
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "${1}" in
|
||||
-h|--help|help)
|
||||
-h|--help|help)
|
||||
usage
|
||||
;;
|
||||
;;
|
||||
-f|--force)
|
||||
OPT_FORCE="1"
|
||||
shift
|
||||
@@ -81,7 +81,7 @@ while [ "$#" -gt 0 ]; do
|
||||
for _opt in $(echo ${1} | sed 's/-//g' | fold -w1); do
|
||||
case ${_opt} in
|
||||
f) OPT_FORCE=1 ;;
|
||||
M) OPT_STATIC_MAC=1 ;;
|
||||
M) OPT_STATIC_MAC=1 ;;
|
||||
v) OPT_ZRECV="-u -v" ;;
|
||||
x) enable_debug ;;
|
||||
*) error_exit "[ERROR]: Unknown Option: \"${1}\"" ;;
|
||||
@@ -111,8 +111,12 @@ fi
|
||||
if [ -z "${bastille_decompress_gz_options}" ]; then
|
||||
bastille_decompress_gz_options="-k -d -c -v"
|
||||
fi
|
||||
if [ -z "${bastille_decompress_zst_options}" ]; then
|
||||
bastille_decompress_zst_options="-k -d -c -v"
|
||||
fi
|
||||
|
||||
validate_archive() {
|
||||
|
||||
# Compare checksums on the target archive
|
||||
# Skip validation for unsupported archive
|
||||
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
|
||||
@@ -438,6 +442,7 @@ update_config() {
|
||||
}
|
||||
|
||||
workout_components() {
|
||||
|
||||
if [ "${FILE_EXT}" = ".tar" ]; then
|
||||
# Workaround to determine the tarball path/components before extract(assumes path/jails/target)
|
||||
JAIL_PATH=$(tar -tvf ${bastille_backupsdir}/${TARGET} | grep -wo "/.*/jails/${TARGET_TRIM}" | tail -n1)
|
||||
@@ -451,6 +456,7 @@ workout_components() {
|
||||
}
|
||||
|
||||
vnet_requirements() {
|
||||
|
||||
# VNET jib script requirement
|
||||
if [ "${bastille_network_vnet_type}" = "if_bridge" ]; then
|
||||
if [ ! "$(command -v jib)" ]; then
|
||||
@@ -472,6 +478,7 @@ vnet_requirements() {
|
||||
}
|
||||
|
||||
config_netif() {
|
||||
|
||||
# Get interface from bastille configuration
|
||||
if [ -n "${bastille_network_loopback}" ]; then
|
||||
NETIF_CONFIG="${bastille_network_loopback}"
|
||||
@@ -509,8 +516,9 @@ update_symlinks() {
|
||||
}
|
||||
|
||||
create_zfs_datasets() {
|
||||
|
||||
# Prepare the ZFS environment and restore from file
|
||||
info "\nImporting '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
|
||||
info "\nImporting '${TARGET_TRIM}' from compressed ${FILE_EXT} archive."
|
||||
echo "Preparing ZFS environment..."
|
||||
|
||||
# Create required ZFS datasets, mountpoint inherited from system
|
||||
@@ -526,12 +534,14 @@ remove_zfs_datasets() {
|
||||
}
|
||||
|
||||
jail_import() {
|
||||
|
||||
# Attempt to import container from file
|
||||
FILE_TRIM=$(echo "${TARGET}" | sed 's/\.xz//g;s/\.gz//g;s/\.tgz//g;s/\.txz//g;s/\.zip//g;s/\.tar\.gz//g;s/\.tar//g')
|
||||
FILE_TRIM=$(echo "${TARGET}" | sed 's/\.xz//g;s/\.gz//g;s/\.zst//g;s/\.tgz//g;s/\.txz//g;s/\.tzst//g;s/\.zip//g;s/\.tar\.gz//g;s/\.tar//g')
|
||||
FILE_EXT=$(echo "${TARGET}" | sed "s/${FILE_TRIM}//g")
|
||||
if [ -d "${bastille_jailsdir}" ]; then
|
||||
if checkyesno bastille_zfs_enable; then
|
||||
if [ -n "${bastille_zfs_zpool}" ]; then
|
||||
|
||||
if [ "${FILE_EXT}" = ".xz" ]; then
|
||||
validate_archive
|
||||
# Import from compressed xz on ZFS systems
|
||||
@@ -539,9 +549,9 @@ jail_import() {
|
||||
echo "Receiving ZFS data stream..."
|
||||
xz ${bastille_decompress_xz_options} "${bastille_backupsdir}/${TARGET}" | \
|
||||
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
|
||||
elif [ "${FILE_EXT}" = ".gz" ]; then
|
||||
validate_archive
|
||||
# Import from compressed xz on ZFS systems
|
||||
@@ -549,7 +559,16 @@ jail_import() {
|
||||
echo "Receiving ZFS data stream..."
|
||||
gzip ${bastille_decompress_gz_options} "${bastille_backupsdir}/${TARGET}" | \
|
||||
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
|
||||
elif [ "${FILE_EXT}" = ".zst" ]; then
|
||||
validate_archive
|
||||
# Import from compressed zst on ZFS systems
|
||||
info "\nImporting '${TARGET_TRIM}' from compressed ${FILE_EXT} image."
|
||||
echo "Receiving ZFS data stream..."
|
||||
zstd ${bastille_decompress_zst_options} "${bastille_backupsdir}/${TARGET}" | \
|
||||
zfs receive ${OPT_ZRECV} "${bastille_zfs_zpool}/${bastille_zfs_prefix}/jails/${TARGET_TRIM}"
|
||||
# Update ZFS mountpoint property if required
|
||||
update_zfsmount
|
||||
|
||||
@@ -557,7 +576,6 @@ jail_import() {
|
||||
validate_archive
|
||||
# Prepare the ZFS environment and restore from existing .txz file
|
||||
create_zfs_datasets
|
||||
|
||||
# Extract required files to the new datasets
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
tar --exclude='root' -Jxf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
@@ -565,11 +583,11 @@ jail_import() {
|
||||
if [ "$?" -ne 0 ]; then
|
||||
remove_zfs_datasets
|
||||
fi
|
||||
|
||||
elif [ "${FILE_EXT}" = ".tgz" ]; then
|
||||
validate_archive
|
||||
# Prepare the ZFS environment and restore from existing .tgz file
|
||||
create_zfs_datasets
|
||||
|
||||
# Extract required files to the new datasets
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
tar --exclude='root' -xf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
@@ -577,7 +595,21 @@ jail_import() {
|
||||
if [ "$?" -ne 0 ]; then
|
||||
remove_zfs_datasets
|
||||
fi
|
||||
|
||||
elif [ "${FILE_EXT}" = ".tzst" ]; then
|
||||
validate_archive
|
||||
# Prepare the ZFS environment and restore from existing .tgz file
|
||||
create_zfs_datasets
|
||||
# Extract required files to the new datasets
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
tar --exclude='root' -xf "${bastille_backupsdir}/${TARGET}" --strip-components 1 -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components 2 -C "${bastille_jailsdir}/${TARGET_TRIM}/root" "${TARGET_TRIM}/root"
|
||||
if [ "$?" -ne 0 ]; then
|
||||
remove_zfs_datasets
|
||||
fi
|
||||
|
||||
elif [ "${FILE_EXT}" = ".zip" ]; then
|
||||
|
||||
validate_archive
|
||||
# Attempt to import a foreign/iocage container
|
||||
info "\nImporting '${TARGET_TRIM}' from foreign compressed ${FILE_EXT} archive."
|
||||
@@ -608,7 +640,9 @@ jail_import() {
|
||||
|
||||
# Generate fstab and jail.conf files
|
||||
generate_config
|
||||
|
||||
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
|
||||
|
||||
# Attempt to import a foreign/ezjail container
|
||||
# Prepare the ZFS environment and restore from existing .tar.gz file
|
||||
create_zfs_datasets
|
||||
@@ -622,12 +656,13 @@ jail_import() {
|
||||
else
|
||||
generate_config
|
||||
fi
|
||||
|
||||
elif [ "${FILE_EXT}" = ".tar" ]; then
|
||||
|
||||
# Attempt to import a foreign/qjail container
|
||||
# Prepare the ZFS environment and restore from existing .tar file
|
||||
create_zfs_datasets
|
||||
workout_components
|
||||
|
||||
# Extract required files to the new datasets
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" --strip-components "${CONF_TRIM}" -C "${bastille_jailsdir}/${TARGET_TRIM}" "${JAIL_CONF}"
|
||||
@@ -641,7 +676,9 @@ jail_import() {
|
||||
else
|
||||
update_config
|
||||
fi
|
||||
|
||||
elif [ -z "${FILE_EXT}" ]; then
|
||||
|
||||
if echo "${TARGET}" | grep -q '_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$'; then
|
||||
validate_archive
|
||||
# Based on the file name, looks like we are importing a raw bastille image
|
||||
@@ -669,19 +706,31 @@ jail_import() {
|
||||
else
|
||||
# Import from standard supported archives on UFS systems
|
||||
if [ "${FILE_EXT}" = ".txz" ]; then
|
||||
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
tar -Jxf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
|
||||
|
||||
elif [ "${FILE_EXT}" = ".tgz" ]; then
|
||||
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
|
||||
|
||||
elif [ "${FILE_EXT}" = ".tzst" ]; then
|
||||
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}"
|
||||
|
||||
elif [ "${FILE_EXT}" = ".tar.gz" ]; then
|
||||
|
||||
# Attempt to import/configure foreign/ezjail container
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
mkdir "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
tar -xf "${bastille_backupsdir}/${TARGET}" -C "${bastille_jailsdir}/${TARGET_TRIM}"
|
||||
mv "${bastille_jailsdir}/${TARGET_TRIM}/ezjail" "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
generate_config
|
||||
|
||||
elif [ "${FILE_EXT}" = ".tar" ]; then
|
||||
|
||||
# Attempt to import/configure foreign/qjail container
|
||||
info "\nExtracting files from '${TARGET}' archive..."
|
||||
mkdir -p "${bastille_jailsdir}/${TARGET_TRIM}/root"
|
||||
@@ -729,9 +778,9 @@ fi
|
||||
# Check if archive exist then trim archive name
|
||||
if [ -f "${bastille_backupsdir}/${TARGET}" ]; then
|
||||
# Filter unsupported/unknown archives
|
||||
if echo "${TARGET}" | grep -q '_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.xz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.gz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.tgz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.txz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}.zip$\|-[0-9]\{12\}.[0-9]\{2\}.tar.gz$\|@[0-9]\{12\}.[0-9]\{2\}.tar$'; then
|
||||
if echo "${TARGET}" | grep -q '_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.xz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.gz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.zst$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.tgz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.txz$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}-[0-9]\{6\}.tzst$\|_[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}.zip$\|-[0-9]\{12\}.[0-9]\{2\}.tar.gz$\|@[0-9]\{12\}.[0-9]\{2\}.tar$'; then
|
||||
if ls "${bastille_backupsdir}" | awk "/^${TARGET}$/" >/dev/null; then
|
||||
TARGET_TRIM=$(echo "${TARGET}" | sed "s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.xz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.gz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.tgz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.txz//;s/_[0-9]*-[0-9]*-[0-9]*.zip//;s/-[0-9]\{12\}.[0-9]\{2\}.tar.gz//;s/@[0-9]\{12\}.[0-9]\{2\}.tar//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*//")
|
||||
TARGET_TRIM=$(echo "${TARGET}" | sed "s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.xz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.gz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.zst//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.tgz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.txz//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*.tzst//;s/_[0-9]*-[0-9]*-[0-9]*.zip//;s/-[0-9]\{12\}.[0-9]\{2\}.tar.gz//;s/@[0-9]\{12\}.[0-9]\{2\}.tar//;s/_[0-9]*-[0-9]*-[0-9]*-[0-9]*//")
|
||||
fi
|
||||
else
|
||||
error_exit "[ERROR]: Unrecognized archive name."
|
||||
@@ -754,4 +803,4 @@ fi
|
||||
if [ -n "${TARGET}" ]; then
|
||||
info "\nAttempting to import jail: ${TARGET_TRIM}..."
|
||||
jail_import
|
||||
fi
|
||||
fi
|
||||
Reference in New Issue
Block a user