|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# Licensed to the Apache Software Foundation (ASF) under one |
| 4 | +# or more contributor license agreements. See the NOTICE file |
| 5 | +# distributed with this work for additional information |
| 6 | +# regarding copyright ownership. The ASF licenses this file |
| 7 | +# to you under the Apache License, Version 2.0 (the |
| 8 | +# "License"); you may not use this file except in compliance |
| 9 | +# with the License. You may obtain a copy of the License at |
| 10 | +# |
| 11 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | +# |
| 13 | +# Unless required by applicable law or agreed to in writing, |
| 14 | +# software distributed under the License is distributed on an |
| 15 | +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 16 | +# KIND, either express or implied. See the License for the |
| 17 | +# specific language governing permissions and limitations |
| 18 | +# under the License. |
| 19 | +# |
| 20 | + |
| 21 | +set -e |
| 22 | + |
| 23 | +if [ "$#" -gt 1 ] || { [ "$#" -eq 1 ] && [ "$1" != "-f" ]; }; then |
| 24 | + echo "Usage: $0 [-f]" |
| 25 | + exit 1 |
| 26 | +fi |
| 27 | +if [ "${1:-}" != "-f" ]; then |
| 28 | + read -r -p "Do you want to clean all the data of IoTDB Edge? y/n (default n): " CLEAN_SERVICE || CLEAN_SERVICE="" |
| 29 | + if [[ "$CLEAN_SERVICE" != "y" && "$CLEAN_SERVICE" != "Y" ]]; then |
| 30 | + echo "Exiting..." |
| 31 | + exit 0 |
| 32 | + fi |
| 33 | +fi |
| 34 | + |
| 35 | +IOTDB_HOME="${IOTDB_HOME:-$(cd "$(dirname "$0")"/../.. && pwd)}" |
| 36 | +IOTDB_HOME="$(cd "$IOTDB_HOME" && pwd -P)" |
| 37 | +export IOTDB_HOME |
| 38 | +IOTDB_CONF="${IOTDB_CONF:-$IOTDB_HOME/conf}" |
| 39 | +IOTDB_DATA_HOME="${IOTDB_DATA_HOME:-$IOTDB_HOME}" |
| 40 | +if [ -d "$IOTDB_DATA_HOME" ]; then |
| 41 | + IOTDB_DATA_HOME="$(cd "$IOTDB_DATA_HOME" && pwd -P)" |
| 42 | +fi |
| 43 | + |
| 44 | +if [ ! -f "$IOTDB_HOME/sbin/stop-edge.sh" ]; then |
| 45 | + echo "Cannot find $IOTDB_HOME/sbin/stop-edge.sh. No data has been removed." |
| 46 | + exit 1 |
| 47 | +fi |
| 48 | + |
| 49 | +# Stop the matching service first so Restart=on-failure cannot race with cleanup. |
| 50 | +if command -v systemctl >/dev/null 2>&1 && |
| 51 | + [ "$(systemctl show --property=PIDFile --value iotdb-edge.service 2>/dev/null)" = "$IOTDB_HOME/edge.pid" ]; then |
| 52 | + systemctl stop iotdb-edge |
| 53 | +fi |
| 54 | +bash "$IOTDB_HOME/sbin/stop-edge.sh" -f |
| 55 | + |
| 56 | +if [ -f "$IOTDB_CONF/iotdb-system.properties" ]; then |
| 57 | + CN_CONFIG="$IOTDB_CONF/iotdb-system.properties" |
| 58 | + DN_CONFIG="$CN_CONFIG" |
| 59 | +else |
| 60 | + CN_CONFIG="$IOTDB_CONF/iotdb-confignode.properties" |
| 61 | + DN_CONFIG="$IOTDB_CONF/iotdb-datanode.properties" |
| 62 | +fi |
| 63 | + |
| 64 | +read_property() { |
| 65 | + local config="$1" key="$2" fallback="$3" |
| 66 | + if [ ! -f "$config" ]; then |
| 67 | + printf '%s\n' "$fallback" |
| 68 | + return |
| 69 | + fi |
| 70 | + # Keep spaces and '=' in values; the last active property wins, as in Java. |
| 71 | + awk -v key="$key" -v fallback="$fallback" ' |
| 72 | + { |
| 73 | + separator = index($0, "=") |
| 74 | + if (!separator) next |
| 75 | + name = substr($0, 1, separator - 1) |
| 76 | + gsub(/^[[:space:]]+|[[:space:]]+$/, "", name) |
| 77 | + if (name == key) { |
| 78 | + value = substr($0, separator + 1) |
| 79 | + gsub(/^[[:space:]]+|[[:space:]]+$/, "", value) |
| 80 | + } |
| 81 | + } |
| 82 | + END { print (value == "" ? fallback : value) } |
| 83 | + ' "$config" |
| 84 | +} |
| 85 | + |
| 86 | +CLEAN_PATHS=() |
| 87 | +add_paths() { |
| 88 | + local directories="$1" base="$2" path protected |
| 89 | + local paths=() |
| 90 | + IFS=';,' read -r -a paths <<< "$directories" |
| 91 | + for path in "${paths[@]}"; do |
| 92 | + path="${path#"${path%%[![:space:]]*}"}" |
| 93 | + path="${path%"${path##*[![:space:]]}"}" |
| 94 | + [ -n "$path" ] || continue |
| 95 | + case "$path" in |
| 96 | + *://*|OBJECT_STORAGE) continue ;; |
| 97 | + /*) ;; |
| 98 | + *) path="$base/$path" ;; |
| 99 | + esac |
| 100 | + # Remove a final symlink itself, not its target. Resolve directory aliases |
| 101 | + # before checking them so '..' and symlinked parents cannot hide a root. |
| 102 | + while [[ "$path" != / && "$path" == */ ]]; do path="${path%/}"; done |
| 103 | + if [ -L "$path" ]; then |
| 104 | + path="$(cd -P "$(dirname "$path")" && pwd -P)/$(basename "$path")" |
| 105 | + elif [ -d "$path" ]; then |
| 106 | + path="$(cd -P "$path" && pwd -P)" |
| 107 | + elif [ -e "$path" ]; then |
| 108 | + echo "Refusing to remove a non-directory data path: $path" |
| 109 | + exit 1 |
| 110 | + else |
| 111 | + continue |
| 112 | + fi |
| 113 | + if [ "$path" = / ]; then |
| 114 | + echo "Refusing to remove the filesystem root." |
| 115 | + exit 1 |
| 116 | + fi |
| 117 | + for protected in "$IOTDB_HOME" "$IOTDB_DATA_HOME" "$HOME"; do |
| 118 | + case "$protected/" in |
| 119 | + "$path/"*) |
| 120 | + echo "Refusing to remove a home directory or its parent: $path" |
| 121 | + exit 1 |
| 122 | + ;; |
| 123 | + esac |
| 124 | + done |
| 125 | + CLEAN_PATHS+=("$path") |
| 126 | + done |
| 127 | +} |
| 128 | + |
| 129 | +# The merged process still uses both sets of node directories. Preserve the |
| 130 | +# local destroy-all behavior as well as every custom path from the node tools. |
| 131 | +add_paths "data" "$IOTDB_HOME" |
| 132 | +add_paths "data/datanode" "$IOTDB_DATA_HOME" |
| 133 | +for key in cn_system_dir cn_consensus_dir; do |
| 134 | + case "$key" in |
| 135 | + cn_system_dir) fallback=data/confignode/system ;; |
| 136 | + cn_consensus_dir) fallback=data/confignode/consensus ;; |
| 137 | + esac |
| 138 | + value=$(read_property "$CN_CONFIG" "$key" "$fallback") |
| 139 | + add_paths "$value" "$IOTDB_HOME" |
| 140 | +done |
| 141 | +for key in dn_system_dir dn_data_dirs dn_consensus_dir dn_wal_dirs dn_tracing_dir dn_sync_dir pipe_receiver_file_dirs iot_consensus_v2_receiver_file_dirs sort_tmp_dir; do |
| 142 | + case "$key" in |
| 143 | + dn_system_dir) fallback=data/datanode/system ;; |
| 144 | + dn_data_dirs) fallback=data/datanode/data ;; |
| 145 | + dn_consensus_dir) fallback=data/datanode/consensus ;; |
| 146 | + dn_wal_dirs) fallback=data/datanode/wal ;; |
| 147 | + dn_tracing_dir) fallback=datanode/tracing ;; |
| 148 | + dn_sync_dir) fallback=data/datanode/sync ;; |
| 149 | + pipe_receiver_file_dirs) fallback=data/datanode/system/pipe/receiver ;; |
| 150 | + iot_consensus_v2_receiver_file_dirs) fallback=data/datanode/system/pipe/consensus/receiver ;; |
| 151 | + sort_tmp_dir) fallback=data/datanode/tmp ;; |
| 152 | + esac |
| 153 | + value=$(read_property "$DN_CONFIG" "$key" "$fallback") |
| 154 | + add_paths "$value" "$IOTDB_DATA_HOME" |
| 155 | +done |
| 156 | + |
| 157 | +# Validate every target before deleting any data, and finish before reporting success. |
| 158 | +for path in "${CLEAN_PATHS[@]}"; do |
| 159 | + rm -rf -- "$path" |
| 160 | +done |
| 161 | +echo "IoTDB Edge clean done ..." |
0 commit comments