#! /usr/bin/env bash SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) USER_HOME=$HOME [[ -n "${SUDO_USER}" ]] && USER_HOME="$(eval "echo ~${SUDO_USER}")" . ${SHRC_D:-$SCRIPT_DIR}/01_util.functions set -e JSON=0 if [[ $# -gt 0 && "$1" =~ ^-- ]]; then if [[ "$1" == "--help" ]]; then cat < sudo ./$(basename $0) [] NOTE: DBG=' ' will add debug output without ZFS_DO=' ' zfs operations will not happen. Description: a simple match pattern, that will list any matching pvc names Must match a unique pvc name, most commonly these are -config or -data.   zfs path to the dataset contianing the restore data (optional) default value for this is: \${ZFS_POOL\}/backup/tmp-\${APP_NAME\}-\${PVC\} available variables are: NAME,APP_NAME,PVC,ZFS_POOL Examples: List all PVCs ending with either '-data' or '-config': sudo ./$(basename $0) '-(data|config)$' Replace gitea-data's pvc with the one stored in tank/backup/gitea/pvc-backup preserving the current gitea-data pvc in the default location: tank/backup/tmp-gitea-data-pvc-... : sudo ./$(basename $0) 'gitea-data' 'tank/backup/gitea/pvc-backup' USAGE exit 0 elif [[ "$1" == "--json" ]]; then JSON=1 fi shift fi require_root PVCS="$( k3s kubectl get persistentvolume --output json \ | jq ' .items[] | select( .spec.claimRef.name | test("'"${1}"'") ) | { name: .spec.claimRef.name ,app: .spec.claimRef.namespace | sub("ix-"; "") ,pvc: .spec.csi.volumeHandle ,zfs_pvc: "\( .spec.csi.volumeAttributes."openebs.io/poolname" )/\( .spec.csi.volumeHandle )" ,zfs_pool: .spec.csi.volumeAttributes."openebs.io/poolname" | split("/")[0] #,raw: . } ' )" DISPLAY_ONLY=0 LEN="$(jq -s 'length' <<<"$PVCS")" if [[ $# -eq 1 || "$LEN" -ne 1 ]]; then DISPLAY_ONLY=1 fi if [[ "$LEN" -eq 0 ]]; then PVCS='"ERROR: EMPTY query results"' fi if [[ "${DISPLAY_ONLY}" != 0 ]]; then jq -r <<<"$PVCS" exit 0 fi ENV="$( <<<"$PVCS" jq -r "[ \"NAME='\(.name)'\" ,\"APP_NAME='\(.app)'\" ,\"PVC='\(.pvc)'\" ,\"ZFS_PVC='\(.zfs_pvc)'\" ,\"ZFS_POOL='\(.zfs_pool)'\" ] | join (\"\n\") " )" ${DBG:-:} echo "$ENV" 1>&2 eval $ENV TMP_DEST="${3:-\${ZFS_POOL\}/backup/tmp-\${APP_NAME\}-\${PVC\}}" ${DBG:-:} echo "$TMP_DEST" 1>&2 eval "TMP_DEST=\"${TMP_DEST}\"" ${DBG:-:} echo "$TMP_DEST" 1>&2 if [[ -z "$(type -fp zfs)" ]]; then printf "ERROR: zfs is not a valid command (is your PATH correct?)\n" 1>&2 exit 2 fi VALIDATE=() zfs list -Ho name "$ZFS_PVC" >/dev/null 2>&1 || VALIDATE=( "${VALIDATE[@]}" "ZFS_PVC '$ZFS_PVC' cannot be found") zfs list -Ho name "${2}" >/dev/null 2>&1 || VALIDATE=( "${VALIDATE[@]}" "Restore source '${2}' cannot be found") || true zfs list -Ho name "${TMP_DEST%/*}" >/dev/null 2>&1 || VALIDATE=( "${VALIDATE[@]}" "Parent of temp-dset '${TMP_DEST%/*}' cannot be found") zfs list -Ho name "$TMP_DEST" >/dev/null 2>&1 && VALIDATE=( "${VALIDATE[@]}" "Temp dest '${TMP_DEST}' already exists") || true if [[ ${#VALIDATE[@]} -ne 0 ]]; then ${DBG:-:} echo "" 1>&2 printf 'ERROR: %s\n' "${VALIDATE[@]}" 1>&2 exit 1 fi printf '%s\n' \ "Performing the following actions:" \ " zfs rename '$ZFS_PVC' '${TMP_DEST}'" \ " zfs rename '${2}' '$ZFS_PVC'" \ '' '' \ 'To revert these changes manualy run:' \ " sudo zfs rename '$ZFS_PVC' '${2}' " \ " sudo zfs rename '${TMP_DEST}' '$ZFS_PVC' " \ '' '' ${ZFS_DO:-:} zfs rename "$ZFS_PVC" "${TMP_DEST}" ${ZFS_DO:-:} zfs rename "${2}" "$ZFS_PVC"