Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
changeset 256:68f091c9524a
Command "copy-skel" implemented
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 12 Sep 2022 09:40:20 +0200 |
| parents | 7f21d242f79f |
| children | 71fcef7b8e65 |
| files | sbin/ftjail |
| diffstat | 1 files changed, 93 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/sbin/ftjail Mon Sep 12 08:26:57 2022 +0200 +++ b/sbin/ftjail Mon Sep 12 09:40:20 2022 +0200 @@ -71,6 +71,15 @@ snapshot-tmpl BASE-RO SKELETON-RW SNAPSHOT-NAME + copy-skel [ OPTIONS ] SOURCE-DS SNAPSHOT-NAME TARGET-DS + + -A Set "canmount=noauto" for all datasets in the target dataset + -L Copy dataset properties optimized for employing a + "skeleton" subdirectory + -P Copy dataset properties optimized for direct mounts + of skeleton children over an already mounted base + -u Do not mount the target dataset automatically + ENVIRONMENT: All environment variables that affect "zfs" are effective also. @@ -242,9 +251,10 @@ # In this case the skeleton root needs to be mounted into a "skeleton" subdir zfs create -u -o canmount=noauto "${_ds_skel}" else - # Only childres are to be mounted + # Only children are to be mounted zfs create -u -o canmount=off "${_ds_skel}" fi + # "usr" is only a container holding "usr/local" zfs create -u -o canmount=off "${_ds_skel}/usr" # # XXX FIXME: What about usr/ports/distfiles @@ -692,6 +702,85 @@ } +#: +#: Implementation of "copy-skel" +#: +command_copy_skel() { + local _ds_source _snapshot_name _ds_target + local _opt_symlink _opt_nomount + + local _opt _name _relative_name _opt_canmount + + _opt_symlink="" + _opt_nomount="" + _opt_canmount="-o canmount=on" + + + while getopts "ALPu" _opt ; do + case ${_opt} in + A) + _opt_canmount="-o canmount=noauto" + ;; + L) + _opt_symlink="yes" + ;; + P) + _opt_symlink="no" + ;; + u) + _opt_nomount="-u" + ;; + \?) + return 2; + ;; + esac + done + shift $((OPTIND-1)) + OPTIND=1 + + [ -z "${_opt_symlink}" ] && { echo "ERROR: -L or -P must be given" 1>&2; return 2; } + + _ds_source="${1-}" + _snapshot_name="${2-}" + _ds_target="${3-}" + + [ -z "${_ds_source}" ] && { echo "ERROR: no source given" 1>&2; return 2; } + [ -z "${_snapshot_name}" ] && { echo "ERROR: no snapshot name given" 1>&2; return 2; } + [ -z "${_ds_target}" ] && { echo "ERROR: no target given" 1>&2; return 2; } + + zfs list -r -t all -o name "${_ds_source}" \ + | { + while IFS=$'\t' read -r _name ; do + if [ "${_name}" = "${_name%@*}@${_snapshot_name}" ]; then + echo "FOUND: $_name" + # Determine the relative name of the dataset + _relative_name="${_name#${_ds_source}}" + _relative_name="${_relative_name%@*}" + echo " -> $_relative_name" + if [ -z "${_relative_name}" ]; then + # root + if [ "${_opt_symlink}" = "yes" ]; then + zfs send -Lec -p -v "${_name}" | zfs receive ${_opt_nomount} -v ${_opt_canmount} -x mountpoint "${_ds_target}${_relative_name}" + else + zfs send -Lec -p -v "${_name}" | zfs receive ${_opt_nomount} -v -o canmount=off -x mountpoint "${_ds_target}${_relative_name}" + fi + else + # child + if [ "${_relative_name}" = "/usr" ]; then + zfs send -Lec -p -v "${_name}" | zfs receive ${_opt_nomount} -v -o canmount=off -x mountpoint "${_ds_target}${_relative_name}" + else + zfs send -Lec -p -v "${_name}" | zfs receive ${_opt_nomount} -v ${_opt_canmount} -x mountpoint "${_ds_target}${_relative_name}" + fi + fi + fi + done + } + # Need only the filesystem data (no associated snapshots) + echo "Destroying unneeded snapshots ..." + zfs destroy -rv "${_ds_target}@${_snapshot_name}" +} + + # # Global option handling # @@ -746,6 +835,9 @@ snapshot-tmpl) command_snapshot_tmpl "$@" ;; + copy-skel) + command_copy_skel "$@" + ;; configure) echo "ERROR: use \`fjail configure' instead" 1>&2; exit 2
