# HG changeset patch # User Franz Glasner # Date 1662812764 -7200 # Node ID 59e933b81dcf7b0ccbadf6a86ef05e15f54af283 # Parent acf16a85900fa62b8f451487eb45614548839237 First attemt to populate base and skeleton using the "skeleton" subdir and symliks from base to RW skeleton subdirs diff -r acf16a85900f -r 59e933b81dcf sbin/ftjail --- a/sbin/ftjail Sat Sep 10 10:09:42 2022 +0200 +++ b/sbin/ftjail Sat Sep 10 14:26:04 2022 +0200 @@ -50,6 +50,15 @@ Unmount mounted datasets BASE-RO and SKELETON-RW + interlink-tmpl MOUNTPOINT + + Create symbolic links between the RO base and the RW skeleton. + Base and skeleton must be canonically mounted already. + + populate MOUNTPOINT BASETXZ + + Populate the directory in MOUNTPOINT with the base system in BASETXZ + ENVIRONMENT: All environment variables that affect "zfs" are effective also. @@ -228,16 +237,18 @@ # -# "populate" -- populate the datasets with content from a FreeBSD base.txz +# "populate-tmpl" -- populate the datasets with content from a FreeBSD base.txz # -# command_populate mountpoint basetxz +# command_populate_tmpl mountpoint basetxz # -command_populate() { +command_populate_tmpl() { # MOUNTPOINT -- base.txz local _mp _basetxz - _mp="$1" - _basetxz="$2" + local _dir + + _mp="${1-}" + _basetxz="${2-}" if [ -z "${_mp}" ]; then echo "ERROR: no mountpoint given" >&2 @@ -260,19 +271,18 @@ # Handle /var/empty separately later: could be already there and # mounted read-only. # - tar -C "${_mp}" --exclude=./var/empty -xJp -f "${_basetxz}" || { echo "ERROR: tar encountered errors" >&2; return 1; } - if [ -d "${_mp}/var/empty" ]; then - # - # If /var/empty exists already try to extract with changing the - # flags (e.g. `schg'). But be ignore errors here. - # - tar -C "${_mp}" -xJp -f "${_basetxz}" ./var/empty || { echo "tar warnings for handling ./var/empty ignored because ./var/empty exists already" >&2; } - else - # Just extract /var/empty normally - tar -C "${_mp}" -xJp -f "${_basetxz}" ./var/empty || { echo "ERROR: tar encountered errors" >&2; return 1; } - fi + echo "Extracting RO base ..." + tar -C "${_mp}" --exclude=./etc --exclude=./root --exclude=./tmp --exclude=./usr/local --exclude=./var --no-safe-writes -xJp -f "${_basetxz}" || return + # "home" is not part of base + for _dir in etc root tmp usr/local var ; do + echo "Extracting RW skeleton: ${_dir} ..." + tar -C "${_mp}/skeleton" --include="./${_dir}" --exclude=./root/.cshrc --exclude=./root/.profile -xJp -f "${_basetxz}" || return + done + # In the original archive they are archived as hardlinks: make symlinks here + (cd "${_mp}/skeleton/root" && ln -s ../../.profile .profile) || return + (cd "${_mp}/skeleton/root" && ln -s ../../.cshrc .cshrc) || return - find "${_mp}/boot" -type f -delete + find "${_mp}/boot" -type f -delete || true } @@ -465,6 +475,39 @@ # +# "interlink-tmpl" -- create links from base to skeleton +# +# command_interlink_tmpl mountpint +# +command_interlink_tmpl() { + local _mountpoint + + local _dir _dirpart _basepart + + _mountpoint="${1-}" + + [ -z "${_mountpoint}" ] && { echo "ERROR: no mountpoint given" 2>&1; return 2; } + [ -d "${_mountpoint}" ] || { echo "ERROR: mountpoint \`${_mountpoint}' does not exist" 2>&1; return 1; } + [ -d "${_mountpoint}/skeleton" ] || { echo "WARNING: skeleton is not mounted at \`${_mountpoint}/skeleton'" 2>&1; } + + for _dir in etc home root tmp usr/local var ; do + case "${_dir}" in + "usr/local") + _dirpart="$(dirname "${_dir}")" + _basepart="$(basename "${_dir}")" + [ -d "${_mountpoint}/${_dirpart}" ] || mkdir "${_mountpoint}/${_dirpart}" || return + ( cd "${_mountpoint}/${_dirpart}" && ln -s "../skeleton/${_dir}" "${_basepart}" ) || return + ;; + *) + ( cd "${_mountpoint}" && ln -s "skeleton/${_dir}" "${_dir}" ) || return + ;; + esac + done + return 0 +} + + +# # Global option handling # while getopts "Vh" _opt ; do @@ -509,8 +552,11 @@ umount-tmpl|unmount-tmpl) command_umount_tmpl "$@" ;; - populate) - command_populate "$@" + interlink-tmpl) + command_interlink_tmpl "$@" + ;; + populate-tmpl) + command_populate_tmpl "$@" ;; *) echo "ERROR: unknown command \`${command}'" >&2