Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
comparison sbin/ftjail @ 334:fdbb78c54ffb
Begin the "ftjail freebsd-update" command
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Fri, 02 Dec 2022 09:36:57 +0100 |
| parents | 8dbd11726ee5 |
| children | a423bc0e2a3f |
comparison
equal
deleted
inserted
replaced
| 333:ebf6c8863d9b | 334:fdbb78c54ffb |
|---|---|
| 98 return 0 | 98 return 0 |
| 99 fi | 99 fi |
| 100 done | 100 done |
| 101 return 1 | 101 return 1 |
| 102 } | 102 } |
| 103 } | |
| 104 | |
| 105 | |
| 106 #: | |
| 107 #: Search for a running jail where it's "path" points to a given location | |
| 108 #: | |
| 109 #: Args: | |
| 110 #: $1: the location to search for | |
| 111 #: | |
| 112 #: Output (stdout): | |
| 113 #: The name if the jail with a "path" that is equal to the input param. | |
| 114 #: Nothing if a jail is not found. | |
| 115 #: | |
| 116 #: Return: | |
| 117 #: - 0: if a running jail is found | |
| 118 #: - 1: error | |
| 119 #: - 2: no running jail found | |
| 120 #: - 3: jail found but currently dying | |
| 121 #: | |
| 122 _get_jail_from_path() { | |
| 123 local _location | |
| 124 | |
| 125 local _name _path _dying | |
| 126 | |
| 127 _location="${1-}" | |
| 128 [ -z "${_location}" ] && { echo "ERROR: no mountpoint given" 1>&2; return 1; } | |
| 129 | |
| 130 | |
| 131 jls -d name path dying \ | |
| 132 | { | |
| 133 while IFS=' '$'\t' read -r _name _path _dying ; do | |
| 134 if [ "${_path}" = "${_location}" ]; then | |
| 135 if [ "${_dying}" != "false" ]; then | |
| 136 echo "Jail \`${_name}' is currently dying" 1>&2 | |
| 137 return 3 | |
| 138 fi | |
| 139 echo "${_name}" | |
| 140 return 0 | |
| 141 fi | |
| 142 done | |
| 143 return 2 | |
| 144 } | |
| 145 } | |
| 146 | |
| 147 | |
| 148 #: | |
| 149 #: Search for mounts and sub-mounts at a given directory. | |
| 150 #: | |
| 151 #: The output is sorted by the mountpoint. | |
| 152 #: | |
| 153 #: Args: | |
| 154 #: $1: the directory where to start for mounts and sub-mounts | |
| 155 #: | |
| 156 #: Output (stdout): | |
| 157 #: The sorted list (lines) of mounts in :manpage:`fstab(5)` format. | |
| 158 #: This list may be empty. | |
| 159 #: | |
| 160 #: Exit: | |
| 161 #: 1: on fatal errors (usage et al.) | |
| 162 #: | |
| 163 #: Important: | |
| 164 #: The input directory **must** be an absolute path. | |
| 165 #: | |
| 166 _get_mounts_at_directory() { | |
| 167 local _directory | |
| 168 | |
| 169 local _fstab | |
| 170 | |
| 171 _directory=${1-} | |
| 172 case "${_directory}" in | |
| 173 /*) | |
| 174 : | |
| 175 ;; | |
| 176 '') | |
| 177 echo "ERROR: no directory given" 1>&2; | |
| 178 exit 1; | |
| 179 ;; | |
| 180 *) | |
| 181 echo "ERROR: directory must be an absolute path" 1>&2; | |
| 182 exit 1; | |
| 183 ;; | |
| 184 esac | |
| 185 _fstab="$(mount -p | grep -E '\s'"${_directory}" | sort -k3)" | |
| 186 echo "${_fstab}" | |
| 103 } | 187 } |
| 104 | 188 |
| 105 | 189 |
| 106 # | 190 # |
| 107 # PARENT-BASE NAME DRY-RUN | 191 # PARENT-BASE NAME DRY-RUN |
| 785 return 1 | 869 return 1 |
| 786 fi | 870 fi |
| 787 } | 871 } |
| 788 | 872 |
| 789 | 873 |
| 874 #: | |
| 875 #: Implement the "freebsd-update" command for a thin jail | |
| 876 #: | |
| 877 command_freebsd_update() { | |
| 878 local _directory | |
| 879 | |
| 880 local _res _jailname _dir_mounts _dir_fn_fstab _dir_basename | |
| 881 local _root_dataset _root_mountpoint _root_type _root_options | |
| 882 local _dummy | |
| 883 local _root_readonly | |
| 884 | |
| 885 _directory="${1-}" | |
| 886 | |
| 887 [ -z "${_directory}" ] && { echo "ERROR: no directory given" 1>&2; return 2; } | |
| 888 [ -d "${_directory}" ] || { echo "ERROR: directory \`${_directory}' does not exist" 1>&2; exit 1; } | |
| 889 | |
| 890 _dir_basename="$(basename ${_directory})" | |
| 891 | |
| 892 set +e | |
| 893 _jailname=$(_get_jail_from_path "${_directory}")ยด | |
| 894 _res=$? | |
| 895 set -e | |
| 896 if [ ${_res} -ne 2 ] ; then | |
| 897 if [ ${_res} -ne 0 ] ; then | |
| 898 exit ${_res} | |
| 899 else | |
| 900 echo "ERROR: Please stop the \`${_jailname}' jail" >&2 | |
| 901 exit 1 | |
| 902 fi | |
| 903 fi | |
| 904 _dir_mounts="$(_get_mounts_at_directory "${_directory}")" | |
| 905 | |
| 906 # | |
| 907 # Check preconditions thoroughly! | |
| 908 # | |
| 909 # Check that the first item/line is a read-only ZFS mount directly | |
| 910 # at the given directory. | |
| 911 # Also check that it is a clone proper. | |
| 912 # | |
| 913 IFS=' '$'\t' read -r _root_dataset _root_mountpoint _root_type _root_options _dummy <<EOF4tHGCSS | |
| 914 ${_dir_mounts} | |
| 915 EOF4tHGCSS | |
| 916 [ "${_root_mountpoint}" != "${_directory}" ] && { echo "ERROR: found root mountpoint does not match given directory" 1>&2; exit 1; } | |
| 917 [ "${_root_type}" != "zfs" ] && { echo "ERROR: root mountpoint is not from a ZFS dataset" 1>&2; exit 1; } | |
| 918 _root_readonly="$(zfs list -H -o readonly "${_root_dataset}")" | |
| 919 [ "${_root_readonly}" != "on" ] && { echo "ERROR: the root dataset is not mounted read-only" 1>&2; exit 1; } | |
| 920 # XXX TBD: Check that it is a proper clone | |
| 921 | |
| 922 # | |
| 923 # XXX FIXME: should we check that _root_options equals "ro" or | |
| 924 # start with "ro," | |
| 925 # | |
| 926 _dir_fn_fstab="$(env TMPDIR=/var/tmp mktemp -t ftjail-fstab.${_dir_basename})" | |
| 927 echo -n "${_dir_mounts}" >>"${_dir_fn_fstab}" | |
| 928 | |
| 929 # Unmount in reverse order: unmount can do it for us | |
| 930 umount -a -F "${_dir_fn_fstab}" -v || exit 1 | |
| 931 | |
| 932 # | |
| 933 # XXX TBD: Hooks to create some new top-level dirs (/srv /proc et | |
| 934 # al.) if needed: clone RW, mount, make the dirs, | |
| 935 # umount, make the clone RO and continue "normally" by | |
| 936 # completely mounting the stored fstab. | |
| 937 # | |
| 938 } | |
| 939 | |
| 940 | |
| 790 # | 941 # |
| 791 # Global option handling | 942 # Global option handling |
| 792 # | 943 # |
| 793 while getopts "Vh" _opt ; do | 944 while getopts "Vh" _opt ; do |
| 794 case ${_opt} in | 945 case ${_opt} in |
| 849 ;; | 1000 ;; |
| 850 configure) | 1001 configure) |
| 851 echo "ERROR: use \`fjail configure' instead" 1>&2; | 1002 echo "ERROR: use \`fjail configure' instead" 1>&2; |
| 852 exit 2 | 1003 exit 2 |
| 853 ;; | 1004 ;; |
| 1005 freebsd-update) | |
| 1006 command_freebsd_update "$@" | |
| 1007 ;; | |
| 854 *) | 1008 *) |
| 855 echo "ERROR: unknown command \`${command}'" 1>&2 | 1009 echo "ERROR: unknown command \`${command}'" 1>&2 |
| 856 exit 2 | 1010 exit 2 |
| 857 ;; | 1011 ;; |
| 858 esac | 1012 esac |
