diff sbin/fjail @ 347:673505e96cea

Implement a "fjail freebsd-update": update "normal" jails and other directories where an OS is mounted
author Franz Glasner <hg@dom66.de>
date Mon, 05 Dec 2022 16:01:54 +0100
parents 3b2935985c73
children c559074302e0
line wrap: on
line diff
--- a/sbin/fjail	Mon Dec 05 09:37:53 2022 +0100
+++ b/sbin/fjail	Mon Dec 05 16:01:54 2022 +0100
@@ -79,6 +79,11 @@
     -r        Copy the datasets with the -Lec options (aka "raw")
     -u        Do not automatically mount received datasets
 
+  freebsd-update [OPTIONS] DIRECTORY OPERATIONS...
+
+    -c CURRENTLY-RUNNING   Assume the systen given in CURRENTLY-RUNNING is
+                           installed/running at given DIRECTORY
+
 ENVIRONMENT:
 
   All environment variables that affect "zfs" are effective also.
@@ -142,6 +147,8 @@
 #:
 #: Args:
 #:   $1: the location where to check for
+#:   $2: an optional reference FreeBSD version to compare to (default is the
+#:       version of the host)
 #:
 #: Returns:
 #:   0 if the userland versions match, 1 otherwise
@@ -150,15 +157,18 @@
 #:   1 on fatal errors (e.g. /bin/freebsd-version not found or errors)
 #:
 _has_same_userland_version() {
-    local directory
+    local directory ref_version
 
-    local _host_version _directory_version
+    local _directory_version
 
     directory="$1"
+    ref_version="${2:-}"
 
-    _host_version=$(/bin/freebsd-version -u) || exit 1
+    if [ -z "${ref_version}" ]; then
+        ref_version=$(/bin/freebsd-version -u) || exit 1
+    fi
     _directory_version=$(chroot "${directory}" /bin/freebsd-version -u) || exit 1
-    if [ "${_host_version%%-*}" = "${_directory_version%%-*}" ]; then
+    if [ "${ref_version%%-*}" = "${_directory_version%%-*}" ]; then
         return 0
     fi
     return 1
@@ -599,6 +609,49 @@
 }
 
 
+#:
+#: Implement the "freebsd-update" command
+#:
+command_freebsd_update() {
+    local directory operations
+
+    local opt_currently_running
+
+    opt_currently_running=""
+    while getopts "c:" _opt ; do
+        case ${_opt} in
+            c)
+                opt_currently_running="$OPTARG"
+                ;;
+            \?|:)
+                return 2;
+                ;;
+        esac
+    done
+    shift $((OPTIND-1))
+    OPTIND=1
+
+    directory="${1-}"
+
+    [ -z "${directory}" ] && { echo "ERROR: no directory given" 1>&2; return 2; }
+    [ -d "${directory}" ] || { echo "ERROR: directory \`${directory}' does not exist" 1>&2; return 1; }
+
+    shift
+    operations="$@"
+
+    if _has_same_userland_version "${directory}" "${opt_currently_running}" ; then
+        if [ -n "${opt_currently_running}" ]; then
+            freebsd-update -b "${directory}" --currently-running "${opt_currently_running}" ${operations}
+        else
+            freebsd-update -b "${directory}" ${operations}
+        fi
+    else
+        echo "ERROR: Userland version mismatch" 1>&2
+        return 1
+    fi
+}
+
+
 #
 # Global option handling
 #
@@ -659,6 +712,9 @@
     copy)
         command_copy "$@"
         ;;
+    freebsd-update)
+        command_freebsd_update "$@"
+        ;;
     *)
         echo "ERROR: unknown command \`${command}'" >&2
         exit 2