Repository navigation
Expand file tree
/
Copy pathinstall.sh
More file actions
198 lines (176 loc) · 6.6 KB
/
Copy pathinstall.sh
File metadata and controls
198 lines (176 loc) · 6.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#!/usr/bin/env bash
# thingboot-cloud-node 一键安装脚本(Linux)
#
# 用法:
# curl -fsSL https://github.com/ThingBoot/thingboot-cloud-node/releases/latest/download/install.sh | sudo bash
# bash install.sh v1.2.3 # 安装指定版本
# bash install.sh uninstall # 卸载
#
# 可配置环境变量(自建镜像时只需覆盖下载地址):
# THINGBOOT_DOWNLOAD_BASE 下载根地址,默认 GitHub Releases
# THINGBOOT_INSTALL_DIR 安装目录,默认 /opt/thingboot
# THINGBOOT_SKIP_SHA256=1 跳过 sha256 校验(镜像不提供校验文件时)
# THINGBOOT_PURGE=1 卸载时不询问,直接删除安装目录(含配置与数据)
set -euo pipefail
# ===== 可配置变量 =====
GITHUB_REPO="ThingBoot/thingboot-cloud-node"
DOWNLOAD_BASE="${THINGBOOT_DOWNLOAD_BASE:-https://github.com/${GITHUB_REPO}/releases/download}"
LATEST_BASE="https://github.com/${GITHUB_REPO}/releases/latest/download"
INSTALL_DIR="${THINGBOOT_INSTALL_DIR:-/opt/thingboot}"
SERVICE_NAME="thingboot"
RUN_USER="thingboot"
WEB_PORT=8899
log() { echo ">> $*"; }
warn() { echo "!! $*" >&2; }
die() { echo "xx $*" >&2; exit 1; }
# ===== 下载工具:curl 优先,wget 兜底 =====
fetch() {
# fetch <url> <输出文件>
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$1" -o "$2"
elif command -v wget >/dev/null 2>&1; then
wget -qO "$2" "$1"
else
die "需要 curl 或 wget,请先安装其中之一"
fi
}
# ===== 卸载 =====
do_uninstall() {
[ "$(id -u)" -eq 0 ] || die "卸载需要 root 权限,请使用 sudo"
log "停止并禁用服务 $SERVICE_NAME"
systemctl disable --now ${SERVICE_NAME}.service 2>/dev/null || true
rm -f /etc/systemd/system/${SERVICE_NAME}.service
systemctl daemon-reload
if [ "${THINGBOOT_PURGE:-}" = "1" ]; then
rm -rf "$INSTALL_DIR"
log "已删除 $INSTALL_DIR(含配置与数据)"
elif [ -d "$INSTALL_DIR" ]; then
local ans=""
if [ -t 0 ]; then
read -r -p "是否删除 $INSTALL_DIR(含配置与数据)?保留请输入 n [y/N] " ans || true
fi
case "$ans" in
y|Y|yes|YES)
rm -rf "$INSTALL_DIR"
log "已删除 $INSTALL_DIR"
;;
*)
log "已保留 $INSTALL_DIR(配置与数据未动)"
;;
esac
fi
log "卸载完成(运行用户 $RUN_USER 未删除,如需清理: userdel $RUN_USER)"
}
# ===== 参数 =====
ACTION="install"
VERSION=""
case "${1:-}" in
uninstall) ACTION="uninstall" ;;
v*|[0-9]*) VERSION="${1#v}" ;;
"") ;;
*) die "未知参数: $1(用法: bash install.sh [vX.Y.Z|uninstall])" ;;
esac
if [ "$ACTION" = "uninstall" ]; then
do_uninstall
exit 0
fi
# ===== 安装前置检查 =====
[ "$(id -u)" -eq 0 ] || die "安装需要 root 权限,请使用 sudo"
[ "$(uname -s)" = "Linux" ] || die "本脚本仅支持 Linux,Windows 请下载 zip 包解压运行"
ARCH="$(uname -m)"
case "$ARCH" in
x86_64) GOARCH="amd64" ;;
aarch64) GOARCH="arm64" ;;
*) die "不支持的架构: $ARCH(仅支持 x86_64 / aarch64)" ;;
esac
# ===== 解析版本(未指定时取 latest) =====
if [ -z "$VERSION" ]; then
if [ -z "${THINGBOOT_DOWNLOAD_BASE:-}" ]; then
log "查询最新版本..."
TMP_VER="$(mktemp)"
fetch "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" "$TMP_VER" \
|| die "查询最新版本失败,可改用: bash install.sh vX.Y.Z 指定版本"
VERSION="$(grep -o '"tag_name"[[:space:]]*:[[:space:]]*"v[^"]*"' "$TMP_VER" | head -1 | grep -o '[0-9][0-9.]*')"
rm -f "$TMP_VER"
[ -n "$VERSION" ] || die "解析最新版本失败,可改用: bash install.sh vX.Y.Z 指定版本"
else
die "使用自建镜像 THINGBOOT_DOWNLOAD_BASE 时必须指定版本: bash install.sh vX.Y.Z"
fi
fi
log "版本: v$VERSION 架构: linux/$GOARCH"
PKG="thingboot-cloud-node_${VERSION}_linux_${GOARCH}.tar.gz"
if [ -n "${THINGBOOT_DOWNLOAD_BASE:-}" ] || [ -n "${1:-}" ]; then
# 自建镜像或钉版本:走 download/v<版本>/ 路径
PKG_URL="${DOWNLOAD_BASE}/v${VERSION}/${PKG}"
SUMS_URL="${DOWNLOAD_BASE}/v${VERSION}/sha256sums.txt"
else
# 默认:GitHub Releases latest
PKG_URL="${LATEST_BASE}/${PKG}"
SUMS_URL="${LATEST_BASE}/sha256sums.txt"
fi
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
log "下载 $PKG_URL"
fetch "$PKG_URL" "$TMP/$PKG" || die "下载失败,请检查版本号与网络"
# ===== sha256 校验 =====
if [ "${THINGBOOT_SKIP_SHA256:-}" = "1" ]; then
warn "已跳过 sha256 校验(THINGBOOT_SKIP_SHA256=1)"
else
fetch "$SUMS_URL" "$TMP/sha256sums.txt" || die "下载 sha256sums.txt 失败(可用 THINGBOOT_SKIP_SHA256=1 跳过校验)"
(cd "$TMP" && grep " $PKG\$" sha256sums.txt | sha256sum -c -) \
|| die "sha256 校验失败,安装中止"
log "sha256 校验通过"
fi
# ===== 解压安装 =====
WAS_ACTIVE=0
systemctl is-active --quiet ${SERVICE_NAME}.service 2>/dev/null && WAS_ACTIVE=1 || true
log "安装到 $INSTALL_DIR"
mkdir -p "$INSTALL_DIR"
tar -xzf "$TMP/$PKG" -C "$INSTALL_DIR"
chmod +x "$INSTALL_DIR/thingboot"
# ===== 独立运行用户 + 443 特权端口授权 =====
if ! id "$RUN_USER" >/dev/null 2>&1; then
useradd --system --no-create-home --shell /usr/sbin/nologin "$RUN_USER"
log "已创建运行用户 $RUN_USER"
fi
# 允许绑定 443 等特权端口(无需 root 运行)
setcap 'cap_net_bind_service=+ep' "$INSTALL_DIR/thingboot" || \
warn "setcap 失败:如不需绑定 443 可忽略,否则请手动执行: setcap 'cap_net_bind_service=+ep' $INSTALL_DIR/thingboot"
chown -R "$RUN_USER:$RUN_USER" "$INSTALL_DIR"
# ===== systemd unit =====
log "注册 systemd 服务 $SERVICE_NAME"
cat > /etc/systemd/system/${SERVICE_NAME}.service <<EOF
[Unit]
Description=thingboot-cloud-node (IoT server middleware)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=$RUN_USER
Group=$RUN_USER
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/thingboot -config $INSTALL_DIR/configs/config.yaml serve
Restart=always
RestartSec=3
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
if [ "$WAS_ACTIVE" = "1" ]; then
systemctl restart ${SERVICE_NAME}.service
log "服务已重启(升级完成)"
else
systemctl enable --now ${SERVICE_NAME}.service
fi
# ===== 完成提示 =====
IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
IP="${IP:-<本机IP>}"
echo
log "安装完成。"
echo " Web 管理界面: http://${IP}:${WEB_PORT}"
echo " 首次启动的随机管理员密码(只在日志出现一次):"
echo " journalctl -u $SERVICE_NAME -n 50"
echo " 或查看 $INSTALL_DIR/logs/ 下的日志文件"
echo " 体检: $INSTALL_DIR/thingboot doctor"
echo " 卸载: bash install.sh uninstall"