Skip to content

Commit 2cb4d74

Browse files
authored
Add daemon and cleanup tools for IoTDB Edge (#18552)
1 parent 012ccad commit 2cb4d74

10 files changed

Lines changed: 861 additions & 3 deletions

File tree

‎.github/scripts/test-edge-ops.py‎

Lines changed: 466 additions & 0 deletions
Large diffs are not rendered by default.

‎.github/workflows/edge-it.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ jobs:
6161

6262
steps:
6363
- uses: actions/checkout@v5
64+
- name: Test Edge ops scripts
65+
run: python3 .github/scripts/test-edge-ops.py
6466
- name: Set up JDK
6567
uses: actions/setup-java@v5
6668
with:
@@ -108,6 +110,8 @@ jobs:
108110
runs-on: windows-latest
109111
steps:
110112
- uses: actions/checkout@v5
113+
- name: Test Edge ops scripts
114+
run: python .github/scripts/test-edge-ops.py
111115
- name: Test Edge Windows launchers
112116
shell: powershell
113117
run: .github/scripts/test-edge-windows.ps1

‎distribution/src/assembly/all.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
<excludes>
102102
<exclude>*ainode.*</exclude>
103103
<exclude>**/*ainode.*</exclude>
104+
<exclude>**/*edge.*</exclude>
104105
</excludes>
105106
<fileMode>0755</fileMode>
106107
</fileSet>

‎distribution/src/assembly/datanode.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
<exclude>**/*confignode.*</exclude>
7474
<exclude>**/*all.*</exclude>
7575
<exclude>**/*ainode.*</exclude>
76+
<exclude>**/*edge.*</exclude>
7677
</excludes>
7778
<fileMode>0755</fileMode>
7879
</fileSet>

‎distribution/src/assembly/edge.xml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,17 @@
125125
</excludes>
126126
<fileMode>0755</fileMode>
127127
</fileSet>
128+
<!-- Edge replacements for the standalone node daemon and cleanup tools. -->
129+
<fileSet>
130+
<outputDirectory>tools</outputDirectory>
131+
<directory>${project.basedir}/../scripts/tools</directory>
132+
<includes>
133+
<include>ops/daemon-edge.sh</include>
134+
<include>ops/destroy-edge.sh</include>
135+
<include>windows/ops/destroy-edge.bat</include>
136+
</includes>
137+
<fileMode>0755</fileMode>
138+
</fileSet>
128139
</fileSets>
129140
<files>
130141
<file>

‎iotdb-core/datanode/src/assembly/server.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
<exclude>**/*confignode.*</exclude>
7171
<exclude>**/*all.*</exclude>
7272
<exclude>**/*ainode.*</exclude>
73+
<exclude>**/*edge.*</exclude>
7374
</excludes>
7475
<fileMode>0755</fileMode>
7576
</fileSet>

‎scripts/sbin/windows/stop-edge.bat‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@
1818
@REM under the License.
1919
@REM
2020

21+
setlocal
2122
echo Stopping IoTDB Edge (the merged ConfigNode + DataNode process)
22-
pushd %~dp0\..\..
23+
pushd "%~dp0\..\.."
2324
set "IOTDB_HOME=%cd%"
2425
popd
25-
powershell -NoProfile -Command "$plain='-DIOTDB_HOME=' + $env:IOTDB_HOME; $quoted='-DIOTDB_HOME=' + [char]34 + $env:IOTDB_HOME + [char]34; Get-CimInstance Win32_Process -Filter \"name='java.exe'\" | Where-Object { $line=$_.CommandLine; $sameHome=$line -and ($line.Contains($plain + ' ') -or $line.EndsWith($plain) -or $line.Contains($quoted + ' ') -or $line.EndsWith($quoted)); $sameHome -and $line.Contains('org.apache.iotdb.edge.EdgeNode') } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force; Write-Host ('IoTDB Edge process ' + $_.ProcessId + ' stopped.') }"
26-
pause
26+
powershell -NoProfile -Command "$ErrorActionPreference='Stop'; $plain='-DIOTDB_HOME=' + $env:IOTDB_HOME; $quoted='-DIOTDB_HOME=' + [char]34 + $env:IOTDB_HOME + [char]34; Get-CimInstance Win32_Process -Filter \"name='java.exe'\" | Where-Object { $line=$_.CommandLine; $sameHome=$line -and ($line.Contains($plain + ' ') -or $line.EndsWith($plain) -or $line.Contains($quoted + ' ') -or $line.EndsWith($quoted)); $sameHome -and $line.Contains('org.apache.iotdb.edge.EdgeNode') } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force; Write-Host ('IoTDB Edge process ' + $_.ProcessId + ' stopped.') }"
27+
set "STOP_STATUS=%errorlevel%"
28+
if not "%~1"=="-f" pause
29+
exit /b %STOP_STATUS%

‎scripts/tools/ops/daemon-edge.sh‎

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
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+
IOTDB_HOME="${IOTDB_HOME:-$(cd "$(dirname "$0")"/../.. && pwd)}"
24+
IOTDB_HOME="$(cd "$IOTDB_HOME" && pwd -P)"
25+
export IOTDB_HOME
26+
IOTDB_SBIN_HOME="$IOTDB_HOME/sbin"
27+
SYSTEMD_DIR="${SYSTEMD_DIR:-/etc/systemd/system}"
28+
29+
if [ ! -d "$SYSTEMD_DIR" ] || ! command -v systemctl >/dev/null 2>&1; then
30+
echo "Current system can't support systemd."
31+
exit 1
32+
fi
33+
34+
JAVA=java
35+
if [ -n "$JAVA_HOME" ]; then
36+
JAVA="$JAVA_HOME/bin/java"
37+
if [ -x "$JAVA_HOME/bin/amd64/java" ]; then
38+
JAVA="$JAVA_HOME/bin/amd64/java"
39+
fi
40+
fi
41+
if ! "$JAVA" --version >/dev/null 2>&1; then
42+
echo "Java is not available. Please check JAVA_HOME and PATH."
43+
exit 1
44+
fi
45+
46+
if [ ! -x "$IOTDB_SBIN_HOME/start-edge.sh" ] || [ ! -x "$IOTDB_SBIN_HOME/stop-edge.sh" ]; then
47+
echo "Cannot find the executable Edge start/stop scripts in $IOTDB_SBIN_HOME."
48+
exit 1
49+
fi
50+
51+
# Quote environment values and executable paths using systemd's syntax.
52+
systemd_quote() {
53+
local value="$1"
54+
value="${value//\\/\\\\}"
55+
value="${value//\"/\\\"}"
56+
value="${value//%/%%}"
57+
printf '"%s"' "$value"
58+
}
59+
60+
FILE_NAME="$SYSTEMD_DIR/iotdb-edge.service"
61+
cat > "$FILE_NAME" <<EOF
62+
[Unit]
63+
Description=iotdb-edge
64+
Documentation=https://iotdb.apache.org/
65+
After=network.target
66+
StartLimitIntervalSec=600s
67+
StartLimitBurst=3
68+
69+
[Service]
70+
StandardOutput=null
71+
StandardError=null
72+
LimitNOFILE=65536
73+
# start-edge.sh forks the JVM and records its PID before returning.
74+
Type=forking
75+
PIDFile=${IOTDB_HOME//%/%%}/edge.pid
76+
WorkingDirectory=${IOTDB_HOME//%/%%}
77+
User=root
78+
Group=root
79+
Environment=$(systemd_quote "JAVA_HOME=$JAVA_HOME")
80+
Environment=$(systemd_quote "PATH=${JAVA_HOME:+$JAVA_HOME/bin:}$PATH")
81+
Environment=$(systemd_quote "IOTDB_HOME=$IOTDB_HOME")
82+
Environment=$(systemd_quote "IOTDB_CONF=${IOTDB_CONF:-$IOTDB_HOME/conf}")
83+
Environment=$(systemd_quote "IOTDB_DATA_HOME=${IOTDB_DATA_HOME:-$IOTDB_HOME}")
84+
Environment=$(systemd_quote "IOTDB_LOG_DIR=${IOTDB_LOG_DIR:-$IOTDB_HOME/logs}")
85+
ExecStart=$(systemd_quote "$IOTDB_SBIN_HOME/start-edge.sh")
86+
ExecStop=$(systemd_quote "$IOTDB_SBIN_HOME/stop-edge.sh")
87+
Restart=on-failure
88+
SuccessExitStatus=143
89+
RestartSec=5
90+
RestartPreventExitStatus=SIGKILL
91+
92+
[Install]
93+
WantedBy=multi-user.target
94+
EOF
95+
96+
systemctl daemon-reload
97+
echo "Daemon service of IoTDB Edge has been successfully registered."
98+
echo
99+
echo "Do you want to execute 'systemctl start iotdb-edge'? y/n (default y)"
100+
read -r START_SERVICE || START_SERVICE=""
101+
if [[ -z "$START_SERVICE" || "$START_SERVICE" =~ ^[Yy]$ ]]; then
102+
# Stop both an existing service and a manually started Edge before starting.
103+
systemctl stop iotdb-edge
104+
"$IOTDB_SBIN_HOME/stop-edge.sh"
105+
systemctl start iotdb-edge
106+
echo "Executed successfully."
107+
fi
108+
echo
109+
echo "Do you want to execute 'systemctl enable iotdb-edge' to start at boot? y/n (default y)"
110+
read -r ADD_STARTUP || ADD_STARTUP=""
111+
if [[ -z "$ADD_STARTUP" || "$ADD_STARTUP" =~ ^[Yy]$ ]]; then
112+
systemctl enable iotdb-edge
113+
echo "Executed successfully."
114+
fi

‎scripts/tools/ops/destroy-edge.sh‎

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
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

Comments
 (0)